mirror of
https://github.com/desktop/desktop
synced 2024-08-24 18:57:33 +00:00
Merge pull request #13807 from desktop/ts-4.5-linting
TypeScript 4.5 linting
This commit is contained in:
commit
de51c3f51d
|
@ -2,7 +2,6 @@ root: true
|
|||
parser: '@typescript-eslint/parser'
|
||||
plugins:
|
||||
- '@typescript-eslint'
|
||||
- babel
|
||||
- react
|
||||
- json
|
||||
- jsdoc
|
||||
|
@ -100,9 +99,7 @@ rules:
|
|||
'@typescript-eslint/no-explicit-any': off
|
||||
'@typescript-eslint/no-inferrable-types': off
|
||||
'@typescript-eslint/no-empty-function': off
|
||||
|
||||
# Babel
|
||||
babel/no-invalid-this: error
|
||||
'@typescript-eslint/no-redeclare': error
|
||||
|
||||
# React
|
||||
react/jsx-boolean-value:
|
||||
|
@ -114,6 +111,10 @@ rules:
|
|||
react/jsx-uses-vars: error
|
||||
react/jsx-uses-react: error
|
||||
react/no-unused-state: error
|
||||
react/no-unused-prop-types: error
|
||||
react/prop-types:
|
||||
- error
|
||||
- ignore: ['children']
|
||||
|
||||
# JSDoc
|
||||
jsdoc/check-alignment: error
|
||||
|
@ -136,9 +137,9 @@ rules:
|
|||
###########
|
||||
curly: error
|
||||
no-new-wrappers: error
|
||||
no-redeclare:
|
||||
- error
|
||||
- builtinGlobals: true
|
||||
# We'll use no-redeclare from @typescript/eslint-plugin instead as that
|
||||
# supports overloads
|
||||
no-redeclare: off
|
||||
no-eval: error
|
||||
no-sync: error
|
||||
no-var: error
|
||||
|
|
|
@ -20,7 +20,7 @@ export interface IMatch<T> {
|
|||
|
||||
export type KeyFunction<T> = (item: T) => ReadonlyArray<string>
|
||||
|
||||
export function match<T, _K extends keyof T>(
|
||||
export function match<T>(
|
||||
query: string,
|
||||
items: ReadonlyArray<T>,
|
||||
getKey: KeyFunction<T>
|
||||
|
|
|
@ -23,9 +23,6 @@ let oauthState: IOAuthState | null = null
|
|||
* flow.
|
||||
*/
|
||||
export function askUserToOAuth(endpoint: string) {
|
||||
// Disable the lint warning since we're storing the `resolve` and `reject`
|
||||
// functions.
|
||||
// tslint:disable-next-line:promise-must-complete
|
||||
return new Promise<Account>((resolve, reject) => {
|
||||
oauthState = { state: uuid(), endpoint, resolve, reject }
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ export class ApiRepositoriesStore extends BaseStore {
|
|||
this.emitUpdate()
|
||||
}
|
||||
|
||||
private updateAccount<T, K extends keyof IAccountRepositories>(
|
||||
private updateAccount<K extends keyof IAccountRepositories>(
|
||||
account: Account,
|
||||
repositories: Pick<IAccountRepositories, K>
|
||||
) {
|
||||
|
|
|
@ -5205,7 +5205,6 @@ export class AppStore extends TypedBaseStore<IAppState> {
|
|||
* resolve when `_completeOpenInDesktop` is called.
|
||||
*/
|
||||
public _startOpenInDesktop(fn: () => void): Promise<Repository | null> {
|
||||
// tslint:disable-next-line:promise-must-complete
|
||||
const p = new Promise<Repository | null>(
|
||||
resolve => (this.resolveOpenInDesktop = resolve)
|
||||
)
|
||||
|
|
|
@ -140,8 +140,6 @@ export class RepositoryIndicatorUpdater {
|
|||
|
||||
public pause() {
|
||||
if (this.paused === false) {
|
||||
// Disable the lint warning since we're storing the `resolve`
|
||||
// tslint:disable-next-line:promise-must-complete
|
||||
this.pausePromise = new Promise<void>(resolve => {
|
||||
this.resolvePausePromise = resolve
|
||||
})
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import * as React from 'react'
|
||||
|
||||
// broken for SFCs: https://github.com/Microsoft/tslint-microsoft-contrib/issues/339
|
||||
/* tslint:disable react-unused-props-and-state */
|
||||
|
||||
interface IHighlightTextProps {
|
||||
/** The text to render */
|
||||
readonly text: string
|
||||
|
|
68
app/src/ui/tab-bar-item.tsx
Normal file
68
app/src/ui/tab-bar-item.tsx
Normal file
|
@ -0,0 +1,68 @@
|
|||
import * as React from 'react'
|
||||
import classNames from 'classnames'
|
||||
import { TabBarType } from './tab-bar-type'
|
||||
|
||||
interface ITabBarItemProps {
|
||||
readonly index: number
|
||||
readonly selected: boolean
|
||||
readonly onClick: (index: number) => void
|
||||
readonly onMouseEnter: (index: number) => void
|
||||
readonly onMouseLeave: () => void
|
||||
readonly onSelectAdjacent: (
|
||||
direction: 'next' | 'previous',
|
||||
index: number
|
||||
) => void
|
||||
readonly onButtonRef: (
|
||||
index: number,
|
||||
button: HTMLButtonElement | null
|
||||
) => void
|
||||
readonly type?: TabBarType
|
||||
}
|
||||
|
||||
export class TabBarItem extends React.Component<ITabBarItemProps, {}> {
|
||||
private onClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
this.props.onClick(this.props.index)
|
||||
}
|
||||
|
||||
private onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {
|
||||
const { type, index } = this.props
|
||||
const previousKey = type === TabBarType.Vertical ? 'ArrowUp' : 'ArrowLeft'
|
||||
const nextKey = type === TabBarType.Vertical ? 'ArrowDown' : 'ArrowRight'
|
||||
if (event.key === previousKey) {
|
||||
this.props.onSelectAdjacent('previous', index)
|
||||
event.preventDefault()
|
||||
} else if (event.key === nextKey) {
|
||||
this.props.onSelectAdjacent('next', index)
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
private onButtonRef = (buttonRef: HTMLButtonElement | null) => {
|
||||
this.props.onButtonRef(this.props.index, buttonRef)
|
||||
}
|
||||
|
||||
private onMouseEnter = () => {
|
||||
this.props.onMouseEnter(this.props.index)
|
||||
}
|
||||
|
||||
public render() {
|
||||
const selected = this.props.selected
|
||||
const className = classNames('tab-bar-item', { selected })
|
||||
return (
|
||||
<button
|
||||
ref={this.onButtonRef}
|
||||
className={className}
|
||||
onClick={this.onClick}
|
||||
role="tab"
|
||||
aria-selected={selected}
|
||||
tabIndex={selected ? undefined : -1}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.props.onMouseLeave}
|
||||
type="button"
|
||||
>
|
||||
{this.props.children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
}
|
11
app/src/ui/tab-bar-type.ts
Normal file
11
app/src/ui/tab-bar-type.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/** The tab bar type. */
|
||||
export enum TabBarType {
|
||||
/** Standard tabs */
|
||||
Tabs,
|
||||
|
||||
/** Simpler switch appearance */
|
||||
Switch,
|
||||
|
||||
/** Vertical tabs */
|
||||
Vertical,
|
||||
}
|
|
@ -1,22 +1,12 @@
|
|||
import * as React from 'react'
|
||||
import classNames from 'classnames'
|
||||
import { dragAndDropManager } from '../lib/drag-and-drop-manager'
|
||||
import { TabBarItem } from './tab-bar-item'
|
||||
import { TabBarType } from './tab-bar-type'
|
||||
export { TabBarType } from './tab-bar-type'
|
||||
|
||||
/** Time to wait for drag element hover before switching tabs */
|
||||
const dragTabSwitchWaitTime = 500
|
||||
|
||||
/** The tab bar type. */
|
||||
export enum TabBarType {
|
||||
/** Standard tabs */
|
||||
Tabs,
|
||||
|
||||
/** Simpler switch appearance */
|
||||
Switch,
|
||||
|
||||
/** Vertical tabs */
|
||||
Vertical,
|
||||
}
|
||||
|
||||
interface ITabBarProps {
|
||||
/** The currently selected tab. */
|
||||
readonly selectedIndex: number
|
||||
|
@ -144,68 +134,3 @@ export class TabBar extends React.Component<ITabBarProps, {}> {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
interface ITabBarItemProps {
|
||||
readonly index: number
|
||||
readonly selected: boolean
|
||||
readonly onClick: (index: number) => void
|
||||
readonly onMouseEnter: (index: number) => void
|
||||
readonly onMouseLeave: () => void
|
||||
readonly onSelectAdjacent: (
|
||||
direction: 'next' | 'previous',
|
||||
index: number
|
||||
) => void
|
||||
readonly onButtonRef: (
|
||||
index: number,
|
||||
button: HTMLButtonElement | null
|
||||
) => void
|
||||
readonly type?: TabBarType
|
||||
}
|
||||
|
||||
class TabBarItem extends React.Component<ITabBarItemProps, {}> {
|
||||
private onClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
this.props.onClick(this.props.index)
|
||||
}
|
||||
|
||||
private onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {
|
||||
const { type, index } = this.props
|
||||
const previousKey = type === TabBarType.Vertical ? 'ArrowUp' : 'ArrowLeft'
|
||||
const nextKey = type === TabBarType.Vertical ? 'ArrowDown' : 'ArrowRight'
|
||||
if (event.key === previousKey) {
|
||||
this.props.onSelectAdjacent('previous', index)
|
||||
event.preventDefault()
|
||||
} else if (event.key === nextKey) {
|
||||
this.props.onSelectAdjacent('next', index)
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
private onButtonRef = (buttonRef: HTMLButtonElement | null) => {
|
||||
this.props.onButtonRef(this.props.index, buttonRef)
|
||||
}
|
||||
|
||||
private onMouseEnter = () => {
|
||||
this.props.onMouseEnter(this.props.index)
|
||||
}
|
||||
|
||||
public render() {
|
||||
const selected = this.props.selected
|
||||
const className = classNames('tab-bar-item', { selected })
|
||||
return (
|
||||
<button
|
||||
ref={this.onButtonRef}
|
||||
className={className}
|
||||
onClick={this.onClick}
|
||||
role="tab"
|
||||
aria-selected={selected}
|
||||
tabIndex={selected ? undefined : -1}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.props.onMouseLeave}
|
||||
type="button"
|
||||
>
|
||||
{this.props.children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import { PopupType } from '../../models/popup'
|
|||
import { PreferencesTab } from '../../models/preferences'
|
||||
import { Ref } from '../lib/ref'
|
||||
import { suggestedExternalEditor } from '../../lib/editors/shared'
|
||||
import { TutorialStepInstructions } from './tutorial-step-instruction'
|
||||
|
||||
const TutorialPanelImage = encodePathAsUrl(
|
||||
__dirname,
|
||||
|
@ -310,93 +311,6 @@ export class TutorialPanel extends React.Component<
|
|||
}
|
||||
}
|
||||
|
||||
interface ITutorialStepInstructionsProps {
|
||||
/** Text displayed to summarize this step */
|
||||
readonly summaryText: string
|
||||
/** Used to find out if this step has been completed */
|
||||
readonly isComplete: (step: ValidTutorialStep) => boolean
|
||||
/** The step for this section */
|
||||
readonly sectionId: ValidTutorialStep
|
||||
/** Used to find out if this is the next step for the user to complete */
|
||||
readonly isNextStepTodo: (step: ValidTutorialStep) => boolean
|
||||
|
||||
/** ID of the currently expanded tutorial step
|
||||
* (used to determine if this step is expanded)
|
||||
*/
|
||||
readonly currentlyOpenSectionId: ValidTutorialStep
|
||||
|
||||
/** Skip button (if possible for this step) */
|
||||
readonly skipLinkButton?: JSX.Element
|
||||
/** Handler to open and close section */
|
||||
readonly onSummaryClick: (id: ValidTutorialStep) => void
|
||||
}
|
||||
|
||||
/** A step (summary and expandable description) in the tutorial side panel */
|
||||
class TutorialStepInstructions extends React.Component<
|
||||
ITutorialStepInstructionsProps
|
||||
> {
|
||||
public render() {
|
||||
return (
|
||||
<li key={this.props.sectionId} onClick={this.onSummaryClick}>
|
||||
<details
|
||||
open={this.props.sectionId === this.props.currentlyOpenSectionId}
|
||||
onClick={this.onSummaryClick}
|
||||
>
|
||||
{this.renderSummary()}
|
||||
<div className="contents">{this.props.children}</div>
|
||||
</details>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
private renderSummary = () => {
|
||||
const shouldShowSkipLink =
|
||||
this.props.skipLinkButton !== undefined &&
|
||||
this.props.currentlyOpenSectionId === this.props.sectionId &&
|
||||
this.props.isNextStepTodo(this.props.sectionId)
|
||||
return (
|
||||
<summary>
|
||||
{this.renderTutorialStepIcon()}
|
||||
<span className="summary-text">{this.props.summaryText}</span>
|
||||
<span className="hang-right">
|
||||
{shouldShowSkipLink ? (
|
||||
this.props.skipLinkButton
|
||||
) : (
|
||||
<Octicon symbol={OcticonSymbol.chevronDown} />
|
||||
)}
|
||||
</span>
|
||||
</summary>
|
||||
)
|
||||
}
|
||||
|
||||
private renderTutorialStepIcon() {
|
||||
if (this.props.isComplete(this.props.sectionId)) {
|
||||
return (
|
||||
<div className="green-circle">
|
||||
<Octicon symbol={OcticonSymbol.check} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// ugh zero-indexing
|
||||
const stepNumber = orderedTutorialSteps.indexOf(this.props.sectionId) + 1
|
||||
return this.props.isNextStepTodo(this.props.sectionId) ? (
|
||||
<div className="blue-circle">{stepNumber}</div>
|
||||
) : (
|
||||
<div className="empty-circle">{stepNumber}</div>
|
||||
)
|
||||
}
|
||||
|
||||
private onSummaryClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||
// prevents the default behavior of toggling on a `details` html element
|
||||
// so we don't have to fight it with our react state
|
||||
// for more info see:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#Events
|
||||
e.preventDefault()
|
||||
this.props.onSummaryClick(this.props.sectionId)
|
||||
}
|
||||
}
|
||||
|
||||
const SkipLinkButton: React.FunctionComponent<{
|
||||
onClick: () => void
|
||||
}> = props => <LinkButton onClick={props.onClick}>Skip</LinkButton>
|
||||
|
|
94
app/src/ui/tutorial/tutorial-step-instruction.tsx
Normal file
94
app/src/ui/tutorial/tutorial-step-instruction.tsx
Normal file
|
@ -0,0 +1,94 @@
|
|||
import * as React from 'react'
|
||||
import {
|
||||
ValidTutorialStep,
|
||||
orderedTutorialSteps,
|
||||
} from '../../models/tutorial-step'
|
||||
import { Octicon } from '../octicons'
|
||||
import * as OcticonSymbol from '../octicons/octicons.generated'
|
||||
|
||||
interface ITutorialStepInstructionsProps {
|
||||
/** Text displayed to summarize this step */
|
||||
readonly summaryText: string
|
||||
/** Used to find out if this step has been completed */
|
||||
readonly isComplete: (step: ValidTutorialStep) => boolean
|
||||
/** The step for this section */
|
||||
readonly sectionId: ValidTutorialStep
|
||||
/** Used to find out if this is the next step for the user to complete */
|
||||
readonly isNextStepTodo: (step: ValidTutorialStep) => boolean
|
||||
|
||||
/** ID of the currently expanded tutorial step
|
||||
* (used to determine if this step is expanded)
|
||||
*/
|
||||
readonly currentlyOpenSectionId: ValidTutorialStep
|
||||
|
||||
/** Skip button (if possible for this step) */
|
||||
readonly skipLinkButton?: JSX.Element
|
||||
/** Handler to open and close section */
|
||||
readonly onSummaryClick: (id: ValidTutorialStep) => void
|
||||
}
|
||||
|
||||
/** A step (summary and expandable description) in the tutorial side panel */
|
||||
export class TutorialStepInstructions extends React.Component<
|
||||
ITutorialStepInstructionsProps
|
||||
> {
|
||||
public render() {
|
||||
return (
|
||||
<li key={this.props.sectionId} onClick={this.onSummaryClick}>
|
||||
<details
|
||||
open={this.props.sectionId === this.props.currentlyOpenSectionId}
|
||||
onClick={this.onSummaryClick}
|
||||
>
|
||||
{this.renderSummary()}
|
||||
<div className="contents">{this.props.children}</div>
|
||||
</details>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
private renderSummary = () => {
|
||||
const shouldShowSkipLink =
|
||||
this.props.skipLinkButton !== undefined &&
|
||||
this.props.currentlyOpenSectionId === this.props.sectionId &&
|
||||
this.props.isNextStepTodo(this.props.sectionId)
|
||||
return (
|
||||
<summary>
|
||||
{this.renderTutorialStepIcon()}
|
||||
<span className="summary-text">{this.props.summaryText}</span>
|
||||
<span className="hang-right">
|
||||
{shouldShowSkipLink ? (
|
||||
this.props.skipLinkButton
|
||||
) : (
|
||||
<Octicon symbol={OcticonSymbol.chevronDown} />
|
||||
)}
|
||||
</span>
|
||||
</summary>
|
||||
)
|
||||
}
|
||||
|
||||
private renderTutorialStepIcon() {
|
||||
if (this.props.isComplete(this.props.sectionId)) {
|
||||
return (
|
||||
<div className="green-circle">
|
||||
<Octicon symbol={OcticonSymbol.check} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// ugh zero-indexing
|
||||
const stepNumber = orderedTutorialSteps.indexOf(this.props.sectionId) + 1
|
||||
return this.props.isNextStepTodo(this.props.sectionId) ? (
|
||||
<div className="blue-circle">{stepNumber}</div>
|
||||
) : (
|
||||
<div className="empty-circle">{stepNumber}</div>
|
||||
)
|
||||
}
|
||||
|
||||
private onSummaryClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||
// prevents the default behavior of toggling on a `details` html element
|
||||
// so we don't have to fight it with our react state
|
||||
// for more info see:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#Events
|
||||
e.preventDefault()
|
||||
this.props.onSummaryClick(this.props.sectionId)
|
||||
}
|
||||
}
|
|
@ -3,8 +3,6 @@ import { TransitionGroup, CSSTransition } from 'react-transition-group'
|
|||
import { WindowState } from '../../lib/window-state'
|
||||
|
||||
interface IFullScreenInfoProps {
|
||||
// react-unused-props-and-state doesn't understand getDerivedStateFromProps
|
||||
// tslint:disable-next-line:react-unused-props-and-state
|
||||
readonly windowState: WindowState | null
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ Our linting tooling uses a combination of
|
|||
|
||||
* [Prettier](https://github.com/prettier/prettier)
|
||||
* [ESLint](https://github.com/eslint/eslint)
|
||||
* [TSLint](https://github.com/palantir/tslint).
|
||||
|
||||
Most (if not all) editors have integrations for these tools so that they will report errors and fix formatting in realtime. See [tooling](./tooling.md) for how to set these integrations up while developing for desktop.
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# TypeScript Style Guide
|
||||
|
||||
Most of our preferred style when writing typescript is configured in our [`tslint.json`](../../tslint.json) and [`.eslintrc.yml`](../../.eslintrc.yml) files.
|
||||
Most of our preferred style when writing typescript is configured in our [`.eslintrc.yml`](../../.eslintrc.yml) files.
|
||||
|
||||
## Do
|
||||
- Use camelCase for methods
|
||||
- Use PascalCase for class names
|
||||
- Enable [TSLint](https://palantir.github.io/tslint/usage/third-party-tools/) and [ESLint](https://eslint.org/docs/user-guide/integrations) in your editor
|
||||
- [ESLint](https://eslint.org/docs/user-guide/integrations) in your editor
|
||||
|
||||
# Documenting your code
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@ Recommended packages:
|
|||
* [build-npm-apm](https://atom.io/packages/build-npm-apm) - invoke
|
||||
all npm scripts straight from the editor by pressing F7 (requires
|
||||
[build](https://atom.io/packages/build))
|
||||
* [linter](https://atom.io/packages/linter) and
|
||||
[linter-tslint](https://atom.io/packages/linter-tslint) - shows linter errors and warning in the editor
|
||||
* [linter](https://atom.io/packages/linter) - shows linter errors and warning in the editor
|
||||
|
||||
You can install them all at once with:
|
||||
|
||||
|
|
22
package.json
22
package.json
|
@ -29,9 +29,8 @@
|
|||
"lint": "yarn prettier && yarn lint:src",
|
||||
"lint:fix": "yarn prettier --write && yarn lint:src:fix",
|
||||
"prettier": "prettier --check \"./**/*.{ts,tsx,js,json,jsx,scss,html,yaml,yml}\"",
|
||||
"lint:src": "yarn tslint && yarn eslint-check && yarn eslint",
|
||||
"lint:src:fix": "yarn tslint --fix && yarn eslint --fix",
|
||||
"tslint": "tslint -p .",
|
||||
"lint:src": "yarn eslint-check && yarn eslint",
|
||||
"lint:src:fix": "yarn eslint --fix",
|
||||
"eslint": "eslint --cache --rulesdir ./eslint-rules \"./eslint-rules/**/*.js\" \"./script/**/*.ts{,x}\" \"./app/{src,typings,test}/**/*.{j,t}s{,x}\" \"./changelog.json\"",
|
||||
"eslint-check": "eslint --print-config .eslintrc.* | eslint-config-prettier-check",
|
||||
"publish": "ts-node -P script/tsconfig.json script/publish.ts",
|
||||
|
@ -60,10 +59,10 @@
|
|||
"@types/marked": "^4.0.1",
|
||||
"@types/plist": "^3.0.2",
|
||||
"@types/react-color": "^3.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^3.5.0",
|
||||
"@typescript-eslint/experimental-utils": "^3.5.0",
|
||||
"@typescript-eslint/parser": "^3.5.0",
|
||||
"@typescript-eslint/typescript-estree": "^3.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.2",
|
||||
"@typescript-eslint/experimental-utils": "^5.10.2",
|
||||
"@typescript-eslint/parser": "^5.10.2",
|
||||
"@typescript-eslint/typescript-estree": "^5.10.2",
|
||||
"airbnb-browser-shims": "^3.0.0",
|
||||
"ajv": "^6.4.0",
|
||||
"awesome-node-loader": "^1.1.0",
|
||||
|
@ -75,11 +74,10 @@
|
|||
"css-loader": "^2.1.0",
|
||||
"eslint": "^7.3.1",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-jsdoc": "^28.6.1",
|
||||
"eslint-plugin-jsdoc": "^37.7.0",
|
||||
"eslint-plugin-json": "^2.1.1",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"eslint-plugin-react": "^7.20.3",
|
||||
"eslint-plugin-react": "7.26.1",
|
||||
"express": "^4.15.0",
|
||||
"fake-indexeddb": "^2.0.4",
|
||||
"file-loader": "^2.0.0",
|
||||
|
@ -109,11 +107,7 @@
|
|||
"ts-jest": "^26.4.4",
|
||||
"ts-loader": "^8",
|
||||
"ts-node": "^7.0.0",
|
||||
"tslint": "^5.11.0",
|
||||
"tslint-config-prettier": "^1.14.0",
|
||||
"tslint-microsoft-contrib": "^6.2.0",
|
||||
"typescript": "^4.5.5",
|
||||
"typescript-tslint-plugin": "^0.0.6",
|
||||
"webpack": "^4.8.3",
|
||||
"webpack-bundle-analyzer": "^3.3.2",
|
||||
"webpack-dev-middleware": "^3.1.3",
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
"lib": ["ES2017", "DOM", "DOM.Iterable", "ES2018.Promise", "ES2020.string"],
|
||||
"useUnknownInCatchVariables": false
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "typescript-tslint-plugin"
|
||||
}
|
||||
],
|
||||
"include": ["app/**/*.ts", "app/**/*.tsx", "app/**/*.d.tsx"],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
|
|
15
tslint.json
15
tslint.json
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"extends": ["tslint-config-prettier"],
|
||||
"rulesDirectory": ["node_modules/tslint-microsoft-contrib/"],
|
||||
"rules": {
|
||||
"promise-must-complete": true,
|
||||
"react-unused-props-and-state": [
|
||||
true,
|
||||
{
|
||||
"props-interface-regex": "Props$",
|
||||
"state-interface-regex": "State$"
|
||||
}
|
||||
],
|
||||
"react-this-binding-issue": true
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue