Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate from TSLint to ESLint #128

Merged
merged 4 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
src/generated/
.dist/
dist/
node_modules/
.vscode/
tsd/
package.json
webpack.config.ts
29 changes: 21 additions & 8 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
// We are using eslint with the typescript parser plugin only to validate things
// which are not supported in tslint, such as react hooks
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
jsx: true,
sourceType: 'module'
root: true,
env: {
browser: true,
es6: true,
node: true
},
plugins: ['react-hooks'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'react-hooks', 'jest'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'plugin:jest/recommended',
'prettier',
'prettier/@typescript-eslint'
],
rules: {
'react-hooks/rules-of-hooks': 'error'
'no-case-declarations': 'warn',
'jest/no-mocks-import': 'off',
'jest/valid-title': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/ban-types': 'warn',
'@typescript-eslint/no-empty-function': 'warn'
}
};
25 changes: 11 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
"build": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' webpack --config webpack.config.ts --mode=development",
"clean": "rm -rf dist",
"codecov": "codecov -f .coverage/coverage-final.json",
"lint": "tslint --project .",
"lint-fix": "tslint --fix --project . && prettier --write './**/*.{js,json}'",
"lint:hooks": "eslint \"src/**/*.{ts,tsx}\"",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint-fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix && prettier --write './**/*.{js,json}'",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we also want prettier to format ts and tsx files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. The separate call to prettier is unnecessary. ESLint is configured to use prettier for formatting rules, so eslint --fix should catch all of it.
I cleaned up the scripts and lint-staged config to skip json/jsx(we don't have jsx files) as well.

"mockApi": "node ./mockApi",
"prebuild": "yarn run clean",
"start": "node -r dotenv/config index.js",
Expand All @@ -37,8 +36,7 @@
"license": "Apache-2.0",
"lint-staged": {
"*.{ts,tsx}": [
"eslint",
"tslint --fix",
"eslint --fix --ext .js,.jsx,.ts,.tsx",
"git add"
],
"*.{js,json}": [
Expand Down Expand Up @@ -131,7 +129,8 @@
"@types/webpack-dev-middleware": "^1.9.2",
"@types/webpack-env": "^1.13.1",
"@types/webpack-hot-middleware": "^2.15.0",
"@typescript-eslint/parser": "^1.0.0",
"@typescript-eslint/eslint-plugin": "^4.9.1",
"@typescript-eslint/parser": "^4.9.1",
"@xstate/react": "^1.0.0",
"add-asset-html-webpack-plugin": "^2.1.3",
"autoprefixer": "^8.3.0",
Expand All @@ -150,8 +149,11 @@
"d3-shape": "^1.2.2",
"debug": "^3.1.0",
"dom-helpers": "^3.4.0",
"eslint": "^5.12.1",
"eslint-plugin-react-hooks": "^2.3.0",
"eslint": "^7.15.0",
"eslint-config-prettier": "^7.0.0",
"eslint-plugin-jest": "^24.1.3",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"favicons-webpack-plugin": "^1.0.2",
"file-loader": "^1.1.11",
"fork-ts-checker-webpack-plugin": "^4.0.3",
Expand Down Expand Up @@ -193,12 +195,7 @@
"ts-jest": "^26.3.0",
"ts-loader": "^6.2.1",
"ts-node": "^8.0.2",
"tslint": "^5.20.1",
"tslint-config-airbnb": "^5.11.2",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^4.1.0",
"typescript": "^4.0.0",
"typescript": "^4.1.2",
"uglifyjs-webpack-plugin": "^1.2.5",
"url-search-params": "^0.10.0",
"use-react-router": "^1.0.7",
Expand Down
8 changes: 4 additions & 4 deletions src/common/test/formatters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ jest.mock('../timezone.ts', () => ({

const invalidDates = ['abc', -200, 0];
// Matches strings in the form 01/01/2000 01:01:00 PM (5 minutes ago)
const dateWithAgoRegex = /^[\w\/:\s]+ (AM|PM)\s+UTC\s+\([a\d] (minute|hour|day|second)s? ago\)$/;
const dateWithAgoRegex = /^[\w/:\s]+ (AM|PM)\s+UTC\s+\([a\d] (minute|hour|day|second)s? ago\)$/;
const dateFromNowRegex = /^[a\d] (minute|hour|day|second)s? ago$/;
const dateRegex = /^[\w\/:\s]+ (AM|PM)/;
const utcDateRegex = /^[\w\/:\s]+ (AM|PM) UTC/;
const localDateRegex = /^[\w\/:\s]+ (AM|PM) (PDT|PST)/;
const dateRegex = /^[\w/:\s]+ (AM|PM)/;
const utcDateRegex = /^[\w/:\s]+ (AM|PM) UTC/;
const localDateRegex = /^[\w/:\s]+ (AM|PM) (PDT|PST)/;

describe('dateWithFromNow', () => {
invalidDates.forEach(v =>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Cache/createCache.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { getCacheKey } from './utils';

type EntityKey = object | string | Symbol;
type EntityKey = object | string | symbol;
interface HasIdObject {
id: object;
}

function hasId(value: Object): value is HasIdObject {
return value.hasOwnProperty('id');
return {}.hasOwnProperty.call(value, ('id'));
}

/** A generic cache for any type of object or Array. Keys can be objects,
Expand Down
7 changes: 5 additions & 2 deletions src/components/Cache/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import * as objectHash from 'object-hash';
/** Generic cache key generator. For object, will generate a unique hash.
* Strings are passed through for convenience.
*/
export function getCacheKey(id: any[] | object | string) {
return typeof id === 'string' || typeof id === 'symbol'
export function getCacheKey(id: any[] | object | string | symbol): string {
if (typeof id === 'symbol') {
return id.toString();
}
return typeof id === 'string'
? id
: // We only want to compare own properties, not .__proto__, .constructor, etc.
objectHash(id, { respectType: false });
Expand Down
8 changes: 4 additions & 4 deletions src/components/Entities/EntityDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,23 @@ export const EntityDetails: React.FC<EntityDetailsProps> = ({ id }) => {
onClickLaunch={onLaunch}
/>
<div className={styles.metadataContainer}>
{!!sections.description ? (
{sections.description ? (
<div className={styles.descriptionContainer}>
<EntityDescription id={id} />
</div>
) : null}
{!!sections.schedules ? (
{sections.schedules ? (
<div className={styles.schedulesContainer}>
<EntitySchedules id={id} />
</div>
) : null}
</div>
{!!sections.executions ? (
{sections.executions ? (
<div className={styles.executionsContainer}>
<EntityExecutions id={id} />
</div>
) : null}
{!!sections.launch ? (
{sections.launch ? (
<Dialog
scroll="paper"
maxWidth="sm"
Expand Down
2 changes: 2 additions & 0 deletions src/components/Entities/test/EntitySchedules.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { render, waitFor } from '@testing-library/react';
// launchPlanData is mock data, not a Jest mock
// eslint-disable-next-line jest/no-mocks-import
import {
createMockLaunchPlan,
mockLaunchPlanSchedules
Expand Down
3 changes: 1 addition & 2 deletions src/components/Errors/test/LoginExpiredHandler.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ describe('LoginExpiredHandler', () => {
})
);

await waitFor(() => {});
expect(getByText('Login')).toBeInTheDocument();
await waitFor(() => getByText('Login'));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const NodeExecutionTabs: React.FC<{
break;
}
case tabIds.task: {
tabContent = !!taskTemplate ? (
tabContent = taskTemplate ? (
<NodeExecutionTaskDetails taskTemplate={taskTemplate} />
) : null;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const useStyles = makeStyles((theme: Theme) => ({
}
}));

const statusSize: number = 11;
const statusSize = 11;

/** Renders an indicator for a node based on execution status */
export const StatusIndicator: React.FC<{
Expand Down
4 changes: 2 additions & 2 deletions src/components/Executions/ExecutionFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const useStyles = makeStyles((theme: Theme) => ({
}));

const RenderFilter: React.FC<{ filter: FilterState }> = ({ filter }) => {
const searchFilterState = filter as SearchFilterState;
switch (filter.type) {
case 'single':
return <SingleSelectForm {...(filter as SingleFilterState<any>)} />;
Expand All @@ -35,8 +36,7 @@ const RenderFilter: React.FC<{ filter: FilterState }> = ({ filter }) => {
<MultiSelectForm {...(filter as MultiFilterState<any, any>)} />
);
case 'search':
const state = filter as SearchFilterState;
return <SearchInputForm {...state} defaultValue={state.value} />;
return <SearchInputForm {...searchFilterState} defaultValue={searchFilterState.value} />;
default:
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Executions/ExecutionInputsOutputsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export const ExecutionInputsOutputsModal: React.FC<ExecutionInputsOutputsModalPr
open={!!execution}
onClose={onClose}
>
{!!execution ? (
{execution ? (
<RenderDialog execution={execution} onClose={onClose} />
) : (
<div />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ const WorkflowExecutionRow: React.FC<WorkflowExecutionRowProps> = ({
);
};

export interface WorkflowExecutionsTableProps extends ListProps<Execution> {}
export type WorkflowExecutionsTableProps = ListProps<Execution>

/** Renders a table of WorkflowExecution records. Executions with errors will
* have an expanadable container rendered as part of the table row.
Expand Down
2 changes: 1 addition & 1 deletion src/components/Executions/filters/useMultiFilterState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useFilterButtonState } from './useFilterButtonState';
function serializeForQueryState(values: any[]) {
return values.join(';');
}
function deserializeFromQueryState(stateValue: string = '') {
function deserializeFromQueryState(stateValue = '') {
return stateValue.split(';');
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/Executions/filters/useSingleFilterState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function valueOrDefault<FilterKey extends string>(
return defaultValue;
}

if (!options.hasOwnProperty(newValue)) {
if (!{}.hasOwnProperty.call(options,newValue)) {
log.warn(`Filter has no option ${newValue}, using default`);
return defaultValue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Executions/useNodeExecutionDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function createWorkflowNodeExecutionDetails(
node: CompiledWorkflowNode
): NodeExecutionDetails {
const displayType = NodeExecutionDisplayType.Workflow;
let displayId: string = '';
let displayId = '';
const { launchplanRef, subWorkflowRef } = node.workflowNode;
const identifier = (launchplanRef
? launchplanRef
Expand Down
7 changes: 3 additions & 4 deletions src/components/Launch/LaunchForm/services.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { RefObject } from 'react';
import { correctInputErrors } from './constants';
import { WorkflowLaunchContext } from './launchMachine';
import { LaunchFormInputsRef } from './types';

export async function validate(
formInputsRef: RefObject<LaunchFormInputsRef>,
{}: WorkflowLaunchContext
) {
formInputsRef: RefObject<LaunchFormInputsRef>
): Promise<boolean> {
if (formInputsRef.current === null) {
throw new Error('Unexpected empty form inputs ref');
}

if (!formInputsRef.current.validate()) {
throw new Error(correctInputErrors);
}
return true;
}
5 changes: 2 additions & 3 deletions src/components/Launch/LaunchForm/useLaunchTaskFormState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ async function loadInputs(

async function validate(
formInputsRef: RefObject<LaunchFormInputsRef>,
roleInputRef: RefObject<LaunchRoleInputRef>,
context: any
roleInputRef: RefObject<LaunchRoleInputRef>
) {
if (roleInputRef.current === null) {
throw new Error('Unexpected empty role input ref');
Expand All @@ -107,7 +106,7 @@ async function validate(
if (!roleInputRef.current.validate()) {
throw new Error(correctInputErrors);
}
return baseValidate(formInputsRef, context);
return baseValidate(formInputsRef);
}

async function submit(
Expand Down
2 changes: 1 addition & 1 deletion src/components/Launch/LaunchPlansTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const useStyles = makeStyles((theme: Theme) => ({
}
}));

export interface LaunchPlansTableProps extends ListProps<LaunchPlan> {}
export type LaunchPlansTableProps = ListProps<LaunchPlan>
export interface CellDataGetterParams extends TableCellDataGetterParams {
rowData: LaunchPlan;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Launch/SchedulesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const useStyles = makeStyles((theme: Theme) => ({
}
}));

export interface SchedulesTableProps extends ListProps<LaunchPlan> {}
export type SchedulesTableProps = ListProps<LaunchPlan>
interface CellDataGetterParams extends TableCellDataGetterParams {
rowData: LaunchPlan;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Literals/Scalar/PrimitiveValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Primitive } from 'models';
function primitiveToString(primitive: Primitive): string {
switch (primitive.value) {
case 'boolean':
return !!primitive.boolean ? 'true' : 'false';
return primitive.boolean ? 'true' : 'false';
case 'datetime':
return formatDateUTC(timestampToDate(primitive.datetime!));
case 'duration':
Expand Down
2 changes: 1 addition & 1 deletion src/components/SelectProject/ProjectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export interface ProjectListProps {
const ProjectCard: React.FC<{ project: Project }> = ({ project }) => {
const styles = useStyles();
const commonStyles = useCommonStyles();
const description = !!project.description
const description = project.description
? project.description
: defaultProjectDescription;
return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/Tables/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TableCellProps as BaseTableCellProps } from 'react-virtualized';
export type LoadMoreRowItem = Symbol;
export type LoadMoreRowItem = symbol;
/** A fixed row height shared across all rows, or a callback which receives an item index and computes the height */
export type RowHeight = number | ((index: number) => number);

Expand Down
2 changes: 1 addition & 1 deletion src/components/Workflow/WorkflowsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const useStyles = makeStyles((theme: Theme) => ({
}
}));

export interface WorkflowsTableProps extends ListProps<Workflow> {}
export type WorkflowsTableProps = ListProps<Workflow>
export interface CellDataGetterParams extends TableCellDataGetterParams {
rowData: Workflow;
}
Expand Down
10 changes: 5 additions & 5 deletions src/components/flytegraph/DragAllowingClickHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export type DragFilteringClickHandlerListener = (
* will be called with the final mouseup event if the click has not been filtered
*/
export class DragFilteringClickHandler {
private deltaX: number = 0;
private deltaY: number = 0;
private xPos: number = 0;
private yPos: number = 0;
private dragging: boolean = false;
private deltaX = 0;
private deltaY = 0;
private xPos = 0;
private yPos = 0;
private dragging = false;

constructor(
private listener: DragFilteringClickHandlerListener,
Expand Down
2 changes: 1 addition & 1 deletion src/components/flytegraph/InteractiveViewBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function scaleViewBox(viewBox: ViewBoxRect, scaleDelta: number): ViewBoxRect {

class InteractiveViewBoxImpl extends React.Component<InteractiveViewBoxProps> {
private viewBox: ViewBoxRect;
private updating: boolean = false;
private updating = false;
private dragData: DragData = defaultDragData;
private viewboxRef: React.RefObject<HTMLDivElement>;

Expand Down
Loading