diff --git a/apps/cli/package.json b/apps/cli/package.json
index ca7404196..3b46584ec 100644
--- a/apps/cli/package.json
+++ b/apps/cli/package.json
@@ -23,7 +23,9 @@
"date-prompt": "^1.0.0",
"inquirer": "^9.2.12",
"inquirer-autocomplete-prompt": "^3.0.1",
- "vorpal": "^1.12.0"
+ "vorpal": "^1.12.0",
+ "winston": "^3.11.0",
+ "winston-daily-rotate-file": "^4.7.1"
},
"devDependencies": {
"@types/inquirer": "9.0.7",
diff --git a/apps/cli/src/commands/operator-control/operator-runtime.ts b/apps/cli/src/commands/operator-control/operator-runtime.ts
index cd093e1b1..939872b1d 100644
--- a/apps/cli/src/commands/operator-control/operator-runtime.ts
+++ b/apps/cli/src/commands/operator-control/operator-runtime.ts
@@ -1,4 +1,5 @@
import Vorpal from "vorpal";
+import Logger from "../../utils/Logger.js"
import { getSignerFromPrivateKey, operatorRuntime, listOwnersForOperator, Challenge, PublicNodeBucketInformation } from "@sentry/core";
/**
@@ -62,7 +63,13 @@ export function bootOperator(cli: Vorpal) {
stopFunction = await operatorRuntime(
signer,
undefined,
- (log: string) => this.log(log),
+ (log: string) => {
+ if (log.startsWith("Error")) {
+ Logger.error(log);
+ return;
+ }
+ Logger.log(log)
+ },
selectedOwners,
(publicNodeData: PublicNodeBucketInformation | undefined, challenge: Challenge, message: string) => {
const errorMessage = `The comparison between public node and challenge failed:\n` +
diff --git a/apps/cli/src/utils/Logger.ts b/apps/cli/src/utils/Logger.ts
new file mode 100644
index 000000000..914f97a8d
--- /dev/null
+++ b/apps/cli/src/utils/Logger.ts
@@ -0,0 +1,75 @@
+import path from 'path';
+import fs from 'fs';
+import DailyRotateFile from 'winston-daily-rotate-file';
+import winston from 'winston';
+
+let logger: winston.Logger;
+const getLogger = () => {
+ if (!logger) {
+ const transports = [];
+
+ transports.push(
+ new winston.transports.Console({
+ format: winston.format.printf((log: { message: string }) => log.message),
+ })
+ )
+
+ const LOG_PATH = getLogPath();
+ mkdir(LOG_PATH);
+ mkdir(path.join(LOG_PATH, 'errors'));
+
+ transports.push(
+ new DailyRotateFile({
+ dirname: LOG_PATH,
+ filename: 'combined',
+ datePattern: 'yyyyMMDD',
+ extension: '.log',
+ maxFiles: '3d'
+ }),
+ )
+
+ transports.push(
+ new DailyRotateFile({
+ dirname: path.join(LOG_PATH, 'errors'),
+ filename: 'error',
+ datePattern: 'yyyyMMDD',
+ level: 'error',
+ extension: '.log',
+ maxFiles: '14d'
+ })
+ )
+
+ logger = winston.createLogger({
+ transports
+ });
+ }
+
+ return logger;
+};
+
+// Return the os specific app data folder
+// OS X - '/Users/user/Library/Preferences/sentry-cli/logs'
+// Windows - 'C:\Users\user\AppData\Roaming\sentry-cli\logs'
+// Linux - '/home/user/.local/share/sentry-cli/logs'
+const getLogPath = (): string => {
+ const root = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Preferences' : process.env.HOME + "/.local/share");
+ return path.join(root, 'sentry-cli', 'logs')
+}
+
+const mkdir = (_path: string): void => {
+ if (!fs.existsSync(_path)) {
+ fs.mkdirSync(_path, { recursive: true });
+ }
+}
+
+const log = (...args: any): void => {
+ getLogger().info({ timestamp: new Date().toLocaleString(), level: 'INFO', message: args, PID: process.pid });
+};
+
+const error = (...args: any): void => {
+ getLogger().error({ timestamp: new Date().toLocaleString(), level: 'ERROR', message: args, PID: process.pid });
+};
+
+export default {
+ log, error
+}
\ No newline at end of file
diff --git a/apps/sentry-client-desktop/electron/main.ts b/apps/sentry-client-desktop/electron/main.ts
index caba13b08..1cebf8095 100644
--- a/apps/sentry-client-desktop/electron/main.ts
+++ b/apps/sentry-client-desktop/electron/main.ts
@@ -9,6 +9,8 @@ import {autoUpdater} from 'electron-updater';
const isWindows = os.platform() === "win32";
+log.initialize();
+
//-------------------------------------------------------------------
// Logging
//
diff --git a/apps/sentry-client-desktop/src/components/blockpass/Blockpass.tsx b/apps/sentry-client-desktop/src/components/blockpass/Blockpass.tsx
index a92654ee0..24454209d 100644
--- a/apps/sentry-client-desktop/src/components/blockpass/Blockpass.tsx
+++ b/apps/sentry-client-desktop/src/components/blockpass/Blockpass.tsx
@@ -1,5 +1,6 @@
import {PropsWithChildren, useState} from "react";
import {CountryDropdown} from "@/components/blockpass/CountryDropdown";
+import log from "electron-log";
interface BlockpassProps {
onClick?: () => void;
@@ -24,7 +25,7 @@ export function Blockpass({onClick = () => {}, children = "Begin KYC"}: PropsWit
return window.electron.openExternal(`https://verify-with.blockpass.org/?clientId=xai_node_007da`);
}
} else {
- console.log("Please select a country");
+ log.info("Please select a country");
}
}
diff --git a/apps/sentry-client-desktop/src/features/home/SentryWallet.tsx b/apps/sentry-client-desktop/src/features/home/SentryWallet.tsx
index b1c260a7d..fe8b793f4 100644
--- a/apps/sentry-client-desktop/src/features/home/SentryWallet.tsx
+++ b/apps/sentry-client-desktop/src/features/home/SentryWallet.tsx
@@ -26,6 +26,7 @@ import {AssignKeysSentryNotRunning} from "@/components/AssignKeysSentryNotRunnin
import {GrRefresh} from "react-icons/gr";
import {LuListChecks} from "react-icons/lu";
import {useStorage} from "@/features/storage";
+import log from "electron-log";
// TODO -> replace with dynamic value later
export const recommendedFundingBalance = ethers.parseEther("0.005");
@@ -84,10 +85,10 @@ export function SentryWallet() {
}, 2000);
})
.catch(err => {
- console.error('Unable to copy to clipboard: ', err);
+ log.error('Unable to copy to clipboard: ', err);
});
} else {
- console.error('Clipboard API not available, unable to copy to clipboard');
+ log.error('Clipboard API not available, unable to copy to clipboard');
}
}
@@ -101,10 +102,10 @@ export function SentryWallet() {
}, 2000);
})
.catch(err => {
- console.error('Unable to copy to clipboard: ', err);
+ log.error('Unable to copy to clipboard: ', err);
});
} else {
- console.error('Clipboard API not available, unable to copy to clipboard');
+ log.error('Clipboard API not available, unable to copy to clipboard');
}
}
diff --git a/apps/sentry-client-desktop/src/features/home/dashboard/SentryNodeStatusCard.tsx b/apps/sentry-client-desktop/src/features/home/dashboard/SentryNodeStatusCard.tsx
index 349677e3e..09d2fbfaa 100644
--- a/apps/sentry-client-desktop/src/features/home/dashboard/SentryNodeStatusCard.tsx
+++ b/apps/sentry-client-desktop/src/features/home/dashboard/SentryNodeStatusCard.tsx
@@ -8,6 +8,7 @@ import {useBalance} from "@/hooks/useBalance";
import {recommendedFundingBalance} from "@/features/home/SentryWallet";
import {getLatestChallenge} from "@sentry/core";
import {ReactNode, useEffect, useState} from "react";
+import log from "electron-log";
export function SentryNodeStatusCard() {
const {publicKey} = useOperator();
@@ -26,7 +27,7 @@ export function SentryNodeStatusCard() {
:
Error retrieving challenge data
);
} catch (error) {
- console.error('Error fetching latest challenge:', error);
+ log.error('Error fetching latest challenge:', error);
setTimeAgoString(Error fetching latest challenge
);
}
};
diff --git a/apps/sentry-client-desktop/src/features/home/modals/ExportSentryDrawer.tsx b/apps/sentry-client-desktop/src/features/home/modals/ExportSentryDrawer.tsx
index 21e9bfa1f..68307e27e 100644
--- a/apps/sentry-client-desktop/src/features/home/modals/ExportSentryDrawer.tsx
+++ b/apps/sentry-client-desktop/src/features/home/modals/ExportSentryDrawer.tsx
@@ -5,6 +5,7 @@ import {useOperator} from "../../operator";
import {PiCopy} from "react-icons/pi";
import {useState} from "react";
import {BiLoaderAlt} from "react-icons/bi";
+import log from "electron-log";
export function ExportSentryDrawer() {
const setDrawerState = useSetAtom(drawerStateAtom);
@@ -21,10 +22,10 @@ export function ExportSentryDrawer() {
}, 2000);
})
.catch(err => {
- console.error('Unable to copy to clipboard: ', err);
+ log.error('Unable to copy to clipboard: ', err);
});
} else {
- console.error('Clipboard API not available, unable to copy to clipboard');
+ log.error('Clipboard API not available, unable to copy to clipboard');
}
}
diff --git a/apps/sentry-client-desktop/src/features/home/modals/actions-required/FundsInSentryWalletCard.tsx b/apps/sentry-client-desktop/src/features/home/modals/actions-required/FundsInSentryWalletCard.tsx
index dd28f9ad9..6e59bff3d 100644
--- a/apps/sentry-client-desktop/src/features/home/modals/actions-required/FundsInSentryWalletCard.tsx
+++ b/apps/sentry-client-desktop/src/features/home/modals/actions-required/FundsInSentryWalletCard.tsx
@@ -9,6 +9,7 @@ import {useOperator} from "@/features/operator";
import {useState} from "react";
import {accruingStateAtom} from "@/hooks/useAccruingInfo";
import {useAtomValue} from "jotai";
+import log from "electron-log";
export function FundsInSentryWalletCard() {
const {isLoading: isOperatorLoading, publicKey: operatorAddress} = useOperator();
@@ -26,10 +27,10 @@ export function FundsInSentryWalletCard() {
}, 2000);
})
.catch(err => {
- console.error('Unable to copy to clipboard: ', err);
+ log.error('Unable to copy to clipboard: ', err);
});
} else {
- console.error('Clipboard API not available, unable to copy to clipboard');
+ log.error('Clipboard API not available, unable to copy to clipboard');
}
}
diff --git a/apps/sentry-client-desktop/src/features/keys/HasKeys.tsx b/apps/sentry-client-desktop/src/features/keys/HasKeys.tsx
index 886bf89fc..3f4a4f69b 100644
--- a/apps/sentry-client-desktop/src/features/keys/HasKeys.tsx
+++ b/apps/sentry-client-desktop/src/features/keys/HasKeys.tsx
@@ -23,6 +23,7 @@ import {ethers} from "ethers";
import {BiLoaderAlt} from "react-icons/bi";
import {useGetWalletBalance} from "@/hooks/useGetWalletBalance";
import {useGetSingleWalletBalance} from "@/hooks/useGetSingleWalletBalance";
+import log from "electron-log";
interface HasKeysProps {
combinedOwners: string[],
@@ -213,10 +214,10 @@ export function HasKeys({combinedOwners, combinedLicensesMap, statusMap, isWalle
}, 1500);
})
.catch(err => {
- console.error('Unable to copy to clipboard: ', err);
+ log.error('Unable to copy to clipboard: ', err);
});
} else {
- console.error('Clipboard API not available, unable to copy to clipboard');
+ log.error('Clipboard API not available, unable to copy to clipboard');
}
}
diff --git a/apps/sentry-client-desktop/src/features/keys/StatusPulse.tsx b/apps/sentry-client-desktop/src/features/keys/StatusPulse.tsx
index 8fdf39403..74dbf012c 100644
--- a/apps/sentry-client-desktop/src/features/keys/StatusPulse.tsx
+++ b/apps/sentry-client-desktop/src/features/keys/StatusPulse.tsx
@@ -1,3 +1,5 @@
+import log from "electron-log";
+
interface PulseStyle {
size?: "sm" | "md"
}
@@ -16,7 +18,7 @@ export function GreenPulse({size="sm"}: PulseStyle) {
pulseH = "1.25rem";
break;
default:
- console.log("Invalid size"); // Handle the case where size is none of the specified values
+ log.info("Invalid size"); // Handle the case where size is none of the specified values
}
const greenPulseStyle = {
@@ -48,7 +50,7 @@ export function YellowPulse({size="sm"}: PulseStyle) {
pulseH = "1.25rem";
break;
default:
- console.log("Invalid size"); // Handle the case where size is none of the specified values
+ log.info("Invalid size"); // Handle the case where size is none of the specified values
}
const yellowPulseStyle = {
diff --git a/apps/sentry-client-desktop/src/features/storage/useStorage.tsx b/apps/sentry-client-desktop/src/features/storage/useStorage.tsx
index d075926b5..61388ebe7 100644
--- a/apps/sentry-client-desktop/src/features/storage/useStorage.tsx
+++ b/apps/sentry-client-desktop/src/features/storage/useStorage.tsx
@@ -1,5 +1,6 @@
import {useEffect, useState} from 'react';
import {atom, useAtom} from 'jotai';
+import log from "electron-log";
const dataAtom = atom(undefined);
@@ -57,7 +58,7 @@ export function useStorage(): IUseStorageResponse {
await window.ipcRenderer.invoke('fs-writeFileSync', filePath, JSON.stringify(newData));
setData(newData);
} catch (error) {
- console.error(error);
+ log.error(error);
} finally {
setLoading(false);
}
@@ -70,7 +71,7 @@ export function useStorage(): IUseStorageResponse {
await window.ipcRenderer.invoke('fs-unlinkSync', filePath);
setData(undefined);
} catch (error) {
- console.error(error);
+ log.error(error);
} finally {
setLoading(false);
}
diff --git a/apps/sentry-client-desktop/src/hooks/useOperatorRuntime.ts b/apps/sentry-client-desktop/src/hooks/useOperatorRuntime.ts
index bf3b8d28d..11a4ae5c5 100644
--- a/apps/sentry-client-desktop/src/hooks/useOperatorRuntime.ts
+++ b/apps/sentry-client-desktop/src/hooks/useOperatorRuntime.ts
@@ -3,6 +3,7 @@ import {useOperator} from "@/features/operator";
import {atom, useAtom} from "jotai";
import {useEffect, useState} from "react";
import {useStorage} from "@/features/storage";
+import log from "electron-log";
function onAssertionMissMatch(publicNodeData: PublicNodeBucketInformation, challenge: Challenge, message: string) {
const errorMessage = `The comparison between public node and challenge failed:\n` +
@@ -36,16 +37,20 @@ export function useOperatorRuntime() {
}
}, [signer]);
- function writeLog(log: string) {
- console.info(log); // for debugging purposes
- const _logs = runtimeLogs.concat([]);
- if (_logs.length === 1000) {
- _logs.shift();
- }
+ function writeLog(message: string) {
+ if (message.startsWith("Error")) {
+ log.error(message);
+ } else {
+ log.info(message);
+ }
+ const _logs = runtimeLogs.concat([]);
+ if (_logs.length === 1000) {
+ _logs.shift();
+ }
- _logs.push(log);
- setRuntimeLogs(_logs);
- }
+ _logs.push(message);
+ setRuntimeLogs(_logs);
+ }
async function startRuntime() {
if (!sentryRunning && stop === undefined) {
diff --git a/apps/sentry-client-desktop/src/main.tsx b/apps/sentry-client-desktop/src/main.tsx
index ebfc659a0..caaefa512 100644
--- a/apps/sentry-client-desktop/src/main.tsx
+++ b/apps/sentry-client-desktop/src/main.tsx
@@ -6,6 +6,7 @@ import * as Sentry from "@sentry/react";
import {HttpClient} from "@sentry/integrations";
import "./index.css";
import {createRoutesFromChildren, matchRoutes, useLocation, useNavigationType} from "react-router-dom";
+import log from "electron-log";
const rootElement = document.getElementById('root')!
@@ -55,5 +56,5 @@ postMessage({payload: 'removeLoading'}, '*')
// Use contextBridge
window.ipcRenderer.on('main-process-message', (_event, message) => {
- console.log(message)
+ log.info(message)
})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d870fa961..1bf25b1e0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -63,6 +63,12 @@ importers:
vorpal:
specifier: ^1.12.0
version: 1.12.0
+ winston:
+ specifier: ^3.11.0
+ version: 3.11.0
+ winston-daily-rotate-file:
+ specifier: ^4.7.1
+ version: 4.7.1(winston@3.11.0)
devDependencies:
'@types/inquirer':
specifier: 9.0.7
@@ -2038,12 +2044,25 @@ packages:
dev: false
optional: true
+ /@colors/colors@1.6.0:
+ resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==}
+ engines: {node: '>=0.1.90'}
+ dev: false
+
/@cspotcode/source-map-support@0.8.1:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/trace-mapping': 0.3.9
+ /@dabh/diagnostics@2.0.3:
+ resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
+ dependencies:
+ colorspace: 1.1.4
+ enabled: 2.0.0
+ kuler: 2.0.0
+ dev: false
+
/@derhuerst/cli-on-key@0.1.0:
resolution: {integrity: sha512-+Q3J+a/4fSyR9SIsV9PEW24AuIHyMwsZ3yNd1nGGOXKIz0aoqovBHE+LQSd7FkfV6ZJi0N1Mw2RwaZq2xMa3BA==}
engines: {node: '>=6'}
@@ -6444,6 +6463,10 @@ packages:
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
dev: false
+ /@types/triple-beam@1.3.5:
+ resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
+ dev: false
+
/@types/trusted-types@2.0.5:
resolution: {integrity: sha512-I3pkr8j/6tmQtKV/ZzHtuaqYSQvyjGRKH4go60Rr0IDLlFxuRT5V32uvB1mecM5G1EVAUyF/4r4QZ1GHgz+mxA==}
dev: false
@@ -7973,7 +7996,6 @@ packages:
/async@3.2.4:
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
- dev: true
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
@@ -9005,6 +9027,20 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ /color-string@1.9.1:
+ resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+ dependencies:
+ color-name: 1.1.4
+ simple-swizzle: 0.2.2
+ dev: false
+
+ /color@3.2.1:
+ resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
+ dependencies:
+ color-convert: 1.9.3
+ color-string: 1.9.1
+ dev: false
+
/colord@2.9.3:
resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
dev: false
@@ -9018,6 +9054,13 @@ packages:
engines: {node: '>=0.1.90'}
dev: true
+ /colorspace@1.1.4:
+ resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==}
+ dependencies:
+ color: 3.2.1
+ text-hex: 1.0.0
+ dev: false
+
/combine-promises@1.2.0:
resolution: {integrity: sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==}
engines: {node: '>=10'}
@@ -10276,6 +10319,10 @@ packages:
resolution: {integrity: sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==}
dev: false
+ /enabled@2.0.0:
+ resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==}
+ dev: false
+
/encode-utf8@1.0.3:
resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==}
dev: false
@@ -11157,6 +11204,7 @@ packages:
dependencies:
is-hex-prefixed: 1.0.0
strip-hex-prefix: 1.0.0
+ bundledDependencies: false
/eval@0.1.8:
resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==}
@@ -11421,6 +11469,10 @@ packages:
pend: 1.2.0
dev: true
+ /fecha@4.2.3:
+ resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==}
+ dev: false
+
/feed@4.2.2:
resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==}
engines: {node: '>=0.4.0'}
@@ -11476,6 +11528,12 @@ packages:
webpack: 5.89.0
dev: false
+ /file-stream-rotator@0.6.1:
+ resolution: {integrity: sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==}
+ dependencies:
+ moment: 2.29.4
+ dev: false
+
/file-uri-to-path@1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
dev: false
@@ -11601,6 +11659,10 @@ packages:
- encoding
dev: false
+ /fn.name@1.1.0:
+ resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==}
+ dev: false
+
/follow-redirects@1.15.2(debug@4.3.4):
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
@@ -13125,6 +13187,10 @@ packages:
/is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+ /is-arrayish@0.3.2:
+ resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+ dev: false
+
/is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
dependencies:
@@ -13819,6 +13885,10 @@ packages:
engines: {node: '>=6'}
dev: false
+ /kuler@2.0.0:
+ resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==}
+ dev: false
+
/latest-version@7.0.0:
resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==}
engines: {node: '>=14.16'}
@@ -14128,6 +14198,18 @@ packages:
cli-cursor: 1.0.2
dev: false
+ /logform@2.6.0:
+ resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==}
+ engines: {node: '>= 12.0.0'}
+ dependencies:
+ '@colors/colors': 1.6.0
+ '@types/triple-beam': 1.3.5
+ fecha: 4.2.3
+ ms: 2.1.3
+ safe-stable-stringify: 2.4.3
+ triple-beam: 1.4.1
+ dev: false
+
/longest-streak@3.1.0:
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
dev: false
@@ -15541,6 +15623,11 @@ packages:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
+ /object-hash@2.2.0:
+ resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
+ engines: {node: '>= 6'}
+ dev: false
+
/object-hash@3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
@@ -15626,6 +15713,12 @@ packages:
dependencies:
wrappy: 1.0.2
+ /one-time@1.0.0:
+ resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==}
+ dependencies:
+ fn.name: 1.1.0
+ dev: false
+
/onetime@1.1.0:
resolution: {integrity: sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==}
engines: {node: '>=0.10.0'}
@@ -18088,6 +18181,12 @@ packages:
simple-concat: 1.0.1
dev: true
+ /simple-swizzle@0.2.2:
+ resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+ dependencies:
+ is-arrayish: 0.3.2
+ dev: false
+
/simple-update-notifier@2.0.0:
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
engines: {node: '>=10'}
@@ -18370,6 +18469,10 @@ packages:
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
dev: false
+ /stack-trace@0.0.10:
+ resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
+ dev: false
+
/stacktrace-parser@0.1.10:
resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==}
engines: {node: '>=6'}
@@ -18936,6 +19039,10 @@ packages:
resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==}
dev: false
+ /text-hex@1.0.0:
+ resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==}
+ dev: false
+
/text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
@@ -19072,6 +19179,11 @@ packages:
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
dev: false
+ /triple-beam@1.4.1:
+ resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==}
+ engines: {node: '>= 14.0.0'}
+ dev: false
+
/trough@2.1.0:
resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==}
dev: false
@@ -20824,6 +20936,45 @@ packages:
is-number: 3.0.0
dev: false
+ /winston-daily-rotate-file@4.7.1(winston@3.11.0):
+ resolution: {integrity: sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==}
+ engines: {node: '>=8'}
+ peerDependencies:
+ winston: ^3
+ dependencies:
+ file-stream-rotator: 0.6.1
+ object-hash: 2.2.0
+ triple-beam: 1.4.1
+ winston: 3.11.0
+ winston-transport: 4.7.0
+ dev: false
+
+ /winston-transport@4.7.0:
+ resolution: {integrity: sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==}
+ engines: {node: '>= 12.0.0'}
+ dependencies:
+ logform: 2.6.0
+ readable-stream: 3.6.2
+ triple-beam: 1.4.1
+ dev: false
+
+ /winston@3.11.0:
+ resolution: {integrity: sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==}
+ engines: {node: '>= 12.0.0'}
+ dependencies:
+ '@colors/colors': 1.6.0
+ '@dabh/diagnostics': 2.0.3
+ async: 3.2.4
+ is-stream: 2.0.1
+ logform: 2.6.0
+ one-time: 1.0.0
+ readable-stream: 3.6.2
+ safe-stable-stringify: 2.4.3
+ stack-trace: 0.0.10
+ triple-beam: 1.4.1
+ winston-transport: 4.7.0
+ dev: false
+
/word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}