aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-01-09 22:16:29 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-01-09 22:17:26 +0100
commitfb7118ff1c8f0dcd61f15e51b193512283d83fa1 (patch)
tree721cee6a64b44a56b7f05f39750a65cda5fb4ef6
parentbuild: Add eslint-plugin-jest (diff)
downloadsophie-fb7118ff1c8f0dcd61f15e51b193512283d83fa1.tar.gz
sophie-fb7118ff1c8f0dcd61f15e51b193512283d83fa1.tar.zst
sophie-fb7118ff1c8f0dcd61f15e51b193512283d83fa1.zip
build: Add eslint-plugin-unicorn
Signed-off-by: Kristóf Marussy <kristof@marussy.com>
-rw-r--r--.electron-builder.config.cjs2
-rw-r--r--.eslintrc.cjs22
-rw-r--r--config/buildConstants.js10
-rw-r--r--config/fileURLToDirname.js10
-rw-r--r--config/fileUrlToDirname.js10
-rw-r--r--config/jest.config.base.js14
-rw-r--r--package.json3
-rw-r--r--packages/main/.eslintrc.cjs4
-rw-r--r--packages/main/esbuild.config.js8
-rw-r--r--packages/main/jest.config.js5
-rw-r--r--packages/main/src/controllers/__tests__/initConfig.spec.ts2
-rw-r--r--packages/main/src/controllers/initConfig.ts14
-rw-r--r--packages/main/src/devTools.ts3
-rw-r--r--packages/main/src/index.ts72
-rw-r--r--packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts24
-rw-r--r--packages/main/src/stores/Config.ts9
-rw-r--r--packages/main/src/utils/log.ts5
-rw-r--r--packages/preload/esbuild.config.js4
-rw-r--r--packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts12
-rw-r--r--packages/preload/src/contextBridge/createSophieRenderer.ts18
-rw-r--r--packages/renderer/src/components/BrowserViewPlaceholder.tsx6
-rw-r--r--packages/renderer/src/components/StoreProvider.tsx5
-rw-r--r--packages/renderer/src/index.tsx4
-rw-r--r--packages/renderer/src/stores/RendererStore.ts4
-rw-r--r--packages/renderer/vite.config.js10
-rw-r--r--packages/service-inject/esbuild.config.js4
-rw-r--r--packages/service-preload/esbuild.config.js4
-rw-r--r--packages/service-preload/src/index.ts4
-rw-r--r--packages/service-shared/esbuild.config.js4
-rw-r--r--packages/shared/esbuild.config.js4
-rw-r--r--scripts/build.js12
-rw-r--r--scripts/updateElectronVendors.js (renamed from scripts/update-electron-vendors.js)20
-rw-r--r--scripts/watch.js52
-rw-r--r--yarn.lock248
34 files changed, 454 insertions, 178 deletions
diff --git a/.electron-builder.config.cjs b/.electron-builder.config.cjs
index f406cc8..aa7d9e0 100644
--- a/.electron-builder.config.cjs
+++ b/.electron-builder.config.cjs
@@ -1,5 +1,3 @@
1// @ts-check
2
3const { Arch } = require('electron-builder'); 1const { Arch } = require('electron-builder');
4const { flipFuses, FuseV1Options, FuseVersion } = require('@electron/fuses'); 2const { flipFuses, FuseV1Options, FuseVersion } = require('@electron/fuses');
5const { join } = require('path'); 3const { join } = require('path');
diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 5bb3c21..e984179 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -12,6 +12,7 @@ module.exports = {
12 'plugin:jest/recommended', 12 'plugin:jest/recommended',
13 'plugin:jest/style', 13 'plugin:jest/style',
14 'plugin:prettier/recommended', 14 'plugin:prettier/recommended',
15 'plugin:unicorn/recommended',
15 ], 16 ],
16 env: { 17 env: {
17 es6: true, 18 es6: true,
@@ -51,6 +52,20 @@ module.exports = {
51 'newlines-between': 'always', 52 'newlines-between': 'always',
52 }, 53 },
53 ], 54 ],
55 // Allows files with names same as the name of their default export.
56 'unicorn/filename-case': [
57 'error',
58 {
59 cases: {
60 camelCase: true,
61 pascalCase: true,
62 },
63 },
64 ],
65 // Airbnb prefers forEach.
66 'unicorn/no-array-for-each': 'off',
67 // Common abbreviations are known and readable.
68 'unicorn/prevent-abbreviations': 'off',
54 }, 69 },
55 overrides: [ 70 overrides: [
56 { 71 {
@@ -120,5 +135,12 @@ module.exports = {
120 'import/no-relative-packages': 'off', 135 'import/no-relative-packages': 'off',
121 }, 136 },
122 }, 137 },
138 {
139 files: ['scripts/**/*.js'],
140 rules: {
141 // Scripts are allowed to `exit` abruptly.
142 'unicorn/no-process-exit': 'off',
143 },
144 },
123 ], 145 ],
124}; 146};
diff --git a/config/buildConstants.js b/config/buildConstants.js
index 3c55500..dfe2ab0 100644
--- a/config/buildConstants.js
+++ b/config/buildConstants.js
@@ -1,14 +1,14 @@
1import { readFileSync } from 'fs'; 1import { readFileSync } from 'node:fs';
2import { join } from 'path'; 2import path from 'node:path';
3 3
4import fileURLToDirname from './fileURLToDirname.js'; 4import fileUrlToDirname from './fileUrlToDirname.js';
5 5
6const thisDir = fileURLToDirname(import.meta.url); 6const thisDir = fileUrlToDirname(import.meta.url);
7 7
8// We import this from a vite config, where top-level await is not available (es2021), 8// We import this from a vite config, where top-level await is not available (es2021),
9// so we have to use the synchronous filesystem API. 9// so we have to use the synchronous filesystem API.
10const electronVendorsJson = readFileSync( 10const electronVendorsJson = readFileSync(
11 join(thisDir, '../.electron-vendors.cache.json'), 11 path.join(thisDir, '../.electron-vendors.cache.json'),
12 'utf8', 12 'utf8',
13); 13);
14 14
diff --git a/config/fileURLToDirname.js b/config/fileURLToDirname.js
deleted file mode 100644
index 70654cb..0000000
--- a/config/fileURLToDirname.js
+++ /dev/null
@@ -1,10 +0,0 @@
1import { dirname } from 'path';
2import { fileURLToPath } from 'url';
3
4/**
5 * @param {string} url
6 * @returns {string}
7 */
8export default function fileURLToDirname(url) {
9 return dirname(fileURLToPath(url));
10}
diff --git a/config/fileUrlToDirname.js b/config/fileUrlToDirname.js
new file mode 100644
index 0000000..9b51305
--- /dev/null
+++ b/config/fileUrlToDirname.js
@@ -0,0 +1,10 @@
1import path from 'node:path';
2import { fileURLToPath } from 'node:url';
3
4/**
5 * @param {string} url
6 * @returns {string}
7 */
8export default function fileUrlToDirname(url) {
9 return path.dirname(fileURLToPath(url));
10}
diff --git a/config/jest.config.base.js b/config/jest.config.base.js
index 21f93be..d9865f9 100644
--- a/config/jest.config.base.js
+++ b/config/jest.config.base.js
@@ -1,24 +1,24 @@
1import { join } from 'path'; 1import path from 'node:path';
2 2
3import fileURLToDirname from './fileURLToDirname.js'; 3import fileUrlToDirname from './fileUrlToDirname.js';
4 4
5const thisDir = fileURLToDirname(import.meta.url); 5const thisDir = fileUrlToDirname(import.meta.url);
6 6
7/** @type {import('@jest/types').Config.InitialOptions} */ 7/** @type {import('@jest/types').Config.InitialOptions} */
8export default { 8export default {
9 transform: { 9 transform: {
10 '\\.tsx?$': join(thisDir, 'jestEsbuildTransformer.js'), 10 '\\.tsx?$': path.join(thisDir, 'jestEsbuildTransformer.js'),
11 }, 11 },
12 extensionsToTreatAsEsm: ['.ts', '.tsx'], 12 extensionsToTreatAsEsm: ['.ts', '.tsx'],
13 moduleNameMapper: { 13 moduleNameMapper: {
14 '^@sophie/(.+)$': join(thisDir, '../packages/$1/src/index.ts'), 14 '^@sophie/(.+)$': path.join(thisDir, '../packages/$1/src/index.ts'),
15 '^(\\.{1,2}/.*)\\.jsx?$': '$1', 15 '^(\\.{1,2}/.*)\\.jsx?$': '$1',
16 // Workaround for jest to recognize the vendored dependencies of chalk. 16 // Workaround for jest to recognize the vendored dependencies of chalk.
17 '^#ansi-styles$': join( 17 '^#ansi-styles$': path.join(
18 thisDir, 18 thisDir,
19 '../node_modules/chalk/source/vendor/ansi-styles/index.js', 19 '../node_modules/chalk/source/vendor/ansi-styles/index.js',
20 ), 20 ),
21 '^#supports-color$': join( 21 '^#supports-color$': path.join(
22 thisDir, 22 thisDir,
23 '../node_modules/chalk/source/vendor/supports-color/index.js', 23 '../node_modules/chalk/source/vendor/supports-color/index.js',
24 ), 24 ),
diff --git a/package.json b/package.json
index 5515d3d..9944155 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
36 "g:typecheck": "cd $INIT_CWD && tsc", 36 "g:typecheck": "cd $INIT_CWD && tsc",
37 "types": "yarn workspaces foreach -vpt run types", 37 "types": "yarn workspaces foreach -vpt run types",
38 "g:types": "cd $INIT_CWD && tsc -b tsconfig.build.json", 38 "g:types": "cd $INIT_CWD && tsc -b tsconfig.build.json",
39 "update-electron-vendors": "node scripts/update-electron-vendors.js", 39 "update-electron-vendors": "node scripts/updateElectronVendors.js",
40 "main": "yarn workspace @sophie/main", 40 "main": "yarn workspace @sophie/main",
41 "preload": "yarn workspace @sophie/preload", 41 "preload": "yarn workspace @sophie/preload",
42 "renderer": "yarn workspace @sophie/renderer", 42 "renderer": "yarn workspace @sophie/renderer",
@@ -73,6 +73,7 @@
73 "eslint-plugin-prettier": "^4.0.0", 73 "eslint-plugin-prettier": "^4.0.0",
74 "eslint-plugin-react": "^7.28.0", 74 "eslint-plugin-react": "^7.28.0",
75 "eslint-plugin-react-hooks": "^4.3.0", 75 "eslint-plugin-react-hooks": "^4.3.0",
76 "eslint-plugin-unicorn": "^40.0.0",
76 "git-repo-info": "^2.1.1", 77 "git-repo-info": "^2.1.1",
77 "jest": "^27.4.7", 78 "jest": "^27.4.7",
78 "prettier": "^2.5.1", 79 "prettier": "^2.5.1",
diff --git a/packages/main/.eslintrc.cjs b/packages/main/.eslintrc.cjs
index 548ea34..cab227c 100644
--- a/packages/main/.eslintrc.cjs
+++ b/packages/main/.eslintrc.cjs
@@ -3,4 +3,8 @@ module.exports = {
3 node: true, 3 node: true,
4 browser: false, 4 browser: false,
5 }, 5 },
6 rules: {
7 // This is an application, so we're allowed to `exit` from it.
8 'unicorn/no-process-exit': 'off',
9 },
6}; 10};
diff --git a/packages/main/esbuild.config.js b/packages/main/esbuild.config.js
index d5f6f1e..ef0aa71 100644
--- a/packages/main/esbuild.config.js
+++ b/packages/main/esbuild.config.js
@@ -1,7 +1,7 @@
1import getRepoInfo from 'git-repo-info'; 1import getRepoInfo from 'git-repo-info';
2 2
3import { node } from '../../config/buildConstants.js'; 3import { node } from '../../config/buildConstants.js';
4import fileURLToDirname from '../../config/fileURLToDirname.js'; 4import fileUrlToDirname from '../../config/fileUrlToDirname.js';
5import getEsbuildConfig from '../../config/getEsbuildConfig.js'; 5import getEsbuildConfig from '../../config/getEsbuildConfig.js';
6 6
7const externalPackages = ['electron']; 7const externalPackages = ['electron'];
@@ -14,7 +14,7 @@ const gitInfo = getRepoInfo();
14 14
15export default getEsbuildConfig( 15export default getEsbuildConfig(
16 { 16 {
17 absWorkingDir: fileURLToDirname(import.meta.url), 17 absWorkingDir: fileUrlToDirname(import.meta.url),
18 entryPoints: ['src/index.ts'], 18 entryPoints: ['src/index.ts'],
19 outfile: 'dist/index.cjs', 19 outfile: 'dist/index.cjs',
20 format: 'cjs', 20 format: 'cjs',
@@ -23,9 +23,9 @@ export default getEsbuildConfig(
23 external: externalPackages, 23 external: externalPackages,
24 }, 24 },
25 { 25 {
26 VITE_DEV_SERVER_URL: process.env.VITE_DEV_SERVER_URL || null, 26 VITE_DEV_SERVER_URL: process.env.VITE_DEV_SERVER_URL || undefined,
27 GIT_SHA: gitInfo.abbreviatedSha, 27 GIT_SHA: gitInfo.abbreviatedSha,
28 GIT_BRANCH: gitInfo.branch, 28 GIT_BRANCH: gitInfo.branch,
29 BUILD_DATE: new Date().getTime(), 29 BUILD_DATE: Date.now(),
30 }, 30 },
31); 31);
diff --git a/packages/main/jest.config.js b/packages/main/jest.config.js
index b86463c..9aaf344 100644
--- a/packages/main/jest.config.js
+++ b/packages/main/jest.config.js
@@ -1,3 +1,4 @@
1import rootConfig from '../../config/jest.config.base.js'; 1import baseConfig from '../../config/jest.config.base.js';
2 2
3export default rootConfig; 3// eslint-disable-next-line unicorn/prefer-export-from -- Can't export from default.
4export default baseConfig;
diff --git a/packages/main/src/controllers/__tests__/initConfig.spec.ts b/packages/main/src/controllers/__tests__/initConfig.spec.ts
index 9a5f85e..11e7690 100644
--- a/packages/main/src/controllers/__tests__/initConfig.spec.ts
+++ b/packages/main/src/controllers/__tests__/initConfig.spec.ts
@@ -133,7 +133,7 @@ describe('when it has loaded the config', () => {
133 }); 133 });
134 134
135 it('should throttle saving changes to the config file', () => { 135 it('should throttle saving changes to the config file', () => {
136 mocked(persistenceService.writeConfig).mockResolvedValue(undefined); 136 mocked(persistenceService.writeConfig).mockResolvedValue();
137 config.setThemeSource('dark'); 137 config.setThemeSource('dark');
138 jest.advanceTimersByTime(lessThanThrottleMs); 138 jest.advanceTimersByTime(lessThanThrottleMs);
139 config.setThemeSource('light'); 139 config.setThemeSource('light');
diff --git a/packages/main/src/controllers/initConfig.ts b/packages/main/src/controllers/initConfig.ts
index e83b8da..915f451 100644
--- a/packages/main/src/controllers/initConfig.ts
+++ b/packages/main/src/controllers/initConfig.ts
@@ -38,7 +38,7 @@ export default async function initConfig(
38): Promise<Disposer> { 38): Promise<Disposer> {
39 log.trace('Initializing config controller'); 39 log.trace('Initializing config controller');
40 40
41 let lastSnapshotOnDisk: ConfigSnapshotOut | null = null; 41 let lastSnapshotOnDisk: ConfigSnapshotOut | undefined;
42 42
43 async function readConfig(): Promise<boolean> { 43 async function readConfig(): Promise<boolean> {
44 const result = await persistenceService.readConfig(); 44 const result = await persistenceService.readConfig();
@@ -46,8 +46,8 @@ export default async function initConfig(
46 try { 46 try {
47 applySnapshot(config, result.data); 47 applySnapshot(config, result.data);
48 lastSnapshotOnDisk = getSnapshot(config); 48 lastSnapshotOnDisk = getSnapshot(config);
49 } catch (err) { 49 } catch (error) {
50 log.error('Failed to apply config snapshot', result.data, err); 50 log.error('Failed to apply config snapshot', result.data, error);
51 } 51 }
52 } 52 }
53 return result.found; 53 return result.found;
@@ -70,8 +70,8 @@ export default async function initConfig(
70 debounce((snapshot) => { 70 debounce((snapshot) => {
71 // We can compare snapshots by reference, since it is only recreated on store changes. 71 // We can compare snapshots by reference, since it is only recreated on store changes.
72 if (lastSnapshotOnDisk !== snapshot) { 72 if (lastSnapshotOnDisk !== snapshot) {
73 writeConfig().catch((err) => { 73 writeConfig().catch((error) => {
74 log.error('Failed to write config on config change', err); 74 log.error('Failed to write config on config change', error);
75 }); 75 });
76 } 76 }
77 }, debounceTime), 77 }, debounceTime),
@@ -80,8 +80,8 @@ export default async function initConfig(
80 const disposeWatcher = persistenceService.watchConfig(async () => { 80 const disposeWatcher = persistenceService.watchConfig(async () => {
81 try { 81 try {
82 await readConfig(); 82 await readConfig();
83 } catch (err) { 83 } catch (error) {
84 log.error('Failed to read config', err); 84 log.error('Failed to read config', error);
85 } 85 }
86 }, debounceTime); 86 }, debounceTime);
87 87
diff --git a/packages/main/src/devTools.ts b/packages/main/src/devTools.ts
index 69f1514..4ca1bf3 100644
--- a/packages/main/src/devTools.ts
+++ b/packages/main/src/devTools.ts
@@ -49,7 +49,8 @@ export async function installDevToolsExtensions(): Promise<void> {
49 /* eslint-disable-next-line 49 /* eslint-disable-next-line
50 import/no-extraneous-dependencies, 50 import/no-extraneous-dependencies,
51 global-require, 51 global-require,
52 @typescript-eslint/no-var-requires 52 @typescript-eslint/no-var-requires,
53 unicorn/prefer-module
53 */ 54 */
54 } = require('electron-devtools-installer') as typeof import('electron-devtools-installer'); 55 } = require('electron-devtools-installer') as typeof import('electron-devtools-installer');
55 await installExtension([REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS], { 56 await installExtension([REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS], {
diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts
index 1f80e44..02e6cda 100644
--- a/packages/main/src/index.ts
+++ b/packages/main/src/index.ts
@@ -19,9 +19,9 @@
19 * SPDX-License-Identifier: AGPL-3.0-only 19 * SPDX-License-Identifier: AGPL-3.0-only
20 */ 20 */
21 21
22import { arch } from 'os'; 22import { arch } from 'node:os';
23import { join } from 'path'; 23import path from 'node:path';
24import { URL } from 'url'; 24import { URL } from 'node:url';
25 25
26import { 26import {
27 ServiceToMainIpcMessage, 27 ServiceToMainIpcMessage,
@@ -101,11 +101,14 @@ app.setAboutPanelOptions({
101 version: '', 101 version: '',
102}); 102});
103 103
104// eslint-disable-next-line unicorn/prefer-module -- Electron apps run in a commonjs environment.
105const thisDir = __dirname;
106
104function getResourcePath(relativePath: string): string { 107function getResourcePath(relativePath: string): string {
105 return join(__dirname, relativePath); 108 return path.join(thisDir, relativePath);
106} 109}
107 110
108const baseUrl = `file://${__dirname}`; 111const baseUrl = `file://${thisDir}`;
109function getResourceUrl(relativePath: string): string { 112function getResourceUrl(relativePath: string): string {
110 return new URL(relativePath, baseUrl).toString(); 113 return new URL(relativePath, baseUrl).toString();
111} 114}
@@ -117,15 +120,15 @@ const serviceInject: WebSource = {
117 url: getResourceUrl(serviceInjectRelativePath), 120 url: getResourceUrl(serviceInjectRelativePath),
118}; 121};
119 122
120let mainWindow: BrowserWindow | null = null; 123let mainWindow: BrowserWindow | undefined;
121 124
122const store = createMainStore(); 125const store = createMainStore();
123init(store) 126init(store)
124 .then((disposeCompositionRoot) => { 127 .then((disposeCompositionRoot) => {
125 app.on('will-quit', disposeCompositionRoot); 128 app.on('will-quit', disposeCompositionRoot);
126 }) 129 })
127 .catch((err) => { 130 .catch((error) => {
128 log.log('Failed to initialize application', err); 131 log.log('Failed to initialize application', error);
129 }); 132 });
130 133
131const rendererBaseUrl = getResourceUrl('../renderer/'); 134const rendererBaseUrl = getResourceUrl('../renderer/');
@@ -136,7 +139,7 @@ function shouldCancelMainWindowRequest(url: string, method: string): boolean {
136 let normalizedUrl: string; 139 let normalizedUrl: string;
137 try { 140 try {
138 normalizedUrl = new URL(url).toString(); 141 normalizedUrl = new URL(url).toString();
139 } catch (_err) { 142 } catch {
140 return true; 143 return true;
141 } 144 }
142 if (isDevelopment) { 145 if (isDevelopment) {
@@ -233,7 +236,7 @@ async function createWindow(): Promise<unknown> {
233 'from webContents', 236 'from webContents',
234 event.sender.id, 237 event.sender.id,
235 ); 238 );
236 return null; 239 throw new Error('Invalid IPC call');
237 } 240 }
238 return getSnapshot(store.shared); 241 return getSnapshot(store.shared);
239 }); 242 });
@@ -262,22 +265,22 @@ async function createWindow(): Promise<unknown> {
262 .then((data) => { 265 .then((data) => {
263 serviceInject.code = data; 266 serviceInject.code = data;
264 }) 267 })
265 .catch((err) => { 268 .catch((error) => {
266 log.error('Error while reloading', serviceInjectPath, err); 269 log.error('Error while reloading', serviceInjectPath, error);
267 }) 270 })
268 .then(() => { 271 .then(() => {
269 browserView.webContents.reload(); 272 browserView.webContents.reload();
270 }) 273 })
271 .catch((err) => { 274 .catch((error) => {
272 log.error('Failed to reload browserView', err); 275 log.error('Failed to reload browserView', error);
273 }); 276 });
274 break; 277 break;
275 default: 278 default:
276 log.error('Unexpected action from UI renderer:', actionToDispatch); 279 log.error('Unexpected action from UI renderer:', actionToDispatch);
277 break; 280 break;
278 } 281 }
279 } catch (err) { 282 } catch (error) {
280 log.error('Error while dispatching renderer action', rawAction, err); 283 log.error('Error while dispatching renderer action', rawAction, error);
281 } 284 }
282 }); 285 });
283 286
@@ -285,9 +288,18 @@ async function createWindow(): Promise<unknown> {
285 webContents.send(MainToRendererIpcMessage.SharedStorePatch, patch); 288 webContents.send(MainToRendererIpcMessage.SharedStorePatch, patch);
286 }); 289 });
287 290
288 ipcMain.handle(ServiceToMainIpcMessage.ApiExposedInMainWorld, (event) => 291 ipcMain.handle(ServiceToMainIpcMessage.ApiExposedInMainWorld, (event) => {
289 event.sender.id === browserView.webContents.id ? serviceInject : null, 292 if (event.sender.id !== browserView.webContents.id) {
290 ); 293 log.warn(
294 'Unexpected',
295 ServiceToMainIpcMessage.ApiExposedInMainWorld,
296 'from webContents',
297 event.sender.id,
298 );
299 throw new Error('Invalid IPC call');
300 }
301 return serviceInject;
302 });
291 303
292 browserView.webContents.on('ipc-message', (_event, channel, ...args) => { 304 browserView.webContents.on('ipc-message', (_event, channel, ...args) => {
293 try { 305 try {
@@ -303,8 +315,8 @@ async function createWindow(): Promise<unknown> {
303 log.error('Unknown IPC message:', channel, args); 315 log.error('Unknown IPC message:', channel, args);
304 break; 316 break;
305 } 317 }
306 } catch (err) { 318 } catch (error) {
307 log.error('Error while processing IPC message:', channel, args, err); 319 log.error('Error while processing IPC message:', channel, args, error);
308 } 320 }
309 }); 321 });
310 322
@@ -316,9 +328,7 @@ async function createWindow(): Promise<unknown> {
316 328
317 browserView.webContents.session.webRequest.onBeforeSendHeaders( 329 browserView.webContents.session.webRequest.onBeforeSendHeaders(
318 ({ url, requestHeaders }, callback) => { 330 ({ url, requestHeaders }, callback) => {
319 const requestUserAgent = url.match( 331 const requestUserAgent = /^[^:]+:\/\/accounts\.google\.[^./]+\//.test(url)
320 /^[^:]+:\/\/accounts\.google\.[^./]+\//,
321 )
322 ? chromelessUserAgent 332 ? chromelessUserAgent
323 : userAgent; 333 : userAgent;
324 callback({ 334 callback({
@@ -332,15 +342,15 @@ async function createWindow(): Promise<unknown> {
332 342
333 browserView.webContents 343 browserView.webContents
334 .loadURL('https://gitlab.com/say-hi-to-sophie/sophie') 344 .loadURL('https://gitlab.com/say-hi-to-sophie/sophie')
335 .catch((err) => { 345 .catch((error) => {
336 log.error('Failed to load browser', err); 346 log.error('Failed to load browser', error);
337 }); 347 });
338 348
339 return mainWindow.loadURL(pageUrl); 349 return mainWindow.loadURL(pageUrl);
340} 350}
341 351
342app.on('second-instance', () => { 352app.on('second-instance', () => {
343 if (mainWindow !== null) { 353 if (mainWindow !== undefined) {
344 if (!mainWindow.isVisible()) { 354 if (!mainWindow.isVisible()) {
345 mainWindow.show(); 355 mainWindow.show();
346 } 356 }
@@ -363,14 +373,14 @@ app
363 if (isDevelopment) { 373 if (isDevelopment) {
364 try { 374 try {
365 await installDevToolsExtensions(); 375 await installDevToolsExtensions();
366 } catch (err) { 376 } catch (error) {
367 log.error('Failed to install devtools extensions', err); 377 log.error('Failed to install devtools extensions', error);
368 } 378 }
369 } 379 }
370 380
371 return createWindow(); 381 return createWindow();
372 }) 382 })
373 .catch((err) => { 383 .catch((error) => {
374 log.error('Failed to create window', err); 384 log.error('Failed to create window', error);
375 process.exit(1); 385 process.exit(1);
376 }); 386 });
diff --git a/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts b/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts
index e92f706..a11a9da 100644
--- a/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts
+++ b/packages/main/src/services/impl/ConfigPersistenceServiceImpl.ts
@@ -17,9 +17,9 @@
17 * 17 *
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20import { watch } from 'fs'; 20import { watch } from 'node:fs';
21import { readFile, stat, writeFile } from 'fs/promises'; 21import { readFile, stat, writeFile } from 'node:fs/promises';
22import { join } from 'path'; 22import path from 'node:path';
23 23
24import JSON5 from 'json5'; 24import JSON5 from 'json5';
25import throttle from 'lodash-es/throttle'; 25import throttle from 'lodash-es/throttle';
@@ -39,26 +39,26 @@ export default class ConfigPersistenceServiceImpl
39 39
40 private writingConfig = false; 40 private writingConfig = false;
41 41
42 private timeLastWritten: Date | null = null; 42 private timeLastWritten: Date | undefined;
43 43
44 constructor( 44 constructor(
45 private readonly userDataDir: string, 45 private readonly userDataDir: string,
46 private readonly configFileName: string = 'config.json5', 46 private readonly configFileName: string = 'config.json5',
47 ) { 47 ) {
48 this.configFileName = configFileName; 48 this.configFileName = configFileName;
49 this.configFilePath = join(this.userDataDir, this.configFileName); 49 this.configFilePath = path.join(this.userDataDir, this.configFileName);
50 } 50 }
51 51
52 async readConfig(): Promise<ReadConfigResult> { 52 async readConfig(): Promise<ReadConfigResult> {
53 let configStr; 53 let configStr;
54 try { 54 try {
55 configStr = await readFile(this.configFilePath, 'utf8'); 55 configStr = await readFile(this.configFilePath, 'utf8');
56 } catch (err) { 56 } catch (error) {
57 if ((err as NodeJS.ErrnoException).code === 'ENOENT') { 57 if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
58 log.debug('Config file', this.configFilePath, 'was not found'); 58 log.debug('Config file', this.configFilePath, 'was not found');
59 return { found: false }; 59 return { found: false };
60 } 60 }
61 throw err; 61 throw error;
62 } 62 }
63 log.info('Read config file', this.configFilePath); 63 log.info('Read config file', this.configFilePath);
64 return { 64 return {
@@ -92,8 +92,8 @@ export default class ConfigPersistenceServiceImpl
92 const stats = await stat(this.configFilePath); 92 const stats = await stat(this.configFilePath);
93 mtime = stats.mtime; 93 mtime = stats.mtime;
94 log.trace('Config file last modified at', mtime); 94 log.trace('Config file last modified at', mtime);
95 } catch (err) { 95 } catch (error) {
96 if ((err as NodeJS.ErrnoException).code === 'ENOENT') { 96 if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
97 log.debug( 97 log.debug(
98 'Config file', 98 'Config file',
99 this.configFilePath, 99 this.configFilePath,
@@ -101,11 +101,11 @@ export default class ConfigPersistenceServiceImpl
101 ); 101 );
102 return; 102 return;
103 } 103 }
104 throw err; 104 throw error;
105 } 105 }
106 if ( 106 if (
107 !this.writingConfig && 107 !this.writingConfig &&
108 (this.timeLastWritten === null || mtime > this.timeLastWritten) 108 (this.timeLastWritten === undefined || mtime > this.timeLastWritten)
109 ) { 109 ) {
110 log.debug( 110 log.debug(
111 'Found a config file modified at', 111 'Found a config file modified at',
diff --git a/packages/main/src/stores/Config.ts b/packages/main/src/stores/Config.ts
index 06dbdeb..ca90c0c 100644
--- a/packages/main/src/stores/Config.ts
+++ b/packages/main/src/stores/Config.ts
@@ -18,12 +18,7 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { 21import { config as originalConfig, ThemeSource } from '@sophie/shared';
22 config as originalConfig,
23 ConfigSnapshotIn,
24 ConfigSnapshotOut,
25 ThemeSource,
26} from '@sophie/shared';
27import { Instance } from 'mobx-state-tree'; 22import { Instance } from 'mobx-state-tree';
28 23
29export const config = originalConfig.actions((self) => ({ 24export const config = originalConfig.actions((self) => ({
@@ -34,4 +29,4 @@ export const config = originalConfig.actions((self) => ({
34 29
35export interface Config extends Instance<typeof config> {} 30export interface Config extends Instance<typeof config> {}
36 31
37export type { ConfigSnapshotIn, ConfigSnapshotOut }; 32export type { ConfigSnapshotIn, ConfigSnapshotOut } from '@sophie/shared';
diff --git a/packages/main/src/utils/log.ts b/packages/main/src/utils/log.ts
index 5218721..0a632d8 100644
--- a/packages/main/src/utils/log.ts
+++ b/packages/main/src/utils/log.ts
@@ -18,8 +18,9 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21// eslint-disable-next-line unicorn/import-style -- Import the type `ChalkInstance` separately.
21import chalk, { ChalkInstance } from 'chalk'; 22import chalk, { ChalkInstance } from 'chalk';
22import loglevel, { Logger } from 'loglevel'; 23import loglevel from 'loglevel';
23import prefix from 'loglevel-plugin-prefix'; 24import prefix from 'loglevel-plugin-prefix';
24 25
25if (import.meta.env?.DEV) { 26if (import.meta.env?.DEV) {
@@ -54,7 +55,7 @@ prefix.apply(loglevel, {
54 }, 55 },
55}); 56});
56 57
57export function getLogger(loggerName: string): Logger { 58export function getLogger(loggerName: string): loglevel.Logger {
58 return loglevel.getLogger(loggerName); 59 return loglevel.getLogger(loggerName);
59} 60}
60 61
diff --git a/packages/preload/esbuild.config.js b/packages/preload/esbuild.config.js
index d888987..87e91d8 100644
--- a/packages/preload/esbuild.config.js
+++ b/packages/preload/esbuild.config.js
@@ -1,9 +1,9 @@
1import { chrome } from '../../config/buildConstants.js'; 1import { chrome } from '../../config/buildConstants.js';
2import fileURLToDirname from '../../config/fileURLToDirname.js'; 2import fileUrlToDirname from '../../config/fileUrlToDirname.js';
3import getEsbuildConfig from '../../config/getEsbuildConfig.js'; 3import getEsbuildConfig from '../../config/getEsbuildConfig.js';
4 4
5export default getEsbuildConfig({ 5export default getEsbuildConfig({
6 absWorkingDir: fileURLToDirname(import.meta.url), 6 absWorkingDir: fileUrlToDirname(import.meta.url),
7 entryPoints: ['src/index.ts'], 7 entryPoints: ['src/index.ts'],
8 outfile: 'dist/index.cjs', 8 outfile: 'dist/index.cjs',
9 format: 'cjs', 9 format: 'cjs',
diff --git a/packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts b/packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts
index b0af280..88b0077 100644
--- a/packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts
+++ b/packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts
@@ -45,7 +45,7 @@ const { default: createSophieRenderer } = await import(
45); 45);
46 46
47const event: Electron.IpcRendererEvent = 47const event: Electron.IpcRendererEvent =
48 null as unknown as Electron.IpcRendererEvent; 48 undefined as unknown as Electron.IpcRendererEvent;
49 49
50const snapshot: SharedStoreSnapshotIn = { 50const snapshot: SharedStoreSnapshotIn = {
51 shouldUseDarkColors: true, 51 shouldUseDarkColors: true,
@@ -183,7 +183,7 @@ describe('SharedStoreConnector', () => {
183 183
184 it('should catch listener errors', () => { 184 it('should catch listener errors', () => {
185 mocked(listener.onPatch).mockImplementation(() => { 185 mocked(listener.onPatch).mockImplementation(() => {
186 throw new Error(); 186 throw new Error('listener error');
187 }); 187 });
188 expect(() => onSharedStorePatch(event, patch)).not.toThrow(); 188 expect(() => onSharedStorePatch(event, patch)).not.toThrow();
189 }); 189 });
@@ -193,7 +193,7 @@ describe('SharedStoreConnector', () => {
193 describe('after the listener threw in onPatch', () => { 193 describe('after the listener threw in onPatch', () => {
194 beforeEach(() => { 194 beforeEach(() => {
195 mocked(listener.onPatch).mockImplementation(() => { 195 mocked(listener.onPatch).mockImplementation(() => {
196 throw new Error(); 196 throw new Error('listener error');
197 }); 197 });
198 onSharedStorePatch(event, patch); 198 onSharedStorePatch(event, patch);
199 listener.onPatch.mockRestore(); 199 listener.onPatch.mockRestore();
@@ -205,7 +205,9 @@ describe('SharedStoreConnector', () => {
205 205
206 describe('when a listener failed to register due to IPC error', () => { 206 describe('when a listener failed to register due to IPC error', () => {
207 beforeEach(async () => { 207 beforeEach(async () => {
208 mocked(ipcRenderer.invoke).mockRejectedValue(new Error()); 208 mocked(ipcRenderer.invoke).mockRejectedValue(
209 new Error('ipcRenderer error'),
210 );
209 try { 211 try {
210 await sut.onSharedStoreChange(listener); 212 await sut.onSharedStoreChange(listener);
211 } catch { 213 } catch {
@@ -237,7 +239,7 @@ describe('SharedStoreConnector', () => {
237 beforeEach(async () => { 239 beforeEach(async () => {
238 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot); 240 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot);
239 mocked(listener.onSnapshot).mockImplementation(() => { 241 mocked(listener.onSnapshot).mockImplementation(() => {
240 throw new Error(); 242 throw new Error('listener error');
241 }); 243 });
242 try { 244 try {
243 await sut.onSharedStoreChange(listener); 245 await sut.onSharedStoreChange(listener);
diff --git a/packages/preload/src/contextBridge/createSophieRenderer.ts b/packages/preload/src/contextBridge/createSophieRenderer.ts
index b97503d..3174fed 100644
--- a/packages/preload/src/contextBridge/createSophieRenderer.ts
+++ b/packages/preload/src/contextBridge/createSophieRenderer.ts
@@ -34,7 +34,7 @@ import type { IJsonPatch } from 'mobx-state-tree';
34class SharedStoreConnector { 34class SharedStoreConnector {
35 private onSharedStoreChangeCalled = false; 35 private onSharedStoreChangeCalled = false;
36 36
37 private listener: SharedStoreListener | null = null; 37 private listener: SharedStoreListener | undefined;
38 38
39 constructor(private readonly allowReplaceListener: boolean) { 39 constructor(private readonly allowReplaceListener: boolean) {
40 ipcRenderer.on( 40 ipcRenderer.on(
@@ -43,9 +43,9 @@ class SharedStoreConnector {
43 try { 43 try {
44 // `mobx-state-tree` will validate the patch, so we can safely cast here. 44 // `mobx-state-tree` will validate the patch, so we can safely cast here.
45 this.listener?.onPatch(patch as IJsonPatch); 45 this.listener?.onPatch(patch as IJsonPatch);
46 } catch (err) { 46 } catch (error) {
47 log.error('Shared store listener onPatch failed', err); 47 log.error('Shared store listener onPatch failed', error);
48 this.listener = null; 48 this.listener = undefined;
49 } 49 }
50 }, 50 },
51 ); 51 );
@@ -57,14 +57,14 @@ class SharedStoreConnector {
57 } 57 }
58 this.onSharedStoreChangeCalled = true; 58 this.onSharedStoreChangeCalled = true;
59 let success = false; 59 let success = false;
60 let snapshot: unknown | null = null; 60 let snapshot: unknown;
61 try { 61 try {
62 snapshot = await ipcRenderer.invoke( 62 snapshot = await ipcRenderer.invoke(
63 RendererToMainIpcMessage.GetSharedStoreSnapshot, 63 RendererToMainIpcMessage.GetSharedStoreSnapshot,
64 ); 64 );
65 success = true; 65 success = true;
66 } catch (err) { 66 } catch (error) {
67 log.error('Failed to get initial shared store snapshot', err); 67 log.error('Failed to get initial shared store snapshot', error);
68 } 68 }
69 if (success) { 69 if (success) {
70 if (sharedStore.is(snapshot)) { 70 if (sharedStore.is(snapshot)) {
@@ -84,10 +84,10 @@ function dispatchAction(actionToDispatch: Action): void {
84 const parsedAction = action.parse(actionToDispatch); 84 const parsedAction = action.parse(actionToDispatch);
85 try { 85 try {
86 ipcRenderer.send(RendererToMainIpcMessage.DispatchAction, parsedAction); 86 ipcRenderer.send(RendererToMainIpcMessage.DispatchAction, parsedAction);
87 } catch (err) { 87 } catch (error) {
88 // Do not leak IPC failure details into the main world. 88 // Do not leak IPC failure details into the main world.
89 const message = 'Failed to dispatch action'; 89 const message = 'Failed to dispatch action';
90 log.error(message, actionToDispatch, err); 90 log.error(message, actionToDispatch, error);
91 throw new Error(message); 91 throw new Error(message);
92 } 92 }
93} 93}
diff --git a/packages/renderer/src/components/BrowserViewPlaceholder.tsx b/packages/renderer/src/components/BrowserViewPlaceholder.tsx
index 8f055e7..58407ee 100644
--- a/packages/renderer/src/components/BrowserViewPlaceholder.tsx
+++ b/packages/renderer/src/components/BrowserViewPlaceholder.tsx
@@ -44,15 +44,15 @@ export default observer(() => {
44 [store], 44 [store],
45 ); 45 );
46 46
47 const resizeObserverRef = useRef<ResizeObserver | null>(null); 47 const resizeObserverRef = useRef<ResizeObserver | undefined>();
48 48
49 const ref = useCallback( 49 const ref = useCallback(
50 (element: HTMLElement | null) => { 50 (element: HTMLElement | null) => {
51 if (resizeObserverRef.current !== null) { 51 if (resizeObserverRef.current !== undefined) {
52 resizeObserverRef.current.disconnect(); 52 resizeObserverRef.current.disconnect();
53 } 53 }
54 if (element === null) { 54 if (element === null) {
55 resizeObserverRef.current = null; 55 resizeObserverRef.current = undefined;
56 return; 56 return;
57 } 57 }
58 resizeObserverRef.current = new ResizeObserver(onResize); 58 resizeObserverRef.current = new ResizeObserver(onResize);
diff --git a/packages/renderer/src/components/StoreProvider.tsx b/packages/renderer/src/components/StoreProvider.tsx
index bb8495c..3360a43 100644
--- a/packages/renderer/src/components/StoreProvider.tsx
+++ b/packages/renderer/src/components/StoreProvider.tsx
@@ -22,11 +22,12 @@ import React, { createContext, useContext } from 'react';
22 22
23import type { RendererStore } from '../stores/RendererStore'; 23import type { RendererStore } from '../stores/RendererStore';
24 24
25const StoreContext = createContext<RendererStore | null>(null); 25// eslint-disable-next-line unicorn/no-useless-undefined -- `createContext` expects 1 parameter.
26const StoreContext = createContext<RendererStore | undefined>(undefined);
26 27
27export function useStore(): RendererStore { 28export function useStore(): RendererStore {
28 const store = useContext(StoreContext); 29 const store = useContext(StoreContext);
29 if (store === null) { 30 if (store === undefined) {
30 throw new Error('useStore can only be called inside of StoreProvider'); 31 throw new Error('useStore can only be called inside of StoreProvider');
31 } 32 }
32 return store; 33 return store;
diff --git a/packages/renderer/src/index.tsx b/packages/renderer/src/index.tsx
index d900e50..a42a30c 100644
--- a/packages/renderer/src/index.tsx
+++ b/packages/renderer/src/index.tsx
@@ -45,8 +45,8 @@ if (isDevelopment) {
45const store = createAndConnectRendererStore(window.sophieRenderer); 45const store = createAndConnectRendererStore(window.sophieRenderer);
46 46
47if (isDevelopment) { 47if (isDevelopment) {
48 exposeToReduxDevtools(store).catch((err) => { 48 exposeToReduxDevtools(store).catch((error) => {
49 log.error('Cannot initialize redux devtools', err); 49 log.error('Cannot initialize redux devtools', error);
50 }); 50 });
51} 51}
52 52
diff --git a/packages/renderer/src/stores/RendererStore.ts b/packages/renderer/src/stores/RendererStore.ts
index 0b78ce1..4cc5163 100644
--- a/packages/renderer/src/stores/RendererStore.ts
+++ b/packages/renderer/src/stores/RendererStore.ts
@@ -86,8 +86,8 @@ export function createAndConnectRendererStore(
86 applyPatch(store.shared, patch); 86 applyPatch(store.shared, patch);
87 }, 87 },
88 }) 88 })
89 .catch((err) => { 89 .catch((error) => {
90 log.error('Failed to connect to shared store', err); 90 log.error('Failed to connect to shared store', error);
91 }); 91 });
92 92
93 return store; 93 return store;
diff --git a/packages/renderer/vite.config.js b/packages/renderer/vite.config.js
index e20e0f1..cb0203c 100644
--- a/packages/renderer/vite.config.js
+++ b/packages/renderer/vite.config.js
@@ -1,15 +1,15 @@
1/* eslint-disable no-process-env */ 1/* eslint-disable no-process-env */
2/* eslint-env node */ 2/* eslint-env node */
3 3
4import { builtinModules } from 'module'; 4import { builtinModules } from 'node:module';
5import { join } from 'path'; 5import path from 'node:path';
6 6
7import react from '@vitejs/plugin-react'; 7import react from '@vitejs/plugin-react';
8 8
9import { banner, chrome } from '../../config/buildConstants.js'; 9import { banner, chrome } from '../../config/buildConstants.js';
10import fileURLToDirname from '../../config/fileURLToDirname.js'; 10import fileUrlToDirname from '../../config/fileUrlToDirname.js';
11 11
12const thisDir = fileURLToDirname(import.meta.url); 12const thisDir = fileUrlToDirname(import.meta.url);
13 13
14const mode = process.env.MODE || 'development'; 14const mode = process.env.MODE || 'development';
15 15
@@ -24,7 +24,7 @@ export default {
24 logLevel: 'info', 24 logLevel: 'info',
25 mode, 25 mode,
26 root: thisDir, 26 root: thisDir,
27 cacheDir: join(thisDir, '../../.vite'), 27 cacheDir: path.join(thisDir, '../../.vite'),
28 plugins: [ 28 plugins: [
29 react({ 29 react({
30 babel: { 30 babel: {
diff --git a/packages/service-inject/esbuild.config.js b/packages/service-inject/esbuild.config.js
index 795b0f6..d8698ac 100644
--- a/packages/service-inject/esbuild.config.js
+++ b/packages/service-inject/esbuild.config.js
@@ -1,9 +1,9 @@
1import { chrome } from '../../config/buildConstants.js'; 1import { chrome } from '../../config/buildConstants.js';
2import fileURLToDirname from '../../config/fileURLToDirname.js'; 2import fileUrlToDirname from '../../config/fileUrlToDirname.js';
3import getEsbuildConfig from '../../config/getEsbuildConfig.js'; 3import getEsbuildConfig from '../../config/getEsbuildConfig.js';
4 4
5export default getEsbuildConfig({ 5export default getEsbuildConfig({
6 absWorkingDir: fileURLToDirname(import.meta.url), 6 absWorkingDir: fileUrlToDirname(import.meta.url),
7 entryPoints: ['src/index.ts'], 7 entryPoints: ['src/index.ts'],
8 outfile: 'dist/index.js', 8 outfile: 'dist/index.js',
9 format: 'iife', 9 format: 'iife',
diff --git a/packages/service-preload/esbuild.config.js b/packages/service-preload/esbuild.config.js
index d888987..87e91d8 100644
--- a/packages/service-preload/esbuild.config.js
+++ b/packages/service-preload/esbuild.config.js
@@ -1,9 +1,9 @@
1import { chrome } from '../../config/buildConstants.js'; 1import { chrome } from '../../config/buildConstants.js';
2import fileURLToDirname from '../../config/fileURLToDirname.js'; 2import fileUrlToDirname from '../../config/fileUrlToDirname.js';
3import getEsbuildConfig from '../../config/getEsbuildConfig.js'; 3import getEsbuildConfig from '../../config/getEsbuildConfig.js';
4 4
5export default getEsbuildConfig({ 5export default getEsbuildConfig({
6 absWorkingDir: fileURLToDirname(import.meta.url), 6 absWorkingDir: fileUrlToDirname(import.meta.url),
7 entryPoints: ['src/index.ts'], 7 entryPoints: ['src/index.ts'],
8 outfile: 'dist/index.cjs', 8 outfile: 'dist/index.cjs',
9 format: 'cjs', 9 format: 'cjs',
diff --git a/packages/service-preload/src/index.ts b/packages/service-preload/src/index.ts
index 2bbfefd..bb4a62d 100644
--- a/packages/service-preload/src/index.ts
+++ b/packages/service-preload/src/index.ts
@@ -61,6 +61,6 @@ async function fetchAndExecuteInjectScript(): Promise<void> {
61 await webFrame.executeJavaScriptInIsolatedWorld(0, [injectSource]); 61 await webFrame.executeJavaScriptInIsolatedWorld(0, [injectSource]);
62} 62}
63 63
64fetchAndExecuteInjectScript().catch((err) => { 64fetchAndExecuteInjectScript().catch((error) => {
65 log.error('Failed to fetch inject source:', err); 65 log.error('Failed to fetch inject source:', error);
66}); 66});
diff --git a/packages/service-shared/esbuild.config.js b/packages/service-shared/esbuild.config.js
index 2b0dec8..62e3d2a 100644
--- a/packages/service-shared/esbuild.config.js
+++ b/packages/service-shared/esbuild.config.js
@@ -1,9 +1,9 @@
1import { chrome, node } from '../../config/buildConstants.js'; 1import { chrome, node } from '../../config/buildConstants.js';
2import fileURLToDirname from '../../config/fileURLToDirname.js'; 2import fileUrlToDirname from '../../config/fileUrlToDirname.js';
3import getEsbuildConfig from '../../config/getEsbuildConfig.js'; 3import getEsbuildConfig from '../../config/getEsbuildConfig.js';
4 4
5export default getEsbuildConfig({ 5export default getEsbuildConfig({
6 absWorkingDir: fileURLToDirname(import.meta.url), 6 absWorkingDir: fileUrlToDirname(import.meta.url),
7 entryPoints: ['src/index.ts'], 7 entryPoints: ['src/index.ts'],
8 outfile: 'dist/index.mjs', 8 outfile: 'dist/index.mjs',
9 format: 'esm', 9 format: 'esm',
diff --git a/packages/shared/esbuild.config.js b/packages/shared/esbuild.config.js
index 44501bd..7a79ce6 100644
--- a/packages/shared/esbuild.config.js
+++ b/packages/shared/esbuild.config.js
@@ -1,9 +1,9 @@
1import { chrome, node } from '../../config/buildConstants.js'; 1import { chrome, node } from '../../config/buildConstants.js';
2import fileURLToDirname from '../../config/fileURLToDirname.js'; 2import fileUrlToDirname from '../../config/fileUrlToDirname.js';
3import getEsbuildConfig from '../../config/getEsbuildConfig.js'; 3import getEsbuildConfig from '../../config/getEsbuildConfig.js';
4 4
5export default getEsbuildConfig({ 5export default getEsbuildConfig({
6 absWorkingDir: fileURLToDirname(import.meta.url), 6 absWorkingDir: fileUrlToDirname(import.meta.url),
7 entryPoints: ['src/index.ts'], 7 entryPoints: ['src/index.ts'],
8 outfile: 'dist/index.mjs', 8 outfile: 'dist/index.mjs',
9 format: 'esm', 9 format: 'esm',
diff --git a/scripts/build.js b/scripts/build.js
index 88267e5..66a1506 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -1,11 +1,11 @@
1import { join } from 'path'; 1import path from 'node:path';
2 2
3import { build as esbuildBuild } from 'esbuild'; 3import { build as esbuildBuild } from 'esbuild';
4import { build as viteBuild } from 'vite'; 4import { build as viteBuild } from 'vite';
5 5
6import fileURLToDirname from '../config/fileURLToDirname.js'; 6import fileUrlToDirname from '../config/fileUrlToDirname.js';
7 7
8const thisDir = fileURLToDirname(import.meta.url); 8const thisDir = fileUrlToDirname(import.meta.url);
9 9
10/** 10/**
11 * @param {string} packageName 11 * @param {string} packageName
@@ -26,7 +26,7 @@ async function buildPackageEsbuild(packageName) {
26 */ 26 */
27function buildPackageVite(packageName) { 27function buildPackageVite(packageName) {
28 return viteBuild({ 28 return viteBuild({
29 configFile: join(thisDir, `../packages/${packageName}/vite.config.js`), 29 configFile: path.join(thisDir, `../packages/${packageName}/vite.config.js`),
30 }); 30 });
31} 31}
32 32
@@ -52,7 +52,7 @@ function buildAll() {
52 ]); 52 ]);
53} 53}
54 54
55buildAll().catch((err) => { 55buildAll().catch((error) => {
56 console.error(err); 56 console.error(error);
57 process.exit(1); 57 process.exit(1);
58}); 58});
diff --git a/scripts/update-electron-vendors.js b/scripts/updateElectronVendors.js
index 6ff5c06..5e8ab36 100644
--- a/scripts/update-electron-vendors.js
+++ b/scripts/updateElectronVendors.js
@@ -1,12 +1,12 @@
1import { execSync } from 'child_process'; 1import { execSync } from 'node:child_process';
2import { writeFile } from 'fs/promises'; 2import { writeFile } from 'node:fs/promises';
3import { join } from 'path'; 3import path from 'node:path';
4 4
5import electronPath from 'electron'; 5import electronPath from 'electron';
6 6
7import fileURLToDirname from '../config/fileURLToDirname.js'; 7import fileUrlToDirname from '../config/fileUrlToDirname.js';
8 8
9const thisDir = fileURLToDirname(import.meta.url); 9const thisDir = fileUrlToDirname(import.meta.url);
10 10
11/** 11/**
12 * Returns versions of electron vendors 12 * Returns versions of electron vendors
@@ -40,17 +40,17 @@ function updateVendors() {
40 const chromeMajorVersion = 40 const chromeMajorVersion =
41 electronRelease.v8.split('.')[0] + electronRelease.v8.split('.')[1]; 41 electronRelease.v8.split('.')[0] + electronRelease.v8.split('.')[1];
42 42
43 const browserslistrcPath = join(thisDir, '../.browserslistrc'); 43 const browserslistrcPath = path.join(thisDir, '../.browserslistrc');
44 44
45 return Promise.all([ 45 return Promise.all([
46 writeFile( 46 writeFile(
47 join(thisDir, '../.electron-vendors.cache.json'), 47 path.join(thisDir, '../.electron-vendors.cache.json'),
48 `${JSON.stringify( 48 `${JSON.stringify(
49 { 49 {
50 chrome: chromeMajorVersion, 50 chrome: chromeMajorVersion,
51 node: nodeMajorVersion, 51 node: nodeMajorVersion,
52 }, 52 },
53 null, 53 undefined,
54 2, 54 2,
55 )}\n`, 55 )}\n`,
56 ), 56 ),
@@ -59,7 +59,7 @@ function updateVendors() {
59 ]); 59 ]);
60} 60}
61 61
62updateVendors().catch((err) => { 62updateVendors().catch((error) => {
63 console.error(err); 63 console.error(error);
64 process.exit(1); 64 process.exit(1);
65}); 65});
diff --git a/scripts/watch.js b/scripts/watch.js
index cf5dbfd..455cfd9 100644
--- a/scripts/watch.js
+++ b/scripts/watch.js
@@ -1,21 +1,21 @@
1import { spawn } from 'child_process'; 1import { spawn } from 'node:child_process';
2import { join } from 'path'; 2import path from 'node:path';
3 3
4import { watch } from 'chokidar'; 4import { watch } from 'chokidar';
5import electronPath from 'electron'; 5import electronPath from 'electron';
6import { build as esbuildBuild } from 'esbuild'; 6import { build as esbuildBuild } from 'esbuild';
7import { createServer } from 'vite'; 7import { createServer } from 'vite';
8 8
9import fileURLToDirname from '../config/fileURLToDirname.js'; 9import fileUrlToDirname from '../config/fileUrlToDirname.js';
10 10
11/** @type {string} */ 11/** @type {string} */
12const thisDir = fileURLToDirname(import.meta.url); 12const thisDir = fileUrlToDirname(import.meta.url);
13 13
14/** @type {string} */ 14/** @type {string} */
15const sharedModule = join(thisDir, '../packages/shared/dist/index.mjs'); 15const sharedModule = path.join(thisDir, '../packages/shared/dist/index.mjs');
16 16
17/** @type {string} */ 17/** @type {string} */
18const serviceSharedModule = join( 18const serviceSharedModule = path.join(
19 thisDir, 19 thisDir,
20 '../packages/service-shared/dist/index.mjs', 20 '../packages/service-shared/dist/index.mjs',
21); 21);
@@ -48,7 +48,7 @@ async function setupEsbuildWatcher(packageName, extraPaths, callback) {
48 48
49 const incrementalBuild = await esbuildBuild(config); 49 const incrementalBuild = await esbuildBuild(config);
50 const paths = [ 50 const paths = [
51 join(thisDir, `../packages/${packageName}/src`), 51 path.join(thisDir, `../packages/${packageName}/src`),
52 ...(extraPaths || []), 52 ...(extraPaths || []),
53 ]; 53 ];
54 const watcher = watch(paths, { 54 const watcher = watch(paths, {
@@ -64,18 +64,18 @@ async function setupEsbuildWatcher(packageName, extraPaths, callback) {
64 .rebuild?.() 64 .rebuild?.()
65 .then(() => { 65 .then(() => {
66 if (callback) { 66 if (callback) {
67 console.log(`\u26a1 Reloading package ${packageName}`); 67 console.log(`\u26A1 Reloading package ${packageName}`);
68 callback(); 68 callback();
69 } 69 }
70 }) 70 })
71 .catch((err) => { 71 .catch((error) => {
72 if (typeof err === 'object' && 'errors' in err) { 72 if (typeof error === 'object' && 'errors' in error) {
73 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- We just checked. 73 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- We just checked.
74 const { errors } = err; 74 const { errors } = error;
75 if (Array.isArray(errors)) { 75 if (Array.isArray(errors)) {
76 const errCount = errors.length; 76 const errCount = errors.length;
77 console.error( 77 console.error(
78 '\ud83d\udd25', 78 '\uD83D\uDD25',
79 errCount, 79 errCount,
80 errCount > 1 ? 'errors' : 'error', 80 errCount > 1 ? 'errors' : 'error',
81 'while rebuilding package', 81 'while rebuilding package',
@@ -85,10 +85,10 @@ async function setupEsbuildWatcher(packageName, extraPaths, callback) {
85 } 85 }
86 } 86 }
87 console.error( 87 console.error(
88 '\ud83d\udd25', 88 '\uD83D\uDD25',
89 'error while rebuilding package', 89 'error while rebuilding package',
90 packageName, 90 packageName,
91 err, 91 error,
92 ); 92 );
93 }); 93 });
94 }); 94 });
@@ -106,7 +106,7 @@ async function setupDevServer(packageName) {
106 clearScreen: false, 106 clearScreen: false,
107 }, 107 },
108 }, 108 },
109 configFile: join(thisDir, `../packages/${packageName}/vite.config.js`), 109 configFile: path.join(thisDir, `../packages/${packageName}/vite.config.js`),
110 }); 110 });
111 await viteDevServer.listen(); 111 await viteDevServer.listen();
112 return viteDevServer; 112 return viteDevServer;
@@ -155,16 +155,16 @@ function setupMainPackageWatcher(viteDevServer) {
155 process.env.VITE_DEV_SERVER_URL = `${protocol}//${hostOrDefault}:${portOrDefault}/`; 155 process.env.VITE_DEV_SERVER_URL = `${protocol}//${hostOrDefault}:${portOrDefault}/`;
156 156
157 /** @type {import('child_process').ChildProcessByStdio<null, null, import('stream').Readable> 157 /** @type {import('child_process').ChildProcessByStdio<null, null, import('stream').Readable>
158 | null} */ 158 | undefined} */
159 let spawnProcess = null; 159 let spawnProcess;
160 160
161 return setupEsbuildWatcher( 161 return setupEsbuildWatcher(
162 'main', 162 'main',
163 [serviceSharedModule, sharedModule], 163 [serviceSharedModule, sharedModule],
164 () => { 164 () => {
165 if (spawnProcess !== null) { 165 if (spawnProcess !== undefined) {
166 spawnProcess.kill('SIGINT'); 166 spawnProcess.kill('SIGINT');
167 spawnProcess = null; 167 spawnProcess = undefined;
168 } 168 }
169 169
170 spawnProcess = spawn(String(electronPath), ['.'], { 170 spawnProcess = spawn(String(electronPath), ['.'], {
@@ -188,11 +188,11 @@ async function setupDevEnvironment() {
188 process.env.MODE = 'development'; 188 process.env.MODE = 'development';
189 process.env.NODE_ENV = 'development'; 189 process.env.NODE_ENV = 'development';
190 190
191 /** @type {import('vite').ViteDevServer | null} */ 191 /** @type {import('vite').ViteDevServer | undefined} */
192 let viteDevServer = null; 192 let viteDevServer;
193 /** @type {(event: import('vite').HMRPayload) => void} */ 193 /** @type {(event: import('vite').HMRPayload) => void} */
194 const sendEvent = (event) => { 194 const sendEvent = (event) => {
195 if (viteDevServer !== null) { 195 if (viteDevServer !== undefined) {
196 viteDevServer.ws.send(event); 196 viteDevServer.ws.send(event);
197 } 197 }
198 }; 198 };
@@ -216,16 +216,16 @@ async function setupDevEnvironment() {
216 ), 216 ),
217 ]); 217 ]);
218 218
219 if (viteDevServer === null) { 219 if (viteDevServer === undefined) {
220 console.error('Failed to create vite dev server'); 220 console.error('Failed to create vite dev server');
221 return; 221 return;
222 } 222 }
223 223
224 console.log('\ud83c\udf80 Sophie is starting up'); 224 console.log('\uD83C\uDF80 Sophie is starting up');
225 await setupMainPackageWatcher(viteDevServer); 225 await setupMainPackageWatcher(viteDevServer);
226} 226}
227 227
228setupDevEnvironment().catch((err) => { 228setupDevEnvironment().catch((error) => {
229 console.error(err); 229 console.error(error);
230 process.exit(1); 230 process.exit(1);
231}); 231});
diff --git a/yarn.lock b/yarn.lock
index 3b96a84..4a391c8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -173,7 +173,7 @@ __metadata:
173 languageName: node 173 languageName: node
174 linkType: hard 174 linkType: hard
175 175
176"@babel/helper-validator-identifier@npm:^7.16.7": 176"@babel/helper-validator-identifier@npm:^7.15.7, @babel/helper-validator-identifier@npm:^7.16.7":
177 version: 7.16.7 177 version: 7.16.7
178 resolution: "@babel/helper-validator-identifier@npm:7.16.7" 178 resolution: "@babel/helper-validator-identifier@npm:7.16.7"
179 checksum: dbb3db9d184343152520a209b5684f5e0ed416109cde82b428ca9c759c29b10c7450657785a8b5c5256aa74acc6da491c1f0cf6b784939f7931ef82982051b69 179 checksum: dbb3db9d184343152520a209b5684f5e0ed416109cde82b428ca9c759c29b10c7450657785a8b5c5256aa74acc6da491c1f0cf6b784939f7931ef82982051b69
@@ -1552,6 +1552,13 @@ __metadata:
1552 languageName: node 1552 languageName: node
1553 linkType: hard 1553 linkType: hard
1554 1554
1555"@types/normalize-package-data@npm:^2.4.0":
1556 version: 2.4.1
1557 resolution: "@types/normalize-package-data@npm:2.4.1"
1558 checksum: e87bccbf11f95035c89a132b52b79ce69a1e3652fe55962363063c9c0dae0fe2477ebc585e03a9652adc6f381d24ba5589cc5e51849df4ced3d3e004a7d40ed5
1559 languageName: node
1560 linkType: hard
1561
1555"@types/parse-json@npm:^4.0.0": 1562"@types/parse-json@npm:^4.0.0":
1556 version: 4.0.0 1563 version: 4.0.0
1557 resolution: "@types/parse-json@npm:4.0.0" 1564 resolution: "@types/parse-json@npm:4.0.0"
@@ -2493,6 +2500,13 @@ __metadata:
2493 languageName: node 2500 languageName: node
2494 linkType: hard 2501 linkType: hard
2495 2502
2503"builtin-modules@npm:^3.0.0":
2504 version: 3.2.0
2505 resolution: "builtin-modules@npm:3.2.0"
2506 checksum: 0265aa1ba78e1a16f4e18668d815cb43fb364e6a6b8aa9189c6f44c7b894a551a43b323c40206959d2d4b2568c1f2805607ad6c88adc306a776ce6904cca6715
2507 languageName: node
2508 linkType: hard
2509
2496"cacache@npm:^15.2.0": 2510"cacache@npm:^15.2.0":
2497 version: 15.3.0 2511 version: 15.3.0
2498 resolution: "cacache@npm:15.3.0" 2512 resolution: "cacache@npm:15.3.0"
@@ -2647,7 +2661,7 @@ __metadata:
2647 languageName: node 2661 languageName: node
2648 linkType: hard 2662 linkType: hard
2649 2663
2650"ci-info@npm:^3.2.0": 2664"ci-info@npm:^3.2.0, ci-info@npm:^3.3.0":
2651 version: 3.3.0 2665 version: 3.3.0
2652 resolution: "ci-info@npm:3.3.0" 2666 resolution: "ci-info@npm:3.3.0"
2653 checksum: c3d86fe374938ecda5093b1ba39acb535d8309185ba3f23587747c6a057e63f45419b406d880304dbc0e1d72392c9a33e42fe9a1e299209bc0ded5efaa232b66 2667 checksum: c3d86fe374938ecda5093b1ba39acb535d8309185ba3f23587747c6a057e63f45419b406d880304dbc0e1d72392c9a33e42fe9a1e299209bc0ded5efaa232b66
@@ -2661,6 +2675,15 @@ __metadata:
2661 languageName: node 2675 languageName: node
2662 linkType: hard 2676 linkType: hard
2663 2677
2678"clean-regexp@npm:^1.0.0":
2679 version: 1.0.0
2680 resolution: "clean-regexp@npm:1.0.0"
2681 dependencies:
2682 escape-string-regexp: ^1.0.5
2683 checksum: 0b1ce281b07da2463c6882ea2e8409119b6cabbd9f687cdbdcee942c45b2b9049a2084f7b5f228c63ef9f21e722963ae0bfe56a735dbdbdd92512867625a7e40
2684 languageName: node
2685 linkType: hard
2686
2664"clean-stack@npm:^2.0.0": 2687"clean-stack@npm:^2.0.0":
2665 version: 2.2.0 2688 version: 2.2.0
2666 resolution: "clean-stack@npm:2.2.0" 2689 resolution: "clean-stack@npm:2.2.0"
@@ -4167,6 +4190,30 @@ __metadata:
4167 languageName: node 4190 languageName: node
4168 linkType: hard 4191 linkType: hard
4169 4192
4193"eslint-plugin-unicorn@npm:^40.0.0":
4194 version: 40.0.0
4195 resolution: "eslint-plugin-unicorn@npm:40.0.0"
4196 dependencies:
4197 "@babel/helper-validator-identifier": ^7.15.7
4198 ci-info: ^3.3.0
4199 clean-regexp: ^1.0.0
4200 eslint-utils: ^3.0.0
4201 esquery: ^1.4.0
4202 indent-string: ^4.0.0
4203 is-builtin-module: ^3.1.0
4204 lodash: ^4.17.21
4205 pluralize: ^8.0.0
4206 read-pkg-up: ^7.0.1
4207 regexp-tree: ^0.1.24
4208 safe-regex: ^2.1.1
4209 semver: ^7.3.5
4210 strip-indent: ^3.0.0
4211 peerDependencies:
4212 eslint: ">=7.32.0"
4213 checksum: 2397ab10b28bd67e08c227c894e7066619e5b6140d4fd6df228782e0e3e2c2518f5ca839bd8e20ebfd7adde341beab71763f8ca38b3c2c1fc59bd0b5e0e5a3c9
4214 languageName: node
4215 linkType: hard
4216
4170"eslint-scope@npm:^5.1.1": 4217"eslint-scope@npm:^5.1.1":
4171 version: 5.1.1 4218 version: 5.1.1
4172 resolution: "eslint-scope@npm:5.1.1" 4219 resolution: "eslint-scope@npm:5.1.1"
@@ -4936,6 +4983,13 @@ __metadata:
4936 languageName: node 4983 languageName: node
4937 linkType: hard 4984 linkType: hard
4938 4985
4986"hosted-git-info@npm:^2.1.4":
4987 version: 2.8.9
4988 resolution: "hosted-git-info@npm:2.8.9"
4989 checksum: c955394bdab888a1e9bb10eb33029e0f7ce5a2ac7b3f158099dc8c486c99e73809dca609f5694b223920ca2174db33d32b12f9a2a47141dc59607c29da5a62dd
4990 languageName: node
4991 linkType: hard
4992
4939"hosted-git-info@npm:^4.0.2": 4993"hosted-git-info@npm:^4.0.2":
4940 version: 4.0.2 4994 version: 4.0.2
4941 resolution: "hosted-git-info@npm:4.0.2" 4995 resolution: "hosted-git-info@npm:4.0.2"
@@ -5222,6 +5276,15 @@ __metadata:
5222 languageName: node 5276 languageName: node
5223 linkType: hard 5277 linkType: hard
5224 5278
5279"is-builtin-module@npm:^3.1.0":
5280 version: 3.1.0
5281 resolution: "is-builtin-module@npm:3.1.0"
5282 dependencies:
5283 builtin-modules: ^3.0.0
5284 checksum: f1e5dd2cd5f252d4d799b20a0c8c4f7e9c399c4d141749af76ca0121058d4062c3015d026f1b1409dd3d2a4ddfb9b15cf6eb9c370fed53fea8652ce35b5e95cb
5285 languageName: node
5286 linkType: hard
5287
5225"is-callable@npm:^1.1.4, is-callable@npm:^1.2.4": 5288"is-callable@npm:^1.1.4, is-callable@npm:^1.2.4":
5226 version: 1.2.4 5289 version: 1.2.4
5227 resolution: "is-callable@npm:1.2.4" 5290 resolution: "is-callable@npm:1.2.4"
@@ -6384,7 +6447,7 @@ __metadata:
6384 languageName: node 6447 languageName: node
6385 linkType: hard 6448 linkType: hard
6386 6449
6387"lodash@npm:^4.17.10, lodash@npm:^4.17.15, lodash@npm:^4.7.0": 6450"lodash@npm:^4.17.10, lodash@npm:^4.17.15, lodash@npm:^4.17.21, lodash@npm:^4.7.0":
6388 version: 4.17.21 6451 version: 4.17.21
6389 resolution: "lodash@npm:4.17.21" 6452 resolution: "lodash@npm:4.17.21"
6390 checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 6453 checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
@@ -6569,6 +6632,13 @@ __metadata:
6569 languageName: node 6632 languageName: node
6570 linkType: hard 6633 linkType: hard
6571 6634
6635"min-indent@npm:^1.0.0":
6636 version: 1.0.1
6637 resolution: "min-indent@npm:1.0.1"
6638 checksum: bfc6dd03c5eaf623a4963ebd94d087f6f4bbbfd8c41329a7f09706b0cb66969c4ddd336abeb587bc44bc6f08e13bf90f0b374f9d71f9f01e04adc2cd6f083ef1
6639 languageName: node
6640 linkType: hard
6641
6572"minimatch@npm:3.0.4, minimatch@npm:^3.0.4": 6642"minimatch@npm:3.0.4, minimatch@npm:^3.0.4":
6573 version: 3.0.4 6643 version: 3.0.4
6574 resolution: "minimatch@npm:3.0.4" 6644 resolution: "minimatch@npm:3.0.4"
@@ -6813,6 +6883,18 @@ __metadata:
6813 languageName: node 6883 languageName: node
6814 linkType: hard 6884 linkType: hard
6815 6885
6886"normalize-package-data@npm:^2.5.0":
6887 version: 2.5.0
6888 resolution: "normalize-package-data@npm:2.5.0"
6889 dependencies:
6890 hosted-git-info: ^2.1.4
6891 resolve: ^1.10.0
6892 semver: 2 || 3 || 4 || 5
6893 validate-npm-package-license: ^3.0.1
6894 checksum: 7999112efc35a6259bc22db460540cae06564aa65d0271e3bdfa86876d08b0e578b7b5b0028ee61b23f1cae9fc0e7847e4edc0948d3068a39a2a82853efc8499
6895 languageName: node
6896 linkType: hard
6897
6816"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": 6898"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
6817 version: 3.0.0 6899 version: 3.0.0
6818 resolution: "normalize-path@npm:3.0.0" 6900 resolution: "normalize-path@npm:3.0.0"
@@ -7152,7 +7234,7 @@ __metadata:
7152 languageName: node 7234 languageName: node
7153 linkType: hard 7235 linkType: hard
7154 7236
7155"path-parse@npm:^1.0.6": 7237"path-parse@npm:^1.0.6, path-parse@npm:^1.0.7":
7156 version: 1.0.7 7238 version: 1.0.7
7157 resolution: "path-parse@npm:1.0.7" 7239 resolution: "path-parse@npm:1.0.7"
7158 checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a 7240 checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a
@@ -7220,6 +7302,13 @@ __metadata:
7220 languageName: node 7302 languageName: node
7221 linkType: hard 7303 linkType: hard
7222 7304
7305"pluralize@npm:^8.0.0":
7306 version: 8.0.0
7307 resolution: "pluralize@npm:8.0.0"
7308 checksum: 08931d4a6a4a5561a7f94f67a31c17e6632cb21e459ab3ff4f6f629d9a822984cf8afef2311d2005fbea5d7ef26016ebb090db008e2d8bce39d0a9a9d218736e
7309 languageName: node
7310 linkType: hard
7311
7223"postcss@npm:^8.4.5": 7312"postcss@npm:^8.4.5":
7224 version: 8.4.5 7313 version: 8.4.5
7225 resolution: "postcss@npm:8.4.5" 7314 resolution: "postcss@npm:8.4.5"
@@ -7499,6 +7588,29 @@ __metadata:
7499 languageName: node 7588 languageName: node
7500 linkType: hard 7589 linkType: hard
7501 7590
7591"read-pkg-up@npm:^7.0.1":
7592 version: 7.0.1
7593 resolution: "read-pkg-up@npm:7.0.1"
7594 dependencies:
7595 find-up: ^4.1.0
7596 read-pkg: ^5.2.0
7597 type-fest: ^0.8.1
7598 checksum: e4e93ce70e5905b490ca8f883eb9e48b5d3cebc6cd4527c25a0d8f3ae2903bd4121c5ab9c5a3e217ada0141098eeb661313c86fa008524b089b8ed0b7f165e44
7599 languageName: node
7600 linkType: hard
7601
7602"read-pkg@npm:^5.2.0":
7603 version: 5.2.0
7604 resolution: "read-pkg@npm:5.2.0"
7605 dependencies:
7606 "@types/normalize-package-data": ^2.4.0
7607 normalize-package-data: ^2.5.0
7608 parse-json: ^5.0.0
7609 type-fest: ^0.6.0
7610 checksum: eb696e60528b29aebe10e499ba93f44991908c57d70f2d26f369e46b8b9afc208ef11b4ba64f67630f31df8b6872129e0a8933c8c53b7b4daf0eace536901222
7611 languageName: node
7612 linkType: hard
7613
7502"readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6": 7614"readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6":
7503 version: 2.3.7 7615 version: 2.3.7
7504 resolution: "readable-stream@npm:2.3.7" 7616 resolution: "readable-stream@npm:2.3.7"
@@ -7541,6 +7653,15 @@ __metadata:
7541 languageName: node 7653 languageName: node
7542 linkType: hard 7654 linkType: hard
7543 7655
7656"regexp-tree@npm:^0.1.24, regexp-tree@npm:~0.1.1":
7657 version: 0.1.24
7658 resolution: "regexp-tree@npm:0.1.24"
7659 bin:
7660 regexp-tree: bin/regexp-tree
7661 checksum: 5807013289d9205288d665e0f8d8cff94843dfd55fdedd1833eb9d9bbd07188a37dfa02942ec5cdc671180037f715148fac1ba6f18fd6be4268e5a8feb49d340
7662 languageName: node
7663 linkType: hard
7664
7544"regexp.prototype.flags@npm:^1.3.1": 7665"regexp.prototype.flags@npm:^1.3.1":
7545 version: 1.3.1 7666 version: 1.3.1
7546 resolution: "regexp.prototype.flags@npm:1.3.1" 7667 resolution: "regexp.prototype.flags@npm:1.3.1"
@@ -7625,6 +7746,19 @@ __metadata:
7625 languageName: node 7746 languageName: node
7626 linkType: hard 7747 linkType: hard
7627 7748
7749"resolve@npm:^1.10.0":
7750 version: 1.21.0
7751 resolution: "resolve@npm:1.21.0"
7752 dependencies:
7753 is-core-module: ^2.8.0
7754 path-parse: ^1.0.7
7755 supports-preserve-symlinks-flag: ^1.0.0
7756 bin:
7757 resolve: bin/resolve
7758 checksum: d7d9092a5c04a048bea16c7e5a2eb605ac3e8363a0cc5644de1fde17d5028e8d5f4343aab1d99bd327b98e91a66ea83e242718150c64dfedcb96e5e7aad6c4f5
7759 languageName: node
7760 linkType: hard
7761
7628"resolve@npm:^1.12.0, resolve@npm:^1.20.0": 7762"resolve@npm:^1.12.0, resolve@npm:^1.20.0":
7629 version: 1.20.0 7763 version: 1.20.0
7630 resolution: "resolve@npm:1.20.0" 7764 resolution: "resolve@npm:1.20.0"
@@ -7645,6 +7779,19 @@ __metadata:
7645 languageName: node 7779 languageName: node
7646 linkType: hard 7780 linkType: hard
7647 7781
7782"resolve@patch:resolve@^1.10.0#~builtin<compat/resolve>":
7783 version: 1.21.0
7784 resolution: "resolve@patch:resolve@npm%3A1.21.0#~builtin<compat/resolve>::version=1.21.0&hash=07638b"
7785 dependencies:
7786 is-core-module: ^2.8.0
7787 path-parse: ^1.0.7
7788 supports-preserve-symlinks-flag: ^1.0.0
7789 bin:
7790 resolve: bin/resolve
7791 checksum: a0a4d1f7409e73190f31f901f8a619960bb3bd4ae38ba3a54c7ea7e1c87758d28a73256bb8d6a35996a903d1bf14f53883f0dcac6c571c063cb8162d813ad26e
7792 languageName: node
7793 linkType: hard
7794
7648"resolve@patch:resolve@^1.12.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>": 7795"resolve@patch:resolve@^1.12.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>":
7649 version: 1.20.0 7796 version: 1.20.0
7650 resolution: "resolve@patch:resolve@npm%3A1.20.0#~builtin<compat/resolve>::version=1.20.0&hash=07638b" 7797 resolution: "resolve@patch:resolve@npm%3A1.20.0#~builtin<compat/resolve>::version=1.20.0&hash=07638b"
@@ -7757,6 +7904,15 @@ __metadata:
7757 languageName: node 7904 languageName: node
7758 linkType: hard 7905 linkType: hard
7759 7906
7907"safe-regex@npm:^2.1.1":
7908 version: 2.1.1
7909 resolution: "safe-regex@npm:2.1.1"
7910 dependencies:
7911 regexp-tree: ~0.1.1
7912 checksum: 5d734e2193c63ef0cb00f60c0244e0f8a30ecb31923633cd34636808d6a7c4c206d650017953ae1db8bc33967c2f06af33488dea6f038f4e38212beb7bed77b4
7913 languageName: node
7914 linkType: hard
7915
7760"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": 7916"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0":
7761 version: 2.1.2 7917 version: 2.1.2
7762 resolution: "safer-buffer@npm:2.1.2" 7918 resolution: "safer-buffer@npm:2.1.2"
@@ -7838,6 +7994,15 @@ __metadata:
7838 languageName: node 7994 languageName: node
7839 linkType: hard 7995 linkType: hard
7840 7996
7997"semver@npm:2 || 3 || 4 || 5":
7998 version: 5.7.1
7999 resolution: "semver@npm:5.7.1"
8000 bin:
8001 semver: ./bin/semver
8002 checksum: 57fd0acfd0bac382ee87cd52cd0aaa5af086a7dc8d60379dfe65fea491fb2489b6016400813930ecd61fd0952dae75c115287a1b16c234b1550887117744dfaf
8003 languageName: node
8004 linkType: hard
8005
7841"semver@npm:^6.0.0, semver@npm:^6.2.0, semver@npm:^6.3.0": 8006"semver@npm:^6.0.0, semver@npm:^6.2.0, semver@npm:^6.3.0":
7842 version: 6.3.0 8007 version: 6.3.0
7843 resolution: "semver@npm:6.3.0" 8008 resolution: "semver@npm:6.3.0"
@@ -8014,6 +8179,7 @@ __metadata:
8014 eslint-plugin-prettier: ^4.0.0 8179 eslint-plugin-prettier: ^4.0.0
8015 eslint-plugin-react: ^7.28.0 8180 eslint-plugin-react: ^7.28.0
8016 eslint-plugin-react-hooks: ^4.3.0 8181 eslint-plugin-react-hooks: ^4.3.0
8182 eslint-plugin-unicorn: ^40.0.0
8017 git-repo-info: ^2.1.1 8183 git-repo-info: ^2.1.1
8018 jest: ^27.4.7 8184 jest: ^27.4.7
8019 preload: ^0.1.0 8185 preload: ^0.1.0
@@ -8062,6 +8228,40 @@ __metadata:
8062 languageName: node 8228 languageName: node
8063 linkType: hard 8229 linkType: hard
8064 8230
8231"spdx-correct@npm:^3.0.0":
8232 version: 3.1.1
8233 resolution: "spdx-correct@npm:3.1.1"
8234 dependencies:
8235 spdx-expression-parse: ^3.0.0
8236 spdx-license-ids: ^3.0.0
8237 checksum: 77ce438344a34f9930feffa61be0eddcda5b55fc592906ef75621d4b52c07400a97084d8701557b13f7d2aae0cb64f808431f469e566ef3fe0a3a131dcb775a6
8238 languageName: node
8239 linkType: hard
8240
8241"spdx-exceptions@npm:^2.1.0":
8242 version: 2.3.0
8243 resolution: "spdx-exceptions@npm:2.3.0"
8244 checksum: cb69a26fa3b46305637123cd37c85f75610e8c477b6476fa7354eb67c08128d159f1d36715f19be6f9daf4b680337deb8c65acdcae7f2608ba51931540687ac0
8245 languageName: node
8246 linkType: hard
8247
8248"spdx-expression-parse@npm:^3.0.0":
8249 version: 3.0.1
8250 resolution: "spdx-expression-parse@npm:3.0.1"
8251 dependencies:
8252 spdx-exceptions: ^2.1.0
8253 spdx-license-ids: ^3.0.0
8254 checksum: a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde
8255 languageName: node
8256 linkType: hard
8257
8258"spdx-license-ids@npm:^3.0.0":
8259 version: 3.0.11
8260 resolution: "spdx-license-ids@npm:3.0.11"
8261 checksum: 1da1acb090257773e60b022094050e810ae9fec874dc1461f65dc0400cd42dd830ab2df6e64fb49c2db3dce386dd0362110780e1b154db7c0bb413488836aaeb
8262 languageName: node
8263 linkType: hard
8264
8065"sprintf-js@npm:^1.1.2": 8265"sprintf-js@npm:^1.1.2":
8066 version: 1.1.2 8266 version: 1.1.2
8067 resolution: "sprintf-js@npm:1.1.2" 8267 resolution: "sprintf-js@npm:1.1.2"
@@ -8206,6 +8406,15 @@ __metadata:
8206 languageName: node 8406 languageName: node
8207 linkType: hard 8407 linkType: hard
8208 8408
8409"strip-indent@npm:^3.0.0":
8410 version: 3.0.0
8411 resolution: "strip-indent@npm:3.0.0"
8412 dependencies:
8413 min-indent: ^1.0.0
8414 checksum: 18f045d57d9d0d90cd16f72b2313d6364fd2cb4bf85b9f593523ad431c8720011a4d5f08b6591c9d580f446e78855c5334a30fb91aa1560f5d9f95ed1b4a0530
8415 languageName: node
8416 linkType: hard
8417
8209"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": 8418"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1":
8210 version: 3.1.1 8419 version: 3.1.1
8211 resolution: "strip-json-comments@npm:3.1.1" 8420 resolution: "strip-json-comments@npm:3.1.1"
@@ -8273,6 +8482,13 @@ __metadata:
8273 languageName: node 8482 languageName: node
8274 linkType: hard 8483 linkType: hard
8275 8484
8485"supports-preserve-symlinks-flag@npm:^1.0.0":
8486 version: 1.0.0
8487 resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
8488 checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae
8489 languageName: node
8490 linkType: hard
8491
8276"symbol-tree@npm:^3.2.4": 8492"symbol-tree@npm:^3.2.4":
8277 version: 3.2.4 8493 version: 3.2.4
8278 resolution: "symbol-tree@npm:3.2.4" 8494 resolution: "symbol-tree@npm:3.2.4"
@@ -8536,6 +8752,20 @@ __metadata:
8536 languageName: node 8752 languageName: node
8537 linkType: hard 8753 linkType: hard
8538 8754
8755"type-fest@npm:^0.6.0":
8756 version: 0.6.0
8757 resolution: "type-fest@npm:0.6.0"
8758 checksum: b2188e6e4b21557f6e92960ec496d28a51d68658018cba8b597bd3ef757721d1db309f120ae987abeeda874511d14b776157ff809f23c6d1ce8f83b9b2b7d60f
8759 languageName: node
8760 linkType: hard
8761
8762"type-fest@npm:^0.8.1":
8763 version: 0.8.1
8764 resolution: "type-fest@npm:0.8.1"
8765 checksum: d61c4b2eba24009033ae4500d7d818a94fd6d1b481a8111612ee141400d5f1db46f199c014766b9fa9b31a6a7374d96fc748c6d688a78a3ce5a33123839becb7
8766 languageName: node
8767 linkType: hard
8768
8539"typedarray-to-buffer@npm:^3.1.5": 8769"typedarray-to-buffer@npm:^3.1.5":
8540 version: 3.1.5 8770 version: 3.1.5
8541 resolution: "typedarray-to-buffer@npm:3.1.5" 8771 resolution: "typedarray-to-buffer@npm:3.1.5"
@@ -8717,6 +8947,16 @@ __metadata:
8717 languageName: node 8947 languageName: node
8718 linkType: hard 8948 linkType: hard
8719 8949
8950"validate-npm-package-license@npm:^3.0.1":
8951 version: 3.0.4
8952 resolution: "validate-npm-package-license@npm:3.0.4"
8953 dependencies:
8954 spdx-correct: ^3.0.0
8955 spdx-expression-parse: ^3.0.0
8956 checksum: 35703ac889d419cf2aceef63daeadbe4e77227c39ab6287eeb6c1b36a746b364f50ba22e88591f5d017bc54685d8137bc2d328d0a896e4d3fd22093c0f32a9ad
8957 languageName: node
8958 linkType: hard
8959
8720"verror@npm:^1.10.0": 8960"verror@npm:^1.10.0":
8721 version: 1.10.1 8961 version: 1.10.1
8722 resolution: "verror@npm:1.10.1" 8962 resolution: "verror@npm:1.10.1"