mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-13 16:22:43 +10:00
Compare commits
7 Commits
cloud-save
...
dev-v0.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b443818d1 | |||
| fa4a881cc0 | |||
| 4f16a6e6b2 | |||
| 47d9e9949b | |||
| a643d6102b | |||
| a71ff160c2 | |||
| a53a566792 |
68
.github/workflows/release.yml
vendored
Normal file
68
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
name: 'publish'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch: {}
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
# This can be used to automatically publish nightlies at UTC nighttime
|
||||||
|
# schedule:
|
||||||
|
# - cron: "0 2 * * *" # run at 2 AM UTC
|
||||||
|
|
||||||
|
# This workflow will trigger on each push to the `release` branch to create or update a GitHub release, build your app, and upload the artifacts to the release.
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-tauri:
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: 'macos-latest' # for Arm based macs (M1 and above).
|
||||||
|
args: '--target aarch64-apple-darwin'
|
||||||
|
- platform: 'macos-latest' # for Intel based macs.
|
||||||
|
args: '--target x86_64-apple-darwin'
|
||||||
|
- platform: 'ubuntu-22.04' # for Tauri v1 you could replace this with ubuntu-20.04.
|
||||||
|
args: ''
|
||||||
|
- platform: 'windows-latest'
|
||||||
|
args: ''
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: setup node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
|
||||||
|
- name: install Rust nightly
|
||||||
|
uses: dtolnay/rust-toolchain@nightly
|
||||||
|
with:
|
||||||
|
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
|
||||||
|
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
||||||
|
|
||||||
|
- name: install dependencies (ubuntu only)
|
||||||
|
if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above.
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
||||||
|
# webkitgtk 4.0 is for Tauri v1 - webkitgtk 4.1 is for Tauri v2.
|
||||||
|
# You can remove the one that doesn't apply to your app to speed up the workflow a bit.
|
||||||
|
|
||||||
|
- name: install frontend dependencies
|
||||||
|
run: yarn install # change this to npm, pnpm or bun depending on which one you use.
|
||||||
|
|
||||||
|
- uses: tauri-apps/tauri-action@v0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tagName: dev-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version.
|
||||||
|
releaseName: 'Auto-release v__VERSION__'
|
||||||
|
releaseBody: 'See the assets to download this version and install. This release was created automatically.'
|
||||||
|
releaseDraft: false
|
||||||
|
prerelease: true
|
||||||
|
args: ${{ matrix.args }}
|
||||||
@ -99,11 +99,6 @@ function navigate(close: () => any, to: NavigationItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const navigation: NavigationItem[] = [
|
const navigation: NavigationItem[] = [
|
||||||
{
|
|
||||||
label: "Account settings",
|
|
||||||
route: "/account",
|
|
||||||
prefix: "",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "App settings",
|
label: "App settings",
|
||||||
route: "/settings",
|
route: "/settings",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "drop-app",
|
"name": "drop-app",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.2.0-beta",
|
"version": "0.3.0-rc-1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="mx-auto max-w-7xl px-8">
|
|
||||||
<div class="border-b border-zinc-700 py-5">
|
|
||||||
<h3 class="text-base font-semibold font-display leading-6 text-zinc-100">
|
|
||||||
Account
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-5">
|
|
||||||
<div class="divide-y divide-zinc-700">
|
|
||||||
<div class="py-6">
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
<div class="flex flex-row items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<h3 class="text-sm font-medium leading-6 text-zinc-100">Sign out</h3>
|
|
||||||
<p class="mt-1 text-sm leading-6 text-zinc-400">
|
|
||||||
Sign out of your Drop account on this device
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
@click="signOut"
|
|
||||||
type="button"
|
|
||||||
class="rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600"
|
|
||||||
>
|
|
||||||
Sign out
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="error" class="rounded-md bg-red-600/10 p-4">
|
|
||||||
<div class="flex">
|
|
||||||
<div class="flex-shrink-0">
|
|
||||||
<XCircleIcon class="h-5 w-5 text-red-600" aria-hidden="true" />
|
|
||||||
</div>
|
|
||||||
<div class="ml-3">
|
|
||||||
<h3 class="text-sm font-medium text-red-600">
|
|
||||||
{{ error }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
|
||||||
import { listen } from '@tauri-apps/api/event'
|
|
||||||
import { useRouter } from '#imports'
|
|
||||||
import { XCircleIcon } from "@heroicons/vue/16/solid";
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const error = ref<string | null>(null)
|
|
||||||
|
|
||||||
// Listen for auth events
|
|
||||||
onMounted(async () => {
|
|
||||||
await listen('auth/signedout', () => {
|
|
||||||
router.push('/auth/signedout')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
async function signOut() {
|
|
||||||
try {
|
|
||||||
error.value = null
|
|
||||||
await invoke('sign_out')
|
|
||||||
} catch (e) {
|
|
||||||
error.value = `Failed to sign out: ${e}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -156,9 +156,9 @@
|
|||||||
<template #default>
|
<template #default>
|
||||||
<div class="sm:flex sm:items-start">
|
<div class="sm:flex sm:items-start">
|
||||||
<div class="mt-3 text-center sm:mt-0 sm:text-left">
|
<div class="mt-3 text-center sm:mt-0 sm:text-left">
|
||||||
<DialogTitle as="h3" class="text-base font-semibold text-zinc-100"
|
<h3 class="text-base font-semibold text-zinc-100"
|
||||||
>Install {{ game.mName }}?
|
>Install {{ game.mName }}?
|
||||||
</DialogTitle>
|
</h3>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<p class="text-sm text-zinc-400">
|
<p class="text-sm text-zinc-400">
|
||||||
Drop will add {{ game.mName }} to the queue to be downloaded.
|
Drop will add {{ game.mName }} to the queue to be downloaded.
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import type { Component } from "vue";
|
|||||||
import type { NavigationItem } from "~/types";
|
import type { NavigationItem } from "~/types";
|
||||||
import { platform } from '@tauri-apps/plugin-os';
|
import { platform } from '@tauri-apps/plugin-os';
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
import { UserIcon } from "@heroicons/vue/20/solid";
|
||||||
|
|
||||||
const systemData = await invoke<{
|
const systemData = await invoke<{
|
||||||
clientId: string;
|
clientId: string;
|
||||||
@ -101,6 +102,12 @@ const navigation = computed(() => [
|
|||||||
prefix: "/settings/downloads",
|
prefix: "/settings/downloads",
|
||||||
icon: ArrowDownTrayIcon,
|
icon: ArrowDownTrayIcon,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Account",
|
||||||
|
route: "/settings/account",
|
||||||
|
prefix: "/settings/account",
|
||||||
|
icon: UserIcon
|
||||||
|
},
|
||||||
...(isDebugMode.value ? [{
|
...(isDebugMode.value ? [{
|
||||||
label: "Debug Info",
|
label: "Debug Info",
|
||||||
route: "/settings/debug",
|
route: "/settings/debug",
|
||||||
|
|||||||
64
pages/settings/account.vue
Normal file
64
pages/settings/account.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div class="border-b border-zinc-700 py-5">
|
||||||
|
<h3 class="text-base font-semibold font-display leading-6 text-zinc-100">
|
||||||
|
General
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-5 flex flex-col gap-4">
|
||||||
|
<div class="flex flex-row items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="text-sm font-medium leading-6 text-zinc-100">Sign out</h3>
|
||||||
|
<p class="mt-1 text-sm leading-6 text-zinc-400">
|
||||||
|
Sign out of your Drop account on this device
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
@click="signOut"
|
||||||
|
type="button"
|
||||||
|
class="rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600"
|
||||||
|
>
|
||||||
|
Sign out
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="error" class="rounded-md bg-red-600/10 p-4">
|
||||||
|
<div class="flex">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<XCircleIcon class="h-5 w-5 text-red-600" aria-hidden="true" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-3">
|
||||||
|
<h3 class="text-sm font-medium text-red-600">
|
||||||
|
{{ error }}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
import { listen } from "@tauri-apps/api/event";
|
||||||
|
import { useRouter } from "#imports";
|
||||||
|
import { XCircleIcon } from "@heroicons/vue/16/solid";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const error = ref<string | null>(null);
|
||||||
|
|
||||||
|
// Listen for auth events
|
||||||
|
onMounted(async () => {
|
||||||
|
await listen("auth/signedout", () => {
|
||||||
|
router.push("/auth/signedout");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async function signOut() {
|
||||||
|
try {
|
||||||
|
error.value = null;
|
||||||
|
await invoke("sign_out");
|
||||||
|
} catch (e) {
|
||||||
|
error.value = `Failed to sign out: ${e}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -1,8 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="border-b border-zinc-700 py-5">
|
||||||
<div class="border-b border-zinc-600 py-2 px-1">
|
<h3 class="text-base font-semibold font-display leading-6 text-zinc-100">
|
||||||
|
Downloads
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<div class="border-b border-zinc-600">
|
||||||
<div class="-ml-4 -mt-2 flex flex-wrap items-center justify-between sm:flex-nowrap">
|
<div class="-ml-4 -mt-2 flex flex-wrap items-center justify-between sm:flex-nowrap">
|
||||||
<div class="ml-4 mt-2">
|
<div class="ml-4 mt-2 pb-4">
|
||||||
<h3 class="text-base font-display font-semibold text-zinc-100">
|
<h3 class="text-base font-display font-semibold text-zinc-100">
|
||||||
Install directories
|
Install directories
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
@ -1,60 +1,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="divide-y divide-zinc-700">
|
<div class="border-b border-zinc-700 py-5">
|
||||||
<div class="py-6">
|
<h3 class="text-base font-semibold font-display leading-6 text-zinc-100">
|
||||||
<h2 class="text-base font-semibold font-display leading-7 text-zinc-100">General</h2>
|
General
|
||||||
<p class="mt-1 text-sm leading-6 text-zinc-400">
|
</h3>
|
||||||
Configure basic application settings
|
</div>
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="mt-10 space-y-8">
|
<div class="mt-5 space-y-8">
|
||||||
<div class="flex flex-row items-center justify-between">
|
<div class="flex flex-row items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-medium leading-6 text-zinc-100">Start with system</h3>
|
<h3 class="text-sm font-medium leading-6 text-zinc-100">
|
||||||
<p class="mt-1 text-sm leading-6 text-zinc-400">
|
Start with system
|
||||||
Drop will automatically start when you log into your computer
|
</h3>
|
||||||
</p>
|
<p class="mt-1 text-sm leading-6 text-zinc-400">
|
||||||
</div>
|
Drop will automatically start when you log into your computer
|
||||||
<Switch
|
</p>
|
||||||
v-model="autostartEnabled"
|
</div>
|
||||||
:class="[
|
<Switch
|
||||||
autostartEnabled ? 'bg-blue-600' : 'bg-zinc-700',
|
v-model="autostartEnabled"
|
||||||
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out'
|
:class="[
|
||||||
]"
|
autostartEnabled ? 'bg-blue-600' : 'bg-zinc-700',
|
||||||
>
|
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out',
|
||||||
<span
|
]"
|
||||||
:class="[
|
>
|
||||||
autostartEnabled ? 'translate-x-5' : 'translate-x-0',
|
<span
|
||||||
'pointer-events-none relative inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out'
|
:class="[
|
||||||
]"
|
autostartEnabled ? 'translate-x-5' : 'translate-x-0',
|
||||||
/>
|
'pointer-events-none relative inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out',
|
||||||
</Switch>
|
]"
|
||||||
</div>
|
/>
|
||||||
</div>
|
</Switch>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Switch } from '@headlessui/vue'
|
import { Switch } from "@headlessui/vue";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
|
||||||
defineProps<{}>()
|
defineProps<{}>();
|
||||||
|
|
||||||
const autostartEnabled = ref<boolean>(false)
|
const autostartEnabled = ref<boolean>(false);
|
||||||
|
|
||||||
// Load initial state
|
// Load initial state
|
||||||
invoke('get_autostart_enabled').then((enabled) => {
|
invoke("get_autostart_enabled").then((enabled) => {
|
||||||
autostartEnabled.value = enabled as boolean
|
autostartEnabled.value = enabled as boolean;
|
||||||
})
|
});
|
||||||
|
|
||||||
// Watch for changes and update autostart
|
// Watch for changes and update autostart
|
||||||
watch(autostartEnabled, async (newValue: boolean) => {
|
watch(autostartEnabled, async (newValue: boolean) => {
|
||||||
try {
|
try {
|
||||||
await invoke('toggle_autostart', { enabled: newValue })
|
await invoke("toggle_autostart", { enabled: newValue });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to toggle autostart:', error)
|
console.error("Failed to toggle autostart:", error);
|
||||||
// Revert the toggle if it failed
|
// Revert the toggle if it failed
|
||||||
autostartEnabled.value = !newValue
|
autostartEnabled.value = !newValue;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
475
src-tauri/Cargo.lock
generated
475
src-tauri/Cargo.lock
generated
@ -569,9 +569,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.17.0"
|
version = "3.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byte-tools"
|
name = "byte-tools"
|
||||||
@ -579,6 +579,12 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytecount"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.21.0"
|
version = "1.21.0"
|
||||||
@ -692,6 +698,19 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_metadata"
|
||||||
|
version = "0.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
|
||||||
|
dependencies = [
|
||||||
|
"camino",
|
||||||
|
"cargo-platform",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo_metadata"
|
name = "cargo_metadata"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
@ -722,8 +741,6 @@ version = "1.2.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
|
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
|
||||||
"libc",
|
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1158,6 +1175,15 @@ dependencies = [
|
|||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "directories"
|
||||||
|
version = "5.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys 0.4.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
@ -1176,15 +1202,6 @@ dependencies = [
|
|||||||
"dirs-sys 0.4.1",
|
"dirs-sys 0.4.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dirs"
|
|
||||||
version = "6.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
|
||||||
dependencies = [
|
|
||||||
"dirs-sys 0.5.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-sys"
|
name = "dirs-sys"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@ -1192,7 +1209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"redox_users 0.4.6",
|
"redox_users",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1204,22 +1221,10 @@ checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users 0.4.6",
|
"redox_users",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dirs-sys"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"option-ext",
|
|
||||||
"redox_users 0.5.0",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dispatch"
|
name = "dispatch"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -1278,6 +1283,12 @@ dependencies = [
|
|||||||
"const-random",
|
"const-random",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "doc-comment"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "downcast-rs"
|
name = "downcast-rs"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@ -1295,7 +1306,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "drop-app"
|
name = "drop-app"
|
||||||
version = "0.2.0-beta-prerelease-1"
|
version = "0.3.0-rc-1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic-instant-full",
|
"atomic-instant-full",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -1303,36 +1314,31 @@ dependencies = [
|
|||||||
"cacache 13.1.0",
|
"cacache 13.1.0",
|
||||||
"chrono",
|
"chrono",
|
||||||
"deranged",
|
"deranged",
|
||||||
"dirs 6.0.0",
|
"directories",
|
||||||
"droplet-rs",
|
"droplet-rs",
|
||||||
"dynfmt",
|
"dynfmt",
|
||||||
"filetime",
|
|
||||||
"gethostname 1.0.1",
|
"gethostname 1.0.1",
|
||||||
"hex 0.4.3",
|
"hex 0.4.3",
|
||||||
"http 1.2.0",
|
"http 1.2.0",
|
||||||
"http-serde 2.1.1",
|
"http-serde 2.1.1",
|
||||||
"known-folders",
|
|
||||||
"log",
|
"log",
|
||||||
"log4rs",
|
"log4rs",
|
||||||
"md5",
|
"md5",
|
||||||
|
"native_db",
|
||||||
|
"native_model 0.6.1",
|
||||||
"parking_lot 0.12.3",
|
"parking_lot 0.12.3",
|
||||||
"rand 0.9.1",
|
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
|
||||||
"reqwest 0.12.9",
|
"reqwest 0.12.9",
|
||||||
"reqwest-middleware 0.4.0",
|
"reqwest-middleware 0.4.0",
|
||||||
"reqwest-middleware-cache",
|
"reqwest-middleware-cache",
|
||||||
"rustbreak",
|
"rustbreak",
|
||||||
"rustix 0.38.42",
|
"rustix 0.38.42",
|
||||||
"schemars",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde-binary",
|
"serde-binary",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"sha1",
|
|
||||||
"shared_child",
|
"shared_child",
|
||||||
"slice-deque",
|
"slice-deque",
|
||||||
"tar",
|
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
"tauri-plugin-autostart",
|
"tauri-plugin-autostart",
|
||||||
@ -1341,17 +1347,13 @@ dependencies = [
|
|||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-shell",
|
"tauri-plugin-shell",
|
||||||
"tauri-plugin-single-instance",
|
"tauri-plugin-single-instance",
|
||||||
"tempfile",
|
|
||||||
"throttle_my_fn",
|
"throttle_my_fn",
|
||||||
"tokio",
|
"tokio",
|
||||||
"umu-wrapper-lib",
|
"umu-wrapper-lib",
|
||||||
"url",
|
"url",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
"uuid",
|
"uuid",
|
||||||
"walkdir",
|
|
||||||
"webbrowser",
|
"webbrowser",
|
||||||
"whoami",
|
|
||||||
"zstd",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1507,6 +1509,15 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "error-chain"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "event-listener"
|
name = "event-listener"
|
||||||
version = "2.5.3"
|
version = "2.5.3"
|
||||||
@ -1565,18 +1576,6 @@ dependencies = [
|
|||||||
"rustc_version",
|
"rustc_version",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "filetime"
|
|
||||||
version = "0.2.25"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"libredox",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.35"
|
version = "1.0.35"
|
||||||
@ -1925,18 +1924,6 @@ dependencies = [
|
|||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "getrandom"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"r-efi",
|
|
||||||
"wasi 0.14.2+wasi-0.2.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.31.1"
|
version = "0.31.1"
|
||||||
@ -2715,20 +2702,11 @@ version = "0.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jobserver"
|
|
||||||
version = "0.1.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.77"
|
version = "0.3.76"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@ -2767,15 +2745,6 @@ dependencies = [
|
|||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "known-folders"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b7d9a1740cc8b46e259a0eb787d79d855e79ff10b9855a5eba58868d5da7927c"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kuchikiki"
|
name = "kuchikiki"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
@ -2862,7 +2831,6 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall 0.5.8",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2895,9 +2863,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.27"
|
version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"value-bag",
|
"value-bag",
|
||||||
@ -3124,6 +3092,85 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native_db"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db7c6b50f9889052a3c1bbd3aa70cc33b76ec1761092aeb0ec0e1ac3cfdb881a"
|
||||||
|
dependencies = [
|
||||||
|
"native_db_macro",
|
||||||
|
"native_model 0.4.20",
|
||||||
|
"redb 1.5.1",
|
||||||
|
"redb 2.5.0",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"skeptic",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native_db_macro"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "434acde56fc4485e0b62533bb2fbc08155ee7e47408b1358348acff556c31b3c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.91",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native_model"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c10f4542302b7fa69ef18b49d93106e27f20b59d695555121d9ed22fe5d716a8"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bincode",
|
||||||
|
"native_model_macro 0.4.20",
|
||||||
|
"serde",
|
||||||
|
"skeptic",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
"zerocopy 0.8.25",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native_model"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7050d759e3da6673361dddda4f4a743492279dd2c6484a21fbee0a8278620df0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bincode",
|
||||||
|
"doc-comment",
|
||||||
|
"native_model_macro 0.6.1",
|
||||||
|
"serde",
|
||||||
|
"thiserror 2.0.9",
|
||||||
|
"zerocopy 0.8.25",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native_model_macro"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f385f3d57adaea8d8868e65a0bc821bcb8ba2228bbf87a1c3c6144ac48f3791"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.91",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native_model_macro"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1577a0bebf5ed1754e240baf5d9b1845f51e598b20600aa894f55e11cd20cc6c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.91",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ndk"
|
name = "ndk"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -3944,7 +3991,7 @@ version = "0.2.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy",
|
"zerocopy 0.7.35",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4012,6 +4059,17 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark"
|
||||||
|
version = "0.9.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"memchr",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-xml"
|
name = "quick-xml"
|
||||||
version = "0.32.0"
|
version = "0.32.0"
|
||||||
@ -4039,12 +4097,6 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "r-efi"
|
|
||||||
version = "5.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
@ -4070,16 +4122,6 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
|
|
||||||
dependencies = [
|
|
||||||
"rand_chacha 0.9.0",
|
|
||||||
"rand_core 0.9.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@ -4100,16 +4142,6 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core 0.9.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -4128,15 +4160,6 @@ dependencies = [
|
|||||||
"getrandom 0.2.15",
|
"getrandom 0.2.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom 0.3.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_hc"
|
name = "rand_hc"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -4195,6 +4218,24 @@ dependencies = [
|
|||||||
"yasna",
|
"yasna",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redb"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd7f82ecd6ba647a39dd1a7172b8a1cd9453c0adee6da20cb553d83a9a460fa5"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redb"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34bc6763177194266fc3773e2b2bb3693f7b02fdf461e285aa33202e3164b74e"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@ -4224,17 +4265,6 @@ dependencies = [
|
|||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_users"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom 0.2.15",
|
|
||||||
"libredox",
|
|
||||||
"thiserror 2.0.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reflink-copy"
|
name = "reflink-copy"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
@ -4558,12 +4588,6 @@ dependencies = [
|
|||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustversion"
|
|
||||||
version = "1.0.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
@ -4590,9 +4614,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schemars"
|
name = "schemars"
|
||||||
version = "0.8.22"
|
version = "0.8.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
|
checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"indexmap 1.9.3",
|
"indexmap 1.9.3",
|
||||||
@ -4605,9 +4629,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schemars_derive"
|
name = "schemars_derive"
|
||||||
version = "0.8.22"
|
version = "0.8.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d"
|
checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -4981,6 +5005,21 @@ version = "0.3.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "skeptic"
|
||||||
|
version = "0.13.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8"
|
||||||
|
dependencies = [
|
||||||
|
"bytecount",
|
||||||
|
"cargo_metadata 0.14.2",
|
||||||
|
"error-chain",
|
||||||
|
"glob",
|
||||||
|
"pulldown-cmark",
|
||||||
|
"tempfile",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
@ -5320,17 +5359,6 @@ dependencies = [
|
|||||||
"syn 2.0.91",
|
"syn 2.0.91",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tar"
|
|
||||||
version = "0.4.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a"
|
|
||||||
dependencies = [
|
|
||||||
"filetime",
|
|
||||||
"libc",
|
|
||||||
"xattr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.12.16"
|
version = "0.12.16"
|
||||||
@ -5658,7 +5686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "9271a88f99b4adea0dc71d0baca4505475a0bbd139fb135f62958721aaa8fe54"
|
checksum = "9271a88f99b4adea0dc71d0baca4505475a0bbd139fb135f62958721aaa8fe54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"cargo_metadata",
|
"cargo_metadata 0.18.1",
|
||||||
"ctor",
|
"ctor",
|
||||||
"dunce",
|
"dunce",
|
||||||
"glob",
|
"glob",
|
||||||
@ -5700,14 +5728,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.19.1"
|
version = "3.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
|
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom 0.3.2",
|
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.0.5",
|
"rustix 0.38.42",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -6301,38 +6329,22 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.14.2+wasi-0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
|
||||||
dependencies = [
|
|
||||||
"wit-bindgen-rt",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasite"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.100"
|
version = "0.2.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustversion",
|
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.100"
|
version = "0.2.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"log",
|
"log",
|
||||||
@ -6344,9 +6356,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-futures"
|
name = "wasm-bindgen-futures"
|
||||||
version = "0.4.50"
|
version = "0.4.49"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
|
checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@ -6357,9 +6369,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.100"
|
version = "0.2.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
@ -6367,9 +6379,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.100"
|
version = "0.2.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -6380,12 +6392,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.100"
|
version = "0.2.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-streams"
|
name = "wasm-streams"
|
||||||
@ -6462,9 +6471,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.77"
|
version = "0.3.76"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
|
checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@ -6578,17 +6587,6 @@ dependencies = [
|
|||||||
"windows-core 0.58.0",
|
"windows-core 0.58.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "whoami"
|
|
||||||
version = "1.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7"
|
|
||||||
dependencies = [
|
|
||||||
"redox_syscall 0.5.8",
|
|
||||||
"wasite",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -7126,15 +7124,6 @@ dependencies = [
|
|||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wit-bindgen-rt"
|
|
||||||
version = "0.39.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.6.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "write16"
|
name = "write16"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -7247,16 +7236,6 @@ dependencies = [
|
|||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xattr"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rustix 1.0.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xdg-home"
|
name = "xdg-home"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@ -7378,7 +7357,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"zerocopy-derive",
|
"zerocopy-derive 0.7.35",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.8.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive 0.8.25",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -7392,6 +7380,17 @@ dependencies = [
|
|||||||
"syn 2.0.91",
|
"syn 2.0.91",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.8.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.91",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerofrom"
|
name = "zerofrom"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@ -7441,34 +7440,6 @@ dependencies = [
|
|||||||
"syn 2.0.91",
|
"syn 2.0.91",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zstd"
|
|
||||||
version = "0.13.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
|
|
||||||
dependencies = [
|
|
||||||
"zstd-safe",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zstd-safe"
|
|
||||||
version = "7.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
|
|
||||||
dependencies = [
|
|
||||||
"zstd-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zstd-sys"
|
|
||||||
version = "2.0.15+zstd.1.5.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zvariant"
|
name = "zvariant"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "drop-app"
|
name = "drop-app"
|
||||||
version = "0.2.0-beta-prerelease-1"
|
version = "0.3.0-rc-1"
|
||||||
description = "The client application for the open-source, self-hosted game distribution platform Drop"
|
description = "The client application for the open-source, self-hosted game distribution platform Drop"
|
||||||
authors = ["Drop OSS"]
|
authors = ["Drop OSS"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@ -29,6 +29,7 @@ tauri-plugin-shell = "2.2.1"
|
|||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
serde-binary = "0.5.0"
|
serde-binary = "0.5.0"
|
||||||
rayon = "1.10.0"
|
rayon = "1.10.0"
|
||||||
|
directories = "5.0.1"
|
||||||
webbrowser = "1.0.2"
|
webbrowser = "1.0.2"
|
||||||
url = "2.5.2"
|
url = "2.5.2"
|
||||||
tauri-plugin-deep-link = "2"
|
tauri-plugin-deep-link = "2"
|
||||||
@ -57,18 +58,8 @@ reqwest-middleware-cache = "0.1.1"
|
|||||||
deranged = "=0.4.0"
|
deranged = "=0.4.0"
|
||||||
droplet-rs = "0.7.3"
|
droplet-rs = "0.7.3"
|
||||||
gethostname = "1.0.1"
|
gethostname = "1.0.1"
|
||||||
zstd = "0.13.3"
|
native_db = "0.8.1"
|
||||||
tar = "0.4.44"
|
native_model = "0.6.1"
|
||||||
rand = "0.9.1"
|
|
||||||
regex = "1.11.1"
|
|
||||||
tempfile = "3.19.1"
|
|
||||||
schemars = "0.8.22"
|
|
||||||
sha1 = "0.10.6"
|
|
||||||
dirs = "6.0.0"
|
|
||||||
whoami = "1.6.0"
|
|
||||||
filetime = "0.2.25"
|
|
||||||
walkdir = "2.5.0"
|
|
||||||
known-folders = "1.2.0"
|
|
||||||
|
|
||||||
[dependencies.dynfmt]
|
[dependencies.dynfmt]
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@ -92,7 +83,11 @@ features = ["fs"]
|
|||||||
|
|
||||||
[dependencies.uuid]
|
[dependencies.uuid]
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
features = ["v4", "fast-rng", "macro-diagnostics"]
|
features = [
|
||||||
|
"v4", # Lets you generate random UUIDs
|
||||||
|
"fast-rng", # Use a faster (but still sufficiently random) RNG
|
||||||
|
"macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies.rustbreak]
|
[dependencies.rustbreak]
|
||||||
version = "2"
|
version = "2"
|
||||||
|
|||||||
@ -1,102 +0,0 @@
|
|||||||
use std::{collections::HashMap, path::PathBuf, str::FromStr};
|
|
||||||
|
|
||||||
use log::warn;
|
|
||||||
|
|
||||||
use crate::{database::db::{GameVersion, DATA_ROOT_DIR}, error::backup_error::BackupError, process::process_manager::Platform};
|
|
||||||
|
|
||||||
use super::path::CommonPath;
|
|
||||||
|
|
||||||
pub struct BackupManager<'a> {
|
|
||||||
pub current_platform: Platform,
|
|
||||||
pub sources: HashMap<(Platform, Platform), &'a (dyn BackupHandler + Sync + Send)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BackupManager<'_> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
BackupManager {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
current_platform: Platform::Windows,
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
current_platform: Platform::MacOs,
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
current_platform: Platform::Linux,
|
|
||||||
|
|
||||||
sources: HashMap::from([
|
|
||||||
// Current platform to target platform
|
|
||||||
(
|
|
||||||
(Platform::Windows, Platform::Windows),
|
|
||||||
&WindowsBackupManager {} as &(dyn BackupHandler + Sync + Send),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
(Platform::Linux, Platform::Linux),
|
|
||||||
&LinuxBackupManager {} as &(dyn BackupHandler + Sync + Send),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
(Platform::MacOs, Platform::MacOs),
|
|
||||||
&MacBackupManager {} as &(dyn BackupHandler + Sync + Send),
|
|
||||||
),
|
|
||||||
|
|
||||||
]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait BackupHandler: Send + Sync {
|
|
||||||
fn root_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { Ok(DATA_ROOT_DIR.lock().unwrap().join("games")) }
|
|
||||||
fn game_translate(&self, _path: &PathBuf, game: &GameVersion) -> Result<PathBuf, BackupError> { Ok(PathBuf::from_str(&game.game_id).unwrap()) }
|
|
||||||
fn base_translate(&self, path: &PathBuf, game: &GameVersion) -> Result<PathBuf, BackupError> { Ok(self.root_translate(path, game)?.join(self.game_translate(path, game)?)) }
|
|
||||||
fn home_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { let c = CommonPath::Home.get().ok_or(BackupError::NotFound); println!("{:?}", c); c }
|
|
||||||
fn store_user_id_translate(&self, _path: &PathBuf, game: &GameVersion) -> Result<PathBuf, BackupError> { PathBuf::from_str(&game.game_id).map_err(|_| BackupError::ParseError) }
|
|
||||||
fn os_user_name_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { Ok(PathBuf::from_str(&whoami::username()).unwrap()) }
|
|
||||||
fn win_app_data_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected Windows Reference in Backup <winAppData>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn win_local_app_data_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected Windows Reference in Backup <winLocalAppData>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn win_local_app_data_low_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected Windows Reference in Backup <winLocalAppDataLow>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn win_documents_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected Windows Reference in Backup <winDocuments>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn win_public_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected Windows Reference in Backup <winPublic>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn win_program_data_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected Windows Reference in Backup <winProgramData>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn win_dir_translate(&self, _path: &PathBuf,_game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected Windows Reference in Backup <winDir>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn xdg_data_translate(&self, _path: &PathBuf,_game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected XDG Reference in Backup <xdgData>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn xdg_config_translate(&self, _path: &PathBuf,_game: &GameVersion) -> Result<PathBuf, BackupError> { warn!("Unexpected XDG Reference in Backup <xdgConfig>"); Err(BackupError::InvalidSystem) }
|
|
||||||
fn skip_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> { Ok(PathBuf::new()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LinuxBackupManager {}
|
|
||||||
impl BackupHandler for LinuxBackupManager {
|
|
||||||
fn xdg_config_translate(&self, _path: &PathBuf,_game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(CommonPath::Data.get().ok_or(BackupError::NotFound)?)
|
|
||||||
}
|
|
||||||
fn xdg_data_translate(&self, _path: &PathBuf,_game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(CommonPath::Config.get().ok_or(BackupError::NotFound)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub struct WindowsBackupManager {}
|
|
||||||
impl BackupHandler for WindowsBackupManager {
|
|
||||||
fn win_app_data_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(CommonPath::Config.get().ok_or(BackupError::NotFound)?)
|
|
||||||
}
|
|
||||||
fn win_local_app_data_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(CommonPath::DataLocal.get().ok_or(BackupError::NotFound)?)
|
|
||||||
}
|
|
||||||
fn win_local_app_data_low_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(CommonPath::DataLocalLow.get().ok_or(BackupError::NotFound)?)
|
|
||||||
}
|
|
||||||
fn win_dir_translate(&self, _path: &PathBuf,_game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(PathBuf::from_str("C:/Windows").unwrap())
|
|
||||||
}
|
|
||||||
fn win_documents_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(CommonPath::Document.get().ok_or(BackupError::NotFound)?)
|
|
||||||
|
|
||||||
}
|
|
||||||
fn win_program_data_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(PathBuf::from_str("C:/ProgramData").unwrap())
|
|
||||||
}
|
|
||||||
fn win_public_translate(&self, _path: &PathBuf, _game: &GameVersion) -> Result<PathBuf, BackupError> {
|
|
||||||
Ok(CommonPath::Public.get().ok_or(BackupError::NotFound)?)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub struct MacBackupManager {}
|
|
||||||
impl BackupHandler for MacBackupManager {}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
use crate::process::process_manager::Platform;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub enum Condition {
|
|
||||||
Os(Platform)
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
use crate::database::db::GameVersion;
|
|
||||||
|
|
||||||
use super::conditions::{Condition};
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct CloudSaveMetadata {
|
|
||||||
pub files: Vec<GameFile>,
|
|
||||||
pub game_version: GameVersion,
|
|
||||||
pub save_id: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct GameFile {
|
|
||||||
pub path: String,
|
|
||||||
pub id: Option<String>,
|
|
||||||
pub data_type: DataType,
|
|
||||||
pub tags: Vec<Tag>,
|
|
||||||
pub conditions: Vec<Condition>
|
|
||||||
}
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub enum DataType {
|
|
||||||
Registry,
|
|
||||||
File,
|
|
||||||
Other
|
|
||||||
}
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub enum Tag {
|
|
||||||
Config,
|
|
||||||
Save,
|
|
||||||
#[default]
|
|
||||||
#[serde(other)]
|
|
||||||
Other,
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
pub mod conditions;
|
|
||||||
pub mod metadata;
|
|
||||||
pub mod resolver;
|
|
||||||
pub mod placeholder;
|
|
||||||
pub mod normalise;
|
|
||||||
pub mod path;
|
|
||||||
pub mod backup_manager;
|
|
||||||
@ -1,162 +0,0 @@
|
|||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use regex::Regex;
|
|
||||||
use crate::process::process_manager::Platform;
|
|
||||||
|
|
||||||
use super::placeholder::*;
|
|
||||||
|
|
||||||
|
|
||||||
pub fn normalize(path: &str, os: Platform) -> String {
|
|
||||||
let mut path = path.trim().trim_end_matches(['/', '\\']).replace('\\', "/");
|
|
||||||
|
|
||||||
if path == "~" || path.starts_with("~/") {
|
|
||||||
path = path.replacen('~', HOME, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static CONSECUTIVE_SLASHES: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"/{2,}").unwrap());
|
|
||||||
static UNNECESSARY_DOUBLE_STAR_1: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"([^/*])\*{2,}").unwrap());
|
|
||||||
static UNNECESSARY_DOUBLE_STAR_2: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"\*{2,}([^/*])").unwrap());
|
|
||||||
static ENDING_WILDCARD: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(/\*)+$").unwrap());
|
|
||||||
static ENDING_DOT: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(/\.)$").unwrap());
|
|
||||||
static INTERMEDIATE_DOT: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(/\./)").unwrap());
|
|
||||||
static BLANK_SEGMENT: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(/\s+/)").unwrap());
|
|
||||||
static APP_DATA: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?i)%appdata%").unwrap());
|
|
||||||
static APP_DATA_ROAMING: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?i)%userprofile%/AppData/Roaming").unwrap());
|
|
||||||
static APP_DATA_LOCAL: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?i)%localappdata%").unwrap());
|
|
||||||
static APP_DATA_LOCAL_2: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?i)%userprofile%/AppData/Local/").unwrap());
|
|
||||||
static USER_PROFILE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?i)%userprofile%").unwrap());
|
|
||||||
static DOCUMENTS: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(?i)%userprofile%/Documents").unwrap());
|
|
||||||
|
|
||||||
for (pattern, replacement) in [
|
|
||||||
(&CONSECUTIVE_SLASHES, "/"),
|
|
||||||
(&UNNECESSARY_DOUBLE_STAR_1, "${1}*"),
|
|
||||||
(&UNNECESSARY_DOUBLE_STAR_2, "*${1}"),
|
|
||||||
(&ENDING_WILDCARD, ""),
|
|
||||||
(&ENDING_DOT, ""),
|
|
||||||
(&INTERMEDIATE_DOT, "/"),
|
|
||||||
(&BLANK_SEGMENT, "/"),
|
|
||||||
(&APP_DATA, WIN_APP_DATA),
|
|
||||||
(&APP_DATA_ROAMING, WIN_APP_DATA),
|
|
||||||
(&APP_DATA_LOCAL, WIN_LOCAL_APP_DATA),
|
|
||||||
(&APP_DATA_LOCAL_2, &format!("{}/", WIN_LOCAL_APP_DATA)),
|
|
||||||
(&USER_PROFILE, HOME),
|
|
||||||
(&DOCUMENTS, WIN_DOCUMENTS),
|
|
||||||
] {
|
|
||||||
path = pattern.replace_all(&path, replacement).to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
if os == Platform::Windows {
|
|
||||||
let documents_2: Regex = Regex::new(r"(?i)<home>/Documents").unwrap();
|
|
||||||
|
|
||||||
#[allow(clippy::single_element_loop)]
|
|
||||||
for (pattern, replacement) in [(&documents_2, WIN_DOCUMENTS)] {
|
|
||||||
path = pattern.replace_all(&path, replacement).to_string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pattern, replacement) in [
|
|
||||||
("{64BitSteamID}", STORE_USER_ID),
|
|
||||||
("{Steam3AccountID}", STORE_USER_ID),
|
|
||||||
] {
|
|
||||||
path = path.replace(pattern, replacement);
|
|
||||||
}
|
|
||||||
|
|
||||||
path
|
|
||||||
}
|
|
||||||
|
|
||||||
fn too_broad(path: &str) -> bool {
|
|
||||||
println!("Path: {}", path);
|
|
||||||
use {BASE, HOME, ROOT, STORE_USER_ID, WIN_APP_DATA, WIN_DIR, WIN_DOCUMENTS, XDG_CONFIG, XDG_DATA};
|
|
||||||
|
|
||||||
let path_lower = path.to_lowercase();
|
|
||||||
|
|
||||||
for item in ALL {
|
|
||||||
if path == *item {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for item in AVOID_WILDCARDS {
|
|
||||||
if path.starts_with(&format!("{}/*", item)) || path.starts_with(&format!("{}/{}", item, STORE_USER_ID)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// These paths are present whether or not the game is installed.
|
|
||||||
// If possible, they should be narrowed down on the wiki.
|
|
||||||
for item in [
|
|
||||||
format!("{}/{}", BASE, STORE_USER_ID), // because `<storeUserId>` is handled as `*`
|
|
||||||
format!("{}/Documents", HOME),
|
|
||||||
format!("{}/Saved Games", HOME),
|
|
||||||
format!("{}/AppData", HOME),
|
|
||||||
format!("{}/AppData/Local", HOME),
|
|
||||||
format!("{}/AppData/Local/Packages", HOME),
|
|
||||||
format!("{}/AppData/LocalLow", HOME),
|
|
||||||
format!("{}/AppData/Roaming", HOME),
|
|
||||||
format!("{}/Documents/My Games", HOME),
|
|
||||||
format!("{}/Library/Application Support", HOME),
|
|
||||||
format!("{}/Library/Application Support/UserData", HOME),
|
|
||||||
format!("{}/Library/Preferences", HOME),
|
|
||||||
format!("{}/.renpy", HOME),
|
|
||||||
format!("{}/.renpy/persistent", HOME),
|
|
||||||
format!("{}/Library", HOME),
|
|
||||||
format!("{}/Library/RenPy", HOME),
|
|
||||||
format!("{}/Telltale Games", HOME),
|
|
||||||
format!("{}/config", ROOT),
|
|
||||||
format!("{}/MMFApplications", WIN_APP_DATA),
|
|
||||||
format!("{}/RenPy", WIN_APP_DATA),
|
|
||||||
format!("{}/RenPy/persistent", WIN_APP_DATA),
|
|
||||||
format!("{}/win.ini", WIN_DIR),
|
|
||||||
format!("{}/SysWOW64", WIN_DIR),
|
|
||||||
format!("{}/My Games", WIN_DOCUMENTS),
|
|
||||||
format!("{}/Telltale Games", WIN_DOCUMENTS),
|
|
||||||
format!("{}/unity3d", XDG_CONFIG),
|
|
||||||
format!("{}/unity3d", XDG_DATA),
|
|
||||||
"C:/Program Files".to_string(),
|
|
||||||
"C:/Program Files (x86)".to_string(),
|
|
||||||
] {
|
|
||||||
let item = item.to_lowercase();
|
|
||||||
if path_lower == item
|
|
||||||
|| path_lower.starts_with(&format!("{}/*", item))
|
|
||||||
|| path_lower.starts_with(&format!("{}/{}", item, STORE_USER_ID.to_lowercase()))
|
|
||||||
|| path_lower.starts_with(&format!("{}/savesdir", item))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Drive letters:
|
|
||||||
let drives: Regex = Regex::new(r"^[a-zA-Z]:$").unwrap();
|
|
||||||
if drives.is_match(path) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Colon not for a drive letter
|
|
||||||
if path.get(2..).is_some_and(|path| path.contains(':')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Root:
|
|
||||||
if path == "/" {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Relative path wildcard:
|
|
||||||
if path.starts_with('*') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn usable(path: &str) -> bool {
|
|
||||||
let unprintable: Regex = Regex::new(r"(\p{Cc}|\p{Cf})").unwrap();
|
|
||||||
|
|
||||||
!path.is_empty()
|
|
||||||
&& !path.contains("{{")
|
|
||||||
&& !path.starts_with("./")
|
|
||||||
&& !path.starts_with("../")
|
|
||||||
&& !too_broad(path)
|
|
||||||
&& !unprintable.is_match(path)
|
|
||||||
}
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
use std::{path::PathBuf, sync::LazyLock};
|
|
||||||
|
|
||||||
pub enum CommonPath {
|
|
||||||
Config,
|
|
||||||
Data,
|
|
||||||
DataLocal,
|
|
||||||
DataLocalLow,
|
|
||||||
Document,
|
|
||||||
Home,
|
|
||||||
Public,
|
|
||||||
SavedGames,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CommonPath {
|
|
||||||
pub fn get(&self) -> Option<PathBuf> {
|
|
||||||
static CONFIG: LazyLock<Option<PathBuf>> = LazyLock::new(|| dirs::config_dir());
|
|
||||||
static DATA: LazyLock<Option<PathBuf>> = LazyLock::new(|| dirs::data_dir());
|
|
||||||
static DATA_LOCAL: LazyLock<Option<PathBuf>> = LazyLock::new(|| dirs::data_local_dir());
|
|
||||||
static DOCUMENT: LazyLock<Option<PathBuf>> = LazyLock::new(|| dirs::document_dir());
|
|
||||||
static HOME: LazyLock<Option<PathBuf>> = LazyLock::new(|| dirs::home_dir());
|
|
||||||
static PUBLIC: LazyLock<Option<PathBuf>> = LazyLock::new(|| dirs::public_dir());
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
static DATA_LOCAL_LOW: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
|
|
||||||
known_folders::get_known_folder_path(known_folders::KnownFolder::LocalAppDataLow)
|
|
||||||
});
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
static DATA_LOCAL_LOW: Option<PathBuf> = None;
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
static SAVED_GAMES: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
|
|
||||||
known_folders::get_known_folder_path(known_folders::KnownFolder::SavedGames)
|
|
||||||
});
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
static SAVED_GAMES: Option<PathBuf> = None;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
Self::Config => CONFIG.clone(),
|
|
||||||
Self::Data => DATA.clone(),
|
|
||||||
Self::DataLocal => DATA_LOCAL.clone(),
|
|
||||||
Self::DataLocalLow => DATA_LOCAL_LOW.clone(),
|
|
||||||
Self::Document => DOCUMENT.clone(),
|
|
||||||
Self::Home => HOME.clone(),
|
|
||||||
Self::Public => PUBLIC.clone(),
|
|
||||||
Self::SavedGames => SAVED_GAMES.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
pub const ALL: &[&str] = &[
|
|
||||||
ROOT,
|
|
||||||
GAME,
|
|
||||||
BASE,
|
|
||||||
HOME,
|
|
||||||
STORE_USER_ID,
|
|
||||||
OS_USER_NAME,
|
|
||||||
WIN_APP_DATA,
|
|
||||||
WIN_LOCAL_APP_DATA,
|
|
||||||
WIN_DOCUMENTS,
|
|
||||||
WIN_PUBLIC,
|
|
||||||
WIN_PROGRAM_DATA,
|
|
||||||
WIN_DIR,
|
|
||||||
XDG_DATA,
|
|
||||||
XDG_CONFIG,
|
|
||||||
];
|
|
||||||
|
|
||||||
/// These are paths where `<placeholder>/*/` is suspicious.
|
|
||||||
pub const AVOID_WILDCARDS: &[&str] = &[
|
|
||||||
ROOT,
|
|
||||||
HOME,
|
|
||||||
WIN_APP_DATA,
|
|
||||||
WIN_LOCAL_APP_DATA,
|
|
||||||
WIN_DOCUMENTS,
|
|
||||||
WIN_PUBLIC,
|
|
||||||
WIN_PROGRAM_DATA,
|
|
||||||
WIN_DIR,
|
|
||||||
XDG_DATA,
|
|
||||||
XDG_CONFIG,
|
|
||||||
];
|
|
||||||
|
|
||||||
pub const ROOT: &str = "<root>"; // a directory where games are installed (configured in backup tool)
|
|
||||||
pub const GAME: &str = "<game>"; // an installDir (if defined) or the game's canonical name in the manifest
|
|
||||||
pub const BASE: &str = "<base>"; // shorthand for <root>/<game> (unless overridden by store-specific rules)
|
|
||||||
pub const HOME: &str = "<home>"; // current user's home directory in the OS (~)
|
|
||||||
pub const STORE_USER_ID: &str = "<storeUserId>"; // a store-specific id from the manifest, corresponding to the root's store type
|
|
||||||
pub const OS_USER_NAME: &str = "<osUserName>"; // current user's ID in the game store
|
|
||||||
pub const WIN_APP_DATA: &str = "<winAppData>"; // current user's name in the OS
|
|
||||||
pub const WIN_LOCAL_APP_DATA: &str = "<winLocalAppData>"; // %APPDATA% on Windows
|
|
||||||
pub const WIN_LOCAL_APP_DATA_LOW: &str = "<winLocalAppDataLow>"; // %LOCALAPPDATA% on Windows
|
|
||||||
pub const WIN_DOCUMENTS: &str = "<winDocuments>"; // <home>/AppData/LocalLow on Windows
|
|
||||||
pub const WIN_PUBLIC: &str = "<winPublic>"; // <home>/Documents (f.k.a. <home>/My Documents) or a localized equivalent on Windows
|
|
||||||
pub const WIN_PROGRAM_DATA: &str = "<winProgramData>"; // %PUBLIC% on Windows
|
|
||||||
pub const WIN_DIR: &str = "<winDir>"; // %PROGRAMDATA% on Windows
|
|
||||||
pub const XDG_DATA: &str = "<xdgData>"; // %WINDIR% on Windows
|
|
||||||
pub const XDG_CONFIG: &str = "<xdgConfig>"; // $XDG_DATA_HOME on Linux
|
|
||||||
pub const SKIP: &str = "<skip>"; // $XDG_CONFIG_HOME on Linux
|
|
||||||
|
|
||||||
pub static OS_USERNAME: LazyLock<String> = LazyLock::new(|| whoami::username());
|
|
||||||
@ -1,255 +0,0 @@
|
|||||||
use std::{
|
|
||||||
fs::{self, create_dir_all, File},
|
|
||||||
io::{self, ErrorKind, Read, Write},
|
|
||||||
path::{Path, PathBuf}, thread::sleep, time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
|
||||||
backup_manager::BackupHandler, conditions::Condition, metadata::GameFile, placeholder::*,
|
|
||||||
};
|
|
||||||
use log::{debug, warn};
|
|
||||||
use rustix::path::Arg;
|
|
||||||
use tempfile::tempfile;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
database::db::GameVersion, error::backup_error::BackupError, process::process_manager::Platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{backup_manager::BackupManager, metadata::CloudSaveMetadata, normalise::normalize};
|
|
||||||
|
|
||||||
pub fn resolve(meta: &mut CloudSaveMetadata) -> File {
|
|
||||||
let f = File::create_new("save").unwrap();
|
|
||||||
let compressor = zstd::Encoder::new(f, 22).unwrap();
|
|
||||||
let mut tarball = tar::Builder::new(compressor);
|
|
||||||
let manager = BackupManager::new();
|
|
||||||
for file in meta.files.iter_mut() {
|
|
||||||
let id = uuid::Uuid::new_v4().to_string();
|
|
||||||
let os = match file
|
|
||||||
.conditions
|
|
||||||
.iter()
|
|
||||||
.find_map(|p| match p {
|
|
||||||
super::conditions::Condition::Os(os) => Some(os),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.cloned()
|
|
||||||
{
|
|
||||||
Some(os) => os,
|
|
||||||
None => {
|
|
||||||
warn!(
|
|
||||||
"File {:?} could not be backed up because it did not provide an OS",
|
|
||||||
&file
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let handler = match manager.sources.get(&(manager.current_platform, os)) {
|
|
||||||
Some(h) => *h,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
let t_path = PathBuf::from(normalize(&file.path, os));
|
|
||||||
println!("{:?}", &t_path);
|
|
||||||
let path = parse_path(t_path, handler, &meta.game_version).unwrap();
|
|
||||||
let f = std::fs::metadata(&path).unwrap(); // TODO: Fix unwrap here
|
|
||||||
if f.is_dir() {
|
|
||||||
tarball.append_dir_all(&id, path).unwrap();
|
|
||||||
} else if f.is_file() {
|
|
||||||
tarball
|
|
||||||
.append_file(&id, &mut File::open(path).unwrap())
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
file.id = Some(id);
|
|
||||||
}
|
|
||||||
let binding = serde_json::to_string(meta).unwrap();
|
|
||||||
println!("Binding: {}", &binding);
|
|
||||||
let serialized = binding.as_bytes();
|
|
||||||
let mut file = tempfile().unwrap();
|
|
||||||
file.write(serialized).unwrap();
|
|
||||||
tarball.append_file("metadata", &mut file).unwrap();
|
|
||||||
tarball.into_inner().unwrap().finish().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extract(file: PathBuf) -> Result<(), BackupError> {
|
|
||||||
let tmpdir = tempfile::tempdir().unwrap();
|
|
||||||
|
|
||||||
// Reopen the file for reading
|
|
||||||
let file = File::open(file).unwrap();
|
|
||||||
|
|
||||||
let decompressor = zstd::Decoder::new(file).unwrap();
|
|
||||||
let mut f = tar::Archive::new(decompressor);
|
|
||||||
f.unpack(tmpdir.path()).unwrap();
|
|
||||||
|
|
||||||
let path = tmpdir.path();
|
|
||||||
|
|
||||||
let mut manifest = File::open(path.join("metadata")).unwrap();
|
|
||||||
|
|
||||||
let mut manifest_slice = Vec::new();
|
|
||||||
manifest.read_to_end(&mut manifest_slice).unwrap();
|
|
||||||
|
|
||||||
let manifest: CloudSaveMetadata = serde_json::from_slice(&manifest_slice).unwrap();
|
|
||||||
|
|
||||||
for file in manifest.files {
|
|
||||||
let current_path = path.join(file.id.as_ref().unwrap());
|
|
||||||
|
|
||||||
let manager = BackupManager::new();
|
|
||||||
let os = match file
|
|
||||||
.conditions
|
|
||||||
.iter()
|
|
||||||
.find_map(|p| match p {
|
|
||||||
super::conditions::Condition::Os(os) => Some(os),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.cloned()
|
|
||||||
{
|
|
||||||
Some(os) => os,
|
|
||||||
None => {
|
|
||||||
warn!(
|
|
||||||
"File {:?} could not be replaced up because it did not provide an OS",
|
|
||||||
&file
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let handler = match manager.sources.get(&(manager.current_platform, os)) {
|
|
||||||
Some(h) => *h,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_path = parse_path(file.path.into(), handler, &manifest.game_version)?;
|
|
||||||
create_dir_all(&new_path.parent().unwrap()).unwrap();
|
|
||||||
|
|
||||||
println!("Current path {:?} copying to {:?}", ¤t_path, &new_path);
|
|
||||||
|
|
||||||
|
|
||||||
copy_item(current_path, new_path).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn copy_item<P: AsRef<Path>>(src: P, dest: P) -> io::Result<()> {
|
|
||||||
let src_path = src.as_ref();
|
|
||||||
let dest_path = dest.as_ref();
|
|
||||||
|
|
||||||
let metadata = fs::metadata(&src_path)?;
|
|
||||||
|
|
||||||
if metadata.is_file() {
|
|
||||||
// Ensure the parent directory of the destination exists for a file copy
|
|
||||||
if let Some(parent) = dest_path.parent() {
|
|
||||||
fs::create_dir_all(parent)?;
|
|
||||||
}
|
|
||||||
fs::copy(&src_path, &dest_path)?;
|
|
||||||
} else if metadata.is_dir() {
|
|
||||||
// For directories, we call the recursive helper function.
|
|
||||||
// The destination for the recursive copy is the `dest_path` itself.
|
|
||||||
copy_dir_recursive(&src_path, &dest_path)?;
|
|
||||||
} else {
|
|
||||||
// Handle other file types like symlinks if necessary,
|
|
||||||
// for now, return an error or skip.
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("Source {:?} is neither a file nor a directory", src_path),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn copy_dir_recursive(src: &Path, dest: &Path) -> io::Result<()> {
|
|
||||||
fs::create_dir_all(&dest)?;
|
|
||||||
|
|
||||||
for entry in fs::read_dir(src)? {
|
|
||||||
let entry = entry?;
|
|
||||||
let entry_path = entry.path();
|
|
||||||
let entry_file_name = match entry_path.file_name() {
|
|
||||||
Some(name) => name,
|
|
||||||
None => continue, // Skip if somehow there's no file name
|
|
||||||
};
|
|
||||||
let dest_entry_path = dest.join(entry_file_name);
|
|
||||||
let metadata = entry.metadata()?;
|
|
||||||
|
|
||||||
if metadata.is_file() {
|
|
||||||
debug!("Writing file {} to {}", entry_path.display(), dest_entry_path.display());
|
|
||||||
fs::copy(&entry_path, &dest_entry_path)?;
|
|
||||||
} else if metadata.is_dir() {
|
|
||||||
copy_dir_recursive(&entry_path, &dest_entry_path)?;
|
|
||||||
}
|
|
||||||
// Ignore other types like symlinks for this basic implementation
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_path(
|
|
||||||
path: PathBuf,
|
|
||||||
backup_handler: &dyn BackupHandler,
|
|
||||||
game: &GameVersion,
|
|
||||||
) -> Result<PathBuf, BackupError> {
|
|
||||||
println!("Parsing: {:?}", &path);
|
|
||||||
let mut s = PathBuf::new();
|
|
||||||
for component in path.components() {
|
|
||||||
match component.as_str().unwrap() {
|
|
||||||
ROOT => s.push(backup_handler.root_translate(&path, game)?),
|
|
||||||
GAME => s.push(backup_handler.game_translate(&path, game)?),
|
|
||||||
BASE => s.push(backup_handler.base_translate(&path, game)?),
|
|
||||||
HOME => s.push(backup_handler.home_translate(&path, game)?),
|
|
||||||
STORE_USER_ID => s.push(backup_handler.store_user_id_translate(&path, game)?),
|
|
||||||
OS_USER_NAME => s.push(backup_handler.os_user_name_translate(&path, game)?),
|
|
||||||
WIN_APP_DATA => s.push(backup_handler.win_app_data_translate(&path, game)?),
|
|
||||||
WIN_LOCAL_APP_DATA => s.push(backup_handler.win_local_app_data_translate(&path, game)?),
|
|
||||||
WIN_LOCAL_APP_DATA_LOW => {
|
|
||||||
s.push(backup_handler.win_local_app_data_low_translate(&path, game)?)
|
|
||||||
}
|
|
||||||
WIN_DOCUMENTS => s.push(backup_handler.win_documents_translate(&path, game)?),
|
|
||||||
WIN_PUBLIC => s.push(backup_handler.win_public_translate(&path, game)?),
|
|
||||||
WIN_PROGRAM_DATA => s.push(backup_handler.win_program_data_translate(&path, game)?),
|
|
||||||
WIN_DIR => s.push(backup_handler.win_dir_translate(&path, game)?),
|
|
||||||
XDG_DATA => s.push(backup_handler.xdg_data_translate(&path, game)?),
|
|
||||||
XDG_CONFIG => s.push(backup_handler.xdg_config_translate(&path, game)?),
|
|
||||||
SKIP => s.push(backup_handler.skip_translate(&path, game)?),
|
|
||||||
_ => s.push(PathBuf::from(component.as_os_str())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Final line: {:?}", &s);
|
|
||||||
Ok(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn test() {
|
|
||||||
let mut meta = CloudSaveMetadata {
|
|
||||||
files: vec![
|
|
||||||
GameFile {
|
|
||||||
path: String::from("<home>/favicon.png"),
|
|
||||||
id: None,
|
|
||||||
data_type: super::metadata::DataType::File,
|
|
||||||
tags: Vec::new(),
|
|
||||||
conditions: vec![Condition::Os(Platform::Linux)],
|
|
||||||
},
|
|
||||||
GameFile {
|
|
||||||
path: String::from("<home>/Documents/Pixel Art"),
|
|
||||||
id: None,
|
|
||||||
data_type: super::metadata::DataType::File,
|
|
||||||
tags: Vec::new(),
|
|
||||||
conditions: vec![Condition::Os(Platform::Linux)],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
game_version: GameVersion {
|
|
||||||
game_id: String::new(),
|
|
||||||
version_name: String::new(),
|
|
||||||
platform: Platform::Linux,
|
|
||||||
launch_command: String::new(),
|
|
||||||
launch_args: Vec::new(),
|
|
||||||
launch_command_template: String::new(),
|
|
||||||
setup_command: String::new(),
|
|
||||||
setup_args: Vec::new(),
|
|
||||||
setup_command_template: String::new(),
|
|
||||||
only_setup: true,
|
|
||||||
version_index: 0,
|
|
||||||
delta: false,
|
|
||||||
umu_id_override: None,
|
|
||||||
},
|
|
||||||
save_id: String::from("aaaaaaa"),
|
|
||||||
};
|
|
||||||
//resolve(&mut meta);
|
|
||||||
|
|
||||||
extract("save".into()).unwrap();
|
|
||||||
}
|
|
||||||
@ -7,6 +7,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
use directories::BaseDirs;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
use rustbreak::{DeSerError, DeSerializer, PathDatabase, RustbreakError};
|
use rustbreak::{DeSerError, DeSerializer, PathDatabase, RustbreakError};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
@ -58,7 +59,7 @@ fn default_template() -> String {
|
|||||||
"{}".to_owned()
|
"{}".to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct GameVersion {
|
pub struct GameVersion {
|
||||||
pub game_id: String,
|
pub game_id: String,
|
||||||
@ -131,8 +132,7 @@ impl Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub static DATA_ROOT_DIR: LazyLock<Mutex<PathBuf>> =
|
pub static DATA_ROOT_DIR: LazyLock<Mutex<PathBuf>> =
|
||||||
LazyLock::new(|| Mutex::new(dirs::data_dir().unwrap().join("drop")));
|
LazyLock::new(|| Mutex::new(BaseDirs::new().unwrap().data_dir().join("drop")));
|
||||||
|
|
||||||
|
|
||||||
// Custom JSON serializer to support everything we need
|
// Custom JSON serializer to support everything we need
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
use std::fmt::Display;
|
|
||||||
|
|
||||||
use serde_with::SerializeDisplay;
|
|
||||||
|
|
||||||
#[derive(Debug, SerializeDisplay, Clone, Copy)]
|
|
||||||
pub enum BackupError {
|
|
||||||
InvalidSystem,
|
|
||||||
NotFound,
|
|
||||||
ParseError
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for BackupError {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
let s = match self {
|
|
||||||
BackupError::InvalidSystem => "Attempted to generate path for invalid system",
|
|
||||||
BackupError::NotFound => "Could not generate or find path",
|
|
||||||
BackupError::ParseError => "Failed to parse path",
|
|
||||||
};
|
|
||||||
write!(f, "{}", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,4 +4,3 @@ pub mod library_error;
|
|||||||
pub mod process_error;
|
pub mod process_error;
|
||||||
pub mod remote_access_error;
|
pub mod remote_access_error;
|
||||||
pub mod setup_error;
|
pub mod setup_error;
|
||||||
pub mod backup_error;
|
|
||||||
@ -3,7 +3,6 @@ mod games;
|
|||||||
|
|
||||||
mod autostart;
|
mod autostart;
|
||||||
mod cleanup;
|
mod cleanup;
|
||||||
mod cloud_saves;
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod download_manager;
|
mod download_manager;
|
||||||
mod error;
|
mod error;
|
||||||
@ -13,7 +12,6 @@ mod remote;
|
|||||||
use crate::database::db::DatabaseImpls;
|
use crate::database::db::DatabaseImpls;
|
||||||
use autostart::{get_autostart_enabled, toggle_autostart};
|
use autostart::{get_autostart_enabled, toggle_autostart};
|
||||||
use cleanup::{cleanup_and_exit, quit};
|
use cleanup::{cleanup_and_exit, quit};
|
||||||
use cloud_saves::resolver::test;
|
|
||||||
use commands::fetch_state;
|
use commands::fetch_state;
|
||||||
use database::commands::{
|
use database::commands::{
|
||||||
add_download_dir, delete_download_dir, fetch_download_dir_stats, fetch_settings,
|
add_download_dir, delete_download_dir, fetch_download_dir_stats, fetch_settings,
|
||||||
@ -106,7 +104,6 @@ pub struct AppState<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn setup(handle: AppHandle) -> AppState<'static> {
|
fn setup(handle: AppHandle) -> AppState<'static> {
|
||||||
test();
|
|
||||||
let logfile = FileAppender::builder()
|
let logfile = FileAppender::builder()
|
||||||
.encoder(Box::new(PatternEncoder::new(
|
.encoder(Box::new(PatternEncoder::new(
|
||||||
"{d} | {l} | {f}:{L} - {m}{n}",
|
"{d} | {l} | {f}:{L} - {m}{n}",
|
||||||
|
|||||||
@ -47,7 +47,7 @@ impl ProcessManager<'_> {
|
|||||||
current_platform: Platform::Windows,
|
current_platform: Platform::Windows,
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
current_platform: Platform::MacOs,
|
current_platform: Platform::macOS,
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
current_platform: Platform::Linux,
|
current_platform: Platform::Linux,
|
||||||
@ -66,7 +66,7 @@ impl ProcessManager<'_> {
|
|||||||
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
(Platform::MacOs, Platform::MacOs),
|
(Platform::macOS, Platform::macOS),
|
||||||
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -324,54 +324,11 @@ impl ProcessManager<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq, Serialize, Deserialize, Clone, Copy, Debug)]
|
#[derive(Eq, Hash, PartialEq, Serialize, Deserialize, Clone, Debug)]
|
||||||
pub enum Platform {
|
pub enum Platform {
|
||||||
Windows,
|
Windows,
|
||||||
Linux,
|
Linux,
|
||||||
MacOs,
|
macOS,
|
||||||
}
|
|
||||||
|
|
||||||
impl Platform {
|
|
||||||
const WINDOWS: bool = cfg!(target_os = "windows");
|
|
||||||
const MAC: bool = cfg!(target_os = "macos");
|
|
||||||
const LINUX: bool = cfg!(target_os = "linux");
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub const HOST: Platform = Self::Windows;
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub const HOST: Platform = Self::MacOs;
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub const HOST: Platform = Self::Linux;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn is_case_sensitive(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::Windows | Self::MacOs => false,
|
|
||||||
Self::Linux => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for Platform {
|
|
||||||
fn from(value: &str) -> Self {
|
|
||||||
match value.to_lowercase().trim() {
|
|
||||||
"windows" => Self::Windows,
|
|
||||||
"linux" => Self::Linux,
|
|
||||||
"mac" | "macos" => Self::MacOs,
|
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<whoami::Platform> for Platform {
|
|
||||||
fn from(value: whoami::Platform) -> Self {
|
|
||||||
match value {
|
|
||||||
whoami::Platform::Windows => Platform::Windows,
|
|
||||||
whoami::Platform::Linux => Platform::Linux,
|
|
||||||
whoami::Platform::MacOS => Platform::MacOs,
|
|
||||||
_ => unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ProcessHandler: Send + 'static {
|
pub trait ProcessHandler: Send + 'static {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2.0.0",
|
"$schema": "https://schema.tauri.app/config/2.0.0",
|
||||||
"productName": "Drop Desktop Client",
|
"productName": "Drop Desktop Client",
|
||||||
"version": "0.2.0-beta",
|
"version": "0.3.0-rc-1",
|
||||||
"identifier": "dev.drop.app",
|
"identifier": "dev.drop.app",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "yarn dev --port 1432",
|
"beforeDevCommand": "yarn dev --port 1432",
|
||||||
|
|||||||
Reference in New Issue
Block a user