Merge branch 'main' into steam_import_fix

This commit is contained in:
Neeraj Gupta 2024-06-03 14:15:51 +05:30
commit 741018b802
54 changed files with 726 additions and 466 deletions

View File

@ -76,7 +76,7 @@ Future<void> _pickAegisJsonFile(BuildContext context) async {
await showErrorDialog(
context,
context.l10n.sorry,
context.l10n.importFailureDesc,
"${context.l10n.importFailureDesc}\n Error: ${e.toString()}",
);
}
}
@ -148,7 +148,7 @@ Future<int?> _processAegisExportFile(
otpUrl =
'otpauth://$kind/$issuer:$account?secret=$secret&issuer=$issuer&algorithm=$algorithm&digits=$digits&counter=$counter';
} else {
throw Exception('Invalid OTP type');
throw Exception('Invalid OTP type: $kind');
}
parsedCodes.add(Code.fromOTPAuthUrl(otpUrl));
}

View File

@ -14,6 +14,7 @@ import 'package:ente_auth/utils/dialog_util.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
Future<void> showBitwardenImportInstruction(BuildContext context) async {
final l10n = context.l10n;
@ -60,12 +61,13 @@ Future<void> _pickBitwardenJsonFile(BuildContext context) async {
if (count != null) {
await importSuccessDialog(context, count);
}
} catch (e) {
} catch (e,s) {
Logger("BitwardenImport").severe('Failed to import',e,s);
await progressDialog.hide();
await showErrorDialog(
context,
context.l10n.sorry,
context.l10n.importFailureDesc,
"${context.l10n.importFailureDesc}\n Error: ${e.toString()}",
);
}
}

View File

@ -14,6 +14,7 @@ import 'package:ente_auth/utils/dialog_util.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
Future<void> showLastpassImportInstruction(BuildContext context) async {
final l10n = context.l10n;
@ -60,12 +61,13 @@ Future<void> _pickLastpassJsonFile(BuildContext context) async {
if (count != null) {
await importSuccessDialog(context, count);
}
} catch (e) {
} catch (e, s) {
Logger('LastPassImport').severe('exception while processing import', e, s);
await progressDialog.hide();
await showErrorDialog(
context,
context.l10n.sorry,
context.l10n.importFailureDesc,
"${context.l10n.importFailureDesc}\n Error: ${e.toString()}",
);
}
}

View File

@ -14,6 +14,7 @@ import 'package:ente_auth/utils/dialog_util.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
Future<void> showRaivoImportInstruction(BuildContext context) async {
final l10n = context.l10n;
@ -60,12 +61,13 @@ Future<void> _pickRaivoJsonFile(BuildContext context) async {
if (count != null) {
await importSuccessDialog(context, count);
}
} catch (e) {
} catch (e, s) {
Logger("RaivoImport").severe('Failed to import', e, s);
await progressDialog.hide();
await showErrorDialog(
context,
context.l10n.sorry,
context.l10n.importFailureDesc,
"${context.l10n.importFailureDesc}\n Error: ${e.toString()}",
);
}
}

View File

@ -72,7 +72,7 @@ Future<void> _pick2FasFile(BuildContext context) async {
await showErrorDialog(
context,
context.l10n.sorry,
context.l10n.importFailureDesc,
"${context.l10n.importFailureDesc}\n Error: ${e.toString()}",
);
}
}

View File

@ -1,6 +1,6 @@
name: ente_auth
description: ente two-factor authenticator
version: 3.0.4+304
version: 3.0.5+305
publish_to: none
environment:

View File

@ -1,36 +0,0 @@
/* eslint-env node */
module.exports = {
root: true,
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/strict-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked",
],
plugins: ["@typescript-eslint"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
},
ignorePatterns: [".eslintrc.js", "app", "out", "dist"],
env: {
es2022: true,
node: true,
},
rules: {
/* Allow numbers to be used in template literals */
"@typescript-eslint/restrict-template-expressions": [
"error",
{
allowNumber: true,
},
],
/* Allow void expressions as the entire body of an arrow function */
"@typescript-eslint/no-confusing-void-expression": [
"error",
{
ignoreArrowShorthand: true,
},
],
},
};

View File

@ -1,5 +1,9 @@
# CHANGELOG
## v1.7.1 (Unreleased)
- Remember the window size across app restarts.
## v1.7.0
v1.7 is a major rewrite to improve the security of our app. In particular, the

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

43
desktop/eslint.config.mjs Normal file
View File

@ -0,0 +1,43 @@
// @ts-check
import js from "@eslint/js";
import ts from "typescript-eslint";
export default ts.config(
js.configs.recommended,
...ts.configs.strictTypeChecked,
...ts.configs.stylisticTypeChecked,
{
// typescript-eslint needs this enabling type checked rules.
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
// The list of (minimatch) globs to ignore. This needs to be the only
// key in this configuration object.
ignores: ["eslint.config.mjs", "app/", "out/", "dist/"],
},
{
// Rule customizations.
rules: {
// Allow numbers to be used in template literals.
"@typescript-eslint/restrict-template-expressions": [
"error",
{
allowNumber: true,
},
],
// Allow void expressions as the entire body of an arrow function.
"@typescript-eslint/no-confusing-void-expression": [
"error",
{
ignoreArrowShorthand: true,
},
],
},
},
);

View File

@ -17,8 +17,8 @@
"dev-main": "tsc && electron .",
"dev-renderer": "cd ../web && yarn install && yarn dev:photos",
"postinstall": "electron-builder install-app-deps",
"lint": "yarn prettier --check --log-level warn . && eslint --ext .ts src && yarn tsc",
"lint-fix": "yarn prettier --write --log-level warn . && eslint --fix --ext .ts src && yarn tsc"
"lint": "yarn prettier --check --log-level warn . && yarn eslint && yarn tsc",
"lint-fix": "yarn prettier --write --log-level warn . && yarn eslint && yarn tsc"
},
"resolutions": {
"jackspeak": "2.1.1"
@ -36,23 +36,24 @@
"jpeg-js": "^0.4",
"next-electron-server": "^1",
"node-stream-zip": "^1.15",
"onnxruntime-node": "^1.17"
"onnxruntime-node": "^1.18"
},
"devDependencies": {
"@eslint/js": "^9.4.0",
"@tsconfig/node20": "^20.1.4",
"@types/auto-launch": "^5.0",
"@types/eslint__js": "^8.42.3",
"@types/ffmpeg-static": "^3.0",
"@typescript-eslint/eslint-plugin": "^7",
"@typescript-eslint/parser": "^7",
"concurrently": "^8",
"electron": "^30",
"electron-builder": "25.0.0-alpha.6",
"eslint": "^8",
"electron-builder": "25.0.0-alpha.8",
"eslint": "^9.4.0",
"prettier": "^3",
"prettier-plugin-organize-imports": "^3",
"prettier-plugin-packagejson": "^2",
"shx": "^0.3",
"typescript": "^5"
"typescript": "^5",
"typescript-eslint": "8.0.0-alpha.10"
},
"packageManager": "yarn@1.22.21",
"productName": "ente"

View File

@ -143,12 +143,20 @@ const registerPrivilegedSchemes = () => {
* This window will show the HTML served from {@link rendererURL}.
*/
const createMainWindow = () => {
const bounds = windowBounds();
// Create the main window. This'll show our web content.
const window = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, "preload.js"),
sandbox: true,
},
// Set the window's position and size (if we have one saved).
...(bounds ?? {}),
// Enforce a minimum size
...minimumWindowSize(),
// (Maybe) fix the dock icon on Linux.
...windowIconOptions(),
// The color to show in the window until the web content gets loaded.
// See: https://www.electronjs.org/docs/latest/api/browser-window#setting-the-backgroundcolor-property
backgroundColor: "black",
@ -162,8 +170,10 @@ const createMainWindow = () => {
// On macOS, also hide the dock icon on macOS.
if (process.platform == "darwin") app.dock.hide();
} else {
// Show our window (maximizing it) otherwise.
window.maximize();
// Show our window otherwise.
//
// If we did not give it an explicit size, maximize it
bounds ? window.show() : window.maximize();
}
// Open the DevTools automatically when running in dev mode
@ -209,11 +219,90 @@ const createMainWindow = () => {
return window;
};
/**
* The position and size of the window the last time it was closed.
*
* The return value of `undefined` is taken to mean that the app's main window
* should be maximized.
*/
const windowBounds = () => userPreferences.get("windowBounds");
/**
* If for some reason {@link windowBounds} is outside the screen's bounds (e.g.
* if the user's screen resolution has changed), then the previously saved
* bounds might not be appropriate.
*
* Luckily, if we try to set an x/y position that is outside the screen's
* bounds, then Electron automatically clamps them to the screen's available
* space, and we do not need to tackle it specifically.
*
* However, there is no minimum window size the Electron enforces by default. As
* a safety valve, provide an (arbitrary) minimum size so that the user can
* resize it back to sanity if something I cannot currently anticipate happens.
*/
const minimumWindowSize = () => ({ minWidth: 200, minHeight: 200 });
/**
* Sibling of {@link windowBounds}, see that function's documentation for more
* details.
*/
const saveWindowBounds = (window: BrowserWindow) => {
if (window.isMaximized()) userPreferences.delete("windowBounds");
else userPreferences.set("windowBounds", window.getBounds());
};
/**
* On Linux the app does not show a dock icon by default, attempt to fix this by
* returning the path to an icon as the "icon" property that can be passed to
* the BrowserWindow during creation.
*/
const windowIconOptions = () => {
if (process.platform != "linux") return {};
// There are two, possibly three, different issues with icons on Linux.
//
// Firstly, the AppImage itself doesn't show an icon. There does not seem to
// be a reasonable workaround either currently. See:
// https://github.com/AppImage/AppImageKit/issues/346
//
// Secondly, and this is the problem we're trying to fix here, when the app
// is started it does not show a dock icon (Ubuntu 22) or shows the generic
// gear icon (Ubuntu 24). The issue possibly exists on other distributions
// too.
//
// Electron provides a `BrowserWindow.setIcon` function which should solve
// our issue, we could call it selectively on Linux. There is also an
// apparently undocumented "icon" option that can be passed when creating a
// new BrowserWindow, and that is what most of the other code I saw on
// GitHub seems to be doing.
//
// However, try what I may, I can't get either of these to work. Which leads
// me to believe there is a third issue: I can't get it to work because I'm
// testing on an Ubuntu 24 VM, where this might just not be working:
// https://askubuntu.com/questions/1511534/ubuntu-24-04-skype-logo-on-the-dock-not-showing-skype-logo
//
// 24 isn't likely the year of the Linux desktop either.
//
// For now, I'm adding a very specific incantation taken from
// https://github.com/arduino/arduino-ide/blob/main/arduino-ide-extension/src/electron-main/fix-app-image-icon.ts
//
// Possibly all this specific naming of the file etc is superstition, and
// just any name would do as long as the path is correct, but let me try it
// this way and see if this gets the icon to appear on Ubuntu 22 etc.
const icon = path.join(
isDev ? "build" : process.resourcesPath,
"icons/512x512.png",
);
return { icon };
};
/**
* Automatically set the save path for user initiated downloads to the system's
* "downloads" directory instead of asking the user to select a save location.
*/
export const setDownloadPath = (webContents: WebContents) => {
const setDownloadPath = (webContents: WebContents) => {
webContents.session.on("will-download", (_, item) => {
item.setSavePath(
uniqueSavePath(app.getPath("downloads"), item.getFilename()),
@ -241,7 +330,7 @@ const uniqueSavePath = (dirPath: string, fileName: string) => {
*
* @param webContents The renderer to configure.
*/
export const allowExternalLinks = (webContents: WebContents) =>
const allowExternalLinks = (webContents: WebContents) =>
// By default, if the user were open a link, say
// https://github.com/ente-io/ente/discussions, then it would open a _new_
// BrowserWindow within our app.
@ -273,7 +362,7 @@ export const allowExternalLinks = (webContents: WebContents) =>
* "Access-Control-Allow-Origin: *" or do a echo-back of `Origin`, we add a
* workaround here instead, intercepting the ACAO header and allowing `*`.
*/
export const allowAllCORSOrigins = (webContents: WebContents) =>
const allowAllCORSOrigins = (webContents: WebContents) =>
webContents.session.webRequest.onHeadersReceived(
({ responseHeaders }, callback) => {
const headers: NonNullable<typeof responseHeaders> = {};
@ -444,7 +533,10 @@ const main = () => {
// app, e.g. by clicking on its dock icon.
app.on("activate", () => mainWindow?.show());
app.on("before-quit", allowWindowClose);
app.on("before-quit", () => {
if (mainWindow) saveWindowBounds(mainWindow);
allowWindowClose();
});
};
main();

View File

@ -1,20 +1,43 @@
import Store, { Schema } from "electron-store";
interface UserPreferences {
/**
* If true, then the user has set a preference to also hide the dock icon on
* macOS whenever the app is hidden. The tray icon is always visible and can
* then be used to reopen the app when needed.
*/
hideDockIcon?: boolean;
skipAppVersion?: string;
muteUpdateNotificationVersion?: string;
/**
* The last position and size of our app's window.
*
* This value is saved when the app is about to quit, and is used to restore
* the window to the previous state when it restarts.
*
* If the user maximizes the window then this value is cleared and instead
* we just re-maximize the window on restart. This is also the behaviour if
* no previously saved `windowRect` is found.
*/
windowBounds?: {
x: number;
y: number;
width: number;
height: number;
};
}
const userPreferencesSchema: Schema<UserPreferences> = {
hideDockIcon: {
type: "boolean",
},
skipAppVersion: {
type: "string",
},
muteUpdateNotificationVersion: {
type: "string",
hideDockIcon: { type: "boolean" },
skipAppVersion: { type: "string" },
muteUpdateNotificationVersion: { type: "string" },
windowBounds: {
properties: {
x: { type: "number" },
y: { type: "number" },
width: { type: "number" },
height: { type: "number" },
},
},
};

View File

@ -19,7 +19,6 @@
* curl -v -H "Location;" -H "User-Agent: FooBar's so-called ""Browser""" "http://www.daveeddy.com/?name=dave&age=24"
Which is suitable for being executed by the shell.
*/
/* eslint-disable no-unused-vars */
declare module "any-shell-escape" {
declare const shellescape: (args: readonly string | string[]) => string;
export default shellescape;

View File

@ -1,4 +1,3 @@
/* eslint-disable no-unused-vars */
/**
* @file The preload script
*

View File

@ -373,7 +373,6 @@ export default class {
return token + "</w>";
}
// eslint-disable-next-line no-constant-condition
while (1) {
let bigram: [string, string] | null = null;
let minRank = Infinity;

View File

@ -32,6 +32,6 @@
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
},
/* Transpile all `.ts` files in `src/` */
"include": ["src/**/*.ts"]
/* Include all `.ts` files in `src/` */
"include": ["src"]
}

View File

@ -65,10 +65,10 @@
fs-extra "^9.0.1"
promise-retry "^2.0.1"
"@electron/osx-sign@1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.5.tgz#0af7149f2fce44d1a8215660fd25a9fb610454d8"
integrity sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==
"@electron/osx-sign@1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.3.0.tgz#bd6fb60c519b76ca8a000e5801f5685690e8adad"
integrity sha512-TEXhxlYSDRr9JWK5nWdOv5MtuUdaZ412uxIIEQ0hLt80o0HYWtQJBlW5QmrQDMtebzATaOjKG9UfCzLyA90zWQ==
dependencies:
compare-version "^0.1.2"
debug "^4.3.4"
@ -122,49 +122,54 @@
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63"
integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==
"@eslint/eslintrc@^2.1.4":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad"
integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==
"@eslint/config-array@^0.15.1":
version "0.15.1"
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.15.1.tgz#1fa78b422d98f4e7979f2211a1fde137e26c7d61"
integrity sha512-K4gzNq+yymn/EVsXYmf+SBcBro8MTf+aXJZUphM96CdzUEr+ClGDvAbpmaEK+cGVigVXIgs9gNmvHAlrzzY5JQ==
dependencies:
"@eslint/object-schema" "^2.1.3"
debug "^4.3.1"
minimatch "^3.0.5"
"@eslint/eslintrc@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6"
integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.6.0"
globals "^13.19.0"
espree "^10.0.1"
globals "^14.0.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@8.57.0":
version "8.57.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f"
integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==
"@eslint/js@9.4.0", "@eslint/js@^9.4.0":
version "9.4.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.4.0.tgz#96a2edd37ec0551ce5f9540705be23951c008a0c"
integrity sha512-fdI7VJjP3Rvc70lC4xkFXHB0fiPeojiL1PxVG6t1ZvXQrarj893PweuBTujxDUFk0Fxj4R7PIIAZ/aiiyZPZcg==
"@eslint/object-schema@^2.1.3":
version "2.1.3"
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.3.tgz#e65ae80ee2927b4fd8c5c26b15ecacc2b2a6cc2a"
integrity sha512-HAbhAYKfsAC2EkTqve00ibWIZlaU74Z1EHwAjYr4PXF0YU2VEA1zSIKSSpKszRLRWwHzzRZXvK632u+uXzvsvw==
"@gar/promisify@^1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
"@humanwhocodes/config-array@^0.11.14":
version "0.11.14"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"
integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==
dependencies:
"@humanwhocodes/object-schema" "^2.0.2"
debug "^4.3.1"
minimatch "^3.0.5"
"@humanwhocodes/module-importer@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
"@humanwhocodes/object-schema@^2.0.2":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3"
integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
"@humanwhocodes/retry@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.0.tgz#6d86b8cb322660f03d3f0aa94b99bdd8e172d570"
integrity sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==
"@isaacs/fs-minipass@^4.0.0":
version "4.0.1"
@ -281,6 +286,26 @@
dependencies:
"@types/ms" "*"
"@types/eslint@*":
version "8.56.10"
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.10.tgz#eb2370a73bf04a901eeba8f22595c7ee0f7eb58d"
integrity sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==
dependencies:
"@types/estree" "*"
"@types/json-schema" "*"
"@types/eslint__js@^8.42.3":
version "8.42.3"
resolved "https://registry.yarnpkg.com/@types/eslint__js/-/eslint__js-8.42.3.tgz#d1fa13e5c1be63a10b4e3afe992779f81c1179a0"
integrity sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==
dependencies:
"@types/eslint" "*"
"@types/estree@*":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/ffmpeg-static@^3.0":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/ffmpeg-static/-/ffmpeg-static-3.0.3.tgz#605358ac6304507a75c2fd5fd861534837b19e2f"
@ -298,7 +323,7 @@
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4"
integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==
"@types/json-schema@^7.0.15":
"@types/json-schema@*", "@types/json-schema@^7.0.15":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
@ -316,9 +341,9 @@
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
"@types/node@*", "@types/node@^20.9.0":
version "20.12.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050"
integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==
version "20.13.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.13.0.tgz#011a76bc1e71ae9a026dddcfd7039084f752c4b6"
integrity sha512-FM6AOb3khNkNIXPnHFDYaHerSv8uN22C91z098AnGccVu+Pcdhi+pNUFDi0iLmPIsVE0JBD0KVS7mzUYt4nRzQ==
dependencies:
undici-types "~5.26.4"
@ -359,16 +384,16 @@
dependencies:
"@types/node" "*"
"@typescript-eslint/eslint-plugin@^7":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz#c78e309fe967cb4de05b85cdc876fb95f8e01b6f"
integrity sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==
"@typescript-eslint/eslint-plugin@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0-alpha.10.tgz#a102e40da7b72a2981cb2da43064d9b3c865ca58"
integrity sha512-jsNKqn41nIS8jz5Li5xsueGEBBmRYLaflUKlclEkj8cWrO1tMK1/7xITeiVz7ZlNFZF2nop2NlXrbLtRpLEzhg==
dependencies:
"@eslint-community/regexpp" "^4.10.0"
"@typescript-eslint/scope-manager" "7.8.0"
"@typescript-eslint/type-utils" "7.8.0"
"@typescript-eslint/utils" "7.8.0"
"@typescript-eslint/visitor-keys" "7.8.0"
"@typescript-eslint/scope-manager" "8.0.0-alpha.10"
"@typescript-eslint/type-utils" "8.0.0-alpha.10"
"@typescript-eslint/utils" "8.0.0-alpha.10"
"@typescript-eslint/visitor-keys" "8.0.0-alpha.10"
debug "^4.3.4"
graphemer "^1.4.0"
ignore "^5.3.1"
@ -376,47 +401,47 @@
semver "^7.6.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/parser@^7":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.8.0.tgz#1e1db30c8ab832caffee5f37e677dbcb9357ddc8"
integrity sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==
"@typescript-eslint/parser@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.0.0-alpha.10.tgz#fbefd39da010d65407b985f2b5c6e0a79bc8a6f4"
integrity sha512-4EerPviLfBKgExHARehJgWrCtX2a7+PXBc0LBPlH93ypSgj0LU1ejMgjrB0gcfd6bJ7LN/UGNAAy3B7/Y785sA==
dependencies:
"@typescript-eslint/scope-manager" "7.8.0"
"@typescript-eslint/types" "7.8.0"
"@typescript-eslint/typescript-estree" "7.8.0"
"@typescript-eslint/visitor-keys" "7.8.0"
"@typescript-eslint/scope-manager" "8.0.0-alpha.10"
"@typescript-eslint/types" "8.0.0-alpha.10"
"@typescript-eslint/typescript-estree" "8.0.0-alpha.10"
"@typescript-eslint/visitor-keys" "8.0.0-alpha.10"
debug "^4.3.4"
"@typescript-eslint/scope-manager@7.8.0":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz#bb19096d11ec6b87fb6640d921df19b813e02047"
integrity sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==
"@typescript-eslint/scope-manager@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.0.0-alpha.10.tgz#25506ce51ab64e99f2bc0b7d3f0f82656e14a794"
integrity sha512-SUU0yhqehjuWilWRJWfhcxf6eMKVrZ3bpV2w6NF6GmBHR3FJo6oWZYLVXP04s6//INxpC2ynvKSglo4LRzWVTw==
dependencies:
"@typescript-eslint/types" "7.8.0"
"@typescript-eslint/visitor-keys" "7.8.0"
"@typescript-eslint/types" "8.0.0-alpha.10"
"@typescript-eslint/visitor-keys" "8.0.0-alpha.10"
"@typescript-eslint/type-utils@7.8.0":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz#9de166f182a6e4d1c5da76e94880e91831e3e26f"
integrity sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==
"@typescript-eslint/type-utils@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.0.0-alpha.10.tgz#d27f0fdd81450380887b3a07297440ba3588a70e"
integrity sha512-6aTcbnDZWKgKr3gquECJSFyvXWLSKtUHrk2ZXDP4DEzmzTDjrkY7tIQpqv4SczPQJ+3/aky3ArPhtnQYJbAMzg==
dependencies:
"@typescript-eslint/typescript-estree" "7.8.0"
"@typescript-eslint/utils" "7.8.0"
"@typescript-eslint/typescript-estree" "8.0.0-alpha.10"
"@typescript-eslint/utils" "8.0.0-alpha.10"
debug "^4.3.4"
ts-api-utils "^1.3.0"
"@typescript-eslint/types@7.8.0":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.8.0.tgz#1fd2577b3ad883b769546e2d1ef379f929a7091d"
integrity sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==
"@typescript-eslint/types@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.0.0-alpha.10.tgz#89be400c6a1751fe86f5917ed8087ec100e002da"
integrity sha512-prbN+b/I4yH6H43WmyenMz8K5e34Hs73BQuWXR4wwij3Cg2xNGLPcpjr2cKWKlH4dZQPTz6R6oBeC+LfaoKi8g==
"@typescript-eslint/typescript-estree@7.8.0":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz#b028a9226860b66e623c1ee55cc2464b95d2987c"
integrity sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==
"@typescript-eslint/typescript-estree@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0-alpha.10.tgz#e850056d2a5029688269a60206dec3bbd7beb953"
integrity sha512-8wBUIhu6IRa440hv5/0ZEnb5JLp/UsfzIXYKRwICUOMTVj2ss1n+w3m1CtT5ghVWy5Z05qkscsbhlKFmZguU8w==
dependencies:
"@typescript-eslint/types" "7.8.0"
"@typescript-eslint/visitor-keys" "7.8.0"
"@typescript-eslint/types" "8.0.0-alpha.10"
"@typescript-eslint/visitor-keys" "8.0.0-alpha.10"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
@ -424,32 +449,27 @@
semver "^7.6.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/utils@7.8.0":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.8.0.tgz#57a79f9c0c0740ead2f622e444cfaeeb9fd047cd"
integrity sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==
"@typescript-eslint/utils@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.0.0-alpha.10.tgz#b77f743227353bfa493e95409c0e079044c9258e"
integrity sha512-WZyNf49CuvaW/whz/B8XjYwXE/wm/EQAXq+Vqgp6BrJb8SC3bMCwGuUxReNDN1o+dNdOC96ofVSvqa8NUQ65Jg==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
"@types/json-schema" "^7.0.15"
"@types/semver" "^7.5.8"
"@typescript-eslint/scope-manager" "7.8.0"
"@typescript-eslint/types" "7.8.0"
"@typescript-eslint/typescript-estree" "7.8.0"
"@typescript-eslint/scope-manager" "8.0.0-alpha.10"
"@typescript-eslint/types" "8.0.0-alpha.10"
"@typescript-eslint/typescript-estree" "8.0.0-alpha.10"
semver "^7.6.0"
"@typescript-eslint/visitor-keys@7.8.0":
version "7.8.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz#7285aab991da8bee411a42edbd5db760d22fdd91"
integrity sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==
"@typescript-eslint/visitor-keys@8.0.0-alpha.10":
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0-alpha.10.tgz#d0a9250c69cc2f73c7f423c36183d222a329e260"
integrity sha512-UohTNnT7S29uQgXsGZY489nWmoBBSJucNdRvog62R1QX9pQQb2pKVV1kHepUxoY2vd+M4tb9SQwZQ3gPNgqQ6w==
dependencies:
"@typescript-eslint/types" "7.8.0"
"@typescript-eslint/types" "8.0.0-alpha.10"
eslint-visitor-keys "^3.4.3"
"@ungap/structured-clone@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
"@xmldom/xmldom@^0.8.8":
version "0.8.10"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
@ -465,7 +485,7 @@ acorn-jsx@^5.3.2:
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn@^8.9.0:
acorn@^8.11.3:
version "8.11.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
@ -554,14 +574,14 @@ app-builder-bin@4.0.0:
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-4.0.0.tgz#1df8e654bd1395e4a319d82545c98667d7eed2f0"
integrity sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==
app-builder-lib@25.0.0-alpha.6:
version "25.0.0-alpha.6"
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-25.0.0-alpha.6.tgz#3edb49843b249a1dd52b32a80f9787677bc5a32b"
integrity sha512-kXveR7MFTJXBwb2xB2geKWeWP+YGcJ3IzWRgTEV96zwyo4IxzE5xRXcndSQQglmlzw/VoM5Mx322E9ErYbMCVg==
app-builder-lib@25.0.0-alpha.8:
version "25.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-25.0.0-alpha.8.tgz#e8065005b0b5d43f22153ac72101f71bf4e1022b"
integrity sha512-d/pcaTcDv3gfdl9AGGP/DKvc+A+TdJmG15f+vqPeEGKOoqLE0ukReaEevXAtH3wOOs5CqgX6QgNPdszeeqFn3Q==
dependencies:
"@develar/schema-utils" "~2.6.5"
"@electron/notarize" "2.3.0"
"@electron/osx-sign" "1.0.5"
"@electron/osx-sign" "1.3.0"
"@electron/rebuild" "3.6.0"
"@electron/universal" "2.0.1"
"@malept/flatpak-bundler" "^0.4.0"
@ -573,7 +593,7 @@ app-builder-lib@25.0.0-alpha.6:
chromium-pickle-js "^0.2.0"
debug "^4.3.4"
ejs "^3.1.8"
electron-publish "25.0.0-alpha.6"
electron-publish "25.0.0-alpha.7"
form-data "^4.0.0"
fs-extra "^10.1.0"
hosted-git-info "^4.1.0"
@ -582,7 +602,7 @@ app-builder-lib@25.0.0-alpha.6:
js-yaml "^4.1.0"
lazy-val "^1.0.5"
minimatch "^5.1.1"
read-config-file "6.3.2"
read-config-file "6.4.0"
sanitize-filename "^1.6.3"
semver "^7.3.8"
tar "^6.1.12"
@ -718,7 +738,14 @@ brace-expansion@^2.0.1:
dependencies:
balanced-match "^1.0.0"
braces@^3.0.2, braces@~3.0.2:
braces@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies:
fill-range "^7.1.1"
braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
@ -1007,6 +1034,14 @@ conf@^10.2.0:
pkg-up "^3.1.0"
semver "^7.3.5"
config-file-ts@0.2.8-rc1:
version "0.2.8-rc1"
resolved "https://registry.yarnpkg.com/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz#fb7fc6ccb2e313f69dbeb78f1db0b00038049de0"
integrity sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==
dependencies:
glob "^10.3.12"
typescript "^5.4.3"
config-file-ts@^0.2.4:
version "0.2.6"
resolved "https://registry.yarnpkg.com/config-file-ts/-/config-file-ts-0.2.6.tgz#b424ff74612fb37f626d6528f08f92ddf5d22027"
@ -1055,13 +1090,20 @@ debounce-fn@^4.0.0:
dependencies:
mimic-fn "^3.0.0"
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
debug@4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@^4.1.0, debug@^4.1.1, debug@^4.3.4:
version "4.3.5"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
dependencies:
ms "2.1.2"
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@ -1149,12 +1191,12 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
dmg-builder@25.0.0-alpha.6:
version "25.0.0-alpha.6"
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-25.0.0-alpha.6.tgz#1a13008de0543c3080595534ab294cde2a5e57e8"
integrity sha512-GStVExwsuumGN6rPGJksA5bLN5n5QEQd5iQrGKyBSxuwR1+LWidFkM+anroXnANIyTwbppk2S7+808vHjT/Eyw==
dmg-builder@25.0.0-alpha.8:
version "25.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-25.0.0-alpha.8.tgz#fe887023ffc9ce72dfd2472303a76ec008a156d2"
integrity sha512-1/Sfl1sQugHkHEobFafyx1HcmgkFj8pV7HFEK0NQ8bH5K2qsGvknjAeHjtYhV2sBoSNGod4P0SfbScS6p6h4eg==
dependencies:
app-builder-lib "25.0.0-alpha.6"
app-builder-lib "25.0.0-alpha.8"
builder-util "25.0.0-alpha.6"
builder-util-runtime "9.2.5-alpha.2"
fs-extra "^10.1.0"
@ -1177,13 +1219,6 @@ dmg-license@^1.0.11:
smart-buffer "^4.0.2"
verror "^1.10.0"
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
dependencies:
esutils "^2.0.2"
dot-prop@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083"
@ -1191,11 +1226,23 @@ dot-prop@^6.0.1:
dependencies:
is-obj "^2.0.0"
dotenv-expand@^11.0.6:
version "11.0.6"
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-11.0.6.tgz#f2c840fd924d7c77a94eff98f153331d876882d3"
integrity sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==
dependencies:
dotenv "^16.4.4"
dotenv-expand@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
dotenv@^16.4.4, dotenv@^16.4.5:
version "16.4.5"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
dotenv@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05"
@ -1208,16 +1255,16 @@ ejs@^3.1.8:
dependencies:
jake "^10.8.5"
electron-builder@25.0.0-alpha.6:
version "25.0.0-alpha.6"
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-25.0.0-alpha.6.tgz#a72f96f7029539ac28f92ce5c83f872ba3b6e7c1"
integrity sha512-qXzzdID2W9hhx3TXddwXv1C5HsqjF6bKnftUtywAB/gtDwu+neifPZvnXDNHI4ZamRrZpJJH59esfkqkc2KNSQ==
electron-builder@25.0.0-alpha.8:
version "25.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-25.0.0-alpha.8.tgz#7238623cf7a753d0da31f16daea8767d0ef6d572"
integrity sha512-nfrtTljEZackbhJE1BcK+RFXrPvrkrBo0TgR0gH2GxNhPiRTwj/S24K3zHbYj6vBaDVtnqlS6Mqm8tMUrRU4tA==
dependencies:
app-builder-lib "25.0.0-alpha.6"
app-builder-lib "25.0.0-alpha.8"
builder-util "25.0.0-alpha.6"
builder-util-runtime "9.2.5-alpha.2"
chalk "^4.1.2"
dmg-builder "25.0.0-alpha.6"
dmg-builder "25.0.0-alpha.8"
fs-extra "^10.1.0"
is-ci "^3.0.0"
lazy-val "^1.0.5"
@ -1226,14 +1273,14 @@ electron-builder@25.0.0-alpha.6:
yargs "^17.6.2"
electron-log@^5.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.1.2.tgz#fb40ad7f4ae694dd0e4c02c662d1a65c03e1243e"
integrity sha512-Cpg4hAZ27yM9wzE77c4TvgzxzavZ+dVltCczParXN+Vb3jocojCSAuSMCVOI9fhFuuOR+iuu3tZLX1cu0y0kgQ==
version "5.1.5"
resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-5.1.5.tgz#70d5051fc5ab7669b2592f53f72034867269c96e"
integrity sha512-vuq10faUAxRbILgQx7yHoMObKZDEfj7hMSZrJPsVrDNeCpV/HN11dU7QuY4UDUe055pzBxhSCB3m0+6D3Aktjw==
electron-publish@25.0.0-alpha.6:
version "25.0.0-alpha.6"
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-25.0.0-alpha.6.tgz#8af3cb6e2435c00b8c71de43c330483808df5924"
integrity sha512-Hin+6j+jiXBc5g6Wlv9JB5Xu7MADBHxZAndt4WE7luCw7b3+OJdQeDvD/uYiCLpiG8cc2NLxu4MyBSVu86MrJA==
electron-publish@25.0.0-alpha.7:
version "25.0.0-alpha.7"
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-25.0.0-alpha.7.tgz#3c1944c8890b22d5f674772bf16c5382da248861"
integrity sha512-d9R6Jnds3PjzBM4Wt3nRn9ramkbM3kBzt9a6WHQL4/09ByyZGZ1Cu9GS9atRCkH3tBJlOIotUYVhVO36lk3sAA==
dependencies:
"@types/fs-extra" "^9.0.11"
builder-util "25.0.0-alpha.6"
@ -1266,9 +1313,9 @@ electron-updater@^6.2:
tiny-typed-emitter "^2.1.0"
electron@^30:
version "30.0.6"
resolved "https://registry.yarnpkg.com/electron/-/electron-30.0.6.tgz#9ddea5f68396ecca88ad7c2c466a30fc9c16144b"
integrity sha512-PkhEPFdpYcTzjAO3gMHZ+map7g2+xCrMDedo/L1i0ir2BRXvAB93IkTJX497U6Srb/09r2cFt+k20VPNVCdw3Q==
version "30.0.9"
resolved "https://registry.yarnpkg.com/electron/-/electron-30.0.9.tgz#b11400e4642a4b635e79244ba365f1d401ee60b5"
integrity sha512-ArxgdGHVu3o5uaP+Tqj8cJDvU03R6vrGrOqiMs7JXLnvQHMqXJIIxmFKQAIdJW8VoT3ac3hD21tA7cPO10RLow==
dependencies:
"@electron/get" "^2.0.0"
"@types/node" "^20.9.0"
@ -1330,54 +1377,55 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-scope@^7.2.2:
version "7.2.2"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f"
integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==
eslint-scope@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.1.tgz#a9601e4b81a0b9171657c343fb13111688963cfc"
integrity sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.3:
version "3.4.3"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint@^8:
version "8.57.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668"
integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==
eslint-visitor-keys@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb"
integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==
eslint@^9.4.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.4.0.tgz#79150c3610ae606eb131f1d648d5f43b3d45f3cd"
integrity sha512-sjc7Y8cUD1IlwYcTS9qPSvGjAC8Ne9LctpxKKu3x/1IC9bnOg98Zy6GxEJUfr1NojMgVPlyANXYns8oE2c1TAA==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.6.1"
"@eslint/eslintrc" "^2.1.4"
"@eslint/js" "8.57.0"
"@humanwhocodes/config-array" "^0.11.14"
"@eslint/config-array" "^0.15.1"
"@eslint/eslintrc" "^3.1.0"
"@eslint/js" "9.4.0"
"@humanwhocodes/module-importer" "^1.0.1"
"@humanwhocodes/retry" "^0.3.0"
"@nodelib/fs.walk" "^1.2.8"
"@ungap/structured-clone" "^1.2.0"
ajv "^6.12.4"
chalk "^4.0.0"
cross-spawn "^7.0.2"
debug "^4.3.2"
doctrine "^3.0.0"
escape-string-regexp "^4.0.0"
eslint-scope "^7.2.2"
eslint-visitor-keys "^3.4.3"
espree "^9.6.1"
eslint-scope "^8.0.1"
eslint-visitor-keys "^4.0.0"
espree "^10.0.1"
esquery "^1.4.2"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
file-entry-cache "^6.0.1"
file-entry-cache "^8.0.0"
find-up "^5.0.0"
glob-parent "^6.0.2"
globals "^13.19.0"
graphemer "^1.4.0"
ignore "^5.2.0"
imurmurhash "^0.1.4"
is-glob "^4.0.0"
is-path-inside "^3.0.3"
js-yaml "^4.1.0"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.4.1"
lodash.merge "^4.6.2"
@ -1387,14 +1435,14 @@ eslint@^8:
strip-ansi "^6.0.1"
text-table "^0.2.0"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==
espree@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-10.0.1.tgz#600e60404157412751ba4a6f3a2ee1a42433139f"
integrity sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==
dependencies:
acorn "^8.9.0"
acorn "^8.11.3"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.4.1"
eslint-visitor-keys "^4.0.0"
esquery@^1.4.2:
version "1.5.0"
@ -1491,12 +1539,12 @@ ffmpeg-static@^5.2:
https-proxy-agent "^5.0.0"
progress "^2.0.3"
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
file-entry-cache@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f"
integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==
dependencies:
flat-cache "^3.0.4"
flat-cache "^4.0.0"
filelist@^1.0.4:
version "1.0.4"
@ -1505,10 +1553,10 @@ filelist@^1.0.4:
dependencies:
minimatch "^5.0.1"
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
fill-range@^7.0.1, fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies:
to-regex-range "^5.0.1"
@ -1527,14 +1575,13 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
flat-cache@^3.0.4:
version "3.2.0"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee"
integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==
flat-cache@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c"
integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==
dependencies:
flatted "^3.2.9"
keyv "^4.5.3"
rimraf "^3.0.2"
keyv "^4.5.4"
flatted@^3.2.9:
version "3.3.1"
@ -1678,7 +1725,7 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
glob@^10.3.10, glob@^10.3.7:
glob@^10.3.10:
version "10.3.12"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b"
integrity sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==
@ -1689,6 +1736,17 @@ glob@^10.3.10, glob@^10.3.7:
minipass "^7.0.4"
path-scurry "^1.10.2"
glob@^10.3.12, glob@^10.3.7:
version "10.4.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.1.tgz#0cfb01ab6a6b438177bfe6a58e2576f6efe909c2"
integrity sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==
dependencies:
foreground-child "^3.1.0"
jackspeak "^3.1.2"
minimatch "^9.0.4"
minipass "^7.1.2"
path-scurry "^1.11.1"
glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
@ -1724,12 +1782,10 @@ global-agent@^3.0.0:
semver "^7.3.2"
serialize-error "^7.0.1"
globals@^13.19.0:
version "13.24.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171"
integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==
dependencies:
type-fest "^0.20.2"
globals@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
globalthis@^1.0.1:
version "1.0.4"
@ -2048,7 +2104,7 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
jackspeak@2.1.1, jackspeak@^2.3.6:
jackspeak@2.1.1, jackspeak@^2.3.6, jackspeak@^3.1.2:
version "2.1.1"
resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.1.1.tgz#2a42db4cfbb7e55433c28b6f75d8b796af9669cd"
integrity sha512-juf9stUEwUaILepraGOWIJTLwg48bUnBmRqd2ln2Os1sW987zeoj/hzhbvRB95oMuS2ZTpjULmdwHNX4rzZIZw==
@ -2114,7 +2170,7 @@ json-stringify-safe@^5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
json5@^2.2.0:
json5@^2.2.0, json5@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
@ -2135,7 +2191,7 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
keyv@^4.0.0, keyv@^4.5.3:
keyv@^4.0.0, keyv@^4.5.4:
version "4.5.4"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
@ -2255,11 +2311,11 @@ merge2@^1.3.0, merge2@^1.4.1:
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
version "4.0.7"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5"
integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==
dependencies:
braces "^3.0.2"
braces "^3.0.3"
picomatch "^2.3.1"
mime-db@1.52.0:
@ -2376,10 +2432,10 @@ minipass@^5.0.0:
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4:
version "7.0.4"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c"
integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4, minipass@^7.1.0, minipass@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
minizlib@^2.1.1, minizlib@^2.1.2:
version "2.1.2"
@ -2526,17 +2582,17 @@ onetime@^5.1.0, onetime@^5.1.2:
dependencies:
mimic-fn "^2.1.0"
onnxruntime-common@1.17.3:
version "1.17.3"
resolved "https://registry.yarnpkg.com/onnxruntime-common/-/onnxruntime-common-1.17.3.tgz#aadc456477873a540ee3d611ae9cd4f3de7c43e5"
integrity sha512-IkbaDelNVX8cBfHFgsNADRIq2TlXMFWW+nG55mwWvQT4i0NZb32Jf35Pf6h9yjrnK78RjcnlNYaI37w394ovMw==
onnxruntime-common@1.18.0:
version "1.18.0"
resolved "https://registry.yarnpkg.com/onnxruntime-common/-/onnxruntime-common-1.18.0.tgz#b904dc6ff134e7f21a3eab702fac17538f59e116"
integrity sha512-lufrSzX6QdKrktAELG5x5VkBpapbCeS3dQwrXbN0eD9rHvU0yAWl7Ztju9FvgAKWvwd/teEKJNj3OwM6eTZh3Q==
onnxruntime-node@^1.17:
version "1.17.3"
resolved "https://registry.yarnpkg.com/onnxruntime-node/-/onnxruntime-node-1.17.3.tgz#53b8b7ef68bf3834bba9d7be592e4c2d718d2018"
integrity sha512-NtbN1pfApTSEjVq46LrJ396aPP2Gjhy+oYZi5Bu1leDXAEvVap/BQ8CZELiLs7z0UnXy3xjJW23HiB4P3//FIw==
onnxruntime-node@^1.18:
version "1.18.0"
resolved "https://registry.yarnpkg.com/onnxruntime-node/-/onnxruntime-node-1.18.0.tgz#ad3947365ca038ec3a16fa4c48972708ccd294e9"
integrity sha512-iTnFcxKpmywCatx8ov4GTbECe3tJk2Bp1OA2mWRJde78q+7tpPYBhKMnwhlaoKy9oKQcy4UoEuuhoy2PSD13ww==
dependencies:
onnxruntime-common "1.17.3"
onnxruntime-common "1.18.0"
tar "^7.0.1"
optionator@^0.9.3:
@ -2648,10 +2704,10 @@ path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-scurry@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.2.tgz#8f6357eb1239d5fa1da8b9f70e9c080675458ba7"
integrity sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==
path-scurry@^1.10.2, path-scurry@^1.11.1:
version "1.11.1"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2"
integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
dependencies:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
@ -2706,9 +2762,9 @@ prettier-plugin-packagejson@^2:
synckit "0.9.0"
prettier@^3:
version "3.2.5"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368"
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
version "3.3.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.0.tgz#d173ea0524a691d4c0b1181752f2b46724328cdf"
integrity sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==
progress@^2.0.3:
version "2.0.3"
@ -2770,6 +2826,18 @@ read-config-file@6.3.2:
json5 "^2.2.0"
lazy-val "^1.0.4"
read-config-file@6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.4.0.tgz#970542833216cccff6b1d83320495003dcf85a45"
integrity sha512-uB5QOBeF84PT61GlV11OTV4jUGHAO3iDEOP6v9ygxhG6Bs9PLg7WsjNT6mtIX2G+x8lJTr4ZWNeG6LDTKkNf2Q==
dependencies:
config-file-ts "0.2.8-rc1"
dotenv "^16.4.5"
dotenv-expand "^11.0.6"
js-yaml "^4.1.0"
json5 "^2.2.3"
lazy-val "^1.0.5"
readable-stream@^3.0.2, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
@ -2860,9 +2928,9 @@ rimraf@^3.0.2:
glob "^7.1.3"
rimraf@^5.0.5:
version "5.0.5"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf"
integrity sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==
version "5.0.7"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.7.tgz#27bddf202e7d89cb2e0381656380d1734a854a74"
integrity sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==
dependencies:
glob "^10.3.7"
@ -2924,12 +2992,12 @@ semver@^6.2.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.2:
semver@^7.3.2, semver@^7.6.0:
version "7.6.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13"
integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==
semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.6.0:
semver@^7.3.5, semver@^7.3.8, semver@^7.5.3:
version "7.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d"
integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
@ -3169,13 +3237,13 @@ tar@^6.0.5, tar@^6.1.11, tar@^6.1.12, tar@^6.1.2:
yallist "^4.0.0"
tar@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-7.0.1.tgz#8f6ccebcd91b69e9767a6fc4892799e8b0e606d5"
integrity sha512-IjMhdQMZFpKsHEQT3woZVxBtCQY+0wk3CVxdRkGXEgyGa0dNS/ehPvOMr2nmfC7x5Zj2N+l6yZUpmICjLGS35w==
version "7.2.0"
resolved "https://registry.yarnpkg.com/tar/-/tar-7.2.0.tgz#f03ae6ecd2e2bab880f2ef33450f502e761d7548"
integrity sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==
dependencies:
"@isaacs/fs-minipass" "^4.0.0"
chownr "^3.0.0"
minipass "^5.0.0"
minipass "^7.1.0"
minizlib "^3.0.1"
mkdirp "^3.0.1"
yallist "^5.0.0"
@ -3251,11 +3319,6 @@ type-fest@^0.13.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
type-fest@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
type-fest@^2.17.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
@ -3266,7 +3329,16 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
typescript@^5, typescript@^5.3.3:
typescript-eslint@8.0.0-alpha.10:
version "8.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.0.0-alpha.10.tgz#2172d41ab30c8447927c3823c5a549b9c09be89f"
integrity sha512-iMbN7boDtUmcSDor/J022+H4G018W3r3RSUUr7yoghMTmFuKVIkI89xJHDg82DBGYkA0xOoDNPBr7XfRFbEXKQ==
dependencies:
"@typescript-eslint/eslint-plugin" "8.0.0-alpha.10"
"@typescript-eslint/parser" "8.0.0-alpha.10"
"@typescript-eslint/utils" "8.0.0-alpha.10"
typescript@^5, typescript@^5.3.3, typescript@^5.4.3:
version "5.4.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==

View File

@ -5,8 +5,6 @@ description: Guide for importing from Steam Authenticator to Ente Auth
# Migrating from Steam Authenticator
A guide written by an ente.io lover
> [!WARNING]
>
> Steam Authenticator code is only supported after auth-v3.0.3, check the app's

View File

@ -41,7 +41,7 @@ NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080 yarn dev
That's about it. If you open http://localhost:3000, you will be able to create
an account on a Ente Photos web app running on your machine, and this web app
will be connecting to the server running on your local machine at
localhost:8080.
`localhost:8080`.
For the mobile apps, you don't even need to build, and can install normal Ente
apps and configure them to use your

View File

@ -12,7 +12,7 @@ description: ente photos application
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.8.128+648
version: 0.8.129+649
publish_to: none
environment:

View File

@ -9,5 +9,5 @@ module.exports = {
tsconfigRootDir: __dirname,
project: "./tsconfig.json",
},
ignorePatterns: [".eslintrc.js", "out"],
ignorePatterns: [".eslintrc.js", "out", "next.config.js"],
};

View File

@ -9,5 +9,5 @@ module.exports = {
tsconfigRootDir: __dirname,
project: "./tsconfig.json",
},
ignorePatterns: [".eslintrc.js", "out"],
ignorePatterns: [".eslintrc.js", "out", "next.config.js"],
};

View File

@ -9,5 +9,11 @@ module.exports = {
tsconfigRootDir: __dirname,
project: "./tsconfig.json",
},
ignorePatterns: [".eslintrc.js", "out", "thirdparty", "public"],
ignorePatterns: [
".eslintrc.js",
"out",
"thirdparty",
"public",
"next.config.js",
],
};

View File

@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@/media": "*",
"@/new": "*",
"@/next": "*",
"@date-io/date-fns": "^2.14.0",
"@ente/accounts": "*",

View File

@ -83,7 +83,6 @@ import {
} from "utils/billing";
import { openLink } from "utils/common";
import { getDownloadAppMessage } from "utils/ui";
import { isInternalUser } from "utils/user";
import { isFamilyAdmin, isPartOfFamily } from "utils/user/family";
import { testUpload } from "../../../tests/upload.test";
import { MemberSubscriptionManage } from "../MemberSubscriptionManage";
@ -553,7 +552,7 @@ const UtilitySection: React.FC<UtilitySectionProps> = ({ closeSidebar }) => {
onClick={openRecoveryKeyModal}
label={t("RECOVERY_KEY")}
/>
{isInternalUser() && (
{isInternalUserViaEmailCheck() && (
<EnteMenuItem
onClick={toggleTheme}
variant="secondary"
@ -572,7 +571,7 @@ const UtilitySection: React.FC<UtilitySectionProps> = ({ closeSidebar }) => {
label={t("TWO_FACTOR")}
/>
{isInternalUser() && (
{isInternalUserViaEmailCheck() && (
<EnteMenuItem
variant="secondary"
onClick={redirectToAccountsPage}
@ -768,7 +767,7 @@ const DebugSection: React.FC = () => {
{appVersion}
</Typography>
)}
{isInternalUser() && (
{isInternalUserViaEmailCheck() && (
<EnteMenuItem
variant="secondary"
onClick={testUpload}
@ -778,3 +777,11 @@ const DebugSection: React.FC = () => {
</>
);
};
// TODO: Legacy synchronous check, use the one for feature-flags.ts instead.
const isInternalUserViaEmailCheck = () => {
const userEmail = getData(LS_KEYS.USER)?.email;
if (!userEmail) return false;
return userEmail.endsWith("@ente.io");
};

View File

@ -54,8 +54,8 @@ import {
isFaceIndexingEnabled,
setIsFaceIndexingEnabled,
} from "services/face/indexer";
import mlWorkManager from "services/face/mlWorkManager";
import { photosLogout } from "services/logout";
import mlWorkManager from "services/machineLearning/mlWorkManager";
import {
getFamilyPortalRedirectURL,
getRoadmapRedirectURL,

View File

@ -1,3 +1,4 @@
import { fetchAndSaveFeatureFlagsIfNeeded } from "@/new/photos/services/feature-flags";
import log from "@/next/log";
import { APPS } from "@ente/shared/apps/constants";
import { CenteredFlex } from "@ente/shared/components/Container";
@ -87,7 +88,6 @@ import {
import downloadManager from "services/download";
import { syncCLIPEmbeddings } from "services/embeddingService";
import { syncEntities } from "services/entityService";
import { fetchAndSaveFeatureFlagsIfNeeded } from "services/feature-flag";
import { getLocalFiles, syncFiles } from "services/fileService";
import locationSearchService from "services/locationSearchService";
import { getLocalTrashedFiles, syncTrash } from "services/trashService";
@ -720,7 +720,7 @@ export default function Gallery() {
await syncCLIPEmbeddings();
// TODO-ML(MR): Disable fetch until we start storing it in the
// same place as the local ones.
// if (isInternalUserForML()) await syncFaceEmbeddings();
// if (isFaceIndexingEnabled()) await syncFaceEmbeddings();
}
if (clipService.isPlatformSupported()) {
void clipService.scheduleImageEmbeddingExtraction();

View File

@ -1,8 +0,0 @@
import { ComlinkWorker } from "@/next/worker/comlink-worker";
import type { DedicatedMLWorker } from "services/face/face.worker";
const createFaceWebWorker = () =>
new Worker(new URL("face.worker.ts", import.meta.url));
export const createFaceComlinkWorker = (name: string) =>
new ComlinkWorker<typeof DedicatedMLWorker>(name, createFaceWebWorker());

View File

@ -1,19 +1,19 @@
import {
isBetaUser,
isInternalUser,
} from "@/new/photos/services/feature-flags";
import { ComlinkWorker } from "@/next/worker/comlink-worker";
import { ensure } from "@/utils/ensure";
import { wait } from "@/utils/promise";
import { type Remote } from "comlink";
import { isBetaUser, isInternalUser } from "services/feature-flag";
import type { Remote } from "comlink";
import { getAllLocalFiles } from "services/fileService";
import mlWorkManager from "services/machineLearning/mlWorkManager";
import type { EnteFile } from "types/file";
import { isInternalUserForML } from "utils/user";
import {
faceIndex,
indexableFileIDs,
indexedAndIndexableCounts,
syncWithLocalFiles,
} from "./db";
import { FaceIndexerWorker } from "./indexer.worker";
import type { FaceIndexerWorker } from "./indexer.worker";
/**
* Face indexing orchestrator.
@ -41,33 +41,33 @@ class FaceIndexer {
/** Timeout for when the next time we will wake up. */
private wakeTimeout: ReturnType<typeof setTimeout> | undefined;
/**
* Add a file to the live indexing queue.
*
* @param enteFile An {@link EnteFile} that should be indexed.
*
* @param file The contents of {@link enteFile} as a web {@link File}
* object, if available.
*/
enqueueFile(enteFile: EnteFile, file: File | undefined) {
// If face indexing is not enabled, don't enqueue anything. Later on if
// the user turns on face indexing these files will get indexed as part
// of the backfilling anyway, the live indexing is just an optimization.
if (!mlWorkManager.isMlSearchEnabled) return;
// /**
// * Add a file to the live indexing queue.
// *
// * @param enteFile An {@link EnteFile} that should be indexed.
// *
// * @param file The contents of {@link enteFile} as a web {@link File}
// * object, if available.
// */
// enqueueFile(enteFile: EnteFile, file: File | undefined) {
// // If face indexing is not enabled, don't enqueue anything. Later on if
// // the user turns on face indexing these files will get indexed as part
// // of the backfilling anyway, the live indexing is just an optimization.
// if (!mlWorkManager.isMlSearchEnabled) return;
this.liveItems.push({ enteFile, file });
this.wakeUpIfNeeded();
}
// this.liveItems.push({ enteFile, file });
// this.wakeUpIfNeeded();
// }
private wakeUpIfNeeded() {
// Already awake.
if (!this.wakeTimeout) return;
// Cancel the alarm, wake up now.
clearTimeout(this.wakeTimeout);
this.wakeTimeout = undefined;
// Get to work.
this.tick();
}
// private wakeUpIfNeeded() {
// // Already awake.
// if (!this.wakeTimeout) return;
// // Cancel the alarm, wake up now.
// clearTimeout(this.wakeTimeout);
// this.wakeTimeout = undefined;
// // Get to work.
// this.tick();
// }
/* TODO-ML(MR): This code is not currently in use */
@ -85,34 +85,34 @@ class FaceIndexer {
faceIndexer = (): Promise<Remote<FaceIndexerWorker>> =>
(this._faceIndexer ??= createFaceIndexerComlinkWorker().remote);
private async tick() {
console.log("tick");
// private async tick() {
// console.log("tick");
const item = this.liveItems.pop();
if (!item) {
// TODO-ML: backfill instead if needed here.
this.wakeTimeout = setTimeout(() => {
this.wakeTimeout = undefined;
this.wakeUpIfNeeded();
}, 30 * 1000);
return;
}
/*
const fileID = item.enteFile.id;
try {
const faceIndex = await indexFaces(item.enteFile, item.file, userAgent);
log.info(`faces in file ${fileID}`, faceIndex);
} catch (e) {
log.error(`Failed to index faces in file ${fileID}`, e);
markIndexingFailed(item.enteFile.id);
}
*/
// Let the runloop drain.
await wait(0);
// Run again.
// TODO
// this.tick();
}
// const item = this.liveItems.pop();
// if (!item) {
// // TODO-ML: backfill instead if needed here.
// this.wakeTimeout = setTimeout(() => {
// this.wakeTimeout = undefined;
// this.wakeUpIfNeeded();
// }, 30 * 1000);
// return;
// }
// /*
// const fileID = item.enteFile.id;
// try {
// const faceIndex = await indexFaces(item.enteFile, item.file, userAgent);
// log.info(`faces in file ${fileID}`, faceIndex);
// } catch (e) {
// log.error(`Failed to index faces in file ${fileID}`, e);
// markIndexingFailed(item.enteFile.id);
// }
// */
// // Let the runloop drain.
// await wait(0);
// // Run again.
// // TODO
// // this.tick();
// }
/**
* Add a newly uploaded file to the face indexing queue.
@ -162,8 +162,9 @@ export interface FaceIndexingStatus {
nTotalFiles: number;
}
export const faceIndexingStatus = async (): Promise<FaceIndexingStatus> => {
const isSyncing = mlWorkManager.isSyncing;
export const faceIndexingStatus = async (
isSyncing: boolean,
): Promise<FaceIndexingStatus> => {
const { indexedCount, indexableCount } = await indexedAndIndexableCounts();
let phase: FaceIndexingStatus["phase"];
@ -200,7 +201,7 @@ export const unidentifiedFaceIDs = async (
* face search in the UI.
*/
export const canEnableFaceIndexing = async () =>
isInternalUserForML() || (await isInternalUser()) || (await isBetaUser());
(await isInternalUser()) || (await isBetaUser());
/**
* Return true if the user has enabled face indexing in the app's settings.

View File

@ -7,12 +7,17 @@ import { eventBus, Events } from "@ente/shared/events";
import { getToken, getUserID } from "@ente/shared/storage/localStorage/helpers";
import debounce from "debounce";
import PQueue from "p-queue";
import { createFaceComlinkWorker } from "services/face";
import type { DedicatedMLWorker } from "services/face/face.worker";
import { EnteFile } from "types/file";
export type JobState = "Scheduled" | "Running" | "NotScheduled";
const createFaceWebWorker = () =>
new Worker(new URL("face.worker.ts", import.meta.url));
const createFaceComlinkWorker = (name: string) =>
new ComlinkWorker<typeof DedicatedMLWorker>(name, createFaceWebWorker());
export class MLSyncJob {
private runCallback: () => Promise<boolean>;
private state: JobState;

View File

@ -1,11 +1,11 @@
import { clearFeatureFlagSessionState } from "@/new/photos/services/feature-flags";
import log from "@/next/log";
import { accountLogout } from "@ente/accounts/services/logout";
import { clipService } from "services/clip-service";
import DownloadManager from "./download";
import exportService from "./export";
import { clearFaceData } from "./face/db";
import { clearFeatureFlagSessionState } from "./feature-flag";
import mlWorkManager from "./machineLearning/mlWorkManager";
import mlWorkManager from "./face/mlWorkManager";
/**
* Logout sequence for the photos app.

View File

@ -21,6 +21,7 @@ import { clipService, computeClipMatchScore } from "./clip-service";
import { localCLIPEmbeddings } from "./embeddingService";
import { getLatestEntities } from "./entityService";
import { faceIndexingStatus, isFaceIndexingEnabled } from "./face/indexer";
import mlWorkManager from "./face/mlWorkManager";
import locationSearchService, { City } from "./locationSearchService";
const DIGITS = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
@ -178,7 +179,8 @@ export async function getAllPeopleSuggestion(): Promise<Array<Suggestion>> {
export async function getIndexStatusSuggestion(): Promise<Suggestion> {
try {
const indexStatus = await faceIndexingStatus();
const isSyncing = mlWorkManager.isSyncing;
const indexStatus = await faceIndexingStatus(isSyncing);
let label: string;
switch (indexStatus.phase) {

View File

@ -1,21 +1,6 @@
import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
import type { User } from "@ente/shared/user/types";
import { UserDetails } from "types/user";
export function getLocalUserDetails(): UserDetails {
return getData(LS_KEYS.USER_DETAILS)?.value;
}
export const isInternalUser = () => {
const userEmail = getData(LS_KEYS.USER)?.email;
if (!userEmail) return false;
return userEmail.endsWith("@ente.io");
};
export const isInternalUserForML = () => {
const userID = (getData(LS_KEYS.USER) as User)?.id;
if (userID == 1 || userID == 2) return true;
return isInternalUser();
};

View File

@ -11,7 +11,7 @@
"dependencies": {
"react": "^18",
"react-dom": "^18",
"yup": "^1.4"
"zod": "^3"
},
"devDependencies": {
"@/build-config": "*",

View File

@ -1,10 +1,10 @@
import { object, type InferType } from "yup";
import { z } from "zod";
const apiOrigin = import.meta.env.VITE_ENTE_ENDPOINT ?? "https://api.ente.io";
const userDetailsSchema = object({});
const UserDetails = z.object({}).passthrough();
export type UserDetails = InferType<typeof userDetailsSchema>;
export type UserDetails = z.infer<typeof UserDetails>;
/** Fetch details of the user associated with the given {@link authToken}. */
export const getUserDetails = async (
@ -17,5 +17,5 @@ export const getUserDetails = async (
},
});
if (!res.ok) throw new Error(`Failed to fetch ${url}: HTTP ${res.status}`);
return await userDetailsSchema.validate(await res.json());
return UserDetails.parse(await res.json());
};

View File

@ -14,11 +14,17 @@ baseline for how our code be in all the workspaces in this (yarn) monorepo.
They also need some support packages, which come from the leaf `@/build-config`
package:
- [@typescript-eslint/parser](https://typescript-eslint.io/packages/eslint-plugin/)
\- Tells ESLint how to read TypeScript syntax.
- [@eslint/js](https://eslint.org/) provides JavaScript ESLint functionality,
and provides the configuration recommended the by ESLint team.
- [@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin/)
\- Provides TypeScript rules and presets
- [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint/)
\- provides TypeScript ESLint functionality and provides a set of
recommended configurations (`typescript-eslint` is the new entry point, our
yet-unmigrated packages use the older method of separately including
[@typescript-eslint/parser](https://typescript-eslint.io/packages/eslint-plugin/)
\- which tells ESLint how to read TypeScript syntax - and
[@typescript-eslint/eslint-plugin](https://typescript-eslint.io/packages/eslint-plugin/)
\- which provides the TypeScript rules and presets).
- [eslint-plugin-react-hooks](https://github.com/jsx-eslint/eslint-plugin-react),
[eslint-plugin-react-hooks](https://reactjs.org/) \- Some React specific
@ -148,6 +154,19 @@ It is more lower level than Next, but the bells and whistles it doesn't have are
the bells and whistles (and the accompanying complexity) that we don't need in
some cases.
## General
- [comlink](https://github.com/GoogleChromeLabs/comlink) provides a minimal
layer on top of Web Workers to make them more easier to use.
- [idb](https://github.com/jakearchibald/idb) provides a promise API over the
browser-native IndexedDB APIs.
> For more details about IDB and its role, see [storage.md](storage.md).
- [zod](https://github.com/colinhacks/zod) is used for runtime typechecking
(e.g. verifying that API responses match the expected TypeScript shape).
## Media
- [jszip](https://github.com/Stuk/jszip) is used for reading zip files in
@ -161,16 +180,6 @@ some cases.
- [heic-convert](https://github.com/catdad-experiments/heic-convert) is used
for converting HEIC files (which browsers don't natively support) into JPEG.
## General
- [comlink](https://github.com/GoogleChromeLabs/comlink) provides a minimal
layer on top of Web Workers to make them more easier to use.
- [idb](https://github.com/jakearchibald/idb) provides a promise API over the
browser-native IndexedDB APIs.
> For more details about IDB and its role, see [storage.md](storage.md).
## Photos app specific
- [react-dropzone](https://github.com/react-dropzone/react-dropzone/) is a

View File

@ -2,9 +2,6 @@
/* A base TSConfig for typechecking our Next.js apps and packages. */
"extends": "@/build-config/tsconfig-typecheck.json",
"compilerOptions": {
/* Also indicate expectation of a WebWorker runtime */
"lib": ["ESnext", "DOM", "DOM.Iterable", "WebWorker"],
/* Next.js insists on adding these. Sigh. */
"allowJs": true,
"incremental": true

View File

@ -10,8 +10,8 @@
* runtime will have.
*
* In our case, we tell it that the code will run in a modern browser,
* and will have access to a latest JS (esnext) and the DOM (dom). Our
* transpiler (Next.js) will ensure that these things hold.
* and will have access to a latest JS ("ESNext") and the DOM ("DOM")
* and web workers ("WebWorker").
*
* Unlike the other individual library components (say how "esnext"
* implies "ESNext.*"), "DOM.Iterable" (the ability to iterate over DOM
@ -21,7 +21,7 @@
* Note that we don't need to specify the `target` compilerOption, since
* tsc isn't actually generating (emitting) the JavaScript.
*/
"lib": ["ESnext", "DOM", "DOM.Iterable"],
"lib": ["ESnext", "DOM", "DOM.Iterable", "WebWorker"],
/*
* The module system to assume the generated JavaScript will use.

View File

@ -5,5 +5,5 @@ module.exports = {
tsconfigRootDir: __dirname,
project: "./tsconfig.json",
},
ignorePatterns: [".eslintrc.js"],
ignorePatterns: [".eslintrc.js", "index.js"],
};

View File

View File

@ -1,10 +1,8 @@
module.exports = {
extends: [
"next/core-web-vitals",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"prettier",
],
parserOptions: {
tsconfigRootDir: __dirname,
@ -34,12 +32,6 @@ module.exports = {
"after",
{ overrides: { "?": "before", ":": "before" } },
],
"import/no-anonymous-default-export": [
"error",
{
allowNew: true,
},
],
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unsafe-assignment": "off",

View File

@ -0,0 +1,3 @@
module.exports = {
extends: ["@/build-config/eslintrc-react"],
};

View File

@ -0,0 +1,11 @@
## @/new
This package only exists so that we can write code that works with TypeScript
strict mode. This provides a gradual way of migrating the existing code in the
old packages to strict mode. Once there is sufficient gravity here, we can flip
the switch on the original packages and move these back to where they came from.
### Packaging
This (internal) package exports a vanilla TypeScript library. We rely on the
importing project to transpile and bundle it.

View File

@ -0,0 +1,12 @@
{
"name": "@/new",
"version": "0.0.0",
"private": true,
"dependencies": {
"@/next": "*",
"@/utils": "*",
"@ente/shared": "*",
"zod": "^3"
},
"devDependencies": {}
}

View File

@ -0,0 +1,2 @@
/** Dummy function to get the package to behave. */
export const hello = (ms: number) => ms;

View File

@ -1,7 +1,11 @@
import { isDevBuild } from "@/next/env";
import { localUser } from "@/next/local-user";
import log from "@/next/log";
import { ensure } from "@/utils/ensure";
import { nullToUndefined } from "@/utils/transform";
import { apiOrigin } from "@ente/shared/network/api";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import { z } from "zod";
let _fetchTimeout: ReturnType<typeof setTimeout> | undefined;
let _haveFetched = false;
@ -12,8 +16,25 @@ let _haveFetched = false;
*
* It fetches only once per session, and so is safe to call as arbitrarily many
* times. Remember to call {@link clearFeatureFlagSessionState} on logout to
* forget that we've already fetched so that these can be fetched again on the
* clear any in memory state so that these can be fetched again on the
* subsequent login.
*
* [Note: Feature Flags]
*
* The workflow with feature flags is:
*
* 1. On app start feature flags are fetched once and saved in local storage. If
* this fetch fails, we try again periodically (on every "sync") until
* success.
*
* 2. Attempts to access any individual feature flage (e.g.
* {@link isInternalUser}) returns the corresponding value from local storage
* (substituting a default if needed).
*
* 3. However, if perchance the fetch-on-app-start hasn't completed yet (or had
* failed), then a new fetch is tried. If even this fetch fails, we return
* the default. Otherwise the now fetched result is saved to local storage
* and the corresponding value returned.
*/
export const fetchAndSaveFeatureFlagsIfNeeded = () => {
if (_haveFetched) return;
@ -61,51 +82,55 @@ const saveFlagJSONString = (s: string) =>
const remoteFeatureFlags = () => {
const s = localStorage.getItem("remoteFeatureFlags");
if (!s) return undefined;
return JSON.parse(s);
return FeatureFlags.parse(JSON.parse(s));
};
const FeatureFlags = z.object({
internalUser: z.boolean().nullish().transform(nullToUndefined),
betaUser: z.boolean().nullish().transform(nullToUndefined),
});
type FeatureFlags = z.infer<typeof FeatureFlags>;
const remoteFeatureFlagsFetchingIfNeeded = async () => {
let ff = await remoteFeatureFlags();
let ff = remoteFeatureFlags();
if (!ff) {
try {
await fetchAndSaveFeatureFlags();
ff = await remoteFeatureFlags();
} catch (e) {
log.warn("Ignoring error when fetching feature flags", e);
}
ff = remoteFeatureFlags();
}
return ff;
};
/**
* Return `true` if the current user is marked as an "internal" user.
*
* 1. Everyone is considered as an internal user in dev builds.
* 2. Emails that end in `@ente.io` are always considered as internal users.
* 3. If the "internalUser" remote feature flag is set, the user is internal.
* 4. Otherwise false.
*
* See also: [Note: Feature Flags].
*/
export const isInternalUser = async () => {
// TODO: Dedup
if (isDevBuild) return true;
const user = localUser();
if (user?.email.endsWith("@ente.io")) return true;
const flags = await remoteFeatureFlagsFetchingIfNeeded();
// TODO(MR): Use Yup here
if (
flags &&
typeof flags === "object" &&
"internalUser" in flags &&
typeof flags.internalUser == "boolean"
)
return flags.internalUser;
return false;
return flags?.internalUser ?? false;
};
/**
* Return `true` if the current user is marked as a "beta" user.
*
* See also: [Note: Feature Flags].
*/
export const isBetaUser = async () => {
const flags = await remoteFeatureFlagsFetchingIfNeeded();
// TODO(MR): Use Yup here
if (
flags &&
typeof flags === "object" &&
"betaUser" in flags &&
typeof flags.betaUser == "boolean"
)
return flags.betaUser;
return false;
return flags?.betaUser ?? false;
};

View File

@ -0,0 +1,4 @@
{
"extends": "@/build-config/tsconfig-typecheck.json",
"include": [".", "../next/global-electron.d.ts"]
}

View File

@ -1,42 +1,40 @@
// TODO: This file belongs to the accounts package
import * as yup from "yup";
import { z } from "zod";
const localUserSchema = yup.object({
const LocalUser = z.object({
/** The user's ID. */
id: yup.number().required(),
id: z.number(),
/** The user's email. */
email: yup.string().required(),
email: z.string(),
/**
* The user's (plaintext) auth token.
*
* It is used for making API calls on their behalf.
*/
token: yup.string().required(),
token: z.string(),
});
/** Locally available data for the logged in user's */
export type LocalUser = yup.InferType<typeof localUserSchema>;
/** Locally available data for the logged in user */
export type LocalUser = z.infer<typeof LocalUser>;
/**
* Return the logged-in user (if someone is indeed logged in).
* Return the logged-in user, if someone is indeed logged in. Otherwise return
* `undefined`.
*
* The user's data is stored in the browser's localStorage.
*/
export const localUser = async (): Promise<LocalUser | undefined> => {
export const localUser = (): LocalUser | undefined => {
// TODO(MR): duplicate of LS_KEYS.USER
const s = localStorage.getItem("user");
if (!s) return undefined;
return await localUserSchema.validate(JSON.parse(s), {
strict: true,
});
return LocalUser.parse(JSON.parse(s));
};
/**
* A wrapper over {@link localUser} with that throws if no one is logged in.
*/
export const ensureLocalUser = async (): Promise<LocalUser> => {
const user = await localUser();
if (!user)
throw new Error("Attempting to access user data when not logged in");
export const ensureLocalUser = (): LocalUser => {
const user = localUser();
if (!user) throw new Error("Not logged in");
return user;
};

View File

@ -51,7 +51,7 @@ const nextConfig = {
emotion: true,
},
// Use Next.js to transpile our internal packages before bundling them.
transpilePackages: ["@/next", "@/utils"],
transpilePackages: ["@/next", "@/utils", "@/new"],
// Add environment variables to the JavaScript bundle. They will be
// available as `process.env.VAR_NAME` to our code.

View File

@ -43,7 +43,7 @@ const workerBridge = {
// Needed: generally (presumably)
logToDisk,
// Needed by ML worker
getAuthToken: () => ensureLocalUser().then((user) => user.token),
getAuthToken: () => ensureLocalUser().token,
convertToJPEG: (imageData: Uint8Array) =>
ensureElectron().convertToJPEG(imageData),
detectFaces: (input: Float32Array) => ensureElectron().detectFaces(input),

View File

@ -9,5 +9,5 @@ module.exports = {
tsconfigRootDir: __dirname,
project: "./tsconfig.json",
},
ignorePatterns: [".eslintrc.js"],
ignorePatterns: [".eslintrc.js", "next/utils/headers.js"],
};

View File

@ -0,0 +1,3 @@
/** Convert `null` to `undefined`, passthrough everything else unchanged. */
export const nullToUndefined = <T>(v: T | null | undefined): T | undefined =>
v === null ? undefined : v;

View File

@ -4992,6 +4992,11 @@ yup@^1.4:
toposort "^2.0.2"
type-fest "^2.19.0"
zod@^3:
version "3.23.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
zxcvbn@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30"