mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 16b9ca79f2 | |||
| 792ad9d777 | |||
| b6ecaa3934 | |||
| bb4ce5505a | |||
| d6aad2690c | |||
| cfb2b35bf7 | |||
| 40f6803b90 | |||
| d2c1d815a1 | |||
| 4c8617a419 | |||
| 444db56d90 | |||
| 4b94b11b53 | |||
| 1a9ed04cc2 | |||
| f3d4c64118 |
+1
-1
@@ -2,7 +2,7 @@ root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
+6
-1
@@ -46,7 +46,12 @@ module.exports = {
|
||||
"react/prop-types": "off",
|
||||
"import/no-cycle": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"react/jsx-no-target-blank": "off"
|
||||
"react/jsx-no-target-blank": "off",
|
||||
"@typescript-eslint/ban-types": ["error", {
|
||||
types: {
|
||||
Function: false,
|
||||
}
|
||||
}]
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
name : e2e-tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
e2e-tests-windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Cleanup files
|
||||
run: cmd /r dir
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
cache: "npm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install Playwright deps
|
||||
run: npx playwright install --with-deps
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Package
|
||||
run: npm exec -c 'electron-builder build --publish "never" --win --x64'
|
||||
|
||||
- name: Run e2e tests
|
||||
run: npm run e2e-test-ci
|
||||
|
||||
- name: Upload test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: playwright-output
|
||||
path: test-results/
|
||||
|
||||
+2
-1
@@ -28,4 +28,5 @@ npm-debug.log.*
|
||||
*.sass.d.ts
|
||||
*.scss.d.ts
|
||||
|
||||
test-results
|
||||
# externals
|
||||
externals/bs-admin-start/target/*
|
||||
|
||||
@@ -67,5 +67,8 @@
|
||||
"username": "Lumberjack462",
|
||||
"type": "diamond",
|
||||
"link": "https://www.youtube.com/@lumberjack462"
|
||||
},
|
||||
{
|
||||
"username": "Xero"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
Binary file not shown.
@@ -1,243 +0,0 @@
|
||||
/**
|
||||
* Code taken from https://github.com/kubeshop/monokle/blob/main/tests/electronHelpers.ts
|
||||
* don't tunch unless you know what you're doing
|
||||
*/
|
||||
|
||||
import { Page } from "@playwright/test";
|
||||
import path from "path";
|
||||
import {ElectronApplication, _electron as electron} from 'playwright-core';
|
||||
import { pause } from "shared/helpers/promise.helpers";
|
||||
import log from "electron-log";
|
||||
import * as fs from 'fs';
|
||||
import * as ASAR from 'asar';
|
||||
|
||||
export const TEST_OUTPUT_DIR = 'test-results';
|
||||
|
||||
export async function startApp(): Promise<StartAppResponse> {
|
||||
const latestBuild = findLatestBuild();
|
||||
const appInfo = parseElectronApp(latestBuild);
|
||||
const electronApp = await electron.launch({
|
||||
args: [appInfo.main],
|
||||
env: {
|
||||
...process.env,
|
||||
E2E_BUILD: "true",
|
||||
},
|
||||
executablePath: appInfo.executable,
|
||||
recordVideo: {
|
||||
dir: getRecordingPath(appInfo.platform),
|
||||
size: {
|
||||
width: 1200,
|
||||
height: 800,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const appWindow = await electronApp.firstWindow();
|
||||
|
||||
if (!appWindow) {
|
||||
throw new Error('Unable to get main window');
|
||||
}
|
||||
|
||||
await pause(3000);
|
||||
|
||||
appWindow.on('console', log.info);
|
||||
appWindow.screenshot({path: path.join(TEST_OUTPUT_DIR, "initial-screen.png")});
|
||||
|
||||
return {appWindow, appInfo, electronApp};
|
||||
}
|
||||
|
||||
export function findLatestBuild(): string {
|
||||
const rootDir = path.resolve('./');
|
||||
const outDir = path.join(rootDir, 'release', 'build');
|
||||
const builds = fs.readdirSync(outDir);
|
||||
const platforms = ['win32', 'win', 'windows', 'darwin', 'mac', 'macos', 'osx', 'linux', 'ubuntu'];
|
||||
|
||||
const latestBuild = builds
|
||||
.map(fileName => {
|
||||
// make sure it's a directory with "-" delimited platform in its name
|
||||
const stats = fs.statSync(path.join(outDir, fileName));
|
||||
const isBuild = fileName.toLocaleLowerCase().split('-').some(part => platforms.includes(part));
|
||||
|
||||
if(!stats.isDirectory() || !isBuild){ return undefined; }
|
||||
|
||||
return {
|
||||
name: fileName,
|
||||
time: fs.statSync(path.join(outDir, fileName)).mtimeMs,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => b.time - a.time)
|
||||
.map(file => file?.name)[0];
|
||||
|
||||
if (!latestBuild) {
|
||||
throw new Error('No build found in out directory');
|
||||
}
|
||||
|
||||
return path.join(outDir, latestBuild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a directory containing an Electron app build,
|
||||
* return the path to the app's executable and the path to the app's main file.
|
||||
*/
|
||||
export function parseElectronApp(buildDir: string): ElectronAppInfo {
|
||||
log.info(`Parsing Electron app in ${buildDir}`);
|
||||
|
||||
let platform: string | undefined;
|
||||
|
||||
if (buildDir.endsWith('.app')) {
|
||||
buildDir = path.dirname(buildDir);
|
||||
platform = 'darwin';
|
||||
}
|
||||
else if (buildDir.endsWith('.exe')) {
|
||||
buildDir = path.dirname(buildDir);
|
||||
platform = 'win32';
|
||||
}
|
||||
|
||||
const baseName = path.basename(buildDir).toLowerCase();
|
||||
if (!platform) {
|
||||
// parse the directory name to figure out the platform
|
||||
if (baseName.includes('win')) {
|
||||
platform = 'win32';
|
||||
}
|
||||
if (baseName.includes('linux') || baseName.includes('ubuntu') || baseName.includes('debian')) {
|
||||
platform = 'linux';
|
||||
}
|
||||
if (baseName.includes('darwin') || baseName.includes('mac') || baseName.includes('osx')) {
|
||||
platform = 'darwin';
|
||||
}
|
||||
}
|
||||
|
||||
if (!platform) {
|
||||
throw new Error(`Platform not found in directory name: ${baseName}`);
|
||||
}
|
||||
|
||||
let arch: Architecture;
|
||||
if (baseName.includes('x32') || baseName.includes('i386')) {
|
||||
arch = 'x32';
|
||||
}
|
||||
if (baseName.includes('x64')) {
|
||||
arch = 'x64';
|
||||
}
|
||||
if (baseName.includes('arm64')) {
|
||||
arch = 'arm64';
|
||||
}
|
||||
|
||||
let executable: string;
|
||||
let main: string;
|
||||
let name: string;
|
||||
let asar: boolean;
|
||||
let resourcesDir: string;
|
||||
|
||||
if (platform === 'darwin') {
|
||||
// MacOS Structure
|
||||
// <buildDir>/
|
||||
// <appName>.app/
|
||||
// Contents/
|
||||
// MacOS/
|
||||
// <appName> (executable)
|
||||
// Info.plist
|
||||
// PkgInfo
|
||||
// Resources/
|
||||
// electron.icns
|
||||
// file.icns
|
||||
// app.asar (asar bundle) - or -
|
||||
// app
|
||||
// package.json
|
||||
// (your app structure)
|
||||
|
||||
const list = fs.readdirSync(buildDir);
|
||||
const appBundle = list.find(fileName => {
|
||||
return fileName.endsWith('.app');
|
||||
});
|
||||
|
||||
const appDir = path.join(buildDir, appBundle, 'Contents', 'MacOS');
|
||||
const appName = fs.readdirSync(appDir)[0];
|
||||
executable = path.join(appDir, appName);
|
||||
|
||||
resourcesDir = path.join(buildDir, appBundle, 'Contents', 'Resources');
|
||||
const resourcesList = fs.readdirSync(resourcesDir);
|
||||
asar = resourcesList.includes('app.asar');
|
||||
|
||||
let packageJson: {main: string; name: string};
|
||||
if (asar) {
|
||||
const asarPath = path.join(resourcesDir, 'app.asar');
|
||||
packageJson = JSON.parse(ASAR.extractFile(asarPath, 'package.json').toString('utf8'));
|
||||
main = path.join(asarPath, packageJson.main);
|
||||
} else {
|
||||
packageJson = JSON.parse(fs.readFileSync(path.join(resourcesDir, 'app', 'package.json'), 'utf8'));
|
||||
main = path.join(resourcesDir, 'app', packageJson.main);
|
||||
}
|
||||
name = packageJson.name;
|
||||
}
|
||||
else if (platform === 'win32') {
|
||||
// Windows Structure
|
||||
// <buildDir>/
|
||||
// <appName>.exe (executable)
|
||||
// resources/
|
||||
// app.asar (asar bundle) - or -
|
||||
// app
|
||||
// package.json
|
||||
// (your app structure)
|
||||
|
||||
const list = fs.readdirSync(buildDir);
|
||||
const exe = list.find(fileName => {
|
||||
return fileName.endsWith('.exe');
|
||||
});
|
||||
|
||||
executable = path.join(buildDir, exe);
|
||||
|
||||
resourcesDir = path.join(buildDir, 'resources');
|
||||
const resourcesList = fs.readdirSync(resourcesDir);
|
||||
asar = resourcesList.includes('app.asar');
|
||||
|
||||
let packageJson: {main: string; name: string};
|
||||
|
||||
if (asar) {
|
||||
const asarPath = path.join(resourcesDir, 'app.asar');
|
||||
packageJson = JSON.parse(ASAR.extractFile(asarPath, 'package.json').toString('utf8'));
|
||||
main = path.join(asarPath, packageJson.main);
|
||||
} else {
|
||||
packageJson = JSON.parse(fs.readFileSync(path.join(resourcesDir, 'app', 'package.json'), 'utf8'));
|
||||
main = path.join(resourcesDir, 'app', packageJson.main);
|
||||
}
|
||||
name = packageJson.name;
|
||||
}
|
||||
else {
|
||||
/** @todo add support for linux */
|
||||
throw new Error(`Platform not supported: ${platform}`);
|
||||
}
|
||||
|
||||
return { executable, main, asar, name, platform, resourcesDir, arch };
|
||||
}
|
||||
|
||||
export function getRecordingPath(...paths: string[]): string {
|
||||
return path.join(TEST_OUTPUT_DIR, ...paths);
|
||||
}
|
||||
|
||||
export function getMainWindow(windows: Page[]): Page {
|
||||
const mainWindow = windows.find(w => w.url().includes('index.html'));
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
type Architecture = 'x64' | 'x32' | 'arm64';
|
||||
export interface ElectronAppInfo {
|
||||
/** Path to the app's executable file */
|
||||
executable: string;
|
||||
/** Path to the app's main (JS) file */
|
||||
main: string;
|
||||
/** Name of the app */
|
||||
name: string;
|
||||
/** Resources directory */
|
||||
resourcesDir: string;
|
||||
/** True if the app is using asar */
|
||||
asar: boolean;
|
||||
/** OS platform */
|
||||
platform: 'darwin' | 'win32' | 'linux';
|
||||
arch: Architecture;
|
||||
}
|
||||
|
||||
interface StartAppResponse {
|
||||
electronApp: ElectronApplication;
|
||||
appWindow: Page;
|
||||
appInfo: ElectronAppInfo;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import {Page} from 'playwright';
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { getRecordingPath, startApp } from './helpers/electron.helpers';
|
||||
import { pause } from 'shared/helpers/promise.helpers';
|
||||
import { MainWindow } from './models/main-window.class';
|
||||
import { AddVersionPanel } from './models/add-version-panel.class';
|
||||
|
||||
|
||||
let appWindow: Page;
|
||||
let mainWindow: MainWindow;
|
||||
let addVersionPanel: AddVersionPanel;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const startAppResponse = await startApp();
|
||||
appWindow = startAppResponse.appWindow;
|
||||
mainWindow = new MainWindow(appWindow);
|
||||
addVersionPanel = new AddVersionPanel(appWindow);
|
||||
});
|
||||
|
||||
test.beforeEach(async () => {
|
||||
await pause(1000);
|
||||
await mainWindow.clickAddVersionButton();
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await pause(1000);
|
||||
});
|
||||
|
||||
test('should be able to select then unselect a bs version', async () => {
|
||||
const versionManifest = "8948172000430595334";
|
||||
await addVersionPanel.selectYear("2021");
|
||||
await pause(1000);
|
||||
|
||||
await addVersionPanel.clickVersion(versionManifest); // select version 0.12.2
|
||||
await pause(1000);
|
||||
|
||||
expect(await addVersionPanel.downloadVersionButton.isVisible()).toBeTruthy();
|
||||
|
||||
await addVersionPanel.clickVersion(versionManifest); // deselect version 0.12.2
|
||||
await pause(3000);
|
||||
|
||||
expect(await addVersionPanel.downloadVersionButton.isVisible()).toBeFalsy();
|
||||
|
||||
// sadly we can't test if the download works or not :( (Steam ids, dot-net, etc)
|
||||
});
|
||||
|
||||
test('should be able to download a map then delete it', async () => {
|
||||
// TODO: implement this test
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await pause(3000);
|
||||
await appWindow.screenshot({path: getRecordingPath("final-screen.png")});
|
||||
await appWindow.close();
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Page, Locator } from "playwright";
|
||||
import { MainWindow } from "./main-window.class";
|
||||
|
||||
export class AddVersionPanel extends MainWindow {
|
||||
|
||||
private readonly _yearsTabBar: Locator;
|
||||
private readonly _downloadVersionButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
|
||||
this._yearsTabBar = page.locator("#version-years-tab-bar");
|
||||
this._downloadVersionButton = page.locator("#download-version-btn");
|
||||
}
|
||||
|
||||
selectYear(year: string): Promise<void>{
|
||||
return this._yearsTabBar.getByText(year).click();
|
||||
}
|
||||
|
||||
clickVersion(manifest: string): Promise<void>{
|
||||
return this._page.locator(`#version-item-${manifest}`).click();
|
||||
}
|
||||
|
||||
get downloadVersionButton(): Locator { return this._downloadVersionButton; }
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import { Page, Locator } from "playwright"
|
||||
|
||||
export class MainWindow {
|
||||
|
||||
protected readonly _page: Page;
|
||||
|
||||
private readonly _bsmLogo: Locator;
|
||||
private readonly _addVersionButton: Locator;
|
||||
private readonly _settingsButton: Locator;
|
||||
private readonly _sharedContentButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this._page = page;
|
||||
|
||||
this._bsmLogo = page.locator("#bsm-logo");
|
||||
this._addVersionButton = page.locator("#add-version-btn");
|
||||
this._settingsButton = page.locator("#settings-btn");
|
||||
this._sharedContentButton = page.locator("#shared-contents-btn");
|
||||
}
|
||||
public async clickBsmLogo(): Promise<void> {
|
||||
return this._bsmLogo.click();
|
||||
}
|
||||
|
||||
public async clickAddVersionButton(): Promise<void> {
|
||||
return this._addVersionButton.click();
|
||||
}
|
||||
|
||||
public async clickSettingsButton(): Promise<void> {
|
||||
return this._settingsButton.click();
|
||||
}
|
||||
|
||||
public async clickSharedContentButton(): Promise<void> {
|
||||
return this._sharedContentButton.click();
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "start_beat_saber_admin"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"winres",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "winres"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c"
|
||||
dependencies = [
|
||||
"toml",
|
||||
]
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "start_beat_saber_admin"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
winres = "0.1.12"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
opt-level = "z"
|
||||
|
||||
[package.metadata.winres]
|
||||
FileDescription = "Start Beat Saber as Admin"
|
||||
LegalCopyright = "Copyright © 2024 Zagrios"
|
||||
CompanyName = "Zagrios"
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
extern crate winres;
|
||||
|
||||
fn main() {
|
||||
if cfg!(target_os = "windows") {
|
||||
let mut res = winres::WindowsResource::new();
|
||||
res.set_manifest(r#"
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
||||
"#);
|
||||
res.set_icon("./icon.ico");
|
||||
res.compile().unwrap();
|
||||
}
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
use std::{process::Command, path::Path};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
|
||||
let mut command = Command::new(args.get(1).unwrap());
|
||||
command.current_dir(Path::new(args.get(1).unwrap()).parent().unwrap());
|
||||
|
||||
for arg in args.iter().skip(1) {
|
||||
command.arg(arg);
|
||||
}
|
||||
|
||||
command.env("SteamAppId", "620980");
|
||||
|
||||
let _ = command.spawn();
|
||||
}
|
||||
Generated
+283
-238
@@ -24,6 +24,7 @@
|
||||
"framer-motion": "^10.16.16",
|
||||
"fs-extra": "^11.2.0",
|
||||
"history": "^5.3.0",
|
||||
"is-elevated": "^3.0.0",
|
||||
"jszip": "^3.10.1",
|
||||
"md5-file": "^5.0.0",
|
||||
"node-abi": "^3.47.0",
|
||||
@@ -55,7 +56,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/rebuild": "^3.2.13",
|
||||
"@playwright/test": "^1.38.1",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.5",
|
||||
"@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
@@ -82,7 +82,6 @@
|
||||
"@types/webpack-env": "^1.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.34.0",
|
||||
"@typescript-eslint/parser": "^5.34.0",
|
||||
"asar": "^3.2.0",
|
||||
"autoprefixer": "^10.4.8",
|
||||
"browserslist-config-erb": "^0.0.3",
|
||||
"chalk": "^4.1.2",
|
||||
@@ -116,8 +115,6 @@
|
||||
"lint-staged": "^12.5.0",
|
||||
"mini-css-extract-plugin": "^2.6.1",
|
||||
"opencollective-postinstall": "^2.0.3",
|
||||
"playwright": "^1.38.1",
|
||||
"playwright-core": "^1.38.1",
|
||||
"postcss": "^8.4.16",
|
||||
"postcss-loader": "^6.2.1",
|
||||
"prettier": "^2.7.1",
|
||||
@@ -141,8 +138,7 @@
|
||||
"webpack-bundle-analyzer": "^4.6.1",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.10.0",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"xvfb-maybe": "^0.2.1"
|
||||
"webpack-merge": "^5.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@adobe/css-tools": {
|
||||
@@ -2020,21 +2016,6 @@
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.38.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz",
|
||||
"integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@pmmmwh/react-refresh-webpack-plugin": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz",
|
||||
@@ -4143,48 +4124,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asar": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
|
||||
"integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==",
|
||||
"deprecated": "Please use @electron/asar moving forward. There is no API change, just a package name change",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chromium-pickle-js": "^0.2.0",
|
||||
"commander": "^5.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"bin": {
|
||||
"asar": "bin/asar.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@types/glob": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/asar/node_modules/@types/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/minimatch": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/asar/node_modules/commander": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
|
||||
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
|
||||
@@ -7109,7 +7048,6 @@
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
@@ -10353,6 +10291,125 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-admin/-/is-admin-3.0.0.tgz",
|
||||
"integrity": "sha512-wOa3CXFJAu8BZ2BDtG9xYOOrsq6oiSvc2jFPy4X/HINx5bmJUcW8e+apItVbU2E7GIfBVaFVO7Zit4oAWtTJcw==",
|
||||
"dependencies": {
|
||||
"execa": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
|
||||
"dependencies": {
|
||||
"nice-try": "^1.0.4",
|
||||
"path-key": "^2.0.1",
|
||||
"semver": "^5.5.0",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/execa": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
|
||||
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"get-stream": "^4.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
"p-finally": "^1.0.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"strip-eof": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
"integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
"integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
|
||||
"dependencies": {
|
||||
"path-key": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
"integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-admin/node_modules/which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arguments": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||
@@ -10493,6 +10550,18 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-elevated": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-elevated/-/is-elevated-3.0.0.tgz",
|
||||
"integrity": "sha512-wjcp6RkouU9jpg55zERl+BglvV5j4jx5c/EMvQ+d12j/+nIEenNWPu+qc0tCg3JkLodbKZMg1qhJzEwG4qjclg==",
|
||||
"dependencies": {
|
||||
"is-admin": "^3.0.0",
|
||||
"is-root": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
@@ -10657,6 +10726,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-root": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
|
||||
"integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/is-set": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
|
||||
@@ -10822,8 +10899,7 @@
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"node_modules/isobject": {
|
||||
"version": "3.0.1",
|
||||
@@ -13634,6 +13710,11 @@
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
|
||||
},
|
||||
"node_modules/no-case": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
|
||||
@@ -14142,6 +14223,14 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||
"integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
@@ -14513,36 +14602,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.38.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz",
|
||||
"integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.38.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz",
|
||||
"integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/plist": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
|
||||
@@ -15481,7 +15540,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
@@ -16721,8 +16779,7 @@
|
||||
"node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"node_modules/simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
@@ -17183,6 +17240,14 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
"integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-final-newline": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||
@@ -19173,46 +19238,6 @@
|
||||
"node": ">=0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/xvfb-maybe": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/xvfb-maybe/-/xvfb-maybe-0.2.1.tgz",
|
||||
"integrity": "sha512-9IyRz3l6Qyhl6LvnGRF5jMPB4oBEepQnuzvVAFTynP6ACLLSevqigICJ9d/+ofl29m2daeaVBChnPYUnaeJ7yA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "^2.2.0",
|
||||
"which": "^1.2.4"
|
||||
},
|
||||
"bin": {
|
||||
"xvfb-maybe": "src/xvfb-maybe.js"
|
||||
}
|
||||
},
|
||||
"node_modules/xvfb-maybe/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xvfb-maybe/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/xvfb-maybe/node_modules/which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
@@ -20807,15 +20832,6 @@
|
||||
"rimraf": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"@playwright/test": {
|
||||
"version": "1.38.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz",
|
||||
"integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"playwright": "1.38.1"
|
||||
}
|
||||
},
|
||||
"@pmmmwh/react-refresh-webpack-plugin": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz",
|
||||
@@ -22541,38 +22557,6 @@
|
||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||
"integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA=="
|
||||
},
|
||||
"asar": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
|
||||
"integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/glob": "^7.1.1",
|
||||
"chromium-pickle-js": "^0.2.0",
|
||||
"commander": "^5.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@types/minimatch": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
|
||||
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
|
||||
@@ -24783,7 +24767,6 @@
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
@@ -27151,6 +27134,94 @@
|
||||
"integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==",
|
||||
"dev": true
|
||||
},
|
||||
"is-admin": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-admin/-/is-admin-3.0.0.tgz",
|
||||
"integrity": "sha512-wOa3CXFJAu8BZ2BDtG9xYOOrsq6oiSvc2jFPy4X/HINx5bmJUcW8e+apItVbU2E7GIfBVaFVO7Zit4oAWtTJcw==",
|
||||
"requires": {
|
||||
"execa": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
|
||||
"requires": {
|
||||
"nice-try": "^1.0.4",
|
||||
"path-key": "^2.0.1",
|
||||
"semver": "^5.5.0",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"execa": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
|
||||
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
|
||||
"requires": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"get-stream": "^4.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
"p-finally": "^1.0.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"strip-eof": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
"integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
"integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
|
||||
"requires": {
|
||||
"path-key": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
"integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
|
||||
"requires": {
|
||||
"shebang-regex": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-arguments": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||
@@ -27246,6 +27317,15 @@
|
||||
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-elevated": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-elevated/-/is-elevated-3.0.0.tgz",
|
||||
"integrity": "sha512-wjcp6RkouU9jpg55zERl+BglvV5j4jx5c/EMvQ+d12j/+nIEenNWPu+qc0tCg3JkLodbKZMg1qhJzEwG4qjclg==",
|
||||
"requires": {
|
||||
"is-admin": "^3.0.0",
|
||||
"is-root": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
@@ -27356,6 +27436,11 @@
|
||||
"has-tostringtag": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-root": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
|
||||
"integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg=="
|
||||
},
|
||||
"is-set": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
|
||||
@@ -27467,8 +27552,7 @@
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"isobject": {
|
||||
"version": "3.0.1",
|
||||
@@ -29756,6 +29840,11 @@
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
|
||||
},
|
||||
"no-case": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
|
||||
@@ -30127,6 +30216,11 @@
|
||||
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
|
||||
"dev": true
|
||||
},
|
||||
"p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||
"integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow=="
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
@@ -30409,22 +30503,6 @@
|
||||
"find-up": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"playwright": {
|
||||
"version": "1.38.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz",
|
||||
"integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fsevents": "2.3.2",
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
"version": "1.38.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz",
|
||||
"integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==",
|
||||
"dev": true
|
||||
},
|
||||
"plist": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
|
||||
@@ -31033,7 +31111,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
@@ -31976,8 +32053,7 @@
|
||||
"signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
@@ -32341,6 +32417,11 @@
|
||||
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
|
||||
"dev": true
|
||||
},
|
||||
"strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
"integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q=="
|
||||
},
|
||||
"strip-final-newline": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||
@@ -33789,42 +33870,6 @@
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
},
|
||||
"xvfb-maybe": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/xvfb-maybe/-/xvfb-maybe-0.2.1.tgz",
|
||||
"integrity": "sha512-9IyRz3l6Qyhl6LvnGRF5jMPB4oBEepQnuzvVAFTynP6ACLLSevqigICJ9d/+ofl29m2daeaVBChnPYUnaeJ7yA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^2.2.0",
|
||||
"which": "^1.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
||||
+3
-9
@@ -14,9 +14,7 @@
|
||||
"start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts",
|
||||
"start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
|
||||
"test": "jest",
|
||||
"publish": "npm run build && electron-builder -c.win.certificateSha1=842a817a51e2a1d360fcd62f54bf5f9193e919e1 --publish always --win --x64",
|
||||
"e2e-test": "npm run package && xvfb-maybe npx playwright test --workers=1",
|
||||
"e2e-test-ci": "xvfb-maybe npx playwright test --workers=1"
|
||||
"publish": "npm run build && electron-builder -c.win.certificateSha1=842a817a51e2a1d360fcd62f54bf5f9193e919e1 --publish always --win --x64"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
@@ -151,7 +149,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/rebuild": "^3.2.13",
|
||||
"@playwright/test": "^1.38.1",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.5",
|
||||
"@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
@@ -178,7 +175,6 @@
|
||||
"@types/webpack-env": "^1.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.34.0",
|
||||
"@typescript-eslint/parser": "^5.34.0",
|
||||
"asar": "^3.2.0",
|
||||
"autoprefixer": "^10.4.8",
|
||||
"browserslist-config-erb": "^0.0.3",
|
||||
"chalk": "^4.1.2",
|
||||
@@ -212,8 +208,6 @@
|
||||
"lint-staged": "^12.5.0",
|
||||
"mini-css-extract-plugin": "^2.6.1",
|
||||
"opencollective-postinstall": "^2.0.3",
|
||||
"playwright": "^1.38.1",
|
||||
"playwright-core": "^1.38.1",
|
||||
"postcss": "^8.4.16",
|
||||
"postcss-loader": "^6.2.1",
|
||||
"prettier": "^2.7.1",
|
||||
@@ -237,8 +231,7 @@
|
||||
"webpack-bundle-analyzer": "^4.6.1",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.10.0",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"xvfb-maybe": "^0.2.1"
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/fuses": "^1.6.2",
|
||||
@@ -257,6 +250,7 @@
|
||||
"framer-motion": "^10.16.16",
|
||||
"fs-extra": "^11.2.0",
|
||||
"history": "^5.3.0",
|
||||
"is-elevated": "^3.0.0",
|
||||
"jszip": "^3.10.1",
|
||||
"md5-file": "^5.0.0",
|
||||
"node-abi": "^3.47.0",
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// require('dotenv').config();
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: "./e2e-tests",
|
||||
testMatch: "**/*.test.ts",
|
||||
timeout: 200000,
|
||||
fullyParallel: true,
|
||||
retries: 1,
|
||||
});
|
||||
Generated
+256
-31
@@ -11,7 +11,8 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ps-list": "^7.2.0",
|
||||
"regedit-rs": "^1.0.1",
|
||||
"query-process": "^0.0.3",
|
||||
"regedit-rs": "^1.0.2",
|
||||
"sharp": "^0.32.6"
|
||||
}
|
||||
},
|
||||
@@ -344,6 +345,160 @@
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process/-/query-process-0.0.3.tgz",
|
||||
"integrity": "sha512-6WRue0P+c84abP0o8MkDvigoS/gkkJzsSBt10PsOoBkP7Yodo4DducFsn9XyS4S+LuVYPAE5Hr4+kVNR5Onykg==",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"query-process-android-arm-eabi": "0.0.3",
|
||||
"query-process-android-arm64": "0.0.3",
|
||||
"query-process-linux-arm-gnueabihf": "0.0.3",
|
||||
"query-process-linux-arm64-gnu": "0.0.3",
|
||||
"query-process-linux-arm64-musl": "0.0.3",
|
||||
"query-process-linux-x64-gnu": "0.0.3",
|
||||
"query-process-linux-x64-musl": "0.0.3",
|
||||
"query-process-win32-arm64-msvc": "0.0.3",
|
||||
"query-process-win32-x64-msvc": "0.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-android-arm-eabi": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-android-arm-eabi/-/query-process-android-arm-eabi-0.0.3.tgz",
|
||||
"integrity": "sha512-NB+9T+/poBcygDiG+7d2lJSeioP5ZyLT0HwUBdnLgNWvNCpzbJxydup1SLpnt5G2NF6nlTgbUZlH4hvxY7t/bw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-android-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-android-arm64/-/query-process-android-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-TiAw2yO62vQzM0s02471LToHyUs/PRkLGGlA715z10BPIM5NckzIe245AI45CDyH6tE/3nVHUd0LX/dfjQtTcw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-linux-arm-gnueabihf": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-arm-gnueabihf/-/query-process-linux-arm-gnueabihf-0.0.3.tgz",
|
||||
"integrity": "sha512-w7NLHBKt7qselCDoh/PVWyeuEb2NiiDDf1A9UB4K3Ns/H24hK3NbfMMBm8mCFxUnFUqoVX8O+VMs7dD/FNlTxA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-linux-arm64-gnu": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-arm64-gnu/-/query-process-linux-arm64-gnu-0.0.3.tgz",
|
||||
"integrity": "sha512-nrPHjnSqCBuuN7IZkZWOnBpiJjyKOjfpT0Xt2EjSGp+I7C0CHbnhCL/vG1hBzaWZn0mxJ5nf0c5N0Fja7krnpQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-linux-arm64-musl": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-arm64-musl/-/query-process-linux-arm64-musl-0.0.3.tgz",
|
||||
"integrity": "sha512-vk8xMYTnS1PRKhwJgqLKyBAGIFP2CYZW2BsaKuNgQKUrDv7NnBaG7yukZT8niHNO1ycSrFpR/xqeJ8R23hO07A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-linux-x64-gnu": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-x64-gnu/-/query-process-linux-x64-gnu-0.0.3.tgz",
|
||||
"integrity": "sha512-j1tGcNnGyVCABJ1PHZD1gKuyuomNzsPow3NDuZzUGjPqvKu67RsmKJJJOhMyT1SvUkcqdLFdtS1KTD20I4GS5Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-linux-x64-musl": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-x64-musl/-/query-process-linux-x64-musl-0.0.3.tgz",
|
||||
"integrity": "sha512-AOGrrI/Qcb30iKFstiW60zNG/HQevCY0Q38eMHGd7LrBZ5sEN7NzZOjzKp43KeNHejuZBDMxf0gdGAqDznOAng==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-win32-arm64-msvc": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-win32-arm64-msvc/-/query-process-win32-arm64-msvc-0.0.3.tgz",
|
||||
"integrity": "sha512-LHvxbzMFwPPUXHe4bDCAqs1bYbp8j0bMW8XyJGPZnIYrnwHz6g8VE5WQEtXQxSznsbfVxAKJXUtn088EjDVazw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/query-process-win32-x64-msvc": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-win32-x64-msvc/-/query-process-win32-x64-msvc-0.0.3.tgz",
|
||||
"integrity": "sha512-LfHAKmfqyKCgl9K+sTz0KyNwMwB79VcXZUy/Et9iQKLuZt7PDYpHWcFdhrfHw2qqIdKWTED8KmnmsOLhUn/2OA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-tick": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
|
||||
@@ -377,22 +532,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/regedit-rs": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs/-/regedit-rs-1.0.1.tgz",
|
||||
"integrity": "sha512-wsvoGP5JDevIcx3q52aATW1c1dY86bQx7/tJ32gqV+L98OHRJykobKkjYqGzROtz9c2Pr+wGJZr0glFyc2dpvQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs/-/regedit-rs-1.0.2.tgz",
|
||||
"integrity": "sha512-4vEgiZNO1FCG8z/Zx3v/6PU1+eZ+ELe6R0ca+VB96Vw+Mi3M0IVHAjtMFbl97lUSX11dJqpyousX/wY8QcI1lA==",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"regedit-rs-win32-arm64-msvc": "1.0.1",
|
||||
"regedit-rs-win32-ia32-msvc": "1.0.1",
|
||||
"regedit-rs-win32-x64-msvc": "1.0.1"
|
||||
"regedit-rs-win32-arm64-msvc": "1.0.2",
|
||||
"regedit-rs-win32-ia32-msvc": "1.0.2",
|
||||
"regedit-rs-win32-x64-msvc": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/regedit-rs-win32-arm64-msvc": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-arm64-msvc/-/regedit-rs-win32-arm64-msvc-1.0.1.tgz",
|
||||
"integrity": "sha512-QA46d/wiUHlW2h0ZlHKrtDhnwoxMpVle+EbFziEbLYC7dimtAiWCeXu4zNymaFClDimYSifQkWgza5GBmD8etg==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-arm64-msvc/-/regedit-rs-win32-arm64-msvc-1.0.2.tgz",
|
||||
"integrity": "sha512-hM1sxazOJWKmiC9DM8QXW9Iqm50Mh/Y9G4/rRYQpWXjMzq7lTqjwVZRkAoBrHliFS6d1Lt4qkm5+Ybt6GkbDpw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -405,9 +560,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/regedit-rs-win32-ia32-msvc": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-ia32-msvc/-/regedit-rs-win32-ia32-msvc-1.0.1.tgz",
|
||||
"integrity": "sha512-V2NisvicQqiozl0yMas9tjDYmBwHWf48M/dMJUWMQxxkJaDCNoHW8PljL59A/h8ew2NBFsJK5RYkYfxW1o+OyQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-ia32-msvc/-/regedit-rs-win32-ia32-msvc-1.0.2.tgz",
|
||||
"integrity": "sha512-FLINrCJ30wm6NYw7skQUDET8NP1N46kH77dqesCiU+/FjWzzPE5luZYY+j4uf+hKjPY6/MCj2CB9l9VdPhaBVQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -420,9 +575,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/regedit-rs-win32-x64-msvc": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-x64-msvc/-/regedit-rs-win32-x64-msvc-1.0.1.tgz",
|
||||
"integrity": "sha512-qhQawjYPzXGrz0xODJiviwrzw0eytGP9+quuQJUQAiLEw2P1tQ0LCyID3jOvNltLH+tqJChSV4JaQcPVleohZg==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-x64-msvc/-/regedit-rs-win32-x64-msvc-1.0.2.tgz",
|
||||
"integrity": "sha512-ccCSyd5vWBKVWftBKLKzegqwwPMWcQtIW0ub66dCFFuv2s+x2EcZZWGdD9dVXX2Z6V9DU2JRPKgWUNjVPaj6Xg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -851,6 +1006,76 @@
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"query-process": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process/-/query-process-0.0.3.tgz",
|
||||
"integrity": "sha512-6WRue0P+c84abP0o8MkDvigoS/gkkJzsSBt10PsOoBkP7Yodo4DducFsn9XyS4S+LuVYPAE5Hr4+kVNR5Onykg==",
|
||||
"requires": {
|
||||
"query-process-android-arm-eabi": "0.0.3",
|
||||
"query-process-android-arm64": "0.0.3",
|
||||
"query-process-linux-arm-gnueabihf": "0.0.3",
|
||||
"query-process-linux-arm64-gnu": "0.0.3",
|
||||
"query-process-linux-arm64-musl": "0.0.3",
|
||||
"query-process-linux-x64-gnu": "0.0.3",
|
||||
"query-process-linux-x64-musl": "0.0.3",
|
||||
"query-process-win32-arm64-msvc": "0.0.3",
|
||||
"query-process-win32-x64-msvc": "0.0.3"
|
||||
}
|
||||
},
|
||||
"query-process-android-arm-eabi": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-android-arm-eabi/-/query-process-android-arm-eabi-0.0.3.tgz",
|
||||
"integrity": "sha512-NB+9T+/poBcygDiG+7d2lJSeioP5ZyLT0HwUBdnLgNWvNCpzbJxydup1SLpnt5G2NF6nlTgbUZlH4hvxY7t/bw==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-android-arm64": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-android-arm64/-/query-process-android-arm64-0.0.3.tgz",
|
||||
"integrity": "sha512-TiAw2yO62vQzM0s02471LToHyUs/PRkLGGlA715z10BPIM5NckzIe245AI45CDyH6tE/3nVHUd0LX/dfjQtTcw==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-linux-arm-gnueabihf": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-arm-gnueabihf/-/query-process-linux-arm-gnueabihf-0.0.3.tgz",
|
||||
"integrity": "sha512-w7NLHBKt7qselCDoh/PVWyeuEb2NiiDDf1A9UB4K3Ns/H24hK3NbfMMBm8mCFxUnFUqoVX8O+VMs7dD/FNlTxA==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-linux-arm64-gnu": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-arm64-gnu/-/query-process-linux-arm64-gnu-0.0.3.tgz",
|
||||
"integrity": "sha512-nrPHjnSqCBuuN7IZkZWOnBpiJjyKOjfpT0Xt2EjSGp+I7C0CHbnhCL/vG1hBzaWZn0mxJ5nf0c5N0Fja7krnpQ==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-linux-arm64-musl": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-arm64-musl/-/query-process-linux-arm64-musl-0.0.3.tgz",
|
||||
"integrity": "sha512-vk8xMYTnS1PRKhwJgqLKyBAGIFP2CYZW2BsaKuNgQKUrDv7NnBaG7yukZT8niHNO1ycSrFpR/xqeJ8R23hO07A==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-linux-x64-gnu": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-x64-gnu/-/query-process-linux-x64-gnu-0.0.3.tgz",
|
||||
"integrity": "sha512-j1tGcNnGyVCABJ1PHZD1gKuyuomNzsPow3NDuZzUGjPqvKu67RsmKJJJOhMyT1SvUkcqdLFdtS1KTD20I4GS5Q==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-linux-x64-musl": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-linux-x64-musl/-/query-process-linux-x64-musl-0.0.3.tgz",
|
||||
"integrity": "sha512-AOGrrI/Qcb30iKFstiW60zNG/HQevCY0Q38eMHGd7LrBZ5sEN7NzZOjzKp43KeNHejuZBDMxf0gdGAqDznOAng==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-win32-arm64-msvc": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-win32-arm64-msvc/-/query-process-win32-arm64-msvc-0.0.3.tgz",
|
||||
"integrity": "sha512-LHvxbzMFwPPUXHe4bDCAqs1bYbp8j0bMW8XyJGPZnIYrnwHz6g8VE5WQEtXQxSznsbfVxAKJXUtn088EjDVazw==",
|
||||
"optional": true
|
||||
},
|
||||
"query-process-win32-x64-msvc": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/query-process-win32-x64-msvc/-/query-process-win32-x64-msvc-0.0.3.tgz",
|
||||
"integrity": "sha512-LfHAKmfqyKCgl9K+sTz0KyNwMwB79VcXZUy/Et9iQKLuZt7PDYpHWcFdhrfHw2qqIdKWTED8KmnmsOLhUn/2OA==",
|
||||
"optional": true
|
||||
},
|
||||
"queue-tick": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
|
||||
@@ -878,31 +1103,31 @@
|
||||
}
|
||||
},
|
||||
"regedit-rs": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs/-/regedit-rs-1.0.1.tgz",
|
||||
"integrity": "sha512-wsvoGP5JDevIcx3q52aATW1c1dY86bQx7/tJ32gqV+L98OHRJykobKkjYqGzROtz9c2Pr+wGJZr0glFyc2dpvQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs/-/regedit-rs-1.0.2.tgz",
|
||||
"integrity": "sha512-4vEgiZNO1FCG8z/Zx3v/6PU1+eZ+ELe6R0ca+VB96Vw+Mi3M0IVHAjtMFbl97lUSX11dJqpyousX/wY8QcI1lA==",
|
||||
"requires": {
|
||||
"regedit-rs-win32-arm64-msvc": "1.0.1",
|
||||
"regedit-rs-win32-ia32-msvc": "1.0.1",
|
||||
"regedit-rs-win32-x64-msvc": "1.0.1"
|
||||
"regedit-rs-win32-arm64-msvc": "1.0.2",
|
||||
"regedit-rs-win32-ia32-msvc": "1.0.2",
|
||||
"regedit-rs-win32-x64-msvc": "1.0.2"
|
||||
}
|
||||
},
|
||||
"regedit-rs-win32-arm64-msvc": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-arm64-msvc/-/regedit-rs-win32-arm64-msvc-1.0.1.tgz",
|
||||
"integrity": "sha512-QA46d/wiUHlW2h0ZlHKrtDhnwoxMpVle+EbFziEbLYC7dimtAiWCeXu4zNymaFClDimYSifQkWgza5GBmD8etg==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-arm64-msvc/-/regedit-rs-win32-arm64-msvc-1.0.2.tgz",
|
||||
"integrity": "sha512-hM1sxazOJWKmiC9DM8QXW9Iqm50Mh/Y9G4/rRYQpWXjMzq7lTqjwVZRkAoBrHliFS6d1Lt4qkm5+Ybt6GkbDpw==",
|
||||
"optional": true
|
||||
},
|
||||
"regedit-rs-win32-ia32-msvc": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-ia32-msvc/-/regedit-rs-win32-ia32-msvc-1.0.1.tgz",
|
||||
"integrity": "sha512-V2NisvicQqiozl0yMas9tjDYmBwHWf48M/dMJUWMQxxkJaDCNoHW8PljL59A/h8ew2NBFsJK5RYkYfxW1o+OyQ==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-ia32-msvc/-/regedit-rs-win32-ia32-msvc-1.0.2.tgz",
|
||||
"integrity": "sha512-FLINrCJ30wm6NYw7skQUDET8NP1N46kH77dqesCiU+/FjWzzPE5luZYY+j4uf+hKjPY6/MCj2CB9l9VdPhaBVQ==",
|
||||
"optional": true
|
||||
},
|
||||
"regedit-rs-win32-x64-msvc": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-x64-msvc/-/regedit-rs-win32-x64-msvc-1.0.1.tgz",
|
||||
"integrity": "sha512-qhQawjYPzXGrz0xODJiviwrzw0eytGP9+quuQJUQAiLEw2P1tQ0LCyID3jOvNltLH+tqJChSV4JaQcPVleohZg==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regedit-rs-win32-x64-msvc/-/regedit-rs-win32-x64-msvc-1.0.2.tgz",
|
||||
"integrity": "sha512-ccCSyd5vWBKVWftBKLKzegqwwPMWcQtIW0ub66dCFFuv2s+x2EcZZWGdD9dVXX2Z6V9DU2JRPKgWUNjVPaj6Xg==",
|
||||
"optional": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bs-manager",
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.4-alpha.1",
|
||||
"description": "BSManager",
|
||||
"main": "./dist/main/main.js",
|
||||
"author": {
|
||||
@@ -15,7 +15,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ps-list": "^7.2.0",
|
||||
"regedit-rs": "^1.0.1",
|
||||
"query-process": "^0.0.3",
|
||||
"regedit-rs": "^1.0.2",
|
||||
"sharp": "^0.32.6"
|
||||
},
|
||||
"license": "MIT"
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import log from "electron-log";
|
||||
import { isPromise } from "../../shared/helpers/promise.helpers";
|
||||
import { tryit } from "../../shared/helpers/error.helpers";
|
||||
|
||||
type LogOptions = {
|
||||
logInput?: boolean;
|
||||
logOutput?: boolean;
|
||||
logArgs?: boolean;
|
||||
};
|
||||
|
||||
const stringifyArgs = (args: unknown[]) => {
|
||||
return args?.map(a => JSON.stringify(a)).join(', ');
|
||||
};
|
||||
|
||||
const logInfo = (message: string, propertyKey: string, args: unknown[], logArgs: boolean, result: unknown) => {
|
||||
log.info(`[${message}] ${propertyKey}(${logArgs ? stringifyArgs(args) : ''})`, result);
|
||||
};
|
||||
|
||||
const logError = (propertyKey: string, args: unknown[], logArgs: boolean, error: unknown) => {
|
||||
log.error(`[ERROR] ${propertyKey}(${logArgs ? stringifyArgs(args) : ''})`, error);
|
||||
throw error;
|
||||
};
|
||||
|
||||
export function Log(options?: LogOptions){
|
||||
|
||||
const logInput = options?.logInput ?? false;
|
||||
const logOutput = options?.logOutput ?? true;
|
||||
const logArgs = options?.logArgs ?? true;
|
||||
|
||||
return (target: unknown, propertyKey: string, descriptor: PropertyDescriptor) => {
|
||||
const originalMethod = descriptor.value;
|
||||
|
||||
descriptor.value = function(...args: unknown[]) {
|
||||
|
||||
if (logInput) {
|
||||
logInfo('INPUT', propertyKey, args, logArgs, null);
|
||||
}
|
||||
|
||||
const outcome = tryit(() => originalMethod.apply(this, args));
|
||||
|
||||
if (isPromise(outcome)) {
|
||||
return outcome.then(({ result, error }) => {
|
||||
|
||||
if (error) {
|
||||
logError(propertyKey, args, logArgs, error);
|
||||
}
|
||||
if (logOutput) {
|
||||
logInfo('OUTPUT', propertyKey, args, logArgs, result);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
const { result, error } = outcome;
|
||||
|
||||
if (error) {
|
||||
logError(propertyKey, args, logArgs, error);
|
||||
}
|
||||
|
||||
if (logOutput) {
|
||||
logInfo('OUTPUT', propertyKey, args, logArgs, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -10,4 +10,16 @@ export async function taskRunning(task: string): Promise<boolean> {
|
||||
log.error(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getProcessPid(task: string): Promise<number> {
|
||||
try {
|
||||
const processes = await psList();
|
||||
const process = processes.find(process => process.name?.includes(task) || process.cmd?.includes(task));
|
||||
return process?.pid;
|
||||
}
|
||||
catch(error){
|
||||
log.error(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -23,7 +23,6 @@ import { LivShortcut } from "./services/liv/liv-shortcut.service";
|
||||
import { SteamLauncherService } from "./services/bs-launcher/steam-launcher.service";
|
||||
|
||||
const isDebug = process.env.NODE_ENV === "development" || process.env.DEBUG_PROD === "true";
|
||||
const isE2E = process.env.E2E_BUILD === "true";
|
||||
|
||||
log.transports.file.level = "info";
|
||||
log.transports.file.resolvePath = () => {
|
||||
@@ -55,7 +54,7 @@ const installExtensions = async () => {
|
||||
.catch(log.error);
|
||||
};
|
||||
|
||||
const createWindow = async (window: AppWindow) => {
|
||||
const createWindow = async (window: AppWindow = "launcher.html") => {
|
||||
if (isDebug) {
|
||||
await installExtensions();
|
||||
}
|
||||
@@ -99,7 +98,7 @@ if (!gotTheLock) {
|
||||
const deepLink = process.argv.find(arg => DeepLinkService.getInstance().isDeepLink(arg));
|
||||
|
||||
if (!deepLink) {
|
||||
createWindow(!isE2E ? "launcher.html" : "index.html");
|
||||
createWindow();
|
||||
} else {
|
||||
DeepLinkService.getInstance().dispatchLinkOpened(deepLink);
|
||||
}
|
||||
|
||||
@@ -61,13 +61,13 @@ export class OculusLauncherService extends AbstractLauncherService implements St
|
||||
log.info("Symlinks found in Oculus library", symlinks);
|
||||
|
||||
const bsSymlinks = symlinks.filter(dirent => dirent.startsWith(OCULUS_BS_DIR));
|
||||
|
||||
|
||||
const bsmSymlinks = (await Promise.all(bsSymlinks.map(async symlink => {
|
||||
const symlinkPath = path.join(oculusLibPath, symlink);
|
||||
const targetPath = await readlink(symlinkPath).catch(err => log.error(err));
|
||||
|
||||
log.info("Oculus Symlink", symlink, "target", targetPath);
|
||||
|
||||
|
||||
if(!targetPath){ return null; }
|
||||
|
||||
const bsmVersionsDir = path.join(this.pathsService.INSTALLATION_FOLDER, this.pathsService.VERSIONS_FOLDER);
|
||||
@@ -138,20 +138,24 @@ export class OculusLauncherService extends AbstractLauncherService implements St
|
||||
if(bsRunning){
|
||||
throw CustomError.fromError(new Error("Cannot start two instance of Beat Saber for Oculus"), BSLaunchError.BS_ALREADY_RUNNING);
|
||||
}
|
||||
|
||||
|
||||
// Remove previously symlinks created by BSM
|
||||
await this.deleteBsSymlinks().catch(err => log.error("Error while deleting BSM symlinks", err));
|
||||
|
||||
const bsPath = await (launchOptions.version.oculus ? prepareOriginalVersion() : prepareDowngradedVersion());
|
||||
|
||||
// Launch Beat Saber
|
||||
const exePath = path.join(bsPath, BS_EXECUTABLE);
|
||||
|
||||
if(!(await pathExists(exePath))){
|
||||
throw CustomError.fromError(new Error(`BS Path not exist ${bsPath}`), BSLaunchError.BS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Make sure Oculus is running
|
||||
await this.oculus.startOculus().catch(err => log.error("Error while starting Oculus", err));
|
||||
|
||||
obs.next({type: BSLaunchEvent.BS_LAUNCHING});
|
||||
|
||||
// Launch Beat Saber
|
||||
return this.launchBs(exePath, this.buildBsLaunchArgs(launchOptions)).catch(err => {
|
||||
throw CustomError.fromError(err, BSLaunchError.BS_EXIT_ERROR);
|
||||
});
|
||||
@@ -170,4 +174,4 @@ export class OculusLauncherService extends AbstractLauncherService implements St
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@ import { BS_APP_ID, BS_EXECUTABLE, STEAMVR_APP_ID } from "../../constants";
|
||||
import log from "electron-log";
|
||||
import { AbstractLauncherService } from "./abstract-launcher.service";
|
||||
import { CustomError } from "../../../shared/models/exceptions/custom-error.class";
|
||||
import isElevated from "is-elevated";
|
||||
import { UtilsService } from "../utils.service";
|
||||
import { exec } from "child_process";
|
||||
|
||||
export class SteamLauncherService extends AbstractLauncherService implements StoreLauncherInterface{
|
||||
|
||||
@@ -21,10 +24,12 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
|
||||
}
|
||||
|
||||
private readonly steam: SteamService;
|
||||
private readonly util: UtilsService;
|
||||
|
||||
private constructor(){
|
||||
super();
|
||||
this.steam = SteamService.getInstance();
|
||||
this.util = UtilsService.getInstance();
|
||||
}
|
||||
|
||||
private getSteamVRPath(): Promise<string> {
|
||||
@@ -41,6 +46,17 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
|
||||
});
|
||||
}
|
||||
|
||||
private needStartBsAsAdmin(): Promise<boolean> {
|
||||
return isElevated().then(elevated => {
|
||||
if(elevated){ return false; }
|
||||
return this.steam.isElevated();
|
||||
})
|
||||
}
|
||||
|
||||
private getStartBsAsAdminExePath(): string {
|
||||
return path.join(this.util.getAssetsScriptsPath(), "start_beat_saber_admin.exe");
|
||||
}
|
||||
|
||||
public async restoreSteamVR(): Promise<void> {
|
||||
const steamVrFolder = await this.getSteamVRPath();
|
||||
const steamVrBackup = `${steamVrFolder}.bak`;
|
||||
@@ -53,7 +69,7 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
|
||||
log.error("Error while restoring SteamVR", err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public launch(launchOptions: LaunchOption): Observable<BSLaunchEventData>{
|
||||
|
||||
return new Observable<BSLaunchEventData>(obs => {(async () => {
|
||||
@@ -90,7 +106,26 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
|
||||
|
||||
obs.next({type: BSLaunchEvent.BS_LAUNCHING});
|
||||
|
||||
await this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} }).then(exitCode => {
|
||||
const needToStartAsAdmin = await this.needStartBsAsAdmin().catch(err => {
|
||||
log.error("Error while checking if need to start BS as Admin", err);
|
||||
return false;
|
||||
});
|
||||
|
||||
const launchPromise = !needToStartAsAdmin ? (
|
||||
this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} })
|
||||
) : (
|
||||
new Promise<number>(resolve => {
|
||||
const adminProcess = exec(`"${this.getStartBsAsAdminExePath()}" "${exePath}" ${launchArgs.join(" ")}`, { env: {...process.env, "SteamAppId": BS_APP_ID} });
|
||||
adminProcess.on("error", err => {log.error("Error while starting BS as Admin", err); resolve(-1)});
|
||||
|
||||
setTimeout(() => {
|
||||
adminProcess.removeAllListeners("error");
|
||||
resolve(-1);
|
||||
}, 35_000);
|
||||
})
|
||||
);
|
||||
|
||||
await launchPromise.then(exitCode => {
|
||||
log.info("BS process exit code", exitCode);
|
||||
}).catch(err => {
|
||||
throw CustomError.fromError(err, BSLaunchError.BS_EXIT_ERROR);
|
||||
@@ -109,4 +144,4 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
|
||||
})});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { execOnOs } from "../../helpers/env.helpers";
|
||||
import { list, createKey, putValue, deleteKey, RegSzValue } from "regedit-rs";
|
||||
import path from "path";
|
||||
import { Log } from "../../decorators/log.decorator";
|
||||
|
||||
export class LivService {
|
||||
|
||||
@@ -20,6 +21,7 @@ export class LivService {
|
||||
|
||||
}
|
||||
|
||||
@Log()
|
||||
public async isLivInstalled(): Promise<boolean> {
|
||||
return execOnOs({
|
||||
win32: async () => {
|
||||
@@ -29,6 +31,7 @@ export class LivService {
|
||||
}, true);
|
||||
}
|
||||
|
||||
@Log()
|
||||
public async createLivShortcut(entry: LivEntry): Promise<void> {
|
||||
return execOnOs({
|
||||
win32: async () => {
|
||||
@@ -46,6 +49,7 @@ export class LivService {
|
||||
});
|
||||
}
|
||||
|
||||
@Log()
|
||||
public async deleteLivShortcuts(ids: string[]): Promise<void> {
|
||||
return execOnOs({
|
||||
win32: async () => {
|
||||
@@ -55,11 +59,13 @@ export class LivService {
|
||||
})
|
||||
}
|
||||
|
||||
@Log()
|
||||
public getLivShortcuts(): Promise<LivEntry[]> {
|
||||
|
||||
return execOnOs({
|
||||
win32: async () => {
|
||||
const regRes = await list(this.livExternalAppsRegeditKey).then(res => res[this.livExternalAppsRegeditKey]);
|
||||
|
||||
|
||||
if(!regRes.exists){
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import { pathExist, resolveGUIDPath } from "../helpers/fs.helpers";
|
||||
import log from "electron-log";
|
||||
import { lstat } from "fs-extra";
|
||||
import { tryit } from "../../shared/helpers/error.helpers";
|
||||
import { shell } from "electron";
|
||||
import { taskRunning } from "../helpers/os.helpers";
|
||||
import { sToMs } from "../../shared/helpers/time.helpers";
|
||||
|
||||
export class OculusService {
|
||||
private static instance: OculusService;
|
||||
@@ -42,11 +45,11 @@ export class OculusService {
|
||||
const libsPath: OculusLibrary[] = (
|
||||
await Promise.all(libsRegData.keys.map(async key => {
|
||||
const originalPath = await list([`${oculusLibsRegKey}\\${key}`]).then(res => res[`${oculusLibsRegKey}\\${key}`]);
|
||||
|
||||
|
||||
if (originalPath.values?.OriginalPath) {
|
||||
return { id: key, path: originalPath.values.OriginalPath.value, isDefault: defaultLibraryId === key } as OculusLibrary;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(originalPath.values?.Path) {
|
||||
const { result } = tryit(() => resolveGUIDPath(originalPath.values.Path.value as string));
|
||||
return result ? { id: key, path: result, isDefault: defaultLibraryId === key } as OculusLibrary : null;
|
||||
@@ -82,7 +85,7 @@ export class OculusService {
|
||||
|
||||
/**
|
||||
* Return the first game folder found in the list
|
||||
* @param {string[]} gameFolders
|
||||
* @param {string[]} gameFolders
|
||||
*/
|
||||
public async tryGetGameFolder(gameFolders: string[]): Promise<string> {
|
||||
for(const gameFolder of gameFolders){
|
||||
@@ -92,6 +95,29 @@ export class OculusService {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public oculusRunning(): Promise<boolean> {
|
||||
return taskRunning("OculusClient");
|
||||
}
|
||||
|
||||
public async startOculus(): Promise<void>{
|
||||
if(await this.oculusRunning()){ return; }
|
||||
|
||||
await shell.openPath("oculus://view/homepage");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const interval = setInterval(async () => {
|
||||
if(!(await this.oculusRunning())){ return; }
|
||||
clearInterval(interval);
|
||||
resolve();
|
||||
}, sToMs(3));
|
||||
|
||||
setTimeout(() => {
|
||||
clearInterval(interval);
|
||||
reject(new Error("Unable to open Oculus"));
|
||||
}, sToMs(30));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface OculusLibrary {
|
||||
|
||||
@@ -5,11 +5,15 @@ import { readFile } from "fs/promises";
|
||||
import { pathExist } from "../helpers/fs.helpers";
|
||||
import log from "electron-log";
|
||||
import { app, shell } from "electron";
|
||||
import { taskRunning } from "../helpers/os.helpers";
|
||||
import { getProcessPid, taskRunning } from "../helpers/os.helpers";
|
||||
import { isElevated } from "query-process";
|
||||
|
||||
export class SteamService {
|
||||
|
||||
private static readonly PROCESS_NAME = "steam";
|
||||
|
||||
private static instance: SteamService;
|
||||
|
||||
private steamPath: string = '';
|
||||
|
||||
private constructor(){}
|
||||
@@ -29,12 +33,25 @@ export class SteamService {
|
||||
}
|
||||
|
||||
public async steamRunning(): Promise<boolean>{
|
||||
const steamProcessRunning = await taskRunning("steam");
|
||||
const steamProcessRunning = await taskRunning(SteamService.PROCESS_NAME);
|
||||
if(process.platform === "linux") { return steamProcessRunning; }
|
||||
const activeUser = await this.getActiveUser().catch(err => log.error(err));
|
||||
return steamProcessRunning && !!activeUser;
|
||||
}
|
||||
|
||||
public async getSteamPid(): Promise<number>{
|
||||
return getProcessPid(SteamService.PROCESS_NAME);
|
||||
}
|
||||
|
||||
public async isElevated(): Promise<boolean>{
|
||||
if(process.platform === "linux"){ return true; }
|
||||
const steamPid = await this.getSteamPid();
|
||||
|
||||
if(!steamPid){ return false; }
|
||||
|
||||
return isElevated(steamPid);
|
||||
}
|
||||
|
||||
public async getSteamPath(): Promise<string>{
|
||||
|
||||
if(this.steamPath){ return this.steamPath; }
|
||||
@@ -68,7 +85,7 @@ export class SteamService {
|
||||
let libraryFolders: any = path.join(steamPath, "steamapps", "libraryfolders.vdf");
|
||||
|
||||
if (!(await pathExist(libraryFolders))) { return null; }
|
||||
|
||||
|
||||
libraryFolders = parse(await readFile(libraryFolders, { encoding: "utf-8" }));
|
||||
|
||||
if (!libraryFolders.libraryfolders) { return null; }
|
||||
@@ -83,7 +100,7 @@ export class SteamService {
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
return null;
|
||||
@@ -91,7 +108,7 @@ export class SteamService {
|
||||
}
|
||||
|
||||
public async openSteam(): Promise<void> {
|
||||
|
||||
|
||||
await shell.openPath("steam://open/games");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
@@ -23,7 +23,7 @@ export const AvailableVersionItem = memo(function AvailableVersionItem({version,
|
||||
const formatedDate = useConstant(() => dateFormat(+version.ReleaseDate * 1000, "ddd. d mmm yyyy"));
|
||||
|
||||
return (
|
||||
<motion.li id={`version-item-${version.BSManifest}`} className="group relative w-72 h-60 active:scale-[.98]" onClick={onClick} onHoverStart={() => setHovered(true)} onHoverEnd={() => setHovered(false)}>
|
||||
<motion.li className="group relative w-72 h-60 active:scale-[.98]" onClick={onClick} onHoverStart={() => setHovered(true)} onHoverEnd={() => setHovered(false)}>
|
||||
<GlowEffect visible={hovered || selected} className="absolute" />
|
||||
<div className={`relative flex flex-col overflow-hidden rounded-md w-72 h-60 cursor-pointer group-hover:shadow-none duration-300 bg-light-main-color-2 dark:bg-main-color-2 ${!selected && "shadow-lg shadow-gray-900"}`}>
|
||||
{version.recommended && (
|
||||
|
||||
@@ -29,7 +29,7 @@ export function AvailableVersionsSlide({ versions }: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<ol id={`version-slide-${versions}`} className="w-full flex items-start justify-center gap-6 shrink-0 content-start flex-wrap px-3.5 py-4 overflow-x-hidden overflow-y-scroll scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900">
|
||||
<ol className="w-full flex items-start justify-center gap-6 shrink-0 content-start flex-wrap px-3.5 py-4 overflow-x-hidden overflow-y-scroll scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900">
|
||||
{getVersions().map(version => (
|
||||
<AvailableVersionItem key={version.BSManifest} version={version} selected={equal(version, context.selectedVersion)} onClick={() => setSelectedVersion(version)}/>
|
||||
))}
|
||||
|
||||
@@ -26,7 +26,7 @@ export function AvailableVersionsSlider() {
|
||||
|
||||
return (
|
||||
<div className="w-full h-fit max-h-full flex flex-col items-center grow min-h-0 gap-3">
|
||||
<TabNavBar id="version-years-tab-bar" tabIndex={yearIndex} tabsText={availableYears} onTabChange={setSelectedYear} />
|
||||
<TabNavBar tabIndex={yearIndex} tabsText={availableYears} onTabChange={setSelectedYear} />
|
||||
<ol className="w-full min-h-0 flex transition-transform duration-300" style={{ transform: `translate(${-(yearIndex * 100)}%, 0)` }}>
|
||||
{availableYears.map(year => (
|
||||
<AvailableVersionsSlide key={year} versions={getVersionOfYear(year)} />
|
||||
|
||||
@@ -31,7 +31,7 @@ export const BsManagerIcon = memo(({ className }: { className?: string }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div id="bsm-logo" className="cursor-pointer" whileTap={{ rotate: -10 }} variants={transitions} animate={playing && bpm > 0 ? "playing" : "idle"} onClick={clickAction}>
|
||||
<motion.div className="cursor-pointer" whileTap={{ rotate: -10 }} variants={transitions} animate={playing && bpm > 0 ? "playing" : "idle"} onClick={clickAction}>
|
||||
<svg className={className} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
|
||||
<g fill={firstColor}>
|
||||
<path d="M626.75,485.91l20.82,351.94a35.21,35.21,0,0,1-15.49,31.36L487.37,965.35l-.06,0A35.56,35.56,0,0,1,476,970.12a34.85,34.85,0,0,1-23.51-2.87L136.58,809.9a115.45,115.45,0,0,1-63.75-96.49L52,361.46a35.26,35.26,0,0,1,15.23-31.21l145.05-96.36a35.72,35.72,0,0,1,11.27-4.7,34.87,34.87,0,0,1,23.51,2.87L563,389.42a115.41,115.41,0,0,1,63.75,96.49Z" />
|
||||
|
||||
@@ -7,14 +7,13 @@ type Props = {
|
||||
progress?: number;
|
||||
isActive?: boolean;
|
||||
onCancel?: (e: React.MouseEvent) => void;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
export function NavBarItem({ progress, isDownloading, children, isActive, onCancel, id }: Props) {
|
||||
export function NavBarItem({ progress, isDownloading, children, isActive, onCancel }: Props) {
|
||||
const { firstColor, secondColor } = useThemeColor();
|
||||
|
||||
return (
|
||||
<li id={id} className={`outline-none relative p-[1px] overflow-hidden rounded-xl flex justify-center items-center mb-1 ${isDownloading && "nav-item-download"} active:translate-y-[1px]`}>
|
||||
<li className={`outline-none relative p-[1px] overflow-hidden rounded-xl flex justify-center items-center mb-1 ${isDownloading && "nav-item-download"} active:translate-y-[1px]`}>
|
||||
{isDownloading && <div className="download-progress absolute top-0 w-full h-full" style={{ transform: `translate(${-(100 - progress)}%, 0)`, background: `linear-gradient(90deg, ${firstColor}, ${secondColor}, ${firstColor}, ${secondColor})` }} />}
|
||||
<div className={`wrapper z-[1] px-1 py-[3px] w-full rounded-xl ${isDownloading && "bg-white dark:bg-black"} ${!isDownloading && "hover:bg-light-main-color-3 dark:hover:bg-main-color-3"} ${isActive && !isDownloading && "bg-light-main-color-3 dark:bg-main-color-3"}`}>
|
||||
{children}
|
||||
|
||||
@@ -16,7 +16,7 @@ export function SharedNavBarItem() {
|
||||
const color = useThemeColor("first-color");
|
||||
|
||||
return (
|
||||
<NavBarItem id="shared-contents-btn" isActive={route === "/shared"}>
|
||||
<NavBarItem isActive={route === "/shared"}>
|
||||
<Tippy content={t("nav-bar.shared.tooltip")} className="font-bold !bg-neutral-900" placement="right-end" arrow={false} duration={[100, 0]} animation="shift-away-subtle">
|
||||
<Link to="shared" className="w-full flex items-center justify-start content-center max-w-full h-[30px]">
|
||||
<BsmIcon className="w-[19px] h-[19px] mr-[5px] shrink-0 brightness-125" icon="link" style={{ color }} />
|
||||
|
||||
@@ -48,12 +48,12 @@ export function NavBar() {
|
||||
<NavBarSpliter />
|
||||
<div className="w-full pb-2 flex flex-col items-center content-center justify-start gap-1">
|
||||
<Tippy placement="right" content={t("nav-bar.add-version")} className="!bg-neutral-900" arrow={false}>
|
||||
<Link id="add-version-btn" className="rounded-md w-9 h-9 flex justify-center items-center hover:bg-light-main-color-3 dark:hover:bg-main-color-3" to="blah">
|
||||
<Link className="rounded-md w-9 h-9 flex justify-center items-center hover:bg-light-main-color-3 dark:hover:bg-main-color-3" to="blah">
|
||||
<BsmIcon icon="add" className="text-blue-500 h-[34px]" style={{ color }} />
|
||||
</Link>
|
||||
</Tippy>
|
||||
<Tippy placement="right" content={t("nav-bar.settings")} className="!bg-neutral-900" arrow={false}>
|
||||
<Link id="settings-btn" className="rounded-md w-9 h-9 flex justify-center items-center hover:bg-light-main-color-3 dark:hover:bg-main-color-3" to="settings">
|
||||
<Link className="rounded-md w-9 h-9 flex justify-center items-center hover:bg-light-main-color-3 dark:hover:bg-main-color-3" to="settings">
|
||||
<BsmIcon icon="settings" className="text-blue-500 h-7" style={{ color }} />
|
||||
</Link>
|
||||
</Tippy>
|
||||
|
||||
@@ -9,7 +9,6 @@ import { getCorrectTextColor } from "renderer/helpers/correct-text-color";
|
||||
type BsmButtonType = "primary" | "secondary" | "success" | "cancel" | "error";
|
||||
|
||||
type Props = {
|
||||
id?: string;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
imgClassName?: string;
|
||||
@@ -30,7 +29,7 @@ type Props = {
|
||||
textClassName?: string;
|
||||
};
|
||||
|
||||
export function BsmButton({ id, className, style, imgClassName, iconClassName, icon, image, text, type, active, withBar = true, disabled, onClickOutside, onClick, typeColor, color, title, iconColor, textClassName }: Props) {
|
||||
export function BsmButton({ className, style, imgClassName, iconClassName, icon, image, text, type, active, withBar = true, disabled, onClickOutside, onClick, typeColor, color, title, iconColor, textClassName }: Props) {
|
||||
const t = useTranslation();
|
||||
const { firstColor, secondColor } = useThemeColor();
|
||||
const ref = useRef(null);
|
||||
@@ -73,7 +72,7 @@ export function BsmButton({ id, className, style, imgClassName, iconClassName, i
|
||||
const handleClick = (e: MouseEvent<HTMLDivElement>) => !disabled && onClick?.(e);
|
||||
|
||||
return (
|
||||
<div id={id} ref={ref} onClick={handleClick} title={t(title)} className={`${className} overflow-hidden group ${!withBar && !disabled && (!!typeColor || !!color) && "hover:brightness-[1.15]"} ${disabled ? "brightness-75 cursor-not-allowed" : "cursor-pointer"} ${renderTypeColor}`} style={{ ...style, backgroundColor: primaryColor || color }}>
|
||||
<div ref={ref} onClick={handleClick} title={t(title)} className={`${className} overflow-hidden group ${!withBar && !disabled && (!!typeColor || !!color) && "hover:brightness-[1.15]"} ${disabled ? "brightness-75 cursor-not-allowed" : "cursor-pointer"} ${renderTypeColor}`} style={{ ...style, backgroundColor: primaryColor || color }}>
|
||||
{image && <BsmImage image={image} className={imgClassName} />}
|
||||
{icon && <BsmIcon icon={icon} className={iconClassName ?? "h-full w-full text-gray-800 dark:text-white"} style={{ color: iconColor || textColor }} />}
|
||||
{text &&
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useTranslation } from "renderer/hooks/use-translation.hook";
|
||||
import { LaserSlider } from "./laser-slider.component";
|
||||
|
||||
type Props = {
|
||||
id?: string,
|
||||
tabIndex: number;
|
||||
tabsText: string[];
|
||||
onTabChange: (index: number) => void;
|
||||
@@ -23,7 +22,7 @@ export function TabNavBar(props: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<nav id={props.id} className={`relative h-8 shrink-0 cursor-pointer rounded-md overflow-hidden shadow-md shadow-black bg-light-main-color-2 dark:bg-main-color-2 ${props.className}`}>
|
||||
<nav className={`relative h-8 shrink-0 cursor-pointer rounded-md overflow-hidden shadow-md shadow-black bg-light-main-color-2 dark:bg-main-color-2 ${props.className}`}>
|
||||
<LaserSlider className="absolute w-full h-1 bottom-0" mode="horizontal" color={secondColor} nbSteps={props.tabsText.length} step={currentIndex} />
|
||||
<ul className="grid" style={{ gridTemplateColumns: `repeat(${props.tabsText.length}, minmax(0, 1fr))` }}>
|
||||
{props.tabsText.map((text, index) =>
|
||||
|
||||
@@ -56,7 +56,7 @@ export function AvailableVersionsList() {
|
||||
<AnimatePresence>
|
||||
{selectedVersion && !downloading && (
|
||||
<motion.div initial={{ y: "150%" }} animate={{ y: "0%" }} exit={{ y: "150%" }} className="absolute bottom-5" onClick={startDownload}>
|
||||
<BsmButton id="download-version-btn" text="misc.download" className="relative text-gray-800 dark:text-gray-100 rounded-md text-3xl font-bold italic tracking-wide px-3 pb-2 pt-1 shadow-md shadow-black" />
|
||||
<BsmButton text="misc.download" className="relative text-gray-800 dark:text-gray-100 rounded-md text-3xl font-bold italic tracking-wide px-3 pb-2 pt-1 shadow-md shadow-black" />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
export function tryit<Return>(func: () => Return): {error: Error, result: Return} {
|
||||
import { isPromise } from "./promise.helpers";
|
||||
|
||||
type TryitReturn<Return> = Return extends Promise<any> ? Promise<{ error: Error | null, result: Awaited<Return> | null }> : { error: Error | null, result: Return | null };
|
||||
|
||||
export function tryit<Return>(func: () => Return): TryitReturn<Return> {
|
||||
try {
|
||||
return { error: null, result: func() };
|
||||
const result = func();
|
||||
|
||||
if(isPromise(result)){
|
||||
return result
|
||||
.then((value) => ({ error: null, result: value }))
|
||||
.catch((err) => ({ error: err instanceof Error ? err : new Error(`${err}`), result: null })) as Return extends Promise<any>
|
||||
? Promise<{error: Error, result: undefined} | {error: undefined, result: Awaited<Return>}>
|
||||
: {error: Error, result: undefined} | {error: undefined, result: Return};
|
||||
}
|
||||
|
||||
return { error: undefined, result } as TryitReturn<Return>;
|
||||
|
||||
} catch (err) {
|
||||
return { error: err instanceof Error ? err : new Error(`${err}`), result: null }
|
||||
return { error: err, result: undefined } as TryitReturn<Return>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export function isFunction(value: any): value is Function {
|
||||
return !!(value && value.constructor && value.call && value.apply)
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { isFunction } from "./function.helpers";
|
||||
|
||||
export type AllSettledHelperOptions = {
|
||||
keepStructure?: boolean;
|
||||
removeFalsy?: boolean;
|
||||
@@ -20,8 +22,9 @@ export async function allSettled<T>(promises: Promise<T>[], options?: AllSettled
|
||||
}, []);
|
||||
}
|
||||
|
||||
export async function pause(ms: number): Promise<void>{
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(), ms);
|
||||
});
|
||||
export function isPromise(value: any): value is Promise<unknown> {
|
||||
if(!value) { return false; }
|
||||
if(!value.then) { return false; }
|
||||
if(!isFunction(value.then)) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-1
@@ -20,7 +20,8 @@
|
||||
"resolveJsonModule": true,
|
||||
"allowJs": true,
|
||||
"outDir": "release/app/dist",
|
||||
"strictNullChecks": false
|
||||
"strictNullChecks": false,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"exclude": ["test", "release/build", "release/app/dist", ".erb/dll"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user