mirror of
https://github.com/actualbudget/actual.git
synced 2026-04-29 18:19:44 -05:00
:electron: Electron package Typescript starting point (#2880)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,6 +21,7 @@ packages/api/dist
|
||||
packages/api/@types
|
||||
packages/crdt/dist
|
||||
packages/desktop-electron/client-build
|
||||
packages/desktop-electron/build
|
||||
packages/desktop-electron/.electron-symbols
|
||||
packages/desktop-electron/dist
|
||||
packages/desktop-electron/loot-core
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
ROOT=`dirname $0`/..
|
||||
|
||||
rm -rf ${ROOT}/client-build
|
||||
cp -r ${ROOT}/../desktop-client/build ${ROOT}/client-build
|
||||
rm -rf ${ROOT}/build
|
||||
mkdir -p ${ROOT}/build
|
||||
cp -r ${ROOT}/../desktop-client/build ${ROOT}/build/client-build
|
||||
|
||||
# Remove the embedded backend for the browser version. Will improve
|
||||
# this process
|
||||
rm -rf ${ROOT}/client-build/data
|
||||
rm -rf ${ROOT}/client-build/*kcab.*
|
||||
rm -rf ${ROOT}/client-build/*.wasm
|
||||
rm -rf ${ROOT}/client-build/*.map
|
||||
rm -rf ${ROOT}/build/client-build/data
|
||||
rm -rf ${ROOT}/build/client-build/*kcab.*
|
||||
rm -rf ${ROOT}/build/client-build/*.wasm
|
||||
rm -rf ${ROOT}/build/client-build/*.map
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
/* eslint-disable import/order */
|
||||
// (I have no idea why the imports are like this. Not touching them.)
|
||||
const isDev = require('electron-is-dev');
|
||||
const fs = require('fs');
|
||||
import fs from 'fs';
|
||||
import NodeModule from 'module';
|
||||
import path from 'path';
|
||||
|
||||
require('module').globalPaths.push(__dirname + '/..');
|
||||
|
||||
const {
|
||||
import {
|
||||
app,
|
||||
ipcMain,
|
||||
BrowserWindow,
|
||||
@@ -14,8 +11,28 @@ const {
|
||||
shell,
|
||||
protocol,
|
||||
utilityProcess,
|
||||
} = require('electron');
|
||||
const promiseRetry = require('promise-retry');
|
||||
UtilityProcess,
|
||||
} from 'electron';
|
||||
import isDev from 'electron-is-dev';
|
||||
import promiseRetry from 'promise-retry';
|
||||
|
||||
import about from './about';
|
||||
import getMenu from './menu';
|
||||
import updater from './updater';
|
||||
import {
|
||||
get as getWindowState,
|
||||
listen as listenToWindowState,
|
||||
} from './window-state';
|
||||
|
||||
import './setRequireHook';
|
||||
|
||||
import './security';
|
||||
|
||||
const Module: typeof NodeModule & { globalPaths: string[] } =
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
NodeModule as unknown as any;
|
||||
|
||||
Module.globalPaths.push(__dirname + '/..');
|
||||
|
||||
// This allows relative URLs to be resolved to app:// which makes
|
||||
// local assets load correctly
|
||||
@@ -25,16 +42,6 @@ protocol.registerSchemesAsPrivileged([
|
||||
|
||||
global.fetch = require('node-fetch');
|
||||
|
||||
const about = require('./about');
|
||||
const getMenu = require('./menu');
|
||||
const updater = require('./updater');
|
||||
|
||||
require('./security');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
require('./setRequireHook');
|
||||
|
||||
if (!isDev || !process.env.ACTUAL_DOCUMENT_DIR) {
|
||||
process.env.ACTUAL_DOCUMENT_DIR = app.getPath('documents');
|
||||
}
|
||||
@@ -43,15 +50,12 @@ if (!isDev || !process.env.ACTUAL_DATA_DIR) {
|
||||
process.env.ACTUAL_DATA_DIR = app.getPath('userData');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/extensions
|
||||
const WindowState = require('./window-state.js');
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let clientWin;
|
||||
let serverProcess;
|
||||
let clientWin: BrowserWindow | null;
|
||||
let serverProcess: UtilityProcess | null;
|
||||
|
||||
updater.onEvent((type, data) => {
|
||||
updater.onEvent((type: string, data: Record<string, string> | string) => {
|
||||
// Notify both the app and the about window
|
||||
if (clientWin) {
|
||||
clientWin.webContents.send(type, data);
|
||||
@@ -99,7 +103,7 @@ function createBackgroundProcess() {
|
||||
}
|
||||
|
||||
async function createWindow() {
|
||||
const windowState = await WindowState.get();
|
||||
const windowState = await getWindowState();
|
||||
|
||||
// Create the browser window.
|
||||
const win = new BrowserWindow({
|
||||
@@ -113,7 +117,6 @@ async function createWindow() {
|
||||
nodeIntegrationInWorker: false,
|
||||
nodeIntegrationInSubFrames: false,
|
||||
contextIsolation: true,
|
||||
enableRemoteModule: false,
|
||||
preload: __dirname + '/preload.js',
|
||||
},
|
||||
});
|
||||
@@ -123,7 +126,7 @@ async function createWindow() {
|
||||
win.webContents.openDevTools();
|
||||
}
|
||||
|
||||
const unlistenToState = WindowState.listen(win, windowState);
|
||||
const unlistenToState = listenToWindowState(win, windowState);
|
||||
|
||||
if (isDev) {
|
||||
win.loadURL(`file://${__dirname}/loading.html`);
|
||||
@@ -148,9 +151,11 @@ async function createWindow() {
|
||||
});
|
||||
|
||||
win.on('focus', async () => {
|
||||
const url = clientWin.webContents.getURL();
|
||||
if (url.includes('app://') || url.includes('localhost:')) {
|
||||
clientWin.webContents.executeJavaScript('__actionsForMenu.focused()');
|
||||
if (clientWin) {
|
||||
const url = clientWin.webContents.getURL();
|
||||
if (url.includes('app://') || url.includes('localhost:')) {
|
||||
clientWin.webContents.executeJavaScript('__actionsForMenu.focused()');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -183,29 +188,28 @@ async function createWindow() {
|
||||
clientWin = win;
|
||||
}
|
||||
|
||||
function isExternalUrl(url) {
|
||||
function isExternalUrl(url: string) {
|
||||
return !url.includes('localhost:') && !url.includes('app://');
|
||||
}
|
||||
|
||||
function updateMenu(budgetId) {
|
||||
function updateMenu(budgetId?: string) {
|
||||
const isBudgetOpen = !!budgetId;
|
||||
const menu = getMenu(isDev, createWindow);
|
||||
const menu = getMenu(isDev, createWindow, budgetId);
|
||||
const file = menu.items.filter(item => item.label === 'File')[0];
|
||||
const fileItems = file.submenu.items;
|
||||
const fileItems = file.submenu?.items || [];
|
||||
fileItems
|
||||
.filter(item => item.label === 'Load Backup...')
|
||||
.forEach(item => {
|
||||
item.enabled = isBudgetOpen;
|
||||
item.budgetId = budgetId;
|
||||
});
|
||||
|
||||
const tools = menu.items.filter(item => item.label === 'Tools')[0];
|
||||
tools.submenu.items.forEach(item => {
|
||||
tools.submenu?.items.forEach(item => {
|
||||
item.enabled = isBudgetOpen;
|
||||
});
|
||||
|
||||
const edit = menu.items.filter(item => item.label === 'Edit')[0];
|
||||
const editItems = edit.submenu.items;
|
||||
const editItems = edit.submenu?.items || [];
|
||||
editItems
|
||||
.filter(item => item.label === 'Undo' || item.label === 'Redo')
|
||||
.map(item => (item.enabled = isBudgetOpen));
|
||||
@@ -312,7 +316,7 @@ ipcMain.handle(
|
||||
async (event, { title, defaultPath, fileContents }) => {
|
||||
const fileLocation = await dialog.showSaveDialog({ title, defaultPath });
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
if (fileLocation) {
|
||||
fs.writeFile(fileLocation.filePath, fileContents, error => {
|
||||
return reject(error);
|
||||
@@ -344,8 +348,9 @@ ipcMain.on('screenshot', () => {
|
||||
const width = 1100;
|
||||
|
||||
// This is for the main screenshot inside the frame
|
||||
clientWin.setSize(width, Math.floor(width * (427 / 623)));
|
||||
// clientWin.setSize(width, Math.floor(width * (495 / 700)));
|
||||
if (clientWin) {
|
||||
clientWin.setSize(width, Math.floor(width * (427 / 623)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -366,14 +371,15 @@ ipcMain.on('apply-update', () => {
|
||||
updater.apply();
|
||||
});
|
||||
|
||||
ipcMain.on('update-menu', (event, budgetId) => {
|
||||
ipcMain.on('update-menu', (event, budgetId?: string) => {
|
||||
updateMenu(budgetId);
|
||||
});
|
||||
|
||||
ipcMain.on('set-theme', theme => {
|
||||
const obj = { theme };
|
||||
|
||||
clientWin.webContents.executeJavaScript(
|
||||
`window.__actionsForMenu && window.__actionsForMenu.saveGlobalPrefs(${obj})`,
|
||||
);
|
||||
if (clientWin) {
|
||||
clientWin.webContents.executeJavaScript(
|
||||
`window.__actionsForMenu && window.__actionsForMenu.saveGlobalPrefs(${obj})`,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
const { Menu, ipcMain, app, shell } = require('electron');
|
||||
|
||||
function getMenu(isDev, createWindow) {
|
||||
function getMenu(isDev, createWindow, budgetId) {
|
||||
const template = [
|
||||
{
|
||||
label: 'File',
|
||||
@@ -9,10 +9,10 @@ function getMenu(isDev, createWindow) {
|
||||
label: 'Load Backup...',
|
||||
enabled: false,
|
||||
click(item, focusedWindow) {
|
||||
if (focusedWindow) {
|
||||
if (focusedWindow && budgetId) {
|
||||
if (focusedWindow.webContents.getTitle() === 'Actual') {
|
||||
focusedWindow.webContents.executeJavaScript(
|
||||
`__actionsForMenu.replaceModal('load-backup', { budgetId: '${item.budgetId}' })`,
|
||||
`__actionsForMenu.replaceModal('load-backup', { budgetId: '${budgetId}' })`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist",
|
||||
"update-client": "bin/update-client",
|
||||
"build": "electron-builder",
|
||||
"watch": "cross-env ACTUAL_DOCUMENT_DIR=\"../../data\" ACTUAL_DATA_DIR=\"../../data\" electron ."
|
||||
"build": "yarn build:dist && electron-builder",
|
||||
"build:dist": "tsc --p tsconfig.dist.json && yarn copy-static-html",
|
||||
"copy-static-html": "copyfiles --exclude 'build/**/*' **/*.html icons/**/* build",
|
||||
"watch": "yarn build:dist && cross-env ACTUAL_DOCUMENT_DIR=\"../../data\" ACTUAL_DATA_DIR=\"../../data\" electron ."
|
||||
},
|
||||
"main": "index.js",
|
||||
"main": "build/index.js",
|
||||
"build": {
|
||||
"appId": "com.actualbudget.actual",
|
||||
"files": [
|
||||
@@ -19,7 +21,8 @@
|
||||
"!**/*.js.map",
|
||||
"!node_modules/@jlongster/sql.js",
|
||||
"!node_modules/absurd-sql",
|
||||
"!node_modules/better-sqlite3/{benchmark,src,bin,docs,deps,build/Release/obj,build/Release/sqlite3.a,build/Release/test_extension.node}"
|
||||
"!node_modules/better-sqlite3/{benchmark,src,bin,docs,deps,build/Release/obj,build/Release/sqlite3.a,build/Release/test_extension.node}",
|
||||
"build"
|
||||
],
|
||||
"publish": {
|
||||
"provider": "github",
|
||||
@@ -63,8 +66,11 @@
|
||||
"devDependencies": {
|
||||
"@electron/notarize": "2.2.0",
|
||||
"@electron/rebuild": "3.6.0",
|
||||
"@types/copyfiles": "^2",
|
||||
"copyfiles": "^2.4.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"electron": "30.0.6",
|
||||
"electron-builder": "24.13.3"
|
||||
"electron-builder": "24.13.3",
|
||||
"typescript": "^5.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
14
packages/desktop-electron/tsconfig.dist.json
Normal file
14
packages/desktop-electron/tsconfig.dist.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
// Using ES2021 because that’s the newest version where
|
||||
// the latest Node 16.x release supports all of the features
|
||||
"target": "ES2021",
|
||||
"module": "CommonJS",
|
||||
"noEmit": false,
|
||||
"declaration": true,
|
||||
"outDir": "build",
|
||||
},
|
||||
"include": ["."],
|
||||
"exclude": ["**/node_modules/*", "build/**/*"]
|
||||
}
|
||||
6
upcoming-release-notes/2880.md
Normal file
6
upcoming-release-notes/2880.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Maintenance
|
||||
authors: [MikesGlitch]
|
||||
---
|
||||
|
||||
Refactoring desktop-electron package to use typescript
|
||||
93
yarn.lock
93
yarn.lock
@@ -5443,6 +5443,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/copyfiles@npm:^2":
|
||||
version: 2.4.4
|
||||
resolution: "@types/copyfiles@npm:2.4.4"
|
||||
checksum: 0513199240828feda5f6ed04c69d6a642c47e6ab66b81214716807f948ed3e865e9b3d2b69f75cbcc6fbe2154630755c47ca473b3913f0a831179366c709a8cc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-array@npm:^3.0.3":
|
||||
version: 3.0.4
|
||||
resolution: "@types/d3-array@npm:3.0.4"
|
||||
@@ -7999,6 +8006,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"copyfiles@npm:^2.4.1":
|
||||
version: 2.4.1
|
||||
resolution: "copyfiles@npm:2.4.1"
|
||||
dependencies:
|
||||
glob: "npm:^7.0.5"
|
||||
minimatch: "npm:^3.0.3"
|
||||
mkdirp: "npm:^1.0.4"
|
||||
noms: "npm:0.0.0"
|
||||
through2: "npm:^2.0.1"
|
||||
untildify: "npm:^4.0.0"
|
||||
yargs: "npm:^16.1.0"
|
||||
bin:
|
||||
copyfiles: copyfiles
|
||||
copyup: copyfiles
|
||||
checksum: 17070f88cbeaf62a9355341cb2521bacd48069e1ac8e7f95a3f69c848c53646f16ff0f94807a789e0f3eedc11407ec8d3980a13ab62e2add6ef81d0a5900fd85
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.34.0":
|
||||
version: 3.36.0
|
||||
resolution: "core-js-compat@npm:3.36.0"
|
||||
@@ -8655,6 +8680,8 @@ __metadata:
|
||||
dependencies:
|
||||
"@electron/notarize": "npm:2.2.0"
|
||||
"@electron/rebuild": "npm:3.6.0"
|
||||
"@types/copyfiles": "npm:^2"
|
||||
copyfiles: "npm:^2.4.1"
|
||||
cross-env: "npm:^7.0.3"
|
||||
electron: "npm:30.0.6"
|
||||
electron-builder: "npm:24.13.3"
|
||||
@@ -8664,6 +8691,7 @@ __metadata:
|
||||
loot-core: "npm:*"
|
||||
node-fetch: "npm:^2.7.0"
|
||||
promise-retry: "npm:^2.0.1"
|
||||
typescript: "npm:^5.0.2"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -10682,7 +10710,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6":
|
||||
"glob@npm:^7.0.5, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6":
|
||||
version: 7.2.3
|
||||
resolution: "glob@npm:7.2.3"
|
||||
dependencies:
|
||||
@@ -11206,7 +11234,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4":
|
||||
"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3, inherits@npm:~2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "inherits@npm:2.0.4"
|
||||
checksum: cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521
|
||||
@@ -11771,6 +11799,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"isarray@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "isarray@npm:0.0.1"
|
||||
checksum: 49191f1425681df4a18c2f0f93db3adb85573bcdd6a4482539d98eac9e705d8961317b01175627e860516a2fc45f8f9302db26e5a380a97a520e272e2a40a8d4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"isarray@npm:^2.0.5":
|
||||
version: 2.0.5
|
||||
resolution: "isarray@npm:2.0.5"
|
||||
@@ -13976,7 +14011,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
|
||||
"minimatch@npm:^3.0.3, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
|
||||
version: 3.1.2
|
||||
resolution: "minimatch@npm:3.1.2"
|
||||
dependencies:
|
||||
@@ -14401,6 +14436,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"noms@npm:0.0.0":
|
||||
version: 0.0.0
|
||||
resolution: "noms@npm:0.0.0"
|
||||
dependencies:
|
||||
inherits: "npm:^2.0.1"
|
||||
readable-stream: "npm:~1.0.31"
|
||||
checksum: a05f056dabf764c86472b6b5aad10455f3adcb6971f366cdf36a72b559b29310a940e316bca30802f2804fdd41707941366224f4cba80c4f53071512245bf200
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"nopt@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "nopt@npm:6.0.0"
|
||||
@@ -15893,7 +15938,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:^2.3.0, readable-stream@npm:^2.3.5":
|
||||
"readable-stream@npm:^2.3.0, readable-stream@npm:^2.3.5, readable-stream@npm:~2.3.6":
|
||||
version: 2.3.8
|
||||
resolution: "readable-stream@npm:2.3.8"
|
||||
dependencies:
|
||||
@@ -15919,6 +15964,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:~1.0.31":
|
||||
version: 1.0.34
|
||||
resolution: "readable-stream@npm:1.0.34"
|
||||
dependencies:
|
||||
core-util-is: "npm:~1.0.0"
|
||||
inherits: "npm:~2.0.1"
|
||||
isarray: "npm:0.0.1"
|
||||
string_decoder: "npm:~0.10.x"
|
||||
checksum: 20537fca5a8ffd4af0f483be1cce0e981ed8cbb1087e0c762e2e92ae77f1005627272cebed8422f28047b465056aa1961fefd24baf532ca6a3616afea6811ae0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readdirp@npm:~3.6.0":
|
||||
version: 3.6.0
|
||||
resolution: "readdirp@npm:3.6.0"
|
||||
@@ -17155,6 +17212,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"string_decoder@npm:~0.10.x":
|
||||
version: 0.10.31
|
||||
resolution: "string_decoder@npm:0.10.31"
|
||||
checksum: cc43e6b1340d4c7843da0e37d4c87a4084c2342fc99dcf6563c3ec273bb082f0cbd4ebf25d5da19b04fb16400d393885fda830be5128e1c416c73b5a6165f175
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"string_decoder@npm:~1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "string_decoder@npm:1.1.1"
|
||||
@@ -17603,6 +17667,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"through2@npm:^2.0.1":
|
||||
version: 2.0.5
|
||||
resolution: "through2@npm:2.0.5"
|
||||
dependencies:
|
||||
readable-stream: "npm:~2.3.6"
|
||||
xtend: "npm:~4.0.1"
|
||||
checksum: cd71f7dcdc7a8204fea003a14a433ef99384b7d4e31f5497e1f9f622b3cf3be3691f908455f98723bdc80922a53af7fa10c3b7abbe51c6fd3d536dbc7850e2c4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"through@npm:^2.3.8":
|
||||
version: 2.3.8
|
||||
resolution: "through@npm:2.3.8"
|
||||
@@ -18335,6 +18409,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"untildify@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "untildify@npm:4.0.0"
|
||||
checksum: 39ced9c418a74f73f0a56e1ba4634b4d959422dff61f4c72a8e39f60b99380c1b45ed776fbaa0a4101b157e4310d873ad7d114e8534ca02609b4916bb4187fb9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"upath@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "upath@npm:1.2.0"
|
||||
@@ -19355,7 +19436,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xtend@npm:^4.0.0":
|
||||
"xtend@npm:^4.0.0, xtend@npm:~4.0.1":
|
||||
version: 4.0.2
|
||||
resolution: "xtend@npm:4.0.2"
|
||||
checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a
|
||||
@@ -19427,7 +19508,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yargs@npm:^16.2.0":
|
||||
"yargs@npm:^16.1.0, yargs@npm:^16.2.0":
|
||||
version: 16.2.0
|
||||
resolution: "yargs@npm:16.2.0"
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user