🚧 wip: hii

Signed-off-by: Pauline <git@ethanlibs.co>
This commit is contained in:
Pauline 2024-08-17 07:36:00 +02:00
parent ca66cf5684
commit 13c8f9135e
No known key found for this signature in database
GPG key ID: 722BB181973296AE
56 changed files with 1213 additions and 466 deletions

1
.gitattributes vendored
View file

@ -1,5 +1,6 @@
* text=auto eol=lf
Cargo.lock -diff linguist-generated
pnpm-lock.yaml -diff linguist-generated
apps/frontend/src/bindings.ts -diff linguist-generated=true
.github/actions/publish-artifacts/dist/index.js -diff linguist-generated=true
.github/actions/clippy/dist/index.js -diff linguist-generated=true

File diff suppressed because one or more lines are too long

View file

@ -18,8 +18,8 @@
"@actions/artifact": "^2.1.9",
"@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1",
"@actions/glob": "^0.4.0",
"@actions/http-client": "^2.2.1",
"@actions/glob": "^0.5.0",
"@actions/http-client": "^2.2.2",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.1",
"pathe": "^1.1.2"

View file

@ -30,6 +30,7 @@ async function run(): Promise<void> {
await exec(
'cargo',
[
'+nightly',
'clippy',
'--color',
'never',
@ -74,12 +75,12 @@ async function run(): Promise<void> {
'-efm=%C%m</code></pre>',
'-efm=%C%m',
'-efm=%C',
`-name=${toolName}`,
`-reporter=${reporter}`,
`-filter-mode=${filterMode}`,
`-fail-on-error=${failOnError}`,
`-level=${level}`,
...parse(reviewdogFlags),
`-name=${toolName}`,
`-reporter=${reporter}`,
`-filter-mode=${filterMode}`,
`-fail-on-error=${failOnError}`,
`-level=${level}`,
...parse(reviewdogFlags),
],
{
cwd,

View file

@ -17,7 +17,7 @@
"dependencies": {
"@actions/artifact": "^2.1.9",
"@actions/core": "^1.10.1",
"@actions/glob": "^0.4.0",
"@actions/glob": "^0.5.0",
"@actions/io": "^1.1.3"
},
"devDependencies": {

View file

@ -9,14 +9,15 @@ runs:
using: composite
steps:
- name: Install pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@ac5bf11548bf5e19b8aadb8182072616590fa4a6
- name: Install Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@26961cf329f22f6837d5f54c3efd76b480300ace
with:
token: ${{ inputs.token }}
check-latest: true
node-version-file: .nvmrc
cache: pnpm
- name: Install dependencies
shell: ${{ runner.os == 'Windows' && 'powershell' || 'bash' }}

View file

@ -15,20 +15,28 @@ inputs:
runs:
using: composite
steps:
- name: Install Rust
uses: IronCoreLabs/rust-toolchain@v1
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a
with:
target: ${{ inputs.target }}
toolchain: stable
targets: ${{ inputs.target }}
components: clippy, rustfmt
- name: Install Rust Nightly
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a
with:
toolchain: nightly
targets: ${{ inputs.target }}
components: clippy, rustfmt
- name: Cache Rust
if: ${{ inputs.restore-cache == 'true' }}
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@9bdad043e88c75890e36ad3bbc8d27f0090dd609
with:
key: ${{ inputs.target }}
save-if: ${{ inputs.save-cache }}
shared-key: stable-cache
# - name: Prepare Cargo
# shell: bash
# run: echo '{}' | pnpm dlx -y mustache - .cargo/config.toml.mustache .cargo/config.toml
- name: Prepare Cargo
shell: bash
run: echo '{}' | npx -y mustache - .cargo/config.toml.mustache .cargo/config.toml

View file

@ -28,7 +28,7 @@ runs:
shell: bash
if: ${{ runner.os == 'Linux' }}
run: |
curl -L# 'https://github.com/rui314/mold/releases/download/v2.32.1/mold-2.32.1-x86_64-linux.tar.gz' \
curl -L# 'https://github.com/rui314/mold/releases/download/v2.33.0/mold-2.33.0-x86_64-linux.tar.gz' \
| sudo tar -xzf- -C /usr/local
- name: (Linux) Cleanup Runner
@ -59,7 +59,7 @@ runs:
shell: powershell
run: ./packages/scripts/setup.ps1
- name: Setup Pnpm
- name: Setup pnpm
uses: ./.github/actions/setup-pnpm
with:
token: ${{ github.token }}

View file

@ -82,14 +82,16 @@ jobs:
changes:
- ${{ runner.os == 'Windows' && 'packages/scripts/setup.ps1' || 'packages/scripts/setup.sh' }}
- 'packages/scripts/prepare.ts'
- 'apps/cli/*/**'
- 'apps/desktop/*/**'
- 'apps/testing/*/**'
- 'apps/cli/**'
- 'apps/desktop/**'
- 'apps/testing/**'
- 'packages/core/**'
- 'packages/macros/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/build.yml'
- '.github/actions/setup-rust/**'
- '.github/actions/setup-system/**'
- name: Setup System
if: steps.filter.outcome != 'success' || steps.filter.outputs.changes == 'true'
@ -150,14 +152,16 @@ jobs:
changes:
- ${{ runner.os == 'Windows' && 'packages/scripts/setup.ps1' || 'packages/scripts/setup.sh' }}
- 'packages/scripts/prepare.ts'
- 'apps/cli/*/**'
- 'apps/desktop/*/**'
- 'apps/testing/*/**'
- 'apps/cli/**'
- 'apps/desktop/**'
- 'apps/testing/**'
- 'packages/core/**'
- 'packages/macros/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/build.yml'
- '.github/actions/setup-rust/**'
- '.github/actions/setup-system/**'
- name: Setup System
if: steps.preparation.outcome != 'success' || steps.preparation.outputs.changes == 'true'

481
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -28,8 +28,7 @@ onelauncher_test = { path = "./apps/testing" }
# # ============= TAURI ============= # #
# tauri uses latest crates.io rc channel
# (temporarily can use v2 and main branches if necessary)
tauri = { version = "=2.0.0-rc.0", features = [
tauri = { version = "=2.0.0-rc.2", features = [
"rustls-tls",
"tracing",
"specta",
@ -38,7 +37,7 @@ tauri = { version = "=2.0.0-rc.0", features = [
] }
# tauri-build is the codegen utility for our tauri buildscript.
tauri-build = { version = "=2.0.0-rc.0" }
tauri-build = { version = "=2.0.0-rc.2" }
# tauri-plugin-shell adds a bridge for opening urls and paths in the frontend.
tauri-plugin-shell = { version = "=2.0.0-rc.0" }
# tauri-plugin-window-state saves the window position and size to be restored.
@ -51,6 +50,8 @@ tauri-plugin-clipboard-manager = { version = "=2.0.0-rc.0" }
tauri-plugin-updater = { version = "=2.0.0-rc.0" }
# tauri-plugin-dialog adds a bridge for opening file manager and message dialogs.
tauri-plugin-dialog = { version = "=2.0.0-rc.0" }
# tauri-plugin-deep-link adds a way to handle custom uri schemes (onelauncher://)
tauri-plugin-deep-link = { version = "=2.0.0-rc.0" }
# # ============= CORE ============= # #
# rspc is used as a faster and more intuitive replacement for tauri-specta
@ -81,7 +82,7 @@ specta = { version = "=2.0.0-rc.20", features = [
] }
# tauri-specta is the tauri adapter for specta.
tauri-specta = { version = "=2.0.0-rc.15", features = [ "javascript", "typescript", "derive" ] }
tauri-specta = { version = "=2.0.0-rc.16", features = [ "javascript", "typescript", "derive" ] }
# specta-typescript is the typescript adapter for specta.
specta-typescript = { version = "=0.0.7" }

View file

@ -2,6 +2,9 @@
- migrate launcher backend storage to `prisma-client-rust` (see `prisma` branch).
- migrate api commands that currently use `tauri-specta` but don't actually rely on `tauri` to `rspc`
- waiting on `rspc` to update to the latest version (hopefully before tauri comes out of beta)
- waiting on `rspc` to update to the latest version (hopefully once tauri comes out of rc)
- bump `tauri` to stable v2 when it releases.
- test all major version/loader combos launching and mod loading.
- legacy fabric, babric, nilloader, java agent support
- nilloader <https://github.com/modrinth/labrinth/issues/903> <https://github.com/orgs/modrinth/discussions/45>
- shared cluster resources and options (<https://github.com/enjarai/shared-resources>)

View file

@ -27,6 +27,7 @@ tauri-plugin-single-instance = { workspace = true }
tauri-plugin-updater = { workspace = true }
tauri-plugin-clipboard-manager = { workspace = true }
tauri-plugin-dialog = { workspace = true }
tauri-plugin-deep-link = { workspace = true }
tauri-specta = { workspace = true }
specta = { workspace = true }
specta-typescript = { workspace = true }

View file

@ -28,6 +28,7 @@
"clipboard-manager:allow-write-text",
"dialog:allow-open",
"dialog:allow-save",
"dialog:allow-confirm"
"dialog:allow-confirm",
"deep-link:default"
]
}

View file

@ -23,6 +23,6 @@
"@onelauncher/frontend": "workspace:*"
},
"devDependencies": {
"@tauri-apps/cli": "2.0.0-rc.3"
"@tauri-apps/cli": "=2.0.0-rc.3"
}
}

View file

@ -0,0 +1,8 @@
use serde::{Deserialize, Serialize};
// TODO: this should be a specta event
#[derive(Debug, Clone, Serialize, Deserialize, specta::Type, tauri_specta::Event)]
#[serde(rename_all = "camelCase")]
pub struct DeepLinkEvent {
data: String,
}

View file

@ -1,4 +1,5 @@
pub mod deeplink;
pub mod macos;
pub mod menu;
pub mod updater;
pub mod specta;
pub mod updater;

View file

@ -1,15 +1,15 @@
use std::io;
use std::process::Command;
use std::path::Path;
use std::process::Command;
pub fn formatter(file: &Path) -> io::Result<()> {
Command::new("pnpm")
Command::new("pnpm")
.arg("eslint")
.arg("--fix")
.arg(file)
.output()
.map(|_| ())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
.arg("--fix")
.arg(file)
.output()
.map(|_| ())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
const _: specta_typescript::FormatterFn = formatter;

View file

@ -16,7 +16,6 @@ impl Update {
}
}
// TODO: tauri-specta event?
#[derive(Default)]
pub struct State {
install_lock: Mutex<()>,
@ -33,7 +32,8 @@ async fn get_update(app: tauri::AppHandle) -> Result<Option<TauriPluginUpdate>,
.map_err(|e| e.to_string())
}
#[derive(Clone, serde::Serialize, specta::Type)]
// TODO: this should be a specta event
#[derive(Debug, Clone, serde::Serialize, specta::Type, tauri_specta::Event)]
#[serde(rename_all = "camelCase", tag = "status")]
pub enum UpdateEvent {
Loading,

View file

@ -66,6 +66,7 @@ pub async fn run_app<F: FnOnce(&tauri::AppHandle<tauri::Wry>) + Send + 'static>(
.plugin(ext::updater::plugin())
.manage(ext::updater::State::default())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_deep_link::init())
// TODO: add back tauri-plugin-window-state -- it's buggy at the moment
// .plugin(tauri_plugin_window_state::Builder::default().build())
.plugin(api::init())

View file

@ -19,17 +19,19 @@
},
"dependencies": {
"@fontsource/poppins": "^5.0.14",
"@formatjs/intl-durationformat": "^0.2.4",
"@iconify-json/logos": "^1.1.44",
"@leeoniya/ufuzzy": "^1.0.14",
"@onelauncher/client": "workspace:*",
"@solid-primitives/i18n": "^2.1.1",
"@solid-primitives/refs": "^1.0.8",
"@solidjs/router": "^0.14.3",
"@t3-oss/env-core": "^0.11.0",
"@tanstack/solid-query": "^5.51.21",
"@tauri-apps/api": "2.0.0-rc.0",
"@tauri-apps/plugin-clipboard-manager": "github:tauri-apps/tauri-plugin-clipboard-manager#v2",
"@tauri-apps/plugin-dialog": "github:tauri-apps/tauri-plugin-dialog#v2",
"@tauri-apps/plugin-shell": "github:tauri-apps/tauri-plugin-shell#v2",
"@tauri-apps/api": "=2.0.0-rc.0",
"@tauri-apps/plugin-clipboard-manager": "=2.0.0-rc.0",
"@tauri-apps/plugin-dialog": "=2.0.0-rc.0",
"@tauri-apps/plugin-shell": "=2.0.0-rc.0",
"@thisbeyond/solid-dnd": "^0.7.5",
"@thisbeyond/solid-select": "^0.15.0",
"@unocss/reset": "^0.62.2",
@ -45,7 +47,7 @@
"devDependencies": {
"@sentry/vite-plugin": "^2.22.2",
"@solidjs/testing-library": "^0.8.9",
"@tauri-apps/cli": "2.0.0-rc.3",
"@tauri-apps/cli": "=2.0.0-rc.3",
"@testing-library/jest-dom": "^6.4.8",
"@types/uuid": "^10.0.0",
"jsdom": "^24.1.1",

View file

@ -6,5 +6,6 @@ import '@fontsource/poppins/600.css';
import 'overlayscrollbars/overlayscrollbars.css';
import 'virtual:uno.css';
import './globals.css';
import '~utils/patches';
export * as bridge from './bindings';

View file

@ -1,3 +1,7 @@
import type { PROGRAM_INFO } from '~bindings';
export type ProgramInfo = typeof PROGRAM_INFO;
export type WithIndex<T> = T & { index: number };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

View file

@ -47,7 +47,7 @@ function Sidebar(props: SidebarProps) {
<a
onClick={() => goto(link[2], link[3])}
class={
`px-3 py-1 rounded-md text-md hover:bg-component-bg-hover active:bg-component-bg-pressed ${isActive(link[2]) ? 'bg-component-bg' : ''}`
`px-3 py-1 rounded-md text-md hover:bg-component-bg-hover active:bg-component-bg-pressed ${isActive(link[2]) ? 'bg-component-bg' : ''}`
}
>
<span class="flex flex-row items-center gap-x-3 *:w-5">

View file

@ -31,7 +31,7 @@ interface ClusterModalController {
finish: () => void;
}
const ClusterModalContext = createContext() as Context<ClusterModalController>;
const ClusterModalContext = createContext<ClusterModalController>() as Context<ClusterModalController>;
export function ClusterModalControllerProvider(props: ParentProps) {
const [partialCluster, setPartialCluster] = createSignal<PartialCluster>({});
@ -65,14 +65,7 @@ export function ClusterModalControllerProvider(props: ParentProps) {
partialCluster,
setPartialCluster,
updatePartialCluster: (key, value) => {
setPartialCluster((prev) => {
return {
...prev,
[key]: value,
};
});
},
updatePartialCluster: (key, value) => setPartialCluster(prev => ({ ...prev, [key]: value })),
async start() {
setPartialCluster({});

View file

@ -8,7 +8,7 @@ import { bridge } from '~imports';
import SelectList from '~ui/components/base/SelectList';
import Checkbox from '~ui/components/base/Checkbox';
import type { Loader, VersionType } from '~bindings';
import { formatVersionRelease, getLoaders } from '~utils';
import { LOADERS, formatVersionRelease } from '~utils';
import LoaderIcon from '~ui/components/game/LoaderIcon';
export default createClusterStep({
@ -55,8 +55,8 @@ function ClusterGameSetup(props: ClusterStepProps) {
</Option>
<Option header="Loader">
<Dropdown onChange={index => setLoader(getLoaders()[index] || 'vanilla')}>
<For each={getLoaders()}>
<Dropdown onChange={index => setLoader(LOADERS[index] || 'vanilla')}>
<For each={LOADERS}>
{loader => (
<Dropdown.Row>
<div class="flex flex-row gap-x-2">

View file

@ -152,21 +152,21 @@ export default HomePage;
// TODO: Replace this into it's own component
// possibly with the core ui lirbary with autogenerated and optimized svgs pls
function _OneConfigLogo() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group 3544">
<g id="Group 3545">
<path id="Secondary" d="M15.635 6.4514C15.6593 6.49541 15.6848 6.54148 15.7046 6.58943C16.1185 7.45825 16.1017 8.7122 15.6275 9.56181L13.9018 12.5487C13.3915 11.7689 12.6768 11.0998 11.8176 10.5943C11.8392 10.5607 11.8585 10.5269 11.8753 10.4933C13.3988 7.41013 11.8176 3.33781 8.0003 3.39798C4.11578 3.333 2.58014 7.47994 4.17113 10.604C3.31664 11.1094 2.6067 11.7761 2.09878 12.5535C2.08691 12.5283 1.91791 12.2378 1.68616 11.8394C1.12277 10.8708 0.18813 9.26419 0.235961 9.27782C-0.0841643 8.50283 -0.0793459 7.4438 0.255235 6.67845C0.27533 6.62445 0.300245 6.57238 0.326452 6.52232C0.341024 6.49435 0.356067 6.46697 0.370757 6.44017L2.83046 2.1753C2.8341 2.17043 2.83716 2.1649 2.84021 2.15944C2.84327 2.15409 2.84621 2.1488 2.84973 2.14404C3.35754 1.29925 4.5586 0.613281 5.53813 0.613281H10.4576C11.5744 0.613281 12.607 1.21017 13.163 2.1753C13.1686 2.18241 14.024 3.66317 14.7254 4.87721C15.2115 5.7186 15.6235 6.43183 15.6275 6.43777L15.635 6.4514Z" fill="#DFEAFF" fill-opacity="0.5" />
<g id="Primary">
<path d="M5.73802 12.1854C7.03039 12.9171 8.98957 12.9147 10.2532 12.1806C11.3314 12.7149 12.1161 13.6247 12.3591 14.6933C11.8272 15.0856 11.1725 15.3527 10.5804 15.3816C10.542 15.3865 10.4987 15.3865 10.4601 15.3865C10.4265 15.3856 9.7571 15.386 8.9193 15.3865H8.87546C7.43983 15.3874 5.53976 15.3886 5.47807 15.3841C4.87154 15.3696 4.1904 15.1 3.64404 14.6933C3.88237 13.6271 4.66459 12.7197 5.73802 12.1854Z" fill="#DFEAFF" fill-opacity="0.5" />
<path d="M10.4314 8.0023C10.5156 11.3598 5.48535 11.3574 5.56961 8.0023C5.5239 4.62553 10.4747 4.62553 10.4314 8.0023Z" fill="#DFEAFF" fill-opacity="0.5" />
</g>
</g>
</g>
</svg>
);
}
// function _OneConfigLogo() {
// return (
// <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
// <g id="Group 3544">
// <g id="Group 3545">
// <path id="Secondary" d="M15.635 6.4514C15.6593 6.49541 15.6848 6.54148 15.7046 6.58943C16.1185 7.45825 16.1017 8.7122 15.6275 9.56181L13.9018 12.5487C13.3915 11.7689 12.6768 11.0998 11.8176 10.5943C11.8392 10.5607 11.8585 10.5269 11.8753 10.4933C13.3988 7.41013 11.8176 3.33781 8.0003 3.39798C4.11578 3.333 2.58014 7.47994 4.17113 10.604C3.31664 11.1094 2.6067 11.7761 2.09878 12.5535C2.08691 12.5283 1.91791 12.2378 1.68616 11.8394C1.12277 10.8708 0.18813 9.26419 0.235961 9.27782C-0.0841643 8.50283 -0.0793459 7.4438 0.255235 6.67845C0.27533 6.62445 0.300245 6.57238 0.326452 6.52232C0.341024 6.49435 0.356067 6.46697 0.370757 6.44017L2.83046 2.1753C2.8341 2.17043 2.83716 2.1649 2.84021 2.15944C2.84327 2.15409 2.84621 2.1488 2.84973 2.14404C3.35754 1.29925 4.5586 0.613281 5.53813 0.613281H10.4576C11.5744 0.613281 12.607 1.21017 13.163 2.1753C13.1686 2.18241 14.024 3.66317 14.7254 4.87721C15.2115 5.7186 15.6235 6.43183 15.6275 6.43777L15.635 6.4514Z" fill="#DFEAFF" fill-opacity="0.5" />
// <g id="Primary">
// <path d="M5.73802 12.1854C7.03039 12.9171 8.98957 12.9147 10.2532 12.1806C11.3314 12.7149 12.1161 13.6247 12.3591 14.6933C11.8272 15.0856 11.1725 15.3527 10.5804 15.3816C10.542 15.3865 10.4987 15.3865 10.4601 15.3865C10.4265 15.3856 9.7571 15.386 8.9193 15.3865H8.87546C7.43983 15.3874 5.53976 15.3886 5.47807 15.3841C4.87154 15.3696 4.1904 15.1 3.64404 14.6933C3.88237 13.6271 4.66459 12.7197 5.73802 12.1854Z" fill="#DFEAFF" fill-opacity="0.5" />
// <path d="M10.4314 8.0023C10.5156 11.3598 5.48535 11.3574 5.56961 8.0023C5.5239 4.62553 10.4747 4.62553 10.4314 8.0023Z" fill="#DFEAFF" fill-opacity="0.5" />
// </g>
// </g>
// </g>
// </svg>
// );
// }
interface BannerProps {
clusters: GroupedClusters | undefined;

View file

@ -1,3 +1,4 @@
import { DurationFormat } from '@formatjs/intl-durationformat';
import type { Cluster, Loader, VersionType } from '~bindings';
export * from './timer';
@ -29,74 +30,46 @@ export function upperFirst(object: any): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
export function abbreviateNumber(n: number) {
if (n < 1e3)
return `${n}`;
else if (n >= 1e3 && n < 1e6)
return `${+(n / 1e3).toFixed(1)}K`;
else if (n >= 1e6 && n < 1e9)
return `${+(n / 1e6).toFixed(1)}M`;
else if (n >= 1e9 && n < 1e12)
return `${+(n / 1e9).toFixed(1)}B`;
else if (n >= 1e12)
return `${+(n / 1e12).toFixed(1)}T`;
return `${n}`;
export function abbreviateNumber(n: number, locale: string = 'en-US'): string {
return new Intl.NumberFormat(locale, {
notation: 'compact',
compactDisplay: 'short',
maximumFractionDigits: 1,
}).format(n);
};
// pro lynith move
// TODO: Probably should use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules
export function pluralize(n: number, word: string): string {
return n === 1 ? word : `${word}s`;
export function pluralize(n: number, word: string, locale: string = 'en'): string {
const pluralRules = new Intl.PluralRules(locale);
const pluralForm = pluralRules.select(n);
return pluralForm === 'one' ? word : `${word}s`;
}
export function secondsToWords(seconds: number | bigint, plural: boolean = true): string {
export function secondsToWords(
seconds: number | bigint,
locale: string = 'en',
style: 'long' | 'short' | 'narrow' | 'digital' = 'long',
): string {
const n = Number(seconds);
const func = (n: number) => {
if (n < 60)
return `${n} second`;
else if (n < (60 * 60))
return `${Math.floor(n / 60)} minute`;
else if (n < (60 * 60 * 24))
return `${Math.floor(n / (60 * 60))} hour`;
else if (n < (60 * 60 * 24 * 7))
return `${Math.floor(n / (60 * 60 * 24))} day`;
else if (n < (60 * 60 * 24 * 30))
return `${Math.floor(n / (60 * 60 * 24 * 7))} week`;
else if (n < (60 * 60 * 24 * 365))
return `${Math.floor(n / (60 * 60 * 24 * 30))} month`;
else if (n < (60 * 60 * 24 * 365 * 10))
return `${Math.floor(n / (60 * 60 * 24 * 365))} year`;
return `${n} second`; // Hmmmmmm
};
const str = func(n);
if (plural) {
const n = str.split(' ')[0];
const word = str.split(' ')[1];
return `${n} ${pluralize(Number(n), word as string)}`;
}
return str;
const formatter = new DurationFormat(locale, { style });
return formatter.format({
seconds: n % 60,
minutes: Math.floor(n / 60) % 60,
hours: Math.floor(n / (60 * 60)) % 24,
days: Math.floor(n / (60 * 60 * 24)) % 7,
weeks: Math.floor(n / (60 * 60 * 24 * 7)) % 4,
months: Math.floor(n / (60 * 60 * 24 * 30)) % 12,
years: Math.floor(n / (60 * 60 * 24 * 365)),
});
}
export function asEnvVariables(str: string): [string, string][] {
return str
.split(' ')
.map((pair) => {
const split = pair.split('=', 1);
if (split.length === 0)
return null;
else if (split.length === 1)
return [split[0]!, ''] as [string, string];
else
return [split[0]!, split[1]!] as [string, string];
const [key, value = ''] = pair.split('=', 1);
return key ? [key, value] as [string, string] : null;
})
.filter(pair => pair !== null);
}
export function getLoaders(): Loader[] {
return ['vanilla', 'fabric', 'forge', 'neoforge', 'quilt'];
}
export const LOADERS: Loader[] = ['vanilla', 'fabric', 'forge', 'neoforge', 'quilt'] as const;

View file

@ -0,0 +1,6 @@
globalThis.isDevelopment = import.meta.env.DEV;
globalThis.onHotReload = (func: () => void) => {
if (import.meta.hot)
import.meta.hot.dispose(func);
};

View file

@ -17,7 +17,8 @@
"types": [
"vitest/globals",
"@testing-library/jest-dom",
"vite-plugin-solid-svg/types"
"vite-plugin-solid-svg/types",
"@formatjs/intl-durationformat"
],
"allowImportingTsExtensions": true,
"strict": true,

View file

@ -38,6 +38,7 @@
"core": "cd packages/core && cargo",
"testing": "cd apps/testing && cargo",
"tauri": "cd apps/desktop && cargo",
"postupdate": "cargo update",
"test:vi": "pnpm vitest run",
"test:update": "pnpm vitest -u",
"test:ui": "pnpm vitest --ui",
@ -54,8 +55,8 @@
]
},
"devDependencies": {
"@flowr/eslint-config": "^3.11.6",
"@types/node": "^22.3.0",
"@flowr/eslint-config": "^3.12.0",
"@types/node": "^22.4.0",
"@unocss/eslint-plugin": "^0.62.2",
"@vitest/ui": "^2.0.5",
"bumpp": "^9.5.1",
@ -63,7 +64,7 @@
"eslint-plugin-solid": "^0.14.1",
"jiti": "^1.21.6",
"ts-node": "^10.9.2",
"tsx": "~4.17.0",
"tsx": "^4.17.0",
"typescript": "^5.5.4",
"vite": "^5.4.1",
"vitest": "^2.0.5"

View file

@ -0,0 +1,3 @@
# wip library expecting rspc but can work with tauri-specta too
h

View file

@ -16,11 +16,16 @@
"types": "./src/index.ts",
"scripts": {},
"dependencies": {
"@flowr/utils": "^3.12.0",
"@solid-primitives/deep": "^0.2.9",
"@tanstack/solid-query": "^5.51.21",
"fast-equals": "^5.0.1",
"plausible-tracker": "^0.3.9",
"react": "^18.3.1",
"solid-js": "^1.8.21",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/react": "^18.3.3"
}
}

View file

@ -1 +1,5 @@
export const WEBSITE = 'https://polyfrost.org/';
// TODO: temporary
export const PROGRAM_INFO = { arch: '64', dev_build: true, launcher_version: '1.0.0-alpha.1', platform: 'osx', tauri_version: '2.0.0-rc.0', webview_version: '19618.3.11.11.5' } as const;
export type ProgramInfo = typeof PROGRAM_INFO;

View file

@ -0,0 +1,3 @@
export * from './usePlausible';
export * from './useDebug';
export * from './useQuery';

View file

@ -0,0 +1,34 @@
import { useEffect, useState } from 'react';
import { createMutable } from 'solid-js/store';
import { createPersistedMutable, useSolidStore } from '../library';
export interface DebugState {
enabled: boolean;
shareFullTelemetry: boolean;
telemetryLogging: boolean;
}
export const debugState = createPersistedMutable(
'onelauncher-debugState',
createMutable<DebugState>({
enabled: globalThis.isDevelopment,
shareFullTelemetry: false,
telemetryLogging: false,
}),
);
export const useDebugState = () => useSolidStore(debugState);
export function useDebugToggle(): () => void {
const [toggled, setToggled] = useState(0);
useEffect(() => {
if (toggled >= 5)
debugState.enabled = true;
const timeout = setTimeout(() => setToggled(0), 1000);
return () => clearTimeout(timeout);
}, [toggled]);
return () => setToggled(c => c + 1);
}

View file

@ -0,0 +1,308 @@
import type { PlausibleOptions as PlausibleTrackerOptions } from 'plausible-tracker';
import Plausible from 'plausible-tracker';
import { useCallback, useEffect, useRef } from 'react';
import { createMutable } from 'solid-js/store';
import { createPersistedMutable, useSolidStore } from '../library';
import { PROGRAM_INFO, type ProgramInfo } from '../constants';
import { useDebugState } from './useDebug';
/**
* Possible platform types for Plausible.
*/
export type PlausiblePlatformType = 'desktop' | 'unknown';
/**
* The Plausible analytics state.
*/
export interface PlausibleState {
shareFullTelemetry: boolean;
platform: PlausiblePlatformType;
programInfo: ProgramInfo;
}
/**
* The mutable solid {@link PlausibleState} holder.
*/
export const plausibleState: PlausibleState = createPersistedMutable(
'onelauncher-layout',
createMutable<PlausibleState>({
shareFullTelemetry: false, // false by default
platform: 'unknown',
programInfo: PROGRAM_INFO,
}),
);
/**
* A solid hook for using the solid store {@link plausibleState}.
*/
export const usePlausibleState = (): PlausibleState => useSolidStore(plausibleState);
const PlausibleProvider = Plausible({
trackLocalhost: true,
domain: 'app.polyfrost.org',
apiHost: 'https://analytics.polyfrost.org',
});
/**
* Defines all possible options that may be provided by events upon submission.
*
* Extends the {@link PlausibleTrackerOptions} provided by the `plausible-tracker`
* package with additional options for custom functionality.
*/
export type PlausibleOptions = PlausibleTrackerOptions & { telemetryOverride?: boolean };
/**
* A base Plausible event, that all other events are derived from for type safety.
*/
interface BasePlausibleEventWithOption<T, O extends keyof PlausibleOptions> {
type: T;
plausibleOptions: Required<{ [K in O]: PlausibleOptions[O]; }>;
}
interface BasePlausibleEventWithoutOption<T> { type: T }
type BasePlausibleEvent<T, O = void> = O extends keyof PlausibleOptions
? BasePlausibleEventWithOption<T, O>
: BasePlausibleEventWithoutOption<T>;
// Plausible events
type PageViewEvent = BasePlausibleEvent<'pageview', 'url'>;
type ClusterCreateEvent = BasePlausibleEvent<'clusterCreate'>;
type ClusterDeleteEvent = BasePlausibleEvent<'clusterDelete'>;
type ModAddedEvent = BasePlausibleEvent<'modAdded'>;
type ModRemovedEvent = BasePlausibleEvent<'modRemoved'>;
type PingEvent = BasePlausibleEvent<'ping'>;
/** All plausible events, added as goals for the currently active domain. */
type PlausibleEvent =
| PageViewEvent
| ClusterCreateEvent
| ClusterDeleteEvent
| ModAddedEvent
| ModRemovedEvent
| PingEvent;
/**
* A wrapper for Plausible events to be handled internally.
*
* Allows for in-depth event logging to console and Plausible.
*/
interface PlausibleTrackerEvent {
eventName: string;
props: {
platform: PlausiblePlatformType;
fullTelemetry: boolean;
coreVersion: string;
commit: string;
debug: boolean;
};
options: PlausibleTrackerOptions;
readonly callback?: () => void;
}
interface SubmitEventProps {
/** The {@link PlausibleEvent plausible event} to submit. */
event: PlausibleEvent;
/** The current {@link PlausiblePlatformType platform type}. */
platformType: PlausiblePlatformType;
/** An optional screen width. Defaults to `window.screen.width` */
screenWidth?: number;
/** Whether or not full telemetry is enabled for the current client. `usePlausibleState().shareFullTelemetry` */
shareFullTelemetry: boolean;
/** Whether or not debug is enabled for the current client. */
debugState: {
enabled: boolean;
shareFullTelemetry: boolean;
telemetryLogging: boolean;
};
programInfo: ProgramInfo;
}
/**
* Submits an event directly to our Plausible server.
*
* **Avoid using this directly, only send telemetry when it is certain that it has been
* allowed by the user. Prefer the {@link usePlausibleEvent `usePlausibleEvent`} hook.**
*
* @remarks
* If any of the conditions are met, this will return and no data will be submitted:
*
* - The app is in debug or development mode.
* - A telemetry override is present and is not true.
* - No telemetry override is present, and telemetry sharing is not true.
*
* Telemetry sharing settings are never matched to `=== false` but rather to
* `!== true`. This is so we can gaurentee that **nothing** will be sent
* unless the user explicitly allows it.
*
* @see {@link https://plausible.io/docs/custom-event-goals Plausible custom events}
* @see {@link https://plausible-tracker.netlify.app/#tracking-custom-events-and-goals Tracking custom Plausible events}
*/
async function submitPlausibleEvent({ event, debugState, ...props }: SubmitEventProps): Promise<void> {
if (props.platformType === 'unknown')
return;
if (debugState.enabled && debugState.shareFullTelemetry !== true)
return;
if (
'plausibleOptions' in event && 'telemetryOverride' in event.plausibleOptions
? event.plausibleOptions.telemetryOverride !== true
: props.shareFullTelemetry !== true && event.type !== 'ping'
)
return;
const fullEvent: PlausibleTrackerEvent = {
eventName: event.type,
props: {
platform: props.platformType,
fullTelemetry: props.shareFullTelemetry,
coreVersion: props.programInfo.launcher_version,
commit: props.programInfo.tauri_version,
debug: debugState.enabled,
},
options: {
domain: 'app.polyfrost.org',
deviceWidth: props.screenWidth ?? window.screen.width,
referrer: '',
...('plausibleOptions' in event ? event.plausibleOptions : undefined),
},
callback: debugState.telemetryLogging
? () => {
const { callback: _, ...event } = fullEvent;
// eslint-disable-next-line no-console -- debug info
console.log(event);
}
: undefined,
};
PlausibleProvider.trackEvent(
fullEvent.eventName,
{
props: fullEvent.props,
callback: fullEvent.callback,
},
fullEvent.options,
);
}
interface EventSubmissionCallbackProps {
/** The {@link PlausibleEvent Plausible event} to be submitted. */
event: PlausibleEvent;
}
/**
* Submits a Plausible Analytics event with a hook.
*
* The returned callback will only the fired once as to avoid flooding analytics.
*
* Certain events provide functionality to override telemetry sharing. This is because
* it should only be used in contexts where telemetry sharing must be allowed by external means.
*
* @remarks
* If any of the conditions are met, this will return and no data will be submitted:
*
* - The app is in debug or development mode.
* - A telemetry override is present and is not true.
* - No telemetry override is present, and telemetry sharing is not true.
*
* @returns a callback that, once executed, will submit the event.
*
* @example
* ```ts
* const submitPlausibleEvent = usePlausibleEvent();
*
* const createdCluster = commands.createCluster('myCluster').then(cluster => {
* submitPlausibleEvent({
* event: {
* type: 'clusterCreate',
* },
* });
* return cluster;
* });
* ```
*/
export function usePlausibleEvent(): (props: EventSubmissionCallbackProps) => Promise<void> {
const debugState = useDebugState();
const plausibleState = usePlausibleState();
const previousEvent = useRef({} as BasePlausibleEvent<string>);
return useCallback(async (props: EventSubmissionCallbackProps) => {
if (previousEvent.current === props.event)
return;
else previousEvent.current = props.event;
submitPlausibleEvent({
debugState,
shareFullTelemetry: plausibleState.shareFullTelemetry,
platformType: plausibleState.platform,
programInfo: plausibleState.programInfo,
...props,
});
}, [debugState, plausibleState]);
}
export interface PlausibleMonitorProps {
/** A sanitized string containing the current active path the client is viewing. */
currentPath: string;
}
/**
* Submits a Plausible Analytics `pageview` event with a hook.
*
* This should watch the Solid router's current path, and send an event if the path is changed.
*
* @remarks
* If any of the conditions are met, this will return and no data will be submitted:
*
* - The app is in debug or development mode.
* - A telemetry override is present and is not true.
* - No telemetry override is present, and telemetry sharing is not true.
*/
export function usePlausiblePageview({ currentPath }: PlausibleMonitorProps): void {
const plausibleEvent = usePlausibleEvent();
useEffect(() => {
plausibleEvent({
event: {
type: 'pageview',
plausibleOptions: { url: currentPath },
},
});
}, [currentPath, plausibleEvent]);
}
/**
* Submits a Plausible Analytics `ping` event with a hook.
*
* This should watch the Solid router's current path, and send an event if the path is changed.
*
* @remarks
* If any of the conditions are met, this will return and no data will be submitted:
*
* - The app is in debug or development mode.
* - A telemetry override is present and is not true.
* - No telemetry override is present, and telemetry sharing is not true.
*/
export function usePlausiblePing({ currentPath }: PlausibleMonitorProps) {
const plausibleEvent = usePlausibleEvent();
useEffect(() => {
plausibleEvent({
event: {
type: 'ping',
},
});
}, [currentPath, plausibleEvent]);
}
export interface PlausibleInitProps {
platformType: PlausiblePlatformType;
programInfo: ProgramInfo;
}
export function initializePlausible(props: PlausibleInitProps): void {
plausibleState.platform = props.platformType;
plausibleState.programInfo = props.programInfo;
}

View file

@ -0,0 +1,2 @@
export { createQuery } from '@tanstack/solid-query';
export { createQuery as default } from '@tanstack/solid-query';

View file

@ -1 +1,18 @@
declare global {
// eslint-disable-next-line vars-on-top, no-var -- global patched variable
var isDevelopment: boolean;
// eslint-disable-next-line vars-on-top, no-var -- global patched variable
var onHotReload: (cb: () => void) => void | undefined;
}
if (globalThis.isDevelopment === undefined || globalThis.localStorage === undefined)
throw new Error('please ensure you have patched `globalThis` before importing the client');
declare global {
// global patched function because tauri/webkit does weird promise polyfills
export function confirm(): boolean | Promise<boolean>;
}
export * from './constants';
export * from './library';
export * from './hooks';

View file

@ -0,0 +1,42 @@
import { trackDeep } from '@solid-primitives/deep';
import { createEffect, createRoot } from 'solid-js';
import type { StoreNode } from 'solid-js/store';
export interface CreatePersistedMutableOpts<T> {
onSave?: (value: T) => T;
}
// copied from `makePersisted` in `@solid-primitives/storage` with `solid-js/store`.
export function createPersistedMutable<T extends StoreNode>(
key: string,
mutable: T,
opts?: CreatePersistedMutableOpts<T>,
): T {
try {
const value = localStorage.getItem(key);
if (value) {
const persisted = JSON.parse(value);
Object.assign(mutable, persisted);
}
}
catch (err) {
console.error(`failed to load persisted state from localStorage '${key}': ${err}`);
}
const dispose = createRoot((dispose) => {
createEffect(() => {
trackDeep(mutable);
const item = opts?.onSave
? JSON.stringify(opts.onSave(mutable))
: JSON.stringify(mutable);
localStorage.setItem(key, item);
});
return dispose;
});
if ('onHotReload' in globalThis)
globalThis?.onHotReload(dispose);
return mutable;
}

View file

@ -0,0 +1,3 @@
export * from './createPersistedMutable';
export * from './useSolidStore';
export * from './useObserver';

View file

@ -0,0 +1,64 @@
import { useEffect, useRef, useState } from 'react';
import type { Owner } from 'solid-js';
import { createReaction, createRoot, runWithOwner } from 'solid-js';
// copied from `useObserver` in `react-solid-state`, ported to work with new versions.
// https://github.com/solidjs/react-solid-state/issues/4
export function useObserver<T>(fn: () => T): T {
const [_, setTick] = useState(0);
const state = useRef({
onUpdate: (): void => {
state.current.firedDuringRender = true;
},
firstRenderFired: false,
firedDuringRender: false,
});
const reaction = useRef<{ dispose: () => void; track: (fn: () => void) => void }>();
if (!reaction.current)
reaction.current = createRoot(dispose => ({
dispose,
track: createReaction(() => state.current.onUpdate()),
}));
useEffect(() => {
if (state.current.firedDuringRender)
setTick(t => t + 1);
state.current.onUpdate = () => setTick(t => t + 1);
state.current.firstRenderFired = true;
return () => {
state.current.onUpdate = () => {
state.current.firedDuringRender = false;
};
if (!state.current.firstRenderFired) {
reaction.current?.dispose();
reaction.current = undefined;
}
};
}, []);
let rendering!: T;
reaction.current.track(() => (rendering = fn()));
return rendering;
}
export function useObserverWithOwner<T>(owner: Owner, fn: () => T): T {
const [_, setTick] = useState(0);
const state = useRef({ onUpdate: () => {} });
const reaction = useRef<{ track: (fn: () => void) => void }>();
if (!reaction.current)
reaction.current = runWithOwner(owner, () => ({
track: createReaction(() => state.current.onUpdate()),
}))!;
useEffect(() => state.current.onUpdate = () => setTick(t => t + 1));
let rendering!: T;
reaction.current.track(() => (rendering = fn()));
return rendering;
}

View file

@ -0,0 +1,13 @@
import type { Store } from 'solid-js/store';
import { useObserver } from './useObserver';
/**
* A wrapper for {@link useObserver} to integrate with `solid-js/store`.
*/
export function useSolidStore<T extends object = object>(store: Store<T>): T {
const state = useObserver(() => ({ ...store }));
return new Proxy(state, {
get: (target, prop) => Reflect.get(target, prop),
set: (_, prop, value) => Reflect.set(store, prop, value),
});
}

View file

@ -2,6 +2,7 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"exactOptionalPropertyTypes": false,
"emitDeclarationOnly": false,
"outDir": "./dist"
},

View file

@ -236,6 +236,31 @@ pub async fn delete_logs_by_file(
Ok(())
}
pub async fn read_log_to_string(path: &std::path::PathBuf) -> crate::Result<String> {
if let Some(ext) = path.extension() {
let mut file = std::fs::File::open(&path).map_err(|e| IOError::with_path(e, &path))?;
let mut contents = [0; 1024];
let mut result = String::new();
if ext == "gz" {
let mut gz = flate2::read::GzDecoder::new(std::io::BufReader::new(file));
while gz.read(&mut contents).map_err(|e| IOError::with_path(e, &path))? > 0 {
result.push_str(&String::from_utf8_lossy(&contents));
contents = [0; 1024];
}
} else if ext == "log" || ext == "txt" {
while file.read(&mut contents).map_err(|e| IOError::with_path(e, &path))? > 0 {
result.push_str(&String::from_utf8_lossy(&contents));
contents = [0; 1024];
}
}
return Ok(result);
}
Err(anyhow::anyhow!("log file extension {} not supported", path.display()).into())
}
/// Get a specific [`ClusterPath`] log file's [`LogOutput`].
#[tracing::instrument]
pub async fn get_output_by_file(
@ -258,40 +283,9 @@ pub async fn get_output_by_file(
.into_values()
.collect();
// todo: make this a utility function
if let Some(ext) = path.extension() {
let mut file = std::fs::File::open(&path).map_err(|e| IOError::with_path(e, &path))?;
let mut contents = [0; 1024];
let mut result = String::new();
let result = read_log_to_string(&path).await?;
if ext == "gz" {
let mut gz = flate2::read::GzDecoder::new(std::io::BufReader::new(file));
while gz
.read(&mut contents)
.map_err(|e| IOError::with_path(e, &path))?
> 0
{
result.push_str(&String::from_utf8_lossy(&contents));
contents = [0; 1024];
}
return Ok(LogOutput::censor_secrets(result, &credentials, None));
} else if ext == "log" || ext == "txt" {
while file
.read(&mut contents)
.map_err(|e| IOError::with_path(e, &path))?
> 0
{
result.push_str(&String::from_utf8_lossy(&contents));
contents = [0; 1024];
}
return Ok(LogOutput::censor_secrets(result, &credentials, None));
}
}
Err(anyhow::anyhow!("log file extension {} not supported", path.display()).into())
return Ok(LogOutput::censor_secrets(result, &credentials, None));
}
/// The log cursor used to parse logs passed into [`LogManager`].

View file

@ -61,7 +61,6 @@ pub async fn remove_user(user: uuid::Uuid) -> crate::Result<()> {
Ok(())
}
// TODO: Store this securely in stronghold
/// Get a list of user [`MinecraftCredentials`].
#[tracing::instrument]
pub async fn users() -> crate::Result<Vec<MinecraftCredentials>> {

View file

@ -84,7 +84,8 @@ impl Providers {
Ok(versions
.into_iter()
.find(|v| v.game_versions.contains(&game_version.to_string()))
.ok_or(anyhow!("no game version found"))?) // TODO: error handling
.ok_or(anyhow!("no game version found"))?
) // TODO: error handling
}
// pub async fn search(&self, query: &str) -> Result<Vec<ManagedPackage>> {

View file

@ -158,7 +158,6 @@ struct SearchResults {
}
// 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(),

View file

@ -137,7 +137,13 @@ pub async fn import_instance(
)
.await
}
ImportType::Modrinth => modrinth::import_modrinth(base_path.join("profiles").join(instance_path), cluster_path.clone()).await,
ImportType::Modrinth => {
modrinth::import_modrinth(
base_path.join("profiles").join(instance_path),
cluster_path.clone(),
)
.await
}
// ImportType::TLauncher => tlauncher::import_tlauncher(path.join("instances").join(instance_path), cluster_path.clone()).await,
// ImportType::Technic => technic::import_technic(path.join("instances").join(instance_path), cluster_path.clone()).await,
// ImportType::FTBLauncher => ftb::import_ftb(path.join("instances").join(instance_path), cluster_path.clone()).await,

View file

@ -15,7 +15,6 @@ use crate::State;
use super::{Cluster, PackagePath};
// TODO: move all of this to prisma, it would be perfect for it
// TODO: Curseforge, Modrinth, SkyClient integration
/// Creates [`Package`] data for a given [`Cluster`] from on-device files and APIs.
@ -260,8 +259,6 @@ impl ManagedVersionFile {
.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?;

View file

@ -5,8 +5,6 @@
use interpulse::api::minecraft::{Os, OsRule};
use regex::Regex;
// todo: add this to interpulse (maybe, generally we keep it unimplemented but these are pretty basic functions).
/// An extension of [`Os`] for utilities on converting the current system's operating system
/// into an [`Os`] structure for simple management.
pub trait OsExt {

9
packages/scripts/dedupe.sh Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail
__dirname="$(CDPATH='' cd "$(dirname "$0")" && pwd -P)"
grep -Po '^\s+"[\w-]+\s+\d(\.\d+)*[^"]*"' "${__dirname}/../../Cargo.lock" \
| xargs printf '%s\n' \
| sort -u -k 1b,2V

View file

@ -19,7 +19,7 @@
"int:prepare": "pnpm tsx prepare.ts"
},
"dependencies": {
"@flowr/utils": "^3.11.6",
"@flowr/utils": "^3.12.0",
"execa": "^9.3.1",
"mustache": "^4.2.0",
"pathe": "^1.1.2",

View file

@ -31,7 +31,7 @@ function targetFilter(filter: 'b' | 't') {
}
const targets = args.filter(targetFilter('t')).flatMap(t => t.split(','));
const bundles = args.filter(targetFilter('b')).flatMap(t => t.split(','));
const bundles = args.filter(targetFilter('b')).flatMap(b => b.split(','));
const store = { code: 0 };

View file

@ -93,6 +93,7 @@ export async function patchTauri(
if (pubKey != null)
tauriPatch.plugins.updater.pubkey = pubKey;
}
// tauriPatch.build.features.push('devtools');
break;
}

321
pnpm-lock.yaml generated
View file

@ -9,11 +9,11 @@ importers:
.:
devDependencies:
'@flowr/eslint-config':
specifier: ^3.11.6
version: 3.11.6(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(@unocss/eslint-plugin@0.62.2(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-solid@0.14.1(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-vue@9.27.0(eslint@9.9.0(jiti@1.21.6)))(eslint-processor-vue-blocks@0.1.2(@vue/compiler-sfc@3.4.38)(eslint@9.9.0(jiti@1.21.6)))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6)))
specifier: ^3.12.0
version: 3.12.0(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(@unocss/eslint-plugin@0.62.2(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-solid@0.14.1(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-vue@9.27.0(eslint@9.9.0(jiti@1.21.6)))(eslint-processor-vue-blocks@0.1.2(@vue/compiler-sfc@3.4.38)(eslint@9.9.0(jiti@1.21.6)))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6)))
'@types/node':
specifier: ^22.3.0
version: 22.3.0
specifier: ^22.4.0
version: 22.4.0
'@unocss/eslint-plugin':
specifier: ^0.62.2
version: 0.62.2(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
@ -34,19 +34,19 @@ importers:
version: 1.21.6
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@22.3.0)(typescript@5.5.4)
version: 10.9.2(@types/node@22.4.0)(typescript@5.5.4)
tsx:
specifier: ~4.17.0
specifier: ^4.17.0
version: 4.17.0
typescript:
specifier: ^5.5.4
version: 5.5.4
vite:
specifier: ^5.4.1
version: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
version: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
vitest:
specifier: ^2.0.5
version: 2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8)
version: 2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8)
.github/actions/clippy:
dependencies:
@ -60,11 +60,11 @@ importers:
specifier: ^1.1.1
version: 1.1.1
'@actions/glob':
specifier: ^0.4.0
version: 0.4.0
specifier: ^0.5.0
version: 0.5.0
'@actions/http-client':
specifier: ^2.2.1
version: 2.2.1
specifier: ^2.2.2
version: 2.2.2
'@actions/io':
specifier: ^1.1.3
version: 1.1.3
@ -88,8 +88,8 @@ importers:
specifier: ^1.10.1
version: 1.10.1
'@actions/glob':
specifier: ^0.4.0
version: 0.4.0
specifier: ^0.5.0
version: 0.5.0
'@actions/io':
specifier: ^1.1.3
version: 1.1.3
@ -111,7 +111,7 @@ importers:
version: link:../frontend
devDependencies:
'@tauri-apps/cli':
specifier: 2.0.0-rc.3
specifier: '=2.0.0-rc.3'
version: 2.0.0-rc.3
apps/frontend:
@ -119,6 +119,9 @@ importers:
'@fontsource/poppins':
specifier: ^5.0.14
version: 5.0.14
'@formatjs/intl-durationformat':
specifier: ^0.2.4
version: 0.2.4
'@iconify-json/logos':
specifier: ^1.1.44
version: 1.1.44
@ -128,6 +131,9 @@ importers:
'@onelauncher/client':
specifier: workspace:*
version: link:../../packages/client
'@solid-primitives/i18n':
specifier: ^2.1.1
version: 2.1.1(solid-js@1.8.21)
'@solid-primitives/refs':
specifier: ^1.0.8
version: 1.0.8(solid-js@1.8.21)
@ -141,17 +147,17 @@ importers:
specifier: ^5.51.21
version: 5.51.21(solid-js@1.8.21)
'@tauri-apps/api':
specifier: 2.0.0-rc.0
specifier: '=2.0.0-rc.0'
version: 2.0.0-rc.0
'@tauri-apps/plugin-clipboard-manager':
specifier: github:tauri-apps/tauri-plugin-clipboard-manager#v2
version: https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/20e84cfbdebcd86bb1854846feb0aaff4481fbd0
specifier: '=2.0.0-rc.0'
version: 2.0.0-rc.0
'@tauri-apps/plugin-dialog':
specifier: github:tauri-apps/tauri-plugin-dialog#v2
version: https://codeload.github.com/tauri-apps/tauri-plugin-dialog/tar.gz/f83833c5445948c1b2f022e3c530ca48be9f8768
specifier: '=2.0.0-rc.0'
version: 2.0.0-rc.0
'@tauri-apps/plugin-shell':
specifier: github:tauri-apps/tauri-plugin-shell#v2
version: https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5cc36dadeaad0520111c6f5e32ecdbbae7cb1311
specifier: '=2.0.0-rc.0'
version: 2.0.0-rc.0
'@thisbeyond/solid-dnd':
specifier: ^0.7.5
version: 0.7.5(solid-js@1.8.21)
@ -193,7 +199,7 @@ importers:
specifier: ^0.8.9
version: 0.8.9(@solidjs/router@0.14.3(solid-js@1.8.21))(solid-js@1.8.21)
'@tauri-apps/cli':
specifier: 2.0.0-rc.3
specifier: '=2.0.0-rc.3'
version: 2.0.0-rc.3
'@testing-library/jest-dom':
specifier: ^6.4.8
@ -209,21 +215,24 @@ importers:
version: 1.77.8
unocss:
specifier: ^0.62.2
version: 0.62.2(postcss@8.4.41)(rollup@4.20.0)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
version: 0.62.2(postcss@8.4.41)(rollup@4.20.0)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
vite-plugin-solid:
specifier: ^2.10.2
version: 2.10.2(@testing-library/jest-dom@6.4.8)(solid-js@1.8.21)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
version: 2.10.2(@testing-library/jest-dom@6.4.8)(solid-js@1.8.21)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
vite-plugin-solid-svg:
specifier: ^0.8.1
version: 0.8.1(solid-js@1.8.21)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
version: 0.8.1(solid-js@1.8.21)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
vite-tsconfig-paths:
specifier: ^5.0.1
version: 5.0.1(typescript@5.5.4)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
version: 5.0.1(typescript@5.5.4)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
apps/testing: {}
packages/client:
dependencies:
'@flowr/utils':
specifier: ^3.12.0
version: 3.12.0
'@solid-primitives/deep':
specifier: ^0.2.9
version: 0.2.9(solid-js@1.8.21)
@ -236,12 +245,19 @@ importers:
plausible-tracker:
specifier: ^0.3.9
version: 0.3.9
react:
specifier: ^18.3.1
version: 18.3.1
solid-js:
specifier: ^1.8.21
version: 1.8.21
zod:
specifier: ^3.23.8
version: 3.23.8
devDependencies:
'@types/react':
specifier: ^18.3.3
version: 18.3.3
packages/core: {}
@ -252,8 +268,8 @@ importers:
packages/scripts:
dependencies:
'@flowr/utils':
specifier: ^3.11.6
version: 3.11.6
specifier: ^3.12.0
version: 3.12.0
execa:
specifier: ^9.3.1
version: 9.3.1
@ -294,11 +310,11 @@ packages:
'@actions/github@5.1.1':
resolution: {integrity: sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==}
'@actions/glob@0.4.0':
resolution: {integrity: sha512-+eKIGFhsFa4EBwaf/GMyzCdWrXWymGXfFmZU3FHQvYS8mPcHtTtZONbkcqqUMzw9mJ/pImEBFET1JNifhqGsAQ==}
'@actions/glob@0.5.0':
resolution: {integrity: sha512-tST2rjPvJLRZLuT9NMUtyBjvj9Yo0MiJS3ow004slMvm8GFM+Zv9HvMJ7HWzfUyJnGrJvDsYkWBaaG3YKXRtCw==}
'@actions/http-client@2.2.1':
resolution: {integrity: sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==}
'@actions/http-client@2.2.2':
resolution: {integrity: sha512-2TvX5LskKQzDDQI+bobIDGAjkn0NJiQlg4MTrKnZ8HfQ7nDEUbtJ1ytxPDb2bfk3Hr2XD99X8oAJISAmIoiSAQ==}
'@actions/io@1.1.3':
resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==}
@ -912,8 +928,8 @@ packages:
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
engines: {node: '>=14'}
'@flowr/eslint-config@3.11.6':
resolution: {integrity: sha512-vJHNIk37sqGaVgYOdy2x5UO2I+MOmDiiP8zLcVJrUCp5q4aiwqZ2/TgyHHE4Fi0ZCShcd0pPCbKCpq5Su9szJw==}
'@flowr/eslint-config@3.12.0':
resolution: {integrity: sha512-5Xl0ScnpO0SiW+hCyQe9yPVzmAgSBAnjtyvsRujuUL3AomUi1sknF+3JoiaEfd2V278EeaHornsZOinpIdzXVQ==}
engines: {node: '>=20'}
peerDependencies:
'@eslint-react/eslint-plugin': ^1.5.8
@ -976,13 +992,22 @@ packages:
vue-eslint-parser:
optional: true
'@flowr/utils@3.11.6':
resolution: {integrity: sha512-ACrMz5ClD5j1w3FQXig5DLLHvqMm89xbsApg8wjBAmk7oYLA3YfcxdMI0G993XLCIKY+44oQYV4wOVdjCCERow==}
'@flowr/utils@3.12.0':
resolution: {integrity: sha512-ZAyinoGoyVWNBl0iAjiiWYaRrAPgu2ApCRVBHh5Kb/abpcsfQnybZzeu6Rz9olxPmtp/OjvBmS36/xLK+9ZJZQ==}
engines: {node: '>=20'}
'@fontsource/poppins@5.0.14':
resolution: {integrity: sha512-nmM1zpPo3Uh4JcGAVSQuWaZNYh2FbbwWhZ5t6hRaynmJaNTBW85d3nEh9zMmzI0HX7X5xqQVdRHeDatKpOGsnA==}
'@formatjs/ecma402-abstract@2.0.0':
resolution: {integrity: sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==}
'@formatjs/intl-durationformat@0.2.4':
resolution: {integrity: sha512-wtmC8eZeIkyQ8fVWdarAjNbqOkAq0wQ7GBoG6aBIK0+O9wU5gq9l0jOpKYymdQq4Hz3lZKpgXgXcZm+Z40w4Rw==}
'@formatjs/intl-localematcher@0.5.4':
resolution: {integrity: sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==}
'@humanwhocodes/module-importer@1.0.1':
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
engines: {node: '>=12.22'}
@ -1286,6 +1311,11 @@ packages:
peerDependencies:
solid-js: ^1.6.12
'@solid-primitives/i18n@2.1.1':
resolution: {integrity: sha512-1p9B8hveu+gzFRWfXcRtdzzEdr7gw3c8uLXm+2bU33JHgiI8kYJsWvG128sE6vU1ZtYGPrGq980Jd6hxYupyZQ==}
peerDependencies:
solid-js: ^1.6.12
'@solid-primitives/memo@1.3.9':
resolution: {integrity: sha512-OIlGcsEPXr6U23fDaSEm8iqezWDT4SNSjLTekWQVOu4qHostnMPlqU8xo1Jf0I7OgRuqA0wTMQ5cu0bYjeR/ZQ==}
peerDependencies:
@ -1326,31 +1356,31 @@ packages:
'@solidjs/router':
optional: true
'@stylistic/eslint-plugin-js@2.6.3':
resolution: {integrity: sha512-VkfqvbP9ro4XlP7wjIe6tWJjh6rzEJYYeIr5oWHTiayHfKgtRgUIRIWTZu1vbJg49aP2CsM0GRFI6iX5xwqTXA==}
'@stylistic/eslint-plugin-js@2.6.4':
resolution: {integrity: sha512-kx1hS3xTvzxZLdr/DCU/dLBE++vcP97sHeEFX2QXhk1Ipa4K1rzPOLw1HCbf4mU3s+7kHP5eYpDe+QteEOFLug==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.40.0'
'@stylistic/eslint-plugin-jsx@2.6.3':
resolution: {integrity: sha512-33GvA4L4uHvD0cdOE6ufy52W2pmpGtjIAQQWlROv5NRFw0mKpe7wK5++mOXmujlY5gbX51k8poPjvludIUK2og==}
'@stylistic/eslint-plugin-jsx@2.6.4':
resolution: {integrity: sha512-bIvVhdtjmyu3S10V7QRIuawtCZSq9gRmzAX23ucjCOdSFzEwlq+di0IM0riBAvvQerrJL4SM6G3xgyPs8BSXIA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.40.0'
'@stylistic/eslint-plugin-plus@2.6.3':
resolution: {integrity: sha512-lQ/BtROkPAOSTORfEsRcL+3lNt8+H/jS7mFF2j859PSyb487bmoO6npmGCr4dNfFrz5d0h11i3zp1hT/trZ8HA==}
'@stylistic/eslint-plugin-plus@2.6.4':
resolution: {integrity: sha512-EuRvtxhf7Hv8OoMIePulP/6rBJIgPTu1l5GAm1780WcF1Cl8bOZXIn84Pdac5pNv6lVlzCOFm8MD3VE+2YROuA==}
peerDependencies:
eslint: '*'
'@stylistic/eslint-plugin-ts@2.6.3':
resolution: {integrity: sha512-eb8v1ad/FgALhPDptANIGP/rpd9b3ESmG/j4q489KK4MmQyeJYiZCks8xN6AHGkJ8QsLziw0xXWNb74KuxbB7g==}
'@stylistic/eslint-plugin-ts@2.6.4':
resolution: {integrity: sha512-yxL8Hj6WkObw1jfiLpBzKy5yfxY6vwlwO4miq34ySErUjUecPV5jxfVbOe4q1QDPKemQGPq93v7sAQS5PzM8lA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.40.0'
'@stylistic/eslint-plugin@2.6.3':
resolution: {integrity: sha512-QCt1XviL9qghGN1Jnb6PCRzQTbvkUq11ybFrASi6ypuiLO1i6Oo/j22uKE3wXKG8lnOkvfjLFm0dumyaqaPG+g==}
'@stylistic/eslint-plugin@2.6.4':
resolution: {integrity: sha512-euUGnjzH8EOqEYTGk9dB2OBINp0FX1nuO7/k4fO82zNRBIKZgJoDwTLM4Ce+Om6W1Qmh1PrZjCr4jh4tMEXGPQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.40.0'
@ -1441,17 +1471,14 @@ packages:
engines: {node: '>= 10'}
hasBin: true
'@tauri-apps/plugin-clipboard-manager@https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/20e84cfbdebcd86bb1854846feb0aaff4481fbd0':
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/20e84cfbdebcd86bb1854846feb0aaff4481fbd0}
version: 2.1.0-beta.6
'@tauri-apps/plugin-clipboard-manager@2.0.0-rc.0':
resolution: {integrity: sha512-2fS3wbRQEtorkk3Np2msJUeKCXRqLQ9sSo2FzlFdUPYNzThsu43uWCF55McGLAfltNOvXQIcQLUBf05jbBL/5w==}
'@tauri-apps/plugin-dialog@https://codeload.github.com/tauri-apps/tauri-plugin-dialog/tar.gz/f83833c5445948c1b2f022e3c530ca48be9f8768':
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-dialog/tar.gz/f83833c5445948c1b2f022e3c530ca48be9f8768}
version: 2.0.0-rc.0
'@tauri-apps/plugin-dialog@2.0.0-rc.0':
resolution: {integrity: sha512-DPOXYe8SQ6Radk/67EOdaomlxL7oF99JO/ZUaPp1IBEs3Wro7lhlz63CfdKIBfKIZTLJLzP1R7/EiPL/GTA3Bg==}
'@tauri-apps/plugin-shell@https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5cc36dadeaad0520111c6f5e32ecdbbae7cb1311':
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5cc36dadeaad0520111c6f5e32ecdbbae7cb1311}
version: 2.0.0-beta.9
'@tauri-apps/plugin-shell@2.0.0-rc.0':
resolution: {integrity: sha512-bhUcQcrqZoK8H1DFXapr5r1Z75oh6Kd5Tltz97XpZFLREEqp+KhN2Fvyh8r/fKAyenYsTYUIsDsyGdjdueuF9g==}
'@testing-library/dom@10.4.0':
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
@ -1528,12 +1555,18 @@ packages:
'@types/node@20.14.10':
resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
'@types/node@22.3.0':
resolution: {integrity: sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==}
'@types/node@22.4.0':
resolution: {integrity: sha512-49AbMDwYUz7EXxKU/r7mXOsxwFr4BYbvB7tWYxVuLdb2ibd30ijjXINSMAHiEEZk5PCRBmW1gUeisn2VMKt3cQ==}
'@types/normalize-package-data@2.4.4':
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
'@types/prop-types@15.7.12':
resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
'@types/react@18.3.3':
resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==}
'@types/semver@7.5.8':
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
@ -2406,8 +2439,8 @@ packages:
vue-eslint-parser:
optional: true
eslint-plugin-petal@3.11.6:
resolution: {integrity: sha512-6ecrlrjBjk1BvQLJB+muTGsOw7fFfcXTu5GPxJaVkaV6c7J2jRULP+T9WDTzVYPaxbxpH8Gnqt0shi38mXISwA==}
eslint-plugin-petal@3.12.0:
resolution: {integrity: sha512-EE1dB1HfHT9YsdjPARgB4r2FtekPDKVE+GKfReDdyWdJa+WZ3E8C/44ZkXMDntzlRJvaGnk22REtB26RC6q+zA==}
engines: {node: '>=20'}
peerDependencies:
eslint: '>=8.40.0'
@ -3024,6 +3057,10 @@ packages:
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
loupe@3.1.1:
resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==}
@ -3447,6 +3484,10 @@ packages:
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
read-pkg-up@7.0.1:
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
engines: {node: '>=8'}
@ -3888,8 +3929,8 @@ packages:
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
undici-types@6.18.2:
resolution: {integrity: sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==}
undici-types@6.19.6:
resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==}
undici@5.28.4:
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
@ -4196,7 +4237,7 @@ snapshots:
dependencies:
'@actions/core': 1.10.1
'@actions/github': 5.1.1
'@actions/http-client': 2.2.1
'@actions/http-client': 2.2.2
'@azure/storage-blob': 12.24.0
'@octokit/core': 3.6.0
'@octokit/plugin-request-log': 1.0.4(@octokit/core@3.6.0)
@ -4215,7 +4256,7 @@ snapshots:
'@actions/core@1.10.1':
dependencies:
'@actions/http-client': 2.2.1
'@actions/http-client': 2.2.2
uuid: 8.3.2
'@actions/exec@1.1.1':
@ -4224,19 +4265,19 @@ snapshots:
'@actions/github@5.1.1':
dependencies:
'@actions/http-client': 2.2.1
'@actions/http-client': 2.2.2
'@octokit/core': 3.6.0
'@octokit/plugin-paginate-rest': 2.21.3(@octokit/core@3.6.0)
'@octokit/plugin-rest-endpoint-methods': 5.16.2(@octokit/core@3.6.0)
transitivePeerDependencies:
- encoding
'@actions/glob@0.4.0':
'@actions/glob@0.5.0':
dependencies:
'@actions/core': 1.10.1
minimatch: 3.1.2
'@actions/http-client@2.2.1':
'@actions/http-client@2.2.2':
dependencies:
tunnel: 0.0.6
undici: 5.28.4
@ -4247,7 +4288,7 @@ snapshots:
dependencies:
'@actions/core': 1.10.1
'@actions/exec': 1.1.1
'@actions/http-client': 2.2.1
'@actions/http-client': 2.2.2
'@actions/io': 1.1.3
semver: 6.3.1
uuid: 3.4.0
@ -4889,15 +4930,15 @@ snapshots:
'@fastify/busboy@2.1.1': {}
'@flowr/eslint-config@3.11.6(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(@unocss/eslint-plugin@0.62.2(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-solid@0.14.1(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-vue@9.27.0(eslint@9.9.0(jiti@1.21.6)))(eslint-processor-vue-blocks@0.1.2(@vue/compiler-sfc@3.4.38)(eslint@9.9.0(jiti@1.21.6)))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6)))':
'@flowr/eslint-config@3.12.0(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(@unocss/eslint-plugin@0.62.2(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-solid@0.14.1(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-vue@9.27.0(eslint@9.9.0(jiti@1.21.6)))(eslint-processor-vue-blocks@0.1.2(@vue/compiler-sfc@3.4.38)(eslint@9.9.0(jiti@1.21.6)))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6)))':
dependencies:
'@antfu/install-pkg': 0.3.5
'@clack/prompts': 0.7.0
'@eslint-community/eslint-plugin-eslint-comments': 4.4.0(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin': 2.6.3(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
'@stylistic/eslint-plugin': 2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/eslint-plugin': 8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/parser': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
'@vitest/eslint-plugin': 1.0.3(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))
'@vitest/eslint-plugin': 1.0.3(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))
eslint: 9.9.0(jiti@1.21.6)
eslint-flat-config-utils: 0.3.0
eslint-merge-processors: 0.1.0(eslint@9.9.0(jiti@1.21.6))
@ -4908,7 +4949,7 @@ snapshots:
eslint-plugin-markdown: 5.1.0(eslint@9.9.0(jiti@1.21.6))
eslint-plugin-n: 17.10.2(eslint@9.9.0(jiti@1.21.6))
eslint-plugin-perfectionist: 3.2.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6)))
eslint-plugin-petal: 3.11.6(eslint@9.9.0(jiti@1.21.6))
eslint-plugin-petal: 3.12.0(eslint@9.9.0(jiti@1.21.6))
eslint-plugin-regexp: 2.6.0(eslint@9.9.0(jiti@1.21.6))
eslint-plugin-toml: 0.11.1(eslint@9.9.0(jiti@1.21.6))
eslint-plugin-unicorn: 55.0.0(eslint@9.9.0(jiti@1.21.6))
@ -4934,10 +4975,25 @@ snapshots:
- typescript
- vitest
'@flowr/utils@3.11.6': {}
'@flowr/utils@3.12.0': {}
'@fontsource/poppins@5.0.14': {}
'@formatjs/ecma402-abstract@2.0.0':
dependencies:
'@formatjs/intl-localematcher': 0.5.4
tslib: 2.6.3
'@formatjs/intl-durationformat@0.2.4':
dependencies:
'@formatjs/ecma402-abstract': 2.0.0
'@formatjs/intl-localematcher': 0.5.4
tslib: 2.6.3
'@formatjs/intl-localematcher@0.5.4':
dependencies:
tslib: 2.6.3
'@humanwhocodes/module-importer@1.0.1': {}
'@humanwhocodes/retry@0.3.0': {}
@ -5256,6 +5312,10 @@ snapshots:
'@solid-primitives/memo': 1.3.9(solid-js@1.8.21)
solid-js: 1.8.21
'@solid-primitives/i18n@2.1.1(solid-js@1.8.21)':
dependencies:
solid-js: 1.8.21
'@solid-primitives/memo@1.3.9(solid-js@1.8.21)':
dependencies:
'@solid-primitives/scheduled': 1.4.3(solid-js@1.8.21)
@ -5290,7 +5350,7 @@ snapshots:
optionalDependencies:
'@solidjs/router': 0.14.3(solid-js@1.8.21)
'@stylistic/eslint-plugin-js@2.6.3(eslint@9.9.0(jiti@1.21.6))':
'@stylistic/eslint-plugin-js@2.6.4(eslint@9.9.0(jiti@1.21.6))':
dependencies:
'@types/eslint': 9.6.0
acorn: 8.12.1
@ -5298,9 +5358,9 @@ snapshots:
eslint-visitor-keys: 4.0.0
espree: 10.1.0
'@stylistic/eslint-plugin-jsx@2.6.3(eslint@9.9.0(jiti@1.21.6))':
'@stylistic/eslint-plugin-jsx@2.6.4(eslint@9.9.0(jiti@1.21.6))':
dependencies:
'@stylistic/eslint-plugin-js': 2.6.3(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-js': 2.6.4(eslint@9.9.0(jiti@1.21.6))
'@types/eslint': 9.6.0
eslint: 9.9.0(jiti@1.21.6)
eslint-visitor-keys: 4.0.0
@ -5308,14 +5368,14 @@ snapshots:
estraverse: 5.3.0
picomatch: 4.0.2
'@stylistic/eslint-plugin-plus@2.6.3(eslint@9.9.0(jiti@1.21.6))':
'@stylistic/eslint-plugin-plus@2.6.4(eslint@9.9.0(jiti@1.21.6))':
dependencies:
'@types/eslint': 9.6.0
eslint: 9.9.0(jiti@1.21.6)
'@stylistic/eslint-plugin-ts@2.6.3(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)':
'@stylistic/eslint-plugin-ts@2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@stylistic/eslint-plugin-js': 2.6.3(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-js': 2.6.4(eslint@9.9.0(jiti@1.21.6))
'@types/eslint': 9.6.0
'@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
eslint: 9.9.0(jiti@1.21.6)
@ -5323,12 +5383,12 @@ snapshots:
- supports-color
- typescript
'@stylistic/eslint-plugin@2.6.3(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)':
'@stylistic/eslint-plugin@2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@stylistic/eslint-plugin-js': 2.6.3(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-jsx': 2.6.3(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-plus': 2.6.3(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-ts': 2.6.3(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
'@stylistic/eslint-plugin-js': 2.6.4(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-jsx': 2.6.4(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-plus': 2.6.4(eslint@9.9.0(jiti@1.21.6))
'@stylistic/eslint-plugin-ts': 2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
'@types/eslint': 9.6.0
eslint: 9.9.0(jiti@1.21.6)
transitivePeerDependencies:
@ -5393,15 +5453,15 @@ snapshots:
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-rc.3
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-rc.3
'@tauri-apps/plugin-clipboard-manager@https://codeload.github.com/tauri-apps/tauri-plugin-clipboard-manager/tar.gz/20e84cfbdebcd86bb1854846feb0aaff4481fbd0':
'@tauri-apps/plugin-clipboard-manager@2.0.0-rc.0':
dependencies:
'@tauri-apps/api': 2.0.0-rc.0
'@tauri-apps/plugin-dialog@https://codeload.github.com/tauri-apps/tauri-plugin-dialog/tar.gz/f83833c5445948c1b2f022e3c530ca48be9f8768':
'@tauri-apps/plugin-dialog@2.0.0-rc.0':
dependencies:
'@tauri-apps/api': 2.0.0-rc.0
'@tauri-apps/plugin-shell@https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5cc36dadeaad0520111c6f5e32ecdbbae7cb1311':
'@tauri-apps/plugin-shell@2.0.0-rc.0':
dependencies:
'@tauri-apps/api': 2.0.0-rc.0
@ -5496,12 +5556,19 @@ snapshots:
dependencies:
undici-types: 5.26.5
'@types/node@22.3.0':
'@types/node@22.4.0':
dependencies:
undici-types: 6.18.2
undici-types: 6.19.6
'@types/normalize-package-data@2.4.4': {}
'@types/prop-types@15.7.12': {}
'@types/react@18.3.3':
dependencies:
'@types/prop-types': 15.7.12
csstype: 3.1.3
'@types/semver@7.5.8': {}
'@types/unist@2.0.11': {}
@ -5665,13 +5732,13 @@ snapshots:
'@typescript-eslint/types': 8.1.0
eslint-visitor-keys: 3.4.3
'@unocss/astro@0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))':
'@unocss/astro@0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))':
dependencies:
'@unocss/core': 0.62.2
'@unocss/reset': 0.62.2
'@unocss/vite': 0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
'@unocss/vite': 0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
optionalDependencies:
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
transitivePeerDependencies:
- rollup
- supports-color
@ -5820,7 +5887,7 @@ snapshots:
dependencies:
'@unocss/core': 0.62.2
'@unocss/vite@0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))':
'@unocss/vite@0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))':
dependencies:
'@ampproject/remapping': 2.3.0
'@rollup/pluginutils': 5.1.0(rollup@4.20.0)
@ -5832,7 +5899,7 @@ snapshots:
chokidar: 3.6.0
magic-string: 0.30.11
tinyglobby: 0.2.2
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
transitivePeerDependencies:
- rollup
- supports-color
@ -5843,13 +5910,13 @@ snapshots:
'@vercel/ncc@0.38.1': {}
'@vitest/eslint-plugin@1.0.3(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))':
'@vitest/eslint-plugin@1.0.3(@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8))':
dependencies:
eslint: 9.9.0(jiti@1.21.6)
optionalDependencies:
'@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)
typescript: 5.5.4
vitest: 2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8)
vitest: 2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8)
'@vitest/expect@2.0.5':
dependencies:
@ -5886,7 +5953,7 @@ snapshots:
pathe: 1.1.2
sirv: 2.0.4
tinyrainbow: 1.2.0
vitest: 2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8)
vitest: 2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8)
'@vitest/utils@2.0.5':
dependencies:
@ -6576,9 +6643,9 @@ snapshots:
- supports-color
- typescript
eslint-plugin-petal@3.11.6(eslint@9.9.0(jiti@1.21.6)):
eslint-plugin-petal@3.12.0(eslint@9.9.0(jiti@1.21.6)):
dependencies:
'@flowr/utils': 3.11.6
'@flowr/utils': 3.12.0
eslint: 9.9.0(jiti@1.21.6)
eslint-plugin-regexp@2.6.0(eslint@9.9.0(jiti@1.21.6)):
@ -7256,6 +7323,10 @@ snapshots:
lodash@4.17.21: {}
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
loupe@3.1.1:
dependencies:
get-func-name: 2.0.2
@ -7642,6 +7713,10 @@ snapshots:
react-is@17.0.2: {}
react@18.3.1:
dependencies:
loose-envify: 1.4.0
read-pkg-up@7.0.1:
dependencies:
find-up: 4.1.0
@ -8007,14 +8082,14 @@ snapshots:
dependencies:
typescript: 5.5.4
ts-node@10.9.2(@types/node@22.3.0)(typescript@5.5.4):
ts-node@10.9.2(@types/node@22.4.0)(typescript@5.5.4):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 22.3.0
'@types/node': 22.4.0
acorn: 8.11.3
acorn-walk: 8.3.2
arg: 4.1.3
@ -8085,7 +8160,7 @@ snapshots:
undici-types@5.26.5: {}
undici-types@6.18.2: {}
undici-types@6.19.6: {}
undici@5.28.4:
dependencies:
@ -8103,9 +8178,9 @@ snapshots:
universalify@0.2.0: {}
unocss@0.62.2(postcss@8.4.41)(rollup@4.20.0)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8)):
unocss@0.62.2(postcss@8.4.41)(rollup@4.20.0)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8)):
dependencies:
'@unocss/astro': 0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
'@unocss/astro': 0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
'@unocss/cli': 0.62.2(rollup@4.20.0)
'@unocss/core': 0.62.2
'@unocss/extractor-arbitrary-variants': 0.62.2
@ -8124,9 +8199,9 @@ snapshots:
'@unocss/transformer-compile-class': 0.62.2
'@unocss/transformer-directives': 0.62.2
'@unocss/transformer-variant-group': 0.62.2
'@unocss/vite': 0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
'@unocss/vite': 0.62.2(rollup@4.20.0)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
optionalDependencies:
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
transitivePeerDependencies:
- postcss
- rollup
@ -8182,13 +8257,13 @@ snapshots:
spdx-correct: 3.2.0
spdx-expression-parse: 3.0.1
vite-node@2.0.5(@types/node@22.3.0)(sass@1.77.8):
vite-node@2.0.5(@types/node@22.4.0)(sass@1.77.8):
dependencies:
cac: 6.7.14
debug: 4.3.6
pathe: 1.1.2
tinyrainbow: 1.2.0
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
transitivePeerDependencies:
- '@types/node'
- less
@ -8200,13 +8275,13 @@ snapshots:
- supports-color
- terser
vite-plugin-solid-svg@0.8.1(solid-js@1.8.21)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8)):
vite-plugin-solid-svg@0.8.1(solid-js@1.8.21)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8)):
dependencies:
solid-js: 1.8.21
svgo: 3.3.2
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
vite-plugin-solid@2.10.2(@testing-library/jest-dom@6.4.8)(solid-js@1.8.21)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8)):
vite-plugin-solid@2.10.2(@testing-library/jest-dom@6.4.8)(solid-js@1.8.21)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8)):
dependencies:
'@babel/core': 7.24.9
'@types/babel__core': 7.20.5
@ -8214,39 +8289,39 @@ snapshots:
merge-anything: 5.1.7
solid-js: 1.8.21
solid-refresh: 0.6.3(solid-js@1.8.21)
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vitefu: 0.2.5(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8))
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
vitefu: 0.2.5(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8))
optionalDependencies:
'@testing-library/jest-dom': 6.4.8
transitivePeerDependencies:
- supports-color
vite-tsconfig-paths@5.0.1(typescript@5.5.4)(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8)):
vite-tsconfig-paths@5.0.1(typescript@5.5.4)(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8)):
dependencies:
debug: 4.3.6
globrex: 0.1.2
tsconfck: 3.1.1(typescript@5.5.4)
optionalDependencies:
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
transitivePeerDependencies:
- supports-color
- typescript
vite@5.4.1(@types/node@22.3.0)(sass@1.77.8):
vite@5.4.1(@types/node@22.4.0)(sass@1.77.8):
dependencies:
esbuild: 0.21.5
postcss: 8.4.41
rollup: 4.20.0
optionalDependencies:
'@types/node': 22.3.0
'@types/node': 22.4.0
fsevents: 2.3.3
sass: 1.77.8
vitefu@0.2.5(vite@5.4.1(@types/node@22.3.0)(sass@1.77.8)):
vitefu@0.2.5(vite@5.4.1(@types/node@22.4.0)(sass@1.77.8)):
optionalDependencies:
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
vitest@2.0.5(@types/node@22.3.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8):
vitest@2.0.5(@types/node@22.4.0)(@vitest/ui@2.0.5)(jsdom@24.1.1)(sass@1.77.8):
dependencies:
'@ampproject/remapping': 2.3.0
'@vitest/expect': 2.0.5
@ -8264,11 +8339,11 @@ snapshots:
tinybench: 2.8.0
tinypool: 1.0.0
tinyrainbow: 1.2.0
vite: 5.4.1(@types/node@22.3.0)(sass@1.77.8)
vite-node: 2.0.5(@types/node@22.3.0)(sass@1.77.8)
vite: 5.4.1(@types/node@22.4.0)(sass@1.77.8)
vite-node: 2.0.5(@types/node@22.4.0)(sass@1.77.8)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 22.3.0
'@types/node': 22.4.0
'@vitest/ui': 2.0.5(vitest@2.0.5)
jsdom: 24.1.1
transitivePeerDependencies: