feature/IO-3702-ESPD-UI-AND-FIXES - Stage 5 (Lint)

This commit is contained in:
Dave
2026-05-27 13:47:21 -04:00
parent 1e7e13ff32
commit 527a5ef16d
16 changed files with 188 additions and 196 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,29 +1,29 @@
#!/usr/bin/env node #!/usr/bin/env node
// Cross-platform script to set artifact naming based on version // Cross-platform script to set artifact naming based on version
const fs = require('fs'); const fs = require("fs");
const path = require('path'); const path = require("path");
const { spawn } = require('child_process'); const { spawn } = require("child_process");
// Read the package.json to get the version // Read the package.json to get the version
const packageJsonPath = path.join(__dirname, '..', 'package.json'); const packageJsonPath = path.join(__dirname, "..", "package.json");
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
const version = packageJson.version; const version = packageJson.version;
console.log(`Current version: ${version}`); console.log(`Current version: ${version}`);
// Determine the artifact suffix based on the version // Determine the artifact suffix based on the version
let artifactSuffix = ''; let artifactSuffix = "";
if (version.includes('alpha')) { if (version.includes("alpha")) {
artifactSuffix = `alpha-${version}-`; artifactSuffix = `alpha-${version}-`;
console.log(`Detected alpha version, setting suffix to: ${artifactSuffix}`); console.log(`Detected alpha version, setting suffix to: ${artifactSuffix}`);
} else if (version.includes('beta')) { } else if (version.includes("beta")) {
artifactSuffix = `beta-${version}-`; artifactSuffix = `beta-${version}-`;
console.log(`Detected beta version, setting suffix to: ${artifactSuffix}`); console.log(`Detected beta version, setting suffix to: ${artifactSuffix}`);
} else { } else {
artifactSuffix = ''; artifactSuffix = "";
console.log('Detected release version, no suffix will be added'); console.log("Detected release version, no suffix will be added");
} }
// Set the environment variable for the current process // Set the environment variable for the current process
@@ -33,21 +33,23 @@ console.log(`ARTIFACT_SUFFIX set to: '${artifactSuffix}'`);
// If arguments are passed, execute the remaining command with the environment variable set // If arguments are passed, execute the remaining command with the environment variable set
if (process.argv.length > 2) { if (process.argv.length > 2) {
const command = process.argv[2]; const command = process.argv[2];
const args = process.argv.slice(3); const args = process.argv.slice(3);
console.log(`Executing: ${command} ${args.join(' ')}`); console.log(`Executing: ${command} ${args.join(" ")}`);
const child = spawn(command, args, { const child = spawn(command, args, {
stdio: 'inherit', stdio: "inherit",
env: { ...process.env, ARTIFACT_SUFFIX: artifactSuffix }, env: { ...process.env, ARTIFACT_SUFFIX: artifactSuffix },
shell: true shell: true,
}); });
child.on('close', (code) => { child.on("close", (code) => {
process.exit(code); process.exit(code);
}); });
} else { } else {
// Just setting the environment variable // Just setting the environment variable
console.log('Environment variable set. Use this script with additional arguments to run commands with the variable set.'); console.log(
"Environment variable set. Use this script with additional arguments to run commands with the variable set.",
);
} }

View File

@@ -1,64 +1,64 @@
#!/usr/bin/env node #!/usr/bin/env node
// Cross-platform test script to demonstrate artifact naming for different versions // Cross-platform test script to demonstrate artifact naming for different versions
const fs = require('fs'); const fs = require("fs");
const path = require('path'); const path = require("path");
console.log('=== Artifact Naming Test (Cross-Platform) ==='); console.log("=== Artifact Naming Test (Cross-Platform) ===");
console.log(''); console.log("");
// Get current version // Get current version
const packageJsonPath = path.join(__dirname, '..', 'package.json'); const packageJsonPath = path.join(__dirname, "..", "package.json");
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
const currentVersion = packageJson.version; const currentVersion = packageJson.version;
console.log(`Current version: ${currentVersion}`); console.log(`Current version: ${currentVersion}`);
// Function to get artifact suffix // Function to get artifact suffix
function getArtifactSuffix(version) { function getArtifactSuffix(version) {
if (version.includes('alpha')) { if (version.includes("alpha")) {
return `alpha-${version}-`; return `alpha-${version}-`;
} else if (version.includes('beta')) { } else if (version.includes("beta")) {
return `beta-${version}-`; return `beta-${version}-`;
} else { } else {
return ''; return "";
} }
} }
// Test scenarios // Test scenarios
const testVersions = [ const testVersions = [
'1.0.5', // Release version "1.0.5", // Release version
'1.0.5-alpha.2', // Alpha version "1.0.5-alpha.2", // Alpha version
'1.0.5-beta.1', // Beta version "1.0.5-beta.1", // Beta version
'2.0.0-alpha.1', // Another alpha "2.0.0-alpha.1", // Another alpha
'1.5.0-beta.3' // Another beta "1.5.0-beta.3", // Another beta
]; ];
console.log('Test scenarios:'); console.log("Test scenarios:");
console.log('=================='); console.log("==================");
testVersions.forEach(version => { testVersions.forEach((version) => {
const suffix = getArtifactSuffix(version); const suffix = getArtifactSuffix(version);
// Different artifact names for different platforms // Different artifact names for different platforms
const windowsArtifact = `imex-partner-${suffix}x64.exe`; const windowsArtifact = `imex-partner-${suffix}x64.exe`;
const macArtifact = `imex-partner-${suffix}x64.dmg`; const macArtifact = `imex-partner-${suffix}x64.dmg`;
const linuxArtifact = `imex-partner-${suffix}x64.AppImage`; const linuxArtifact = `imex-partner-${suffix}x64.AppImage`;
console.log(`Version: ${version}`); console.log(`Version: ${version}`);
console.log(` Suffix: '${suffix}'`); console.log(` Suffix: '${suffix}'`);
console.log(` Windows: ${windowsArtifact}`); console.log(` Windows: ${windowsArtifact}`);
console.log(` Mac: ${macArtifact}`); console.log(` Mac: ${macArtifact}`);
console.log(` Linux: ${linuxArtifact}`); console.log(` Linux: ${linuxArtifact}`);
console.log(''); console.log("");
}); });
console.log('Current configuration will produce:'); console.log("Current configuration will produce:");
const currentSuffix = getArtifactSuffix(currentVersion); const currentSuffix = getArtifactSuffix(currentVersion);
console.log(` Windows: imex-partner-${currentSuffix}x64.exe`); console.log(` Windows: imex-partner-${currentSuffix}x64.exe`);
console.log(` Mac: imex-partner-${currentSuffix}x64.dmg`); console.log(` Mac: imex-partner-${currentSuffix}x64.dmg`);
console.log(` Linux: imex-partner-${currentSuffix}x64.AppImage`); console.log(` Linux: imex-partner-${currentSuffix}x64.AppImage`);
console.log(''); console.log("");
console.log(`Platform detected: ${process.platform}`); console.log(`Platform detected: ${process.platform}`);
console.log(`Architecture: ${process.arch}`); console.log(`Architecture: ${process.arch}`);

View File

@@ -5,44 +5,42 @@ import eslintPluginReactHooks from "eslint-plugin-react-hooks";
import eslintPluginReactRefresh from "eslint-plugin-react-refresh"; import eslintPluginReactRefresh from "eslint-plugin-react-refresh";
export default tseslint.config( export default tseslint.config(
{ ignores: ["**/node_modules", "**/dist", "**/out", "**/.serverless"] }, { ignores: ["**/node_modules", "**/dist", "**/out", "**/.serverless"] },
{ {
files: ["**/*.{ts,tsx}"], files: ["**/*.{ts,tsx}"],
extends: [tseslint.configs.recommended], extends: [tseslint.configs.recommended],
},
eslintPluginReact.configs.flat.recommended,
eslintPluginReact.configs.flat["jsx-runtime"],
{
settings: {
react: {
version: "detect",
},
}, },
eslintPluginReact.configs.flat.recommended, },
eslintPluginReact.configs.flat["jsx-runtime"], {
{ files: ["**/*.{ts,tsx}"],
settings: { plugins: {
react: { "react-hooks": eslintPluginReactHooks,
version: "detect", "react-refresh": eslintPluginReactRefresh,
},
},
}, },
{ rules: {
files: ["**/*.{ts,tsx}"], ...eslintPluginReactHooks.configs.recommended.rules,
plugins: { ...eslintPluginReactRefresh.configs.vite.rules,
"react-hooks": eslintPluginReactHooks,
"react-refresh": eslintPluginReactRefresh,
},
rules: {
...eslintPluginReactHooks.configs.recommended.rules,
...eslintPluginReactRefresh.configs.vite.rules,
},
}, },
{ },
files: ["serverless/**/*.js"], {
rules: { files: ["serverless/**/*.js"],
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], rules: {
}, "no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
}, },
{ },
files: ["**/*.{js,mjs,ts,tsx,jsx,tsx}"], {
rules: { files: ["**/*.{js,mjs,ts,tsx,jsx,tsx}"],
"prettier/prettier": ["error", { "endOfLine": "auto" }] rules: {
} "prettier/prettier": ["error", { endOfLine: "auto" }],
}, },
eslintConfigPrettier, },
) eslintConfigPrettier,
);

View File

@@ -29,3 +29,5 @@ yarn-error.log*
.env .env
.env.local .env.local
.env.*.local .env.*.local
.
.eslintcache

View File

@@ -27,7 +27,7 @@ interface EmsUploadResponse {
* @param {string} esApiKey - The ES API Key to validate * @param {string} esApiKey - The ES API Key to validate
* @returns {boolean} - Always returns true for now (placeholder) * @returns {boolean} - Always returns true for now (placeholder)
*/ */
function validateEmsUploadId(_esApiKey: string): boolean { function validateEmsUploadId(): boolean {
// Placeholder validation - always returns true // Placeholder validation - always returns true
// TODO: Implement actual validation logic // TODO: Implement actual validation logic
return true; return true;
@@ -54,7 +54,7 @@ export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayPr
} }
// Validate the EMS Upload ID // Validate the EMS Upload ID
const isValid = validateEmsUploadId(esApiKey); const isValid = validateEmsUploadId();
if (!isValid) { if (!isValid) {
return { return {
statusCode: 401, statusCode: 401,

View File

@@ -172,10 +172,9 @@ async function ImportJob(filepath: string): Promise<void> {
mainWindow.show(); mainWindow.show();
mainWindow.focus(); mainWindow.focus();
if (scrubHistoryJobId) { if (scrubHistoryJobId) {
mainWindow.webContents.send( mainWindow.webContents.send(ipcTypes.toRenderer.scrub.openHistoryItem, {
ipcTypes.toRenderer.scrub.openHistoryItem, jobId: scrubHistoryJobId,
{ jobId: scrubHistoryJobId }, });
);
} }
}; };
@@ -362,6 +361,13 @@ export function ReplaceOwnerInfoWithClaimant<
> >
>, >,
>(jobObject: T): T { >(jobObject: T): T {
const mutableJob = jobObject as T &
Record<string, unknown> & {
owner?: {
data?: Record<string, unknown>;
};
};
// Promote claimant data first if owner identity is entirely missing; otherwise fallback to insured data. // Promote claimant data first if owner identity is entirely missing; otherwise fallback to insured data.
const identityKeys = ["ln", "fn", "co_nm"] as const; // keys used to determine presence const identityKeys = ["ln", "fn", "co_nm"] as const; // keys used to determine presence
const copyKeys = [ const copyKeys = [
@@ -381,27 +387,23 @@ export function ReplaceOwnerInfoWithClaimant<
] as const; // full set of fields to copy/delete ] as const; // full set of fields to copy/delete
const ownerMissing = identityKeys.every((k) => const ownerMissing = identityKeys.every((k) =>
_.isEmpty((jobObject as any)[`ownr_${k}`]), _.isEmpty(mutableJob[`ownr_${k}`]),
); );
const claimantHasSome = identityKeys.some( const claimantHasSome = identityKeys.some(
(k) => !_.isEmpty((jobObject as any)[`clmt_${k}`]), (k) => !_.isEmpty(mutableJob[`clmt_${k}`]),
); );
const claimantMissing = identityKeys.every((k) => const claimantMissing = identityKeys.every((k) =>
_.isEmpty((jobObject as any)[`clmt_${k}`]), _.isEmpty(mutableJob[`clmt_${k}`]),
); );
const { owner } = jobObject as any; // destructure for optional nested updates const { owner } = mutableJob; // destructure for optional nested updates
// Copy helper inline (no extra function as requested) // Copy helper inline (no extra function as requested)
const promote = (sourcePrefix: "clmt" | "insd"): void => { const promote = (sourcePrefix: "clmt" | "insd"): void => {
copyKeys.forEach((suffix) => { copyKeys.forEach((suffix) => {
(jobObject as any)[`ownr_${suffix}`] = (jobObject as any)[ mutableJob[`ownr_${suffix}`] = mutableJob[`${sourcePrefix}_${suffix}`];
`${sourcePrefix}_${suffix}`
];
if (owner?.data) { if (owner?.data) {
owner.data[`ownr_${suffix}`] = (jobObject as any)[ owner.data[`ownr_${suffix}`] = mutableJob[`${sourcePrefix}_${suffix}`];
`${sourcePrefix}_${suffix}`
];
} }
}); });
}; };
@@ -413,9 +415,9 @@ export function ReplaceOwnerInfoWithClaimant<
} }
// Delete the claimant info as it's not needed. // Delete the claimant info as it's not needed.
copyKeys.forEach((suffix) => delete (jobObject as any)[`clmt_${suffix}`]); copyKeys.forEach((suffix) => delete mutableJob[`clmt_${suffix}`]);
// Delete the insured info as it's not needed. // Delete the insured info as it's not needed.
copyKeys.forEach((suffix) => delete (jobObject as any)[`insd_${suffix}`]); copyKeys.forEach((suffix) => delete mutableJob[`insd_${suffix}`]);
return jobObject; return jobObject;
} }

View File

@@ -107,7 +107,7 @@ function createWindow(): void {
const template = [ const template = [
// { role: 'appMenu' } // { role: 'appMenu' }
// @ts-ignore // @ts-ignore -- Electron menu role unions are narrower than this conditional template.
...(isMac ...(isMac
? [ ? [
{ {
@@ -128,7 +128,7 @@ function createWindow(): void {
{ {
label: "File", label: "File",
submenu: [ submenu: [
// @ts-ignore // @ts-ignore -- Electron menu role unions are narrower than this conditional template.
isMac ? { role: "close" } : { role: "quit" }, isMac ? { role: "close" } : { role: "quit" },
], ],
}, },
@@ -142,7 +142,7 @@ function createWindow(): void {
{ role: "cut" }, { role: "cut" },
{ role: "copy" }, { role: "copy" },
{ role: "paste" }, { role: "paste" },
// @ts-ignore // @ts-ignore -- Electron menu role unions are narrower than this conditional template.
...(isMac ...(isMac
? [ ? [
{ role: "pasteAndMatchStyle" }, { role: "pasteAndMatchStyle" },
@@ -160,7 +160,7 @@ function createWindow(): void {
// { role: 'viewMenu' } // { role: 'viewMenu' }
{ {
label: "View", label: "View",
// @ts-ignore // @ts-ignore -- Electron menu role unions are narrower than this conditional template.
submenu: [ submenu: [
{ role: "reload" }, { role: "reload" },
{ role: "forceReload" }, { role: "forceReload" },
@@ -175,7 +175,7 @@ function createWindow(): void {
}, },
{ {
label: "Application", label: "Application",
// @ts-ignore // @ts-ignore -- Electron menu role unions are narrower than this conditional template.
submenu: [ submenu: [
{ {
label: "Open on Startup", label: "Open on Startup",
@@ -376,7 +376,7 @@ function createWindow(): void {
submenu: [ submenu: [
{ role: "minimize" }, { role: "minimize" },
{ role: "zoom" }, { role: "zoom" },
// @ts-ignore // @ts-ignore -- Electron menu role unions are narrower than this conditional template.
...(isMac ...(isMac
? [ ? [
{ type: "separator" }, { type: "separator" },
@@ -399,7 +399,7 @@ function createWindow(): void {
// Update the menu to make the hidden item visible // Update the menu to make the hidden item visible
// Find the menu item dynamically by its id // Find the menu item dynamically by its id
const fileMenu = template.find((item) => item.label === "Application"); const fileMenu = template.find((item) => item.label === "Application");
// @ts-ignore // @ts-ignore -- Electron menu submenu typing does not expose array helpers after casting.
const hiddenItem = fileMenu?.submenu?.find( const hiddenItem = fileMenu?.submenu?.find(
(item: { id: string }) => item.id === "development", (item: { id: string }) => item.id === "development",
); );

View File

@@ -15,8 +15,8 @@ export interface GraphQLResponse {
shopname: string; shopname: string;
}; };
jobs?: Array<{ jobs?: Array<{
labhrs: any; labhrs: unknown;
larhrs: any; larhrs: unknown;
ro_number: string; ro_number: string;
ownr_ln: string; ownr_ln: string;
ownr_fn: string; ownr_fn: string;

View File

@@ -14,15 +14,15 @@ import {
const getSetting = async ( const getSetting = async (
_event: IpcMainInvokeEvent, _event: IpcMainInvokeEvent,
key: string, key: string,
): Promise<any> => { ): Promise<unknown> => {
return Store.get(`settings.${key}`); return Store.get(`settings.${key}`);
}; };
const setSetting = async ( const setSetting = async (
_event: IpcMainInvokeEvent, _event: IpcMainInvokeEvent,
key: string, key: string,
value: any, value: unknown,
): Promise<any> => { ): Promise<unknown> => {
Store.set(`settings.${key}`, value); Store.set(`settings.${key}`, value);
return Store.get(`settings.${key}`); return Store.get(`settings.${key}`);
}; };

View File

@@ -1,11 +1,11 @@
import {BrowserWindow} from "electron"; import { BrowserWindow } from "electron";
import log from "electron-log/main"; import log from "electron-log/main";
const getMainWindow = (): Electron.BrowserWindow => { const getMainWindow = (): Electron.BrowserWindow => {
return BrowserWindow.getAllWindows()[0]; return BrowserWindow.getAllWindows()[0];
}; };
const sendIpcToRenderer = (ipcMessage: string, ...args: any[]): void => { const sendIpcToRenderer = (ipcMessage: string, ...args: unknown[]): void => {
const window = getMainWindow(); const window = getMainWindow();
if (window) { if (window) {
window.webContents.send(ipcMessage, ...args); window.webContents.send(ipcMessage, ...args);

View File

@@ -1,4 +1,5 @@
import { nativeImage, type NativeImage, type Tray } from "electron"; import { nativeImage, type NativeImage, type Tray } from "electron";
import { PNG } from "pngjs";
let trayInstance: Tray | undefined; let trayInstance: Tray | undefined;
let trayBaseImage: NativeImage | undefined; let trayBaseImage: NativeImage | undefined;
@@ -29,29 +30,8 @@ function buildStatusTrayImage(
started: boolean, started: boolean,
): NativeImage { ): NativeImage {
try { try {
const pngjs = (() => {
try {
return require("pngjs") as {
PNG?: {
sync?: {
read?: (b: Buffer) => unknown;
write?: (p: unknown) => Buffer;
};
};
};
} catch {
return null;
}
})();
if (!pngjs?.PNG?.sync?.read || !pngjs.PNG.sync.write) return base;
const basePng = base.toPNG(); const basePng = base.toPNG();
const png = pngjs.PNG.sync.read(basePng) as { const png = PNG.sync.read(basePng);
width: number;
height: number;
data: Uint8Array;
};
const width = png.width; const width = png.width;
const height = png.height; const height = png.height;
@@ -86,7 +66,7 @@ function buildStatusTrayImage(
} }
} }
return nativeImage.createFromBuffer(pngjs.PNG.sync.write(png)); return nativeImage.createFromBuffer(PNG.sync.write(png));
} catch { } catch {
return base; return base;
} }

View File

@@ -3,22 +3,22 @@
* @param obj The object whose keys need to be converted to uppercase * @param obj The object whose keys need to be converted to uppercase
* @returns A new object with all keys converted to uppercase * @returns A new object with all keys converted to uppercase
*/ */
function uppercaseObjectKeys<T extends Record<string, any>>( function isRecord(value: unknown): value is Record<string, unknown> {
obj: T, return typeof value === "object" && value !== null;
): Record<string, any> { }
if (typeof obj !== "object" || obj === null) {
return obj;
}
function uppercaseObjectKeys(
obj: Record<string, unknown>,
): Record<string, unknown> {
return Object.entries(obj).reduce( return Object.entries(obj).reduce(
(result, [key, value]) => { (result, [key, value]) => {
const uppercaseKey = key.toUpperCase(); const uppercaseKey = key.toUpperCase();
result[uppercaseKey] = typeof value === "object" && value !== null result[uppercaseKey] = isRecord(value)
? uppercaseObjectKeys(value) ? uppercaseObjectKeys(value)
: value; : value;
return result; return result;
}, },
{} as Record<string, any>, {} as Record<string, unknown>,
); );
} }
export default uppercaseObjectKeys; export default uppercaseObjectKeys;

View File

@@ -1,5 +1,6 @@
import { Card, Form, Input, Space } from "antd"; import { Card, Form, Input, Space } from "antd";
import { FC, useEffect } from "react"; import type { FormProps } from "antd";
import { FC, useEffect, useMemo } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import ipcTypes from "../../../../util/ipcTypes.json"; import ipcTypes from "../../../../util/ipcTypes.json";
@@ -7,31 +8,36 @@ const SettingsConfig: FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const settingFields = [ const settingFields = useMemo(
{ () => [
name: "esApiKey", {
label: t("settings.labels.esApiKey"), name: "esApiKey",
component: Input.Password, label: t("settings.labels.esApiKey"),
hasFeedback: true, component: Input.Password,
componentProps: { hasFeedback: true,
placeholder: "Enter your API key", componentProps: {
placeholder: "Enter your API key",
},
}, },
}, ],
]; [t],
);
useEffect(() => { useEffect(() => {
settingFields.forEach((field) => { settingFields.forEach((field) => {
window.electron.ipcRenderer window.electron.ipcRenderer
.invoke(ipcTypes.toMain.settings.get, field.name) .invoke(ipcTypes.toMain.settings.get, field.name)
.then((value: any) => { .then((value: unknown) => {
form.setFieldsValue({ [field.name]: value }); form.setFieldsValue({ [field.name]: value });
}); });
}); });
}, []); }, [form, settingFields]);
const handleFieldChange = (changedFields: any): void => { const handleFieldChange: FormProps["onFieldsChange"] = (changedFields) => {
changedFields.forEach((field) => { changedFields.forEach((field) => {
const fieldName = field.name[0]; const fieldName = Array.isArray(field.name)
? String(field.name[0])
: String(field.name);
const { value } = field; const { value } = field;
// Placeholder for validation // Placeholder for validation
@@ -46,7 +52,7 @@ const SettingsConfig: FC = () => {
}); });
}; };
const validateField = (fieldName: string, value: any): boolean => { const validateField = (fieldName: string, value: unknown): boolean => {
// Placeholder for actual validation logic // Placeholder for actual validation logic
console.log(`Validating ${fieldName}:`, value); console.log(`Validating ${fieldName}:`, value);
return true; return true;

View File

@@ -1,17 +1,19 @@
import {createContext, FC, ReactNode, useContext} from "react"; import { createContext, FC, ReactNode, useContext } from "react";
import { notification } from "antd"; import { notification } from "antd";
/** /**
* Create our NotificationContext to store the `api` object * Create our NotificationContext to store the `api` object
* returned by notification.useNotification(). * returned by notification.useNotification().
*/ */
const NotificationContext = createContext(null); type NotificationApi = ReturnType<typeof notification.useNotification>[0];
const NotificationContext = createContext<NotificationApi | null>(null);
/** /**
* A custom hook to make usage easier in child components. * A custom hook to make usage easier in child components.
*/ */
// eslint-disable-next-line react-refresh/only-export-components, @typescript-eslint/explicit-function-return-type // eslint-disable-next-line react-refresh/only-export-components
export const useNotification = () => { export const useNotification = (): NotificationApi | null => {
return useContext(NotificationContext); return useContext(NotificationContext);
}; };
@@ -26,8 +28,7 @@ interface NotificationProviderProps {
} }
export const NotificationProvider: FC<NotificationProviderProps> = ({ export const NotificationProvider: FC<NotificationProviderProps> = ({
// eslint-disable-next-line react/prop-types children,
children, //TODO: Unable to resolve this. Adding an eslint disable.
}) => { }) => {
const [api, contextHolder] = notification.useNotification({ const [api, contextHolder] = notification.useNotification({
placement: "bottomRight", placement: "bottomRight",
@@ -36,7 +37,6 @@ export const NotificationProvider: FC<NotificationProviderProps> = ({
}); });
return ( return (
// @ts-ignore
<NotificationContext.Provider value={api}> <NotificationContext.Provider value={api}>
{/* contextHolder must be rendered in the DOM so notifications can appear */} {/* contextHolder must be rendered in the DOM so notifications can appear */}
{contextHolder} {contextHolder}

View File

@@ -3,6 +3,7 @@ import log from "electron-log/main";
import fs from "fs"; import fs from "fs";
import os from "os"; import os from "os";
import path from "path"; import path from "path";
import * as v8 from "v8";
import Store from "../main/store/store"; import Store from "../main/store/store";
/** /**
* Human-readable memory/cpu/resource snapshot. * Human-readable memory/cpu/resource snapshot.
@@ -39,6 +40,10 @@ export type MemoryUsageStats = {
}; };
// (merged into top import) // (merged into top import)
type GlobalWithGc = typeof globalThis & {
gc?: () => void;
};
/** /**
* Options for dumpMemoryStats. * Options for dumpMemoryStats.
*/ */
@@ -89,9 +94,11 @@ export async function dumpMemoryStats(
} = options; } = options;
// Allow GC if requested and available to get a cleaner snapshot // Allow GC if requested and available to get a cleaner snapshot
if (runGc && typeof (global as any).gc === "function") { const runtimeGlobal = globalThis as GlobalWithGc;
if (runGc && typeof runtimeGlobal.gc === "function") {
try { try {
(global as any).gc(); runtimeGlobal.gc();
} catch { } catch {
// ignore GC errors // ignore GC errors
} }
@@ -143,8 +150,6 @@ export async function dumpMemoryStats(
if (includeHeapSpaces) { if (includeHeapSpaces) {
try { try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const v8: typeof import("v8") = require("v8");
if (typeof v8.getHeapSpaceStatistics === "function") { if (typeof v8.getHeapSpaceStatistics === "function") {
stats.heapSpaces = v8.getHeapSpaceStatistics(); stats.heapSpaces = v8.getHeapSpaceStatistics();
} }
@@ -155,15 +160,13 @@ export async function dumpMemoryStats(
if (writeHeapSnapshot) { if (writeHeapSnapshot) {
try { try {
if (!runGc && typeof (global as any).gc === "function") { if (!runGc && typeof runtimeGlobal.gc === "function") {
try { try {
(global as any).gc(); runtimeGlobal.gc();
} catch { } catch {
/* ignore */ /* ignore */
} }
} }
// eslint-disable-next-line @typescript-eslint/no-var-requires
const v8: typeof import("v8") = require("v8");
if (typeof v8.writeHeapSnapshot === "function") { if (typeof v8.writeHeapSnapshot === "function") {
const baseDir = const baseDir =
heapSnapshotDir || path.dirname(log.transports.file.getFile().path); heapSnapshotDir || path.dirname(log.transports.file.getFile().path);