fix eslint and update eslint to 8.0.0

This commit is contained in:
Rohid
2024-08-31 01:34:01 +06:00
parent a87b17e48c
commit d7cd69783b
27 changed files with 5875 additions and 3876 deletions

View File

@@ -8,18 +8,20 @@ module.exports = {
}, },
extends: [ extends: [
'eslint:recommended', 'eslint:recommended',
'kentcdodds/best-practices', // 'kentcdodds/best-practices',
'kentcdodds/es6/possible-errors', // 'kentcdodds/es6/possible-errors',
'kentcdodds',
// 'kentcdodds/react',
'kentcdodds/import', 'kentcdodds/import',
'kentcdodds/jest', 'kentcdodds/jest',
'kentcdodds/possible-errors', // 'kentcdodds/possible-errors',
// 'plugin:@typescript-eslint/recommended',
'plugin:jest-dom/recommended', 'plugin:jest-dom/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:import/errors', 'plugin:import/errors',
'plugin:import/typescript', 'plugin:import/typescript',
'plugin:prettier/recommended', 'plugin:prettier/recommended',
'plugin:react/recommended', 'plugin:react/recommended',
'plugin:react/jsx-runtime', // 'plugin:react/jsx-runtime',
'plugin:typescript-sort-keys/recommended', 'plugin:typescript-sort-keys/recommended',
'plugin:react-hooks/recommended', 'plugin:react-hooks/recommended',
], ],
@@ -36,7 +38,7 @@ module.exports = {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports sourceType: 'module', // Allows for the use of imports
}, },
plugins: ['react', '@typescript-eslint', 'typescript-sort-keys', 'sort-keys-fix'], plugins: ['react', 'typescript-sort-keys', 'sort-keys-fix'],
rules: { rules: {
'no-await-in-loop': 'off', 'no-await-in-loop': 'off',
'prettier/prettier': 'error', 'prettier/prettier': 'error',

9581
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -74,8 +74,8 @@
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@types/wait-on": "^5.2.0", "@types/wait-on": "^5.2.0",
"@types/webextension-polyfill": "^0.10.0", "@types/webextension-polyfill": "^0.10.0",
"@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^4.33.0", "@typescript-eslint/parser": "^7.18.0",
"@xarc/run": "^1.0.4", "@xarc/run": "^1.0.4",
"axios": "^1.7.5", "axios": "^1.7.5",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
@@ -85,17 +85,19 @@
"clean-webpack-plugin": "^4.0.0", "clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^11.0.0", "copy-webpack-plugin": "^11.0.0",
"del": "^7.0.0", "del": "^7.0.0",
"eslint": "^7.32.0", "eslint": "^8.57.0",
"eslint-config-kentcdodds": "^19.2.0", "eslint-config-kentcdodds": "^21.0.0",
"eslint-config-prettier": "^8.6.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest-dom": "^4.0.3", "eslint-plugin-jest-dom": "^5.4.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-kentcdodds": "^1.0.3",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.32.0", "eslint-plugin-react": "^7.32.0",
"eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-sort-keys-fix": "^1.1.2", "eslint-plugin-sort-keys-fix": "^1.1.2",
"eslint-plugin-testing-library": "^5.9.1", "eslint-plugin-testing-library": "^5.9.1",
"eslint-plugin-typescript-sort-keys": "^2.1.0", "eslint-plugin-typescript-sort-keys": "^3.2.0",
"husky": "^4.3.7", "husky": "^4.3.7",
"jest": "^29.3.1", "jest": "^29.3.1",
"jest-cli": "^29.3.1", "jest-cli": "^29.3.1",
@@ -118,7 +120,7 @@
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"ts-loader": "^9.5.1", "ts-loader": "^9.5.1",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5.5.4", "typescript": "~5.5.4",
"wait-on": "^8.0.0", "wait-on": "^8.0.0",
"web-ext": "^8.2.0", "web-ext": "^8.2.0",
"webpack": "^5.94.0", "webpack": "^5.94.0",

View File

@@ -1,4 +1,4 @@
import '@testing-library/jest-dom/extend-expect'; import '@testing-library/jest-dom';
import chrome from 'sinon-chrome'; import chrome from 'sinon-chrome';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment

View File

@@ -1,11 +1,12 @@
import React from 'react';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react';
import Alert from './Alert'; import Alert from './Alert';
describe('Alert Component', () => { describe('Alert Component', () => {
it('should render with proper text on success type', () => { it('should render with proper text on success type', () => {
const text = 'Test Text'; const text = 'Test Text';
const { container } = render(<Alert text={text} type="success" />); const { container } = render(<Alert text={text} type="success" />);
// eslint-disable-next-line testing-library/prefer-implicit-assert
expect(screen.getByText(text)).toBeInTheDocument(); expect(screen.getByText(text)).toBeInTheDocument();
expect(container).toMatchInlineSnapshot(` expect(container).toMatchInlineSnapshot(`
<div> <div>
@@ -20,6 +21,7 @@ describe('Alert Component', () => {
it('should render wtih proper text on danger type', () => { it('should render wtih proper text on danger type', () => {
const text = 'Test Text'; const text = 'Test Text';
const { container } = render(<Alert text={text} type="danger" />); const { container } = render(<Alert text={text} type="danger" />);
// eslint-disable-next-line testing-library/prefer-implicit-assert
expect(screen.getByText(text)).toBeInTheDocument(); expect(screen.getByText(text)).toBeInTheDocument();
expect(container).toMatchInlineSnapshot(` expect(container).toMatchInlineSnapshot(`
<div> <div>

View File

@@ -1,5 +1,5 @@
import React, { MouseEventHandler, CSSProperties } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { CSSProperties, MouseEventHandler } from 'react';
import { SuccessOrFailType } from '../config/config'; import { SuccessOrFailType } from '../config/config';
interface AlertProps { interface AlertProps {
onClick?: MouseEventHandler<HTMLDivElement>; onClick?: MouseEventHandler<HTMLDivElement>;

View File

@@ -52,7 +52,7 @@ export default function CustomProjectNameList({
{label} {label}
</label> </label>
{sites.length > 0 && ( {sites.length > 0 ? (
<div className="d-flex flex-column gap-2"> <div className="d-flex flex-column gap-2">
{sites.map((site, i) => ( {sites.map((site, i) => (
<div key={i} className="d-flex gap-2"> <div key={i} className="d-flex gap-2">
@@ -77,15 +77,15 @@ export default function CustomProjectNameList({
className="btn btn-sm btn-default" className="btn btn-sm btn-default"
onClick={() => handleRemoveSite(i)} onClick={() => handleRemoveSite(i)}
> >
<i className="fa fa-fw fa-times"></i> <i className="fa fa-fw fa-times" />
</button> </button>
</div> </div>
))} ))}
</div> </div>
)} ) : null}
<button type="button" onClick={handleAddNewSite} className="btn btn-default col-12"> <button type="button" onClick={handleAddNewSite} className="btn btn-default col-12">
<i className="fa fa-fw fa-plus me-2"></i> <i className="fa fa-fw fa-plus me-2" />
Add Project Name Add Project Name
</button> </button>
</div> </div>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { renderWithProviders } from '../utils/test-utils'; import { renderWithProviders } from '../utils/test-utils';
import MainList from './MainList'; import MainList from './MainList';
jest.mock('webextension-polyfill', () => { jest.mock<typeof import('webextension-polyfill')>('webextension-polyfill', () => {
return { return {
runtime: { runtime: {
getManifest: () => { getManifest: () => {
@@ -13,8 +13,7 @@ jest.mock('webextension-polyfill', () => {
}); });
describe('MainList', () => { describe('MainList', () => {
let loggingEnabled: boolean; let loggingEnabled: boolean, totalTimeLoggedToday: string;
let totalTimeLoggedToday: string;
beforeEach(() => { beforeEach(() => {
loggingEnabled = false; loggingEnabled = false;
totalTimeLoggedToday = '1/1/1999'; totalTimeLoggedToday = '1/1/1999';

View File

@@ -45,7 +45,7 @@ export default function MainList({
return ( return (
<div> <div>
{user && ( {user ? (
<div className="row"> <div className="row">
<div className="col-xs-12"> <div className="col-xs-12">
<blockquote> <blockquote>
@@ -56,8 +56,8 @@ export default function MainList({
</blockquote> </blockquote>
</div> </div>
</div> </div>
)} ) : null}
{loggingEnabled && user && ( {loggingEnabled && user ? (
<div className="row"> <div className="row">
<div className="col-xs-12"> <div className="col-xs-12">
<p> <p>
@@ -71,8 +71,8 @@ export default function MainList({
</p> </p>
</div> </div>
</div> </div>
)} ) : null}
{!loggingEnabled && user && ( {!loggingEnabled && user ? (
<div className="row"> <div className="row">
<div className="col-xs-12"> <div className="col-xs-12">
<p> <p>
@@ -86,28 +86,28 @@ export default function MainList({
</p> </p>
</div> </div>
</div> </div>
)} ) : null}
<div className="list-group"> <div className="list-group">
<a href="#" className="list-group-item text-body-secondary" onClick={openOptionsPage}> <a href="#" className="list-group-item text-body-secondary" onClick={openOptionsPage}>
<i className="fa fa-fw fa-cogs me-2"></i> <i className="fa fa-fw fa-cogs me-2" />
Options Options
</a> </a>
{user && ( {user ? (
<div> <div>
<a href="#" className="list-group-item text-body-secondary" onClick={logoutUser}> <a href="#" className="list-group-item text-body-secondary" onClick={logoutUser}>
<i className="fa fa-fw fa-sign-out me-2"></i> <i className="fa fa-fw fa-sign-out me-2" />
Logout Logout
</a> </a>
</div> </div>
)} ) : null}
{!user && ( {user ? null : (
<a <a
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
href="https://wakatime.com/login" href="https://wakatime.com/login"
className="list-group-item text-body-secondary" className="list-group-item text-body-secondary"
> >
<i className="fa fa-fw fa-sign-in me-2"></i> <i className="fa fa-fw fa-sign-in me-2" />
Login Login
</a> </a>
)} )}

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { renderWithProviders } from '../utils/test-utils'; import { renderWithProviders } from '../utils/test-utils';
import NavBar from './NavBar'; import NavBar from './NavBar';
jest.mock('webextension-polyfill', () => { jest.mock<typeof import('webextension-polyfill')>('webextension-polyfill', () => {
return { return {
runtime: { runtime: {
getManifest: () => { getManifest: () => {

View File

@@ -30,7 +30,7 @@ export default function NavBar(): JSX.Element {
rel="noreferrer" rel="noreferrer"
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center" className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
> >
<i className="fa fa-fw fa-filter me-2"></i> <i className="fa fa-fw fa-filter me-2" />
Custom Rules Custom Rules
</a> </a>
</li> </li>
@@ -50,7 +50,7 @@ export default function NavBar(): JSX.Element {
rel="noreferrer" rel="noreferrer"
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center" className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
> >
<i className="fa fa-fw fa-tachometer me-2"></i> <i className="fa fa-fw fa-tachometer me-2" />
Dashboard Dashboard
</a> </a>
</li> </li>
@@ -77,7 +77,7 @@ export default function NavBar(): JSX.Element {
aria-label="Toggle navigation" aria-label="Toggle navigation"
> >
<span className="sr-only">Toggle navigation</span> <span className="sr-only">Toggle navigation</span>
<i className="fa fa-fw fa-cogs"></i> <i className="fa fa-fw fa-cogs" />
</button> </button>
</div> </div>
@@ -94,9 +94,9 @@ export default function NavBar(): JSX.Element {
role="button" role="button"
aria-expanded="false" aria-expanded="false"
> >
<i className="fa fa-fw fa-info me-2"></i> <i className="fa fa-fw fa-info me-2" />
About About
<span className="caret"></span> <span className="caret" />
</a> </a>
<ul className="dropdown-menu shadow-none ms-4" role="menu"> <ul className="dropdown-menu shadow-none ms-4" role="menu">
<li className="mb-2"> <li className="mb-2">
@@ -106,7 +106,7 @@ export default function NavBar(): JSX.Element {
rel="noreferrer" rel="noreferrer"
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center" className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
> >
<i className="fa fa-fw fa-bug me-2"></i> <i className="fa fa-fw fa-bug me-2" />
Report an Issue Report an Issue
</a> </a>
</li> </li>
@@ -117,7 +117,7 @@ export default function NavBar(): JSX.Element {
rel="noreferrer" rel="noreferrer"
className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center" className="text-body-secondary link-underline link-underline-opacity-0 d-flex w-100 align-items-center"
> >
<i className="fa fa-fw fa-github me-2"></i> <i className="fa fa-fw fa-github me-2" />
View on GitHub View on GitHub
</a> </a>
</li> </li>

View File

@@ -301,7 +301,7 @@ export default function Options(): JSX.Element {
className="btn-close" className="btn-close"
data-bs-dismiss="modal" data-bs-dismiss="modal"
aria-label="Close" aria-label="Close"
></button> />
</div> </div>
<div className="modal-body"> <div className="modal-body">
<SitesList <SitesList

View File

@@ -40,7 +40,7 @@ export default function SitesList({
{label} {label}
</label> </label>
{sites.length > 0 && ( {sites.length > 0 ? (
<div className="d-flex flex-column gap-2"> <div className="d-flex flex-column gap-2">
{sites.map((site, i) => ( {sites.map((site, i) => (
<div key={i} className="d-flex gap-2"> <div key={i} className="d-flex gap-2">
@@ -57,15 +57,15 @@ export default function SitesList({
className="btn btn-sm btn-default" className="btn btn-sm btn-default"
onClick={() => handleRemoveSite(i)} onClick={() => handleRemoveSite(i)}
> >
<i className="fa fa-fw fa-times"></i> <i className="fa fa-fw fa-times" />
</button> </button>
</div> </div>
))} ))}
</div> </div>
)} ) : null}
<button type="button" onClick={handleAddNewSite} className="btn btn-default col-12"> <button type="button" onClick={handleAddNewSite} className="btn btn-default col-12">
<i className="fa fa-fw fa-plus me-2"></i> <i className="fa fa-fw fa-plus me-2" />
Add Site Add Site
</button> </button>
<span className="text-secondary">{helpText}</span> <span className="text-secondary">{helpText}</span>

View File

@@ -38,18 +38,18 @@ export default function WakaTime(): JSX.Element {
return ( return (
<div className="py-4 px-2 pt-0"> <div className="py-4 px-2 pt-0">
<NavBar /> <NavBar />
{isApiKeyValid && extensionStatus === 'notSignedIn' && ( {isApiKeyValid && extensionStatus === 'notSignedIn' ? (
<Alert <Alert
type={config.alert.failure.type} type={config.alert.failure.type}
text={'Invalid API key or API url'} text="Invalid API key or API url"
onClick={() => browser.runtime.openOptionsPage()} onClick={() => browser.runtime.openOptionsPage()}
style={{ cursor: 'pointer' }} style={{ cursor: 'pointer' }}
/> />
)} ) : null}
{!isApiKeyValid && ( {isApiKeyValid ? null : (
<Alert <Alert
type={config.alert.failure.type} type={config.alert.failure.type}
text={'Please update your api key'} text="Please update your api key"
onClick={() => browser.runtime.openOptionsPage()} onClick={() => browser.runtime.openOptionsPage()}
style={{ cursor: 'pointer' }} style={{ cursor: 'pointer' }}
/> />

View File

@@ -1,6 +1,6 @@
import config from './config'; import config from './config';
jest.mock('webextension-polyfill', () => { jest.mock<typeof import('webextension-polyfill')>('webextension-polyfill', () => {
return { return {
runtime: { runtime: {
getManifest: () => { getManifest: () => {

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,3 +1,3 @@
<!DOCTYPE html> <!doctype html>
<script src="public/js/browser-polyfill.min.js"></script> <script src="public/js/browser-polyfill.min.js"></script>
<script src="devtools.js"></script> <script src="devtools.js"></script>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />

View File

@@ -50,9 +50,9 @@ export async function changeExtensionIcon(color?: ColorIconTypes): Promise<void>
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (IS_FIREFOX && browser.browserAction) { if (IS_FIREFOX && browser.browserAction) {
await browser.browserAction.setIcon({ path: path }); // Support for FF with manifest V2 await browser.browserAction.setIcon({ path }); // Support for FF with manifest V2
} else if ((browser.action as browser.Action.Static | undefined) !== undefined) { } else if ((browser.action as browser.Action.Static | undefined) !== undefined) {
await browser.action.setIcon({ path: path }); // Support for Chrome with manifest V3 await browser.action.setIcon({ path }); // Support for Chrome with manifest V3
} }
} }

View File

@@ -4,7 +4,7 @@
export default function getDomainFromUrl(url: string): string { export default function getDomainFromUrl(url: string): string {
const parts = url.split('/'); const parts = url.split('/');
return parts[0] + '//' + parts[2]; return `${parts[0]}//${parts[2]}`;
} }
/** /**

View File

@@ -1,10 +1,10 @@
export const IS_EDGE = navigator.userAgent.includes('Edg'); export const IS_EDGE = navigator.userAgent.includes('Edg');
export const IS_FIREFOX = navigator.userAgent.includes('Firefox'); export const IS_FIREFOX = navigator.userAgent.includes('Firefox');
export const IS_CHROME = IS_EDGE === false && IS_FIREFOX === false; export const IS_CHROME = !IS_EDGE && !IS_FIREFOX;
export const getOperatingSystem = (): Promise<string> => { export const getOperatingSystem = (): Promise<string> => {
return new Promise((resolve) => { return new Promise((resolve) => {
chrome.runtime.getPlatformInfo(function (info) { chrome.runtime.getPlatformInfo((info) => {
resolve(`${info.os}_${info.arch}`); resolve(`${info.os}_${info.arch}`);
}); });
}); });

View File

@@ -202,7 +202,7 @@ const Canva: HeartbeatParser = (_url: string): OptionalHeartbeat | undefined =>
// make sure the page title matches the design input element's value, meaning this is a design file // make sure the page title matches the design input element's value, meaning this is a design file
const canvaProjectInput = Array.from( const canvaProjectInput = Array.from(
document.querySelector('nav')?.querySelectorAll('input')?.values() ?? [], document.querySelector('nav')?.querySelectorAll('input').values() ?? [],
).find((inp) => inp.value === projectName); ).find((inp) => inp.value === projectName);
if (!canvaProjectInput) return; if (!canvaProjectInput) return;

View File

@@ -1,7 +1,5 @@
import type { PreloadedState } from '@reduxjs/toolkit';
import { combineReducers, configureStore, Store } from '@reduxjs/toolkit'; import { combineReducers, configureStore, Store } from '@reduxjs/toolkit';
import type { RenderOptions } from '@testing-library/react'; import { render, type RenderOptions } from '@testing-library/react';
import { render } from '@testing-library/react';
import React, { PropsWithChildren } from 'react'; import React, { PropsWithChildren } from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { RootState } from '../stores/createStore'; import { RootState } from '../stores/createStore';
@@ -13,7 +11,9 @@ import userReducer, { initialState as InitalCurrentUser } from '../reducers/curr
// This type interface extends the default options for render from RTL, as well // This type interface extends the default options for render from RTL, as well
// as allows the user to specify other things such as initialState, store. // as allows the user to specify other things such as initialState, store.
interface ExtendedRenderOptions extends Omit<RenderOptions, 'queries'> { interface ExtendedRenderOptions extends Omit<RenderOptions, 'queries'> {
preloadedState?: PreloadedState<RootState>; // TODO: Fix Type as `PreloadedState` is not exported in the latest version of `@redux/toolkit`
// preloadedState?: PreloadedState<RootState>;
preloadedState?: object;
store?: Store<RootState>; store?: Store<RootState>;
} }

View File

@@ -12,8 +12,7 @@ const fiveMinutes = 300000;
* @returns {() => void} The debounced function. * @returns {() => void} The debounced function.
*/ */
function debounce(func: () => void, timeout = oneMinute, maxWaitTime = fiveMinutes) { function debounce(func: () => void, timeout = oneMinute, maxWaitTime = fiveMinutes) {
let timer: NodeJS.Timeout | undefined; let timer: NodeJS.Timeout | undefined, lastExecutionTime: number | undefined;
let lastExecutionTime: number | undefined;
return (...args: unknown[]) => { return (...args: unknown[]) => {
clearTimeout(timer); clearTimeout(timer);
if (lastExecutionTime && lastExecutionTime + maxWaitTime < Date.now()) { if (lastExecutionTime && lastExecutionTime + maxWaitTime < Date.now()) {
@@ -28,7 +27,7 @@ function debounce(func: () => void, timeout = oneMinute, maxWaitTime = fiveMinut
} }
const sendHeartbeat = debounce(async () => { const sendHeartbeat = debounce(async () => {
chrome.runtime.sendMessage({ task: 'handleActivity' }); void chrome.runtime.sendMessage({ task: 'handleActivity' });
}); });
chrome.runtime.onMessage.addListener( chrome.runtime.onMessage.addListener(

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />

View File

@@ -56,12 +56,12 @@ const getConfigByBrowser = (isProd: boolean, browser: BrowserTypes): webpack.Con
], ],
}), }),
new webpack.DefinePlugin({ new webpack.DefinePlugin({
['process.env.API_URL']: JSON.stringify('https://api.wakatime.com/api/v1'), 'process.env.API_URL': JSON.stringify('https://api.wakatime.com/api/v1'),
['process.env.CURRENT_USER_API_URL']: JSON.stringify('/users/current'), 'process.env.CURRENT_USER_API_URL': JSON.stringify('/users/current'),
['process.env.HEARTBEAT_API_URL']: JSON.stringify('/users/current/heartbeats.bulk'), 'process.env.HEARTBEAT_API_URL': JSON.stringify('/users/current/heartbeats.bulk'),
['process.env.LOGOUT_USER_URL']: JSON.stringify('https://wakatime.com/logout'), 'process.env.LOGOUT_USER_URL': JSON.stringify('https://wakatime.com/logout'),
['process.env.NODE_ENV']: JSON.stringify(isProd ? 'production' : 'development'), 'process.env.NODE_ENV': JSON.stringify(isProd ? 'production' : 'development'),
['process.env.SUMMARIES_API_URL']: JSON.stringify('/users/current/summaries'), 'process.env.SUMMARIES_API_URL': JSON.stringify('/users/current/summaries'),
}), }),
], ],
resolve: { resolve: {