mirror of
https://github.com/cpvalente/ontime.git
synced 2026-07-26 10:38:55 +00:00
chore: configure project wide linter (#577)
* chore(lint): configure project-wide linter * chore(lint): improve linting in files * chore(lint): hide warnings in CI
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"ONTIME_VERSION.js"
|
||||
@@ -6,8 +6,16 @@
|
||||
"es6": true,
|
||||
"jest": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier",
|
||||
"eslint-config-prettier"
|
||||
],
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"prettier"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
@@ -21,6 +29,27 @@
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"no-console": ["warn", { "allow": ["warn", "error"]}]
|
||||
"no-useless-concat": "warn",
|
||||
"prefer-template": "warn",
|
||||
"no-console": [
|
||||
"warn",
|
||||
{
|
||||
"allow": [
|
||||
"warn",
|
||||
"error"
|
||||
]
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"argsIgnorePattern": "^_",
|
||||
"caughtErrorsIgnorePattern": "^_",
|
||||
"destructuredArrayIgnorePattern": "^_",
|
||||
"varsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"prettier/prettier": "warn"
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,23 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
# Run code quality per package
|
||||
- name: React - Run linter
|
||||
run: pnpm lint
|
||||
working-directory: ./apps/client
|
||||
|
||||
- name: Server - Run linter
|
||||
run: pnpm lint
|
||||
working-directory: ./apps/server
|
||||
|
||||
- name: Utils - Run linter
|
||||
run: pnpm lint
|
||||
working-directory: ./packages/utils
|
||||
|
||||
- name: Types - Run linter
|
||||
run: pnpm lint
|
||||
working-directory: ./packages/types
|
||||
|
||||
# We choose to run tests separately
|
||||
- name: React - Run unit tests
|
||||
run: pnpm test:pipeline
|
||||
|
||||
+2
-18
@@ -8,34 +8,18 @@
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"eslint-config-prettier",
|
||||
"plugin:@tanstack/eslint-plugin-query/recommended",
|
||||
"prettier"
|
||||
"plugin:@tanstack/eslint-plugin-query/recommended"
|
||||
],
|
||||
"plugins": [
|
||||
"react",
|
||||
"testing-library",
|
||||
"simple-import-sort",
|
||||
"@tanstack/query",
|
||||
"@typescript-eslint",
|
||||
"prettier"
|
||||
"@tanstack/query"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
],
|
||||
"no-useless-concat": "warn",
|
||||
"prefer-template": "warn",
|
||||
"react/jsx-no-bind": [
|
||||
"error",
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"build": "vite build",
|
||||
"build:local": "cross-env NODE_ENV=local vite build",
|
||||
"build:docker": "vite build",
|
||||
"lint": "eslint .",
|
||||
"lint": "eslint . --quiet",
|
||||
"test": "vitest",
|
||||
"test:pipeline": "vitest run",
|
||||
"cleanup": "rm -rf .turbo && rm -rf node_modules && rm -rf build"
|
||||
|
||||
@@ -25,8 +25,14 @@ export default function MultiPartProgressBar(props: MultiPartProgressBar) {
|
||||
return (
|
||||
<div className={`multiprogress-bar ${hidden ? 'multiprogress-bar--hidden' : ''} ${className}`}>
|
||||
<div className='multiprogress-bar__bg-normal' style={{ backgroundColor: normalColor }} />
|
||||
<div className='multiprogress-bar__bg-warning' style={{ width: `${warningWidth}%`, backgroundColor: warningColor }} />
|
||||
<div className='multiprogress-bar__bg-danger' style={{ width: `${dangerWidth}%`, backgroundColor: dangerColor }} />
|
||||
<div
|
||||
className='multiprogress-bar__bg-warning'
|
||||
style={{ width: `${warningWidth}%`, backgroundColor: warningColor }}
|
||||
/>
|
||||
<div
|
||||
className='multiprogress-bar__bg-danger'
|
||||
style={{ width: `${dangerWidth}%`, backgroundColor: dangerColor }}
|
||||
/>
|
||||
<div className='multiprogress-bar__indicator' style={{ width: `${percentComplete}%` }} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -14,16 +14,7 @@ interface ScheduleItemProps {
|
||||
}
|
||||
|
||||
export default function ScheduleItem(props: ScheduleItemProps) {
|
||||
const {
|
||||
selected,
|
||||
timeStart,
|
||||
timeEnd,
|
||||
title,
|
||||
presenter,
|
||||
backstageEvent,
|
||||
colour,
|
||||
skip,
|
||||
} = props;
|
||||
const { selected, timeStart, timeEnd, title, presenter, backstageEvent, colour, skip } = props;
|
||||
|
||||
const start = formatTime(timeStart, { format: 'hh:mm' });
|
||||
const end = formatTime(timeEnd, { format: 'hh:mm' });
|
||||
@@ -37,9 +28,7 @@ export default function ScheduleItem(props: ScheduleItemProps) {
|
||||
{`${start} → ${end} ${backstageEvent ? '*' : ''}`}
|
||||
</div>
|
||||
<div className='entry-title'>{title}</div>
|
||||
{presenter && (
|
||||
<div className='entry-presenter'>{presenter}</div>
|
||||
)}
|
||||
{presenter && <div className='entry-presenter'>{presenter}</div>}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,12 +13,11 @@ export default function ScheduleNav({ className }: ScheduleNavProps) {
|
||||
<div className={`schedule-nav ${className}`}>
|
||||
{numPages > 1 &&
|
||||
[...Array(numPages).keys()].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={i === visiblePage ? 'schedule-nav__item schedule-nav__item--selected' : 'schedule-nav__item'}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
<div
|
||||
key={i}
|
||||
className={i === visiblePage ? 'schedule-nav__item schedule-nav__item--selected' : 'schedule-nav__item'}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ export default function useClickOutside<T extends HTMLElement = HTMLElement>(
|
||||
ref: RefObject<T>,
|
||||
callback: ClickOutsideEventHandler,
|
||||
) {
|
||||
|
||||
useEffect(() => {
|
||||
function handleClick(event: MouseEvent) {
|
||||
const element = ref?.current;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
|
||||
export type TLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
||||
|
||||
@@ -26,13 +20,13 @@ const LOG_LEVEL: Record<TLogLevel, number> = {
|
||||
};
|
||||
|
||||
const useFitText = ({
|
||||
logLevel: logLevelOption = 'info',
|
||||
maxFontSize = 100,
|
||||
minFontSize = 20,
|
||||
onFinish,
|
||||
onStart,
|
||||
resolution = 5,
|
||||
}: TOptions = {}) => {
|
||||
logLevel: logLevelOption = 'info',
|
||||
maxFontSize = 100,
|
||||
minFontSize = 20,
|
||||
onFinish,
|
||||
onStart,
|
||||
resolution = 5,
|
||||
}: TOptions = {}) => {
|
||||
const logLevel = LOG_LEVEL[logLevelOption];
|
||||
|
||||
const initState = useCallback(() => {
|
||||
@@ -112,8 +106,7 @@ const useFitText = ({
|
||||
const isWithinResolution = Math.abs(fontSize - fontSizePrev) <= resolution;
|
||||
const isOverflow =
|
||||
!!ref.current &&
|
||||
(ref.current.scrollHeight > ref.current.offsetHeight ||
|
||||
ref.current.scrollWidth > ref.current.offsetWidth);
|
||||
(ref.current.scrollHeight > ref.current.offsetHeight || ref.current.scrollWidth > ref.current.offsetWidth);
|
||||
const isFailed = isOverflow && fontSize === fontSizePrev;
|
||||
const isAsc = fontSize > fontSizePrev;
|
||||
|
||||
@@ -123,9 +116,7 @@ const useFitText = ({
|
||||
if (isFailed) {
|
||||
isCalculatingRef.current = false;
|
||||
if (logLevel <= LOG_LEVEL.info) {
|
||||
console.info(
|
||||
`[use-fit-text] reached \`minFontSize = ${minFontSize}\` without fitting text`,
|
||||
);
|
||||
console.info(`[use-fit-text] reached \`minFontSize = ${minFontSize}\` without fitting text`);
|
||||
}
|
||||
} else if (isOverflow) {
|
||||
setState({
|
||||
@@ -160,16 +151,7 @@ const useFitText = ({
|
||||
fontSizeMin: newMin,
|
||||
fontSizePrev: fontSize,
|
||||
});
|
||||
}, [
|
||||
calcKey,
|
||||
fontSize,
|
||||
fontSizeMax,
|
||||
fontSizeMin,
|
||||
fontSizePrev,
|
||||
onFinish,
|
||||
ref,
|
||||
resolution,
|
||||
]);
|
||||
}, [calcKey, fontSize, fontSizeMax, fontSizeMin, fontSizePrev, onFinish, ref, resolution]);
|
||||
|
||||
return { fontSize: `${fontSize}%`, ref };
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
/**
|
||||
* @description utility hook to around setInterval
|
||||
|
||||
@@ -46,7 +46,7 @@ export const useLocalStorage = <T>(key: string, initialValue: T): [T, (value: T
|
||||
setStoredValue(valueToStore);
|
||||
window.localStorage.setItem(`ontime-${key}`, JSON.stringify(valueToStore));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
return [storedValue, setValue];
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { resolvePath } from 'react-router-dom';
|
||||
import { validateAlias, generateURLFromAlias, getAliasRoute } from '../aliases';
|
||||
|
||||
import { generateURLFromAlias, getAliasRoute, validateAlias } from '../aliases';
|
||||
|
||||
describe('An alias fails if incorrect', () => {
|
||||
const testsToFail = [
|
||||
|
||||
@@ -12,7 +12,7 @@ test('Clamps a set of numbers correctly', () => {
|
||||
{ num: -50, min: 0, max: 0, result: 0 },
|
||||
{ num: 50.5, min: 0, max: 100, result: 50.5 },
|
||||
{ num: 50, min: 0, max: 20.32, result: 20.32 },
|
||||
{ num: 10, min: 20.32, max: 40, result: 20.32 }
|
||||
{ num: 10, min: 20.32, max: 40, result: 20.32 },
|
||||
];
|
||||
|
||||
testCases.forEach((t) => expect(clamp(t.num, t.min, t.max)).toBe(t.result));
|
||||
|
||||
+2
-3
@@ -13,9 +13,8 @@ declare global {
|
||||
};
|
||||
process: {
|
||||
type: string;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/no-anonymous-default-export
|
||||
export default {}
|
||||
export default {};
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@ import 'vitest';
|
||||
// https://github.com/testing-library/jest-dom/issues/123
|
||||
declare global {
|
||||
namespace Vi {
|
||||
interface Assertion<T = any> extends TestingLibraryMatchers<T, void> {}
|
||||
type Assertion<T = any> = TestingLibraryMatchers<T, void>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
interface CuesheetRowProps {
|
||||
row: OntimeRundownEntry;
|
||||
isSelected: boolean;
|
||||
}
|
||||
|
||||
function CuesheetRow() {}
|
||||
@@ -21,7 +21,9 @@ import style from './SettingsModal.module.scss';
|
||||
const aliasesDocsUrl = 'https://ontime.gitbook.io/v2/features/url-aliases';
|
||||
|
||||
// we wrap the array in an object to be simplify react-hook-form
|
||||
type Aliases = { aliases: Alias[] };
|
||||
type Aliases = {
|
||||
aliases: Alias[];
|
||||
};
|
||||
|
||||
export default function AliasesForm() {
|
||||
const { data, status, isFetching, refetch } = useAliases();
|
||||
@@ -93,8 +95,7 @@ export default function AliasesForm() {
|
||||
<AlertDescription>
|
||||
Custom aliases allow providing a short name for any ontime URL. <br />
|
||||
It serves two primary purposes: <br />
|
||||
- Providing dynamic URLs for automation or unattended screens <br />
|
||||
- Simplifying complex URLs
|
||||
- Providing dynamic URLs for automation or unattended screens <br />- Simplifying complex URLs
|
||||
<ModalLink href={aliasesDocsUrl}>For more information, see the docs</ModalLink>
|
||||
</AlertDescription>
|
||||
</div>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "",
|
||||
"lint": "eslint . --quiet",
|
||||
"dev:electron": "cross-env NODE_ENV=development electron .",
|
||||
"dist-win": "electron-builder --publish=never --x64 --win",
|
||||
"dist-mac": "electron-builder --publish=never --mac",
|
||||
|
||||
@@ -8,23 +8,23 @@ function getApplicationMenu(isMac, askToQuit) {
|
||||
return [
|
||||
...(isMac
|
||||
? [
|
||||
{
|
||||
label: 'Ontime',
|
||||
submenu: [
|
||||
{ role: 'about' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'hide' },
|
||||
{ role: 'hideOthers' },
|
||||
{ role: 'unhide' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'quit',
|
||||
click: () => askToQuit(),
|
||||
accelerator: 'Cmd+Q',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
{
|
||||
label: 'Ontime',
|
||||
submenu: [
|
||||
{ role: 'about' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'hide' },
|
||||
{ role: 'hideOthers' },
|
||||
{ role: 'unhide' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'quit',
|
||||
click: () => askToQuit(),
|
||||
accelerator: 'Cmd+Q',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: 'File',
|
||||
@@ -41,15 +41,15 @@ function getApplicationMenu(isMac, askToQuit) {
|
||||
{ role: 'paste' },
|
||||
...(isMac
|
||||
? [
|
||||
{ role: 'pasteAndMatchStyle' },
|
||||
{ role: 'delete' },
|
||||
{ role: 'selectAll' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Speech',
|
||||
submenu: [{ role: 'startSpeaking' }, { role: 'stopSpeaking' }],
|
||||
},
|
||||
]
|
||||
{ role: 'pasteAndMatchStyle' },
|
||||
{ role: 'delete' },
|
||||
{ role: 'selectAll' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Speech',
|
||||
submenu: [{ role: 'startSpeaking' }, { role: 'stopSpeaking' }],
|
||||
},
|
||||
]
|
||||
: [{ role: 'delete' }, { type: 'separator' }, { role: 'selectAll' }]),
|
||||
],
|
||||
},
|
||||
@@ -161,4 +161,4 @@ function getApplicationMenu(isMac, askToQuit) {
|
||||
];
|
||||
}
|
||||
|
||||
module.exports = { getApplicationMenu }
|
||||
module.exports = { getApplicationMenu };
|
||||
|
||||
@@ -13,7 +13,7 @@ function getTrayMenu(showApp, askToQuit) {
|
||||
label: 'Shutdown',
|
||||
click: () => askToQuit(),
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
module.exports = { getTrayMenu }
|
||||
module.exports = { getTrayMenu };
|
||||
|
||||
@@ -2,23 +2,8 @@
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"plugins": ["@typescript-eslint", "prettier"],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"build:local": "pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --bundle --minify --outfile=dist/index.cjs",
|
||||
"build:docker": "pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --minify --bundle --outfile=dist/docker.cjs",
|
||||
"build:debug": "pnpm prebuild && esbuild src/app.ts --platform=node --format=cjs --bundle --outfile=dist/index.cjs",
|
||||
"lint": "eslint .",
|
||||
"lint": "eslint . --quiet",
|
||||
"test": "cross-env IS_TEST=true vitest",
|
||||
"test:pipeline": "cross-env IS_TEST=true vitest run",
|
||||
"typecheck": "tsc --noEmit",
|
||||
|
||||
@@ -30,7 +30,7 @@ const whitelistedPayload = {
|
||||
};
|
||||
|
||||
export function parse(field: string, value: unknown) {
|
||||
if (!whitelistedPayload.hasOwnProperty(field)) {
|
||||
if (!Object.hasOwn(whitelistedPayload, field)) {
|
||||
throw new Error(`Field ${field} not permitted`);
|
||||
}
|
||||
const parserFn = whitelistedPayload[field];
|
||||
@@ -51,7 +51,7 @@ export function updateEvent(
|
||||
const event = EventLoader.getEventWithId(eventId);
|
||||
|
||||
if (event) {
|
||||
let propertiesToUpdate = { [propertyName]: newValue };
|
||||
const propertiesToUpdate = { [propertyName]: newValue };
|
||||
|
||||
// Handles the special case for duration
|
||||
// needs to be converted to milliseconds
|
||||
|
||||
@@ -14,7 +14,7 @@ export function dispatchFromAdapter(
|
||||
payload: unknown;
|
||||
params?: Array<string>;
|
||||
},
|
||||
source?: 'osc' | 'ws',
|
||||
_source?: 'osc' | 'ws',
|
||||
) {
|
||||
const payload = args.payload;
|
||||
const typeComponents = type.toLowerCase().split('/');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable no-console -- we are mocking the console */
|
||||
import { vi } from 'vitest';
|
||||
|
||||
import { EndAction, TimerType } from 'ontime-types';
|
||||
import { EndAction, OntimeEvent, TimerType } from 'ontime-types';
|
||||
|
||||
import { dbModel } from '../../models/dataModel.js';
|
||||
import { parseExcel, parseJson, validateEvent } from '../parser.js';
|
||||
|
||||
+1
-6
@@ -4,10 +4,5 @@
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
],
|
||||
"plugins": [],
|
||||
"rules": {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"dev": "turbo run dev",
|
||||
"dev:electron": "turbo run dev --filter=ontime",
|
||||
"dev:server": "turbo run dev --filter=ontime-server",
|
||||
"lint": "turbo run lint",
|
||||
"build": "turbo run build",
|
||||
"build:local": "turbo run build:local",
|
||||
"dist-win": "turbo run dist-win",
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"private": true,
|
||||
"description": "shared typings for ontime",
|
||||
"scripts": {
|
||||
"cleanup": "rm -rf .turbo && rm -rf node_modules"
|
||||
"cleanup": "rm -rf .turbo && rm -rf node_modules",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
||||
@@ -2,4 +2,4 @@ export type Alias = {
|
||||
enabled: boolean;
|
||||
alias: string;
|
||||
pathAndParams: string;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,5 +9,4 @@ export type UserFields = {
|
||||
user7: string;
|
||||
user8: string;
|
||||
user9: string;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -6,4 +6,4 @@ export type ViewSettings = {
|
||||
warningThreshold: number;
|
||||
dangerColor: string;
|
||||
dangerThreshold: number;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -23,5 +23,5 @@ export enum LogOrigin {
|
||||
Rx = 'RX',
|
||||
Server = 'SERVER',
|
||||
Tx = 'TX',
|
||||
User = 'USER'
|
||||
User = 'USER',
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@ export type Message = {
|
||||
export type TimerMessage = Message & {
|
||||
timerBlink: boolean;
|
||||
timerBlackout: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,27 +3,14 @@
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"simple-import-sort",
|
||||
"prettier"
|
||||
],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier"
|
||||
"simple-import-sort"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
],
|
||||
"simple-import-sort/exports": "error",
|
||||
"simple-import-sort/imports": "error"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"private": true,
|
||||
"description": "shared logic for ontime",
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"lint": "eslint . --quiet",
|
||||
"test": "vitest",
|
||||
"test:pipeline": "vitest run",
|
||||
"cleanup": "rm -rf .turbo && rm -rf node_modules"
|
||||
|
||||
@@ -17,6 +17,7 @@ export function getIncrement(input: string): string {
|
||||
const match = regex.exec(input);
|
||||
if (match) {
|
||||
// If a number is found, extract the non-numeric prefix, integer part, and decimal part
|
||||
// eslint-disable-next-line prefer-const -- some items in the destructuring are modified
|
||||
let [, prefix, integerPart, decimalPart] = match;
|
||||
|
||||
if (decimalPart) {
|
||||
|
||||
Reference in New Issue
Block a user