From 0cd911a916805d3b1f8043584e4685f3edd5c427 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 21 Dec 2021 21:42:40 +0100 Subject: [PATCH 1/6] fix(eslint-plugin): [consistent-type-definitions] correct fixer with declare keyword (#4334) --- .../src/rules/consistent-type-definitions.ts | 4 +- .../rules/consistent-type-definitions.test.ts | 46 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts index efb7bdd8d5da..c71d812efd92 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts @@ -58,7 +58,7 @@ export default util.createRule({ const typeNode = node.typeParameters ?? node.id; const fixes: TSESLint.RuleFix[] = []; - const firstToken = sourceCode.getFirstToken(node); + const firstToken = sourceCode.getTokenBefore(node.id); if (firstToken) { fixes.push(fixer.replaceText(firstToken, 'interface')); fixes.push( @@ -98,7 +98,7 @@ export default util.createRule({ const typeNode = node.typeParameters ?? node.id; const fixes: TSESLint.RuleFix[] = []; - const firstToken = sourceCode.getFirstToken(node); + const firstToken = sourceCode.getTokenBefore(node.id); if (firstToken) { fixes.push(fixer.replaceText(firstToken, 'type')); fixes.push( diff --git a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts index f96672a213fc..9bcd9574986a 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts @@ -305,5 +305,51 @@ export default Test }, ], }, + { + // https://github.com/typescript-eslint/typescript-eslint/issues/4333 + code: ` +export declare type Test = { + foo: string; + bar: string; +}; + `, + output: ` +export declare interface Test { + foo: string; + bar: string; +} + `, + options: ['interface'], + errors: [ + { + messageId: 'interfaceOverType', + line: 2, + column: 21, + }, + ], + }, + { + // https://github.com/typescript-eslint/typescript-eslint/issues/4333 + code: ` +export declare interface Test { + foo: string; + bar: string; +} + `, + output: noFormat` +export declare type Test = { + foo: string; + bar: string; +} + `, + options: ['type'], + errors: [ + { + messageId: 'typeOverInterface', + line: 2, + column: 26, + }, + ], + }, ], }); From 135f30af3d24db23d1641ff08b29d4acf77a578f Mon Sep 17 00:00:00 2001 From: Armano Date: Thu, 23 Dec 2021 19:00:49 +0100 Subject: [PATCH 2/6] docs(website): add preview of scope manager to playground (#4312) --- packages/website-eslint/src/linter/linter.js | 9 +- packages/website-eslint/types/index.d.ts | 13 +- .../src/components/ASTViewerESTree.tsx | 64 ++---- .../website/src/components/ASTViewerScope.tsx | 29 +++ .../website/src/components/ASTViewerTS.tsx | 151 +++++-------- .../src/components/OptionsSelector.tsx | 1 + .../website/src/components/Playground.tsx | 55 +++-- .../website/src/components/ast/ASTViewer.tsx | 35 +-- .../website/src/components/ast/Elements.tsx | 151 ++++++------- .../website/src/components/ast/HiddenItem.tsx | 35 +-- .../website/src/components/ast/ItemGroup.tsx | 41 ++-- .../src/components/ast/PropertyName.tsx | 41 ++-- .../src/components/ast/PropertyValue.tsx | 45 ++-- .../website/src/components/ast/SimpleItem.tsx | 49 +++++ .../components/ast/serializer/serializer.ts | 89 ++++++++ .../ast/serializer/serializerESTree.ts | 34 +++ .../ast/serializer/serializerScope.ts | 203 ++++++++++++++++++ .../components/ast/serializer/serializerTS.ts | 57 +++++ packages/website/src/components/ast/types.ts | 61 ++++-- packages/website/src/components/ast/utils.ts | 33 ++- .../src/components/editor/LoadedEditor.tsx | 2 + .../website/src/components/editor/types.ts | 4 +- .../src/components/hooks/useHashState.ts | 4 +- packages/website/src/components/types.ts | 2 +- packages/website/tsconfig.json | 2 +- 25 files changed, 823 insertions(+), 387 deletions(-) create mode 100644 packages/website/src/components/ASTViewerScope.tsx create mode 100644 packages/website/src/components/ast/SimpleItem.tsx create mode 100644 packages/website/src/components/ast/serializer/serializer.ts create mode 100644 packages/website/src/components/ast/serializer/serializerESTree.ts create mode 100644 packages/website/src/components/ast/serializer/serializerScope.ts create mode 100644 packages/website/src/components/ast/serializer/serializerTS.ts diff --git a/packages/website-eslint/src/linter/linter.js b/packages/website-eslint/src/linter/linter.js index 1643dcf2562f..aae8ecc0feda 100644 --- a/packages/website-eslint/src/linter/linter.js +++ b/packages/website-eslint/src/linter/linter.js @@ -9,14 +9,17 @@ export function loadLinter() { const linter = new Linter(); let storedAST; let storedTsAST; + let storedScope; linter.defineParser(PARSER_NAME, { parseForESLint(code, options) { const toParse = parseForESLint(code, options); storedAST = toParse.ast; storedTsAST = toParse.tsAst; + storedScope = toParse.scopeManager; return toParse; - }, // parse(code: string, options: ParserOptions): ParseForESLintResult['ast'] { + }, + // parse(code: string, options: ParserOptions): ParseForESLintResult['ast'] { // const toParse = parseForESLint(code, options); // storedAST = toParse.ast; // return toParse.ast; @@ -37,6 +40,10 @@ export function loadLinter() { return { ruleNames: ruleNames, + getScope() { + return storedScope; + }, + getAst() { return storedAST; }, diff --git a/packages/website-eslint/types/index.d.ts b/packages/website-eslint/types/index.d.ts index 86e0c02eed6c..4e923c2fef1c 100644 --- a/packages/website-eslint/types/index.d.ts +++ b/packages/website-eslint/types/index.d.ts @@ -1,18 +1,18 @@ -import type { TSESLint } from '@typescript-eslint/experimental-utils'; +import type { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; import type { ParserOptions } from '@typescript-eslint/types'; +import type { SourceFile } from 'typescript'; export type LintMessage = TSESLint.Linter.LintMessage; export type RuleFix = TSESLint.RuleFix; export type RulesRecord = TSESLint.Linter.RulesRecord; export type RuleEntry = TSESLint.Linter.RuleEntry; -export type ParseForESLintResult = TSESLint.Linter.ESLintParseResult; -export type ESLintAST = ParseForESLintResult['ast']; export interface WebLinter { ruleNames: { name: string; description?: string }[]; - getAst(): ESLintAST; - getTsAst(): Record; + getAst(): TSESTree.Program; + getTsAst(): SourceFile; + getScope(): Record; lint( code: string, @@ -25,11 +25,10 @@ export interface LinterLoader { loadLinter(): WebLinter; } -export type { TSESTree } from '@typescript-eslint/types'; - export type { DebugLevel, EcmaVersion, ParserOptions, SourceType, + TSESTree, } from '@typescript-eslint/types'; diff --git a/packages/website/src/components/ASTViewerESTree.tsx b/packages/website/src/components/ASTViewerESTree.tsx index 899daeedba9a..7d46efdfb110 100644 --- a/packages/website/src/components/ASTViewerESTree.tsx +++ b/packages/website/src/components/ASTViewerESTree.tsx @@ -1,52 +1,32 @@ -import React, { useCallback } from 'react'; +import React, { useEffect, useState } from 'react'; import ASTViewer from './ast/ASTViewer'; -import { isRecord } from './ast/utils'; -import type { ASTViewerBaseProps, SelectedRange } from './ast/types'; -import { TSESTree } from '@typescript-eslint/website-eslint'; +import type { ASTViewerBaseProps, ASTViewerModelMap } from './ast/types'; +import type { TSESTree } from '@typescript-eslint/website-eslint'; +import { serialize } from './ast/serializer/serializer'; +import { createESTreeSerializer } from './ast/serializer/serializerESTree'; -function isESTreeNode( - value: unknown, -): value is Record & TSESTree.BaseNode { - return isRecord(value) && 'type' in value && 'loc' in value; +export interface ASTESTreeViewerProps extends ASTViewerBaseProps { + readonly value: TSESTree.BaseNode | string; } -export const propsToFilter = ['parent', 'comments', 'tokens']; +export default function ASTViewerESTree({ + value, + position, + onSelectNode, +}: ASTESTreeViewerProps): JSX.Element { + const [model, setModel] = useState(''); -export default function ASTViewerESTree( - props: ASTViewerBaseProps, -): JSX.Element { - const filterProps = useCallback( - (item: [string, unknown]): boolean => - !propsToFilter.includes(item[0]) && - !item[0].startsWith('_') && - item[1] !== undefined, - [], - ); - - const getRange = useCallback( - (value: unknown): SelectedRange | undefined => - isESTreeNode(value) - ? { - start: value.loc.start, - end: value.loc.end, - } - : undefined, - [], - ); - - const getNodeName = useCallback( - (value: unknown): string | undefined => - isESTreeNode(value) ? String(value.type) : undefined, - [], - ); + useEffect(() => { + if (typeof value === 'string') { + setModel(value); + } else { + const astSerializer = createESTreeSerializer(); + setModel(serialize(value, astSerializer)); + } + }, [value]); return ( - + ); } diff --git a/packages/website/src/components/ASTViewerScope.tsx b/packages/website/src/components/ASTViewerScope.tsx new file mode 100644 index 000000000000..b14514855381 --- /dev/null +++ b/packages/website/src/components/ASTViewerScope.tsx @@ -0,0 +1,29 @@ +import React, { useEffect, useState } from 'react'; + +import ASTViewer from './ast/ASTViewer'; +import type { ASTViewerBaseProps, ASTViewerModelMap } from './ast/types'; + +import { serialize } from './ast/serializer/serializer'; +import { createScopeSerializer } from './ast/serializer/serializerScope'; + +export interface ASTScopeViewerProps extends ASTViewerBaseProps { + readonly value: Record | string; +} + +export default function ASTViewerScope({ + value, + onSelectNode, +}: ASTScopeViewerProps): JSX.Element { + const [model, setModel] = useState(''); + + useEffect(() => { + if (typeof value === 'string') { + setModel(value); + } else { + const scopeSerializer = createScopeSerializer(); + setModel(serialize(value, scopeSerializer)); + } + }, [value]); + + return ; +} diff --git a/packages/website/src/components/ASTViewerTS.tsx b/packages/website/src/components/ASTViewerTS.tsx index f30265ba574e..6cd080262960 100644 --- a/packages/website/src/components/ASTViewerTS.tsx +++ b/packages/website/src/components/ASTViewerTS.tsx @@ -1,16 +1,13 @@ import React, { useCallback, useEffect, useState } from 'react'; import ASTViewer from './ast/ASTViewer'; -import { isRecord } from './ast/utils'; -import type { - ASTViewerBaseProps, - SelectedRange, - SelectedPosition, -} from './ast/types'; -import type { Node, SourceFile } from 'typescript'; +import type { ASTViewerBaseProps, ASTViewerModelMap } from './ast/types'; +import type { SourceFile } from 'typescript'; +import { serialize } from './ast/serializer/serializer'; +import { createTsSerializer } from './ast/serializer/serializerTS'; export interface ASTTsViewerProps extends ASTViewerBaseProps { - readonly version: string; + readonly value: SourceFile | string; } function extractEnum( @@ -28,10 +25,6 @@ function extractEnum( return result; } -function isTsNode(value: unknown): value is Node { - return isRecord(value) && typeof value.kind === 'number'; -} - function getFlagNamesFromEnum( allFlags: Record, flags: number, @@ -42,108 +35,64 @@ function getFlagNamesFromEnum( .map(([_, name]) => `${prefix}.${name}`); } -export function getLineAndCharacterFor( - pos: number, - ast: SourceFile, -): SelectedPosition { - const loc = ast.getLineAndCharacterOfPosition(pos); - return { - line: loc.line + 1, - column: loc.character, - }; -} - -export function getLocFor( - start: number, - end: number, - ast: SourceFile, -): SelectedRange { - return { - start: getLineAndCharacterFor(start, ast), - end: getLineAndCharacterFor(end, ast), - }; -} - -export const propsToFilter = [ - 'parent', - 'jsDoc', - 'lineMap', - 'externalModuleIndicator', - 'bindDiagnostics', - 'transformFlags', - 'resolvedModules', - 'imports', -]; - -export default function ASTViewerTS(props: ASTTsViewerProps): JSX.Element { - const [syntaxKind, setSyntaxKind] = useState>({}); - const [nodeFlags, setNodeFlags] = useState>({}); - const [tokenFlags, setTokenFlags] = useState>({}); - const [modifierFlags, setModifierFlags] = useState>( - {}, - ); +export default function ASTViewerTS({ + value, + position, + onSelectNode, +}: ASTTsViewerProps): JSX.Element { + const [model, setModel] = useState(''); + const [syntaxKind] = useState(() => extractEnum(window.ts.SyntaxKind)); + const [nodeFlags] = useState(() => extractEnum(window.ts.NodeFlags)); + const [tokenFlags] = useState(() => extractEnum(window.ts.TokenFlags)); + const [modifierFlags] = useState(() => extractEnum(window.ts.ModifierFlags)); useEffect(() => { - setSyntaxKind(extractEnum(window.ts.SyntaxKind)); - setNodeFlags(extractEnum(window.ts.NodeFlags)); - setTokenFlags(extractEnum(window.ts.TokenFlags)); - setModifierFlags(extractEnum(window.ts.ModifierFlags)); - }, [props.version]); + if (typeof value === 'string') { + setModel(value); + } else { + const scopeSerializer = createTsSerializer(value, syntaxKind); + setModel(serialize(value, scopeSerializer)); + } + }, [value, syntaxKind]); + // TODO: move this to serializer const getTooltip = useCallback( - (key: string, value: unknown): string | undefined => { - if (key === 'flags' && typeof value === 'number') { - return getFlagNamesFromEnum(nodeFlags, value, 'NodeFlags').join('\n'); - } else if (key === 'numericLiteralFlags' && typeof value === 'number') { - return getFlagNamesFromEnum(tokenFlags, value, 'TokenFlags').join('\n'); - } else if (key === 'modifierFlagsCache' && typeof value === 'number') { - return getFlagNamesFromEnum(modifierFlags, value, 'ModifierFlags').join( - '\n', - ); - } else if (key === 'kind' && typeof value === 'number') { - return `SyntaxKind.${syntaxKind[value]}`; + (data: ASTViewerModelMap): string | undefined => { + if (data.model.type === 'number') { + switch (data.key) { + case 'flags': + return getFlagNamesFromEnum( + nodeFlags, + Number(data.model.value), + 'NodeFlags', + ).join('\n'); + case 'numericLiteralFlags': + return getFlagNamesFromEnum( + tokenFlags, + Number(data.model.value), + 'TokenFlags', + ).join('\n'); + case 'modifierFlagsCache': + return getFlagNamesFromEnum( + modifierFlags, + Number(data.model.value), + 'ModifierFlags', + ).join('\n'); + case 'kind': + return `SyntaxKind.${syntaxKind[Number(data.model.value)]}`; + } } return undefined; }, [nodeFlags, tokenFlags, syntaxKind], ); - const getNodeName = useCallback( - (value: unknown): string | undefined => - isTsNode(value) ? syntaxKind[value.kind] : undefined, - [syntaxKind], - ); - - const filterProps = useCallback( - (item: [string, unknown]): boolean => - !propsToFilter.includes(item[0]) && - !item[0].startsWith('_') && - item[1] !== undefined, - [], - ); - - const getRange = useCallback( - (value: unknown): SelectedRange | undefined => { - if (props.value && isTsNode(value)) { - return getLocFor( - value.pos, - value.end, - // @ts-expect-error: unsafe cast - props.value as SourceFile, - ); - } - return undefined; - }, - [props.value], - ); - return ( ); } diff --git a/packages/website/src/components/OptionsSelector.tsx b/packages/website/src/components/OptionsSelector.tsx index 64f573590b00..83715fc3ae5c 100644 --- a/packages/website/src/components/OptionsSelector.tsx +++ b/packages/website/src/components/OptionsSelector.tsx @@ -32,6 +32,7 @@ const ASTOptions = [ { value: false, label: 'Disabled' }, { value: 'es', label: 'ESTree' }, { value: 'ts', label: 'TypeScript' }, + { value: 'scope', label: 'Scope' }, ] as const; function OptionsSelector({ diff --git a/packages/website/src/components/Playground.tsx b/packages/website/src/components/Playground.tsx index 844b955dd8b8..b766bd9a9746 100644 --- a/packages/website/src/components/Playground.tsx +++ b/packages/website/src/components/Playground.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from 'react'; +import React, { useReducer, useState } from 'react'; import type Monaco from 'monaco-editor'; import clsx from 'clsx'; import useThemeContext from '@theme/hooks/useThemeContext'; @@ -18,6 +18,25 @@ import ASTViewerTS from './ASTViewerTS'; import type { RuleDetails, SelectedRange } from './types'; import type { TSESTree } from '@typescript-eslint/website-eslint'; +import type { SourceFile } from 'typescript'; +import ASTViewerScope from '@site/src/components/ASTViewerScope'; + +function rangeReducer( + prevState: T, + action: T, +): T { + if (prevState !== action) { + if ( + !prevState || + !action || + !shallowEqual(prevState.start, action.start) || + !shallowEqual(prevState.end, action.end) + ) { + return action; + } + } + return prevState; +} function Playground(): JSX.Element { const [state, setState] = useHashState({ @@ -31,29 +50,14 @@ function Playground(): JSX.Element { }); const { isDarkTheme } = useThemeContext(); const [esAst, setEsAst] = useState(); - const [tsAst, setTsAST] = useState | string | null>(); + const [tsAst, setTsAST] = useState(); + const [scope, setScope] = useState | string | null>(); const [ruleNames, setRuleNames] = useState([]); const [isLoading, setIsLoading] = useState(true); const [tsVersions, setTSVersion] = useState([]); - const [selectedRange, setSelectedRange] = useState( - null, - ); + const [selectedRange, setSelectedRange] = useReducer(rangeReducer, null); const [position, setPosition] = useState(null); - const updateSelectedNode = useCallback( - (value: SelectedRange | null) => { - if ( - !value || - !selectedRange || - !shallowEqual(selectedRange.start, value.start) || - !shallowEqual(selectedRange.end, value.end) - ) { - setSelectedRange(value); - } - }, - [selectedRange], - ); - return (
@@ -85,6 +89,7 @@ function Playground(): JSX.Element { showAST={state.showAST} onEsASTChange={setEsAst} onTsASTChange={setTsAST} + onScopeChange={setScope} decoration={selectedRange} onChange={(code): void => setState({ code: code })} onLoaded={(ruleNames, tsVersions): void => { @@ -101,15 +106,21 @@ function Playground(): JSX.Element { )) || + (state.showAST === 'scope' && scope && ( + + )) || (esAst && ( ))}
diff --git a/packages/website/src/components/ast/ASTViewer.tsx b/packages/website/src/components/ast/ASTViewer.tsx index aa1e35687ec0..8b54f3420d58 100644 --- a/packages/website/src/components/ast/ASTViewer.tsx +++ b/packages/website/src/components/ast/ASTViewer.tsx @@ -3,38 +3,39 @@ import styles from './ASTViewer.module.css'; import type { SelectedPosition, ASTViewerProps } from './types'; -import { ComplexItem } from './Elements'; -import { isRecord } from './utils'; +import { ElementItem } from './Elements'; -function ASTViewer(props: ASTViewerProps): JSX.Element { +function ASTViewer({ + position, + value, + getTooltip, + onSelectNode, +}: ASTViewerProps): JSX.Element { const [selection, setSelection] = useState(null); useEffect(() => { setSelection( - props.position + position ? { - line: props.position.lineNumber, - column: props.position.column - 1, + line: position.lineNumber, + column: position.column - 1, } : null, ); - }, [props.position]); + }, [position]); - return isRecord(props.value) ? ( + return typeof value === 'string' ? ( +
{value}
+ ) : (
-
- ) : ( -
{props.value}
); } diff --git a/packages/website/src/components/ast/Elements.tsx b/packages/website/src/components/ast/Elements.tsx index be573770d94d..47521a5057e7 100644 --- a/packages/website/src/components/ast/Elements.tsx +++ b/packages/website/src/components/ast/Elements.tsx @@ -1,140 +1,117 @@ import React, { useCallback, useEffect, useState } from 'react'; -import type { GenericParams } from './types'; +import type { + GenericParams, + ASTViewerModelMap, + ASTViewerModelMapComplex, + ASTViewerModelMapSimple, +} from './types'; -import { hasChildInRange, isArrayInRange, isInRange, isRecord } from './utils'; +import { hasChildInRange, isArrayInRange, isInRange } from './utils'; -import styles from '@site/src/components/ast/ASTViewer.module.css'; +import styles from './ASTViewer.module.css'; -import PropertyValue from '@site/src/components/ast/PropertyValue'; -import ItemGroup from '@site/src/components/ast/ItemGroup'; -import HiddenItem from '@site/src/components/ast/HiddenItem'; -import Tooltip from '@site/src/components/inputs/Tooltip'; +import ItemGroup from './ItemGroup'; +import HiddenItem from './HiddenItem'; +import { SimpleItem } from './SimpleItem'; -export function ComplexItem( - props: GenericParams | unknown[]>, -): JSX.Element { - const [isExpanded, setIsExpanded] = useState( - () => props.level === 'ast', - ); +export function ComplexItem({ + data, + onSelectNode, + level, + selection, + getTooltip, +}: GenericParams): JSX.Element { + const [isExpanded, setIsExpanded] = useState(() => level === 'ast'); const [isSelected, setIsSelected] = useState(false); - const [model, setModel] = useState<[string, unknown][]>([]); - - useEffect(() => { - setModel( - Object.entries(props.value).filter(item => props.filterProps(item)), - ); - }, [props.value, props.filterProps]); const onHover = useCallback( (state: boolean) => { - if (props.onSelectNode) { - const range = props.getRange(props.value); + if (onSelectNode) { + const range = data.model.range; if (range) { - props.onSelectNode(state ? range : null); + onSelectNode(state ? range : null); } } }, - [props.value], + [data], ); useEffect(() => { - const selected = props.selection - ? props.isArray - ? isArrayInRange(props.selection, props.value, props.getRange) - : isInRange(props.selection, props.value, props.getRange) + const selected = selection + ? data.model.type === 'array' + ? isArrayInRange(selection, data.model) + : isInRange(selection, data.model) : false; setIsSelected( - props.level !== 'ast' && - selected && - !hasChildInRange(props.selection, model, props.getRange), + level !== 'ast' && selected && !hasChildInRange(selection, data.model), ); if (selected && !isExpanded) { setIsExpanded(selected); } - }, [model, props.selection, props.value, props.isArray, props.getRange]); + }, [selection, data]); return ( setIsExpanded(!isExpanded)} > - {props.isArray ? '[' : '{'} + {data.model.type === 'array' ? '[' : '{'} {isExpanded ? (
- {model.map((item, index) => ( + {data.model.value.map((item, index) => ( ))}
) : ( - + )} - {props.isArray ? ']' : '}'} + {data.model.type === 'array' ? ']' : '}'}
); } -export function SimpleItem(props: GenericParams): JSX.Element { - const [tooltip, setTooltip] = useState(); - - useEffect(() => { - setTooltip(props.getTooltip?.(props.propName ?? '', props.value)); - }, [props.getTooltip, props.propName, props.value]); - - return ( - - {tooltip ? ( - - - - ) : ( - - )} - - ); -} - -export function ElementItem(props: GenericParams): JSX.Element { - const isArray = Array.isArray(props.value); - if (isArray || isRecord(props.value)) { +export function ElementItem({ + level, + getTooltip, + selection, + data, + onSelectNode, +}: GenericParams): JSX.Element { + if (data.model.type === 'array' || data.model.type === 'object') { return ( ); } else { - return ; + return ( + + ); } } diff --git a/packages/website/src/components/ast/HiddenItem.tsx b/packages/website/src/components/ast/HiddenItem.tsx index 26717b349567..284bc2c2cad1 100644 --- a/packages/website/src/components/ast/HiddenItem.tsx +++ b/packages/website/src/components/ast/HiddenItem.tsx @@ -1,45 +1,48 @@ import React, { useEffect, useState } from 'react'; import styles from './ASTViewer.module.css'; import PropertyValue from './PropertyValue'; +import type { ASTViewerModelMap } from './types'; export interface HiddenItemProps { - readonly value: [string, unknown][]; + readonly value: ASTViewerModelMap[]; readonly level: string; readonly isArray?: boolean; } -export default function HiddenItem(props: HiddenItemProps): JSX.Element { +export default function HiddenItem({ + value, + level, + isArray, +}: HiddenItemProps): JSX.Element { const [isComplex, setIsComplex] = useState(true); const [length, setLength] = useState(0); useEffect(() => { - if (props.isArray) { - const filtered = props.value.filter(item => !isNaN(Number(item[0]))); - setIsComplex( - !filtered.some(item => typeof item[1] !== 'object' || item[1] === null), - ); + if (isArray) { + const filtered = value.filter(item => !isNaN(Number(item.key))); + setIsComplex(filtered.some(item => item.model.type !== 'number')); setLength(filtered.length); } - }, [props.value, props.isArray]); + }, [value, isArray]); return ( - {props.isArray && !isComplex ? ( - props.value.map((item, index) => ( - + {isArray && !isComplex ? ( + value.map((item, index) => ( + {index > 0 && ', '} - + )) - ) : props.isArray ? ( + ) : isArray ? ( <> {length} {length === 1 ? 'element' : 'elements'} ) : ( - props.value.map((item, index) => ( - + value.map((item, index) => ( + {index > 0 && ', '} - {String(item[0])} + {String(item.key)} )) )} diff --git a/packages/website/src/components/ast/ItemGroup.tsx b/packages/website/src/components/ast/ItemGroup.tsx index a117c9c05f89..bf6c5e3ca77d 100644 --- a/packages/website/src/components/ast/ItemGroup.tsx +++ b/packages/website/src/components/ast/ItemGroup.tsx @@ -4,15 +4,11 @@ import clsx from 'clsx'; import styles from './ASTViewer.module.css'; -import PropertyNameComp from './PropertyName'; -import type { GetNodeNameFn } from './types'; - -const PropertyName = React.memo(PropertyNameComp); +import PropertyName from './PropertyName'; +import type { ASTViewerModelMap } from './types'; export interface ItemGroupProps { - readonly propName?: string; - readonly value: unknown; - readonly getNodeName: GetNodeNameFn; + readonly data: ASTViewerModelMap; readonly isSelected?: boolean; readonly isExpanded?: boolean; readonly canExpand?: boolean; @@ -21,32 +17,39 @@ export interface ItemGroupProps { readonly children: JSX.Element | false | (JSX.Element | false)[]; } -export default function ItemGroup(props: ItemGroupProps): JSX.Element { +export default function ItemGroup({ + data, + isSelected, + isExpanded, + canExpand, + onClick, + onHover, + children, +}: ItemGroupProps): JSX.Element { const listItem = useRef(null); useEffect(() => { - if (listItem.current && props.isSelected) { + if (listItem.current && isSelected) { scrollIntoViewIfNeeded(listItem.current); } - }, [props.isSelected, listItem]); + }, [isSelected, listItem]); return (
props.onHover?.(true)} - onMouseLeave={(): void => props.onHover?.(false)} - onClick={(props.canExpand && props.onClick) || undefined} + propName={data.key} + typeName={data.model.name} + onHover={onHover} + onClick={(canExpand && onClick) || undefined} /> - {React.Children.map(props.children, child => child)} + {React.Children.map(children, child => child)}
); } diff --git a/packages/website/src/components/ast/PropertyName.tsx b/packages/website/src/components/ast/PropertyName.tsx index 36c3a6341534..8ff4b7c62406 100644 --- a/packages/website/src/components/ast/PropertyName.tsx +++ b/packages/website/src/components/ast/PropertyName.tsx @@ -1,24 +1,38 @@ -import React, { MouseEvent } from 'react'; +import React, { MouseEvent, useCallback } from 'react'; import styles from './ASTViewer.module.css'; export interface PropertyNameProps { readonly typeName?: string; readonly propName?: string; readonly onClick?: (e: MouseEvent) => void; - readonly onMouseEnter?: (e: MouseEvent) => void; - readonly onMouseLeave?: (e: MouseEvent) => void; + readonly onHover?: (e: boolean) => void; } export default function PropertyName(props: PropertyNameProps): JSX.Element { - return props.onClick ? ( + const onClick = useCallback( + (e: MouseEvent) => { + e.preventDefault(); + props.onClick?.(e); + }, + [props.onClick], + ); + + const onMouseEnter = useCallback(() => { + props.onHover?.(true); + }, [props.onHover]); + + const onMouseLeave = useCallback(() => { + props.onHover?.(false); + }, [props.onHover]); + + return props.onClick || props.onHover ? ( <> {props.propName && ( - // eslint-disable-next-line jsx-a11y/anchor-is-valid {props.propName} @@ -26,12 +40,11 @@ export default function PropertyName(props: PropertyNameProps): JSX.Element { )} {props.propName && : } {props.typeName && ( - // eslint-disable-next-line jsx-a11y/anchor-is-valid {props.typeName} diff --git a/packages/website/src/components/ast/PropertyValue.tsx b/packages/website/src/components/ast/PropertyValue.tsx index 4d777b3a4bf4..6539042d9af0 100644 --- a/packages/website/src/components/ast/PropertyValue.tsx +++ b/packages/website/src/components/ast/PropertyValue.tsx @@ -1,32 +1,33 @@ import React from 'react'; import styles from './ASTViewer.module.css'; -import { objType } from './utils'; +import type { ASTViewerModelMap } from './types'; export interface PropertyValueProps { - readonly value: unknown; + readonly value: ASTViewerModelMap; } -function PropertyValue(props: PropertyValueProps): JSX.Element { - if (typeof props.value === 'string') { - return ( - {JSON.stringify(props.value)} - ); - } else if (typeof props.value === 'number') { - return {props.value}; - } else if (typeof props.value === 'bigint') { - return {String(props.value)}n; - } else if (props.value instanceof RegExp) { - return {String(props.value)}; - } else if (typeof props.value === 'undefined' || props.value === null) { - return {String(props.value)}; - } else if (typeof props.value === 'boolean') { - return ( - - {props.value ? 'true' : 'false'} - - ); +function PropertyValue({ value }: PropertyValueProps): JSX.Element { + switch (value.model.type) { + case 'string': + return {value.model.value}; + case 'bigint': + return {value.model.value}; + case 'number': + return {value.model.value}; + case 'regexp': + return {value.model.value}; + case 'undefined': + return {value.model.value}; + case 'boolean': + return {value.model.value}; + case 'array': + case 'object': + return {value.key}; + case 'class': + case 'ref': + default: + return {value.model.value}; } - return {objType(props.value)}; } export default PropertyValue; diff --git a/packages/website/src/components/ast/SimpleItem.tsx b/packages/website/src/components/ast/SimpleItem.tsx new file mode 100644 index 000000000000..cb20dc0ccbb8 --- /dev/null +++ b/packages/website/src/components/ast/SimpleItem.tsx @@ -0,0 +1,49 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import ItemGroup from './ItemGroup'; +import Tooltip from '@site/src/components/inputs/Tooltip'; +import PropertyValue from './PropertyValue'; + +import type { + ASTViewerModelMapSimple, + GetTooltipFn, + OnSelectNodeFn, +} from './types'; + +export interface SimpleItemProps { + readonly getTooltip?: GetTooltipFn; + readonly data: ASTViewerModelMapSimple; + readonly onSelectNode?: OnSelectNodeFn; +} + +export function SimpleItem({ + getTooltip, + data, + onSelectNode, +}: SimpleItemProps): JSX.Element { + const [tooltip, setTooltip] = useState(); + + useEffect(() => { + setTooltip(getTooltip?.(data)); + }, [getTooltip, data]); + + const onHover = useCallback( + (state: boolean) => { + if (onSelectNode && data.model.range) { + onSelectNode(state ? data.model.range : null); + } + }, + [data], + ); + + return ( + + {tooltip ? ( + + + + ) : ( + + )} + + ); +} diff --git a/packages/website/src/components/ast/serializer/serializer.ts b/packages/website/src/components/ast/serializer/serializer.ts new file mode 100644 index 000000000000..3cbea9174a10 --- /dev/null +++ b/packages/website/src/components/ast/serializer/serializer.ts @@ -0,0 +1,89 @@ +import type { + ASTViewerModelSimple, + ASTViewerModelMap, + Serializer, +} from '../types'; +import { isRecord, objType } from '../utils'; + +function getSimpleModel(data: unknown): ASTViewerModelSimple { + if (typeof data === 'string') { + return { + value: JSON.stringify(data), + type: 'string', + }; + } else if (typeof data === 'number') { + return { + value: String(data), + type: 'number', + }; + } else if (typeof data === 'bigint') { + return { + value: `${data}n`, + type: 'bigint', + }; + } else if (data instanceof RegExp) { + return { + value: String(data), + type: 'regexp', + }; + } else if (typeof data === 'undefined' || data === null) { + return { + value: String(data), + type: 'undefined', + }; + } else if (typeof data === 'boolean') { + return { + value: data ? 'true' : 'false', + type: 'boolean', + }; + } + return { + value: objType(data), + type: 'class', + }; +} + +export function serialize( + data: unknown, + serializer?: Serializer, +): ASTViewerModelMap { + function processValue(data: [string, unknown][]): ASTViewerModelMap[] { + return data + .filter(item => !item[0].startsWith('_') && item[1] !== undefined) + .map(item => _serialize(item[1], item[0])); + } + + function _serialize(data: unknown, key?: string): ASTViewerModelMap { + if (isRecord(data)) { + const serialized = serializer + ? serializer(data, key, processValue) + : undefined; + if (serialized) { + return { key, model: serialized }; + } + return { + key, + model: { + value: processValue(Object.entries(data)), + type: 'object', + }, + }; + } else if (Array.isArray(data)) { + return { + key, + model: { + value: processValue(Object.entries(data)), + type: 'array', + }, + }; + } + + if (typeof data === 'function' && key) { + return { key: `${key}()`, model: getSimpleModel(data()) }; + } + + return { key, model: getSimpleModel(data) }; + } + + return _serialize(data); +} diff --git a/packages/website/src/components/ast/serializer/serializerESTree.ts b/packages/website/src/components/ast/serializer/serializerESTree.ts new file mode 100644 index 000000000000..7f467757c8a3 --- /dev/null +++ b/packages/website/src/components/ast/serializer/serializerESTree.ts @@ -0,0 +1,34 @@ +import type { ASTViewerModel, Serializer } from '../types'; +import { isRecord } from '../utils'; +import type { TSESTree } from '@typescript-eslint/website-eslint'; + +export const propsToFilter = ['parent', 'comments', 'tokens']; + +function isESTreeNode( + value: unknown, +): value is Record & TSESTree.BaseNode { + return isRecord(value) && 'type' in value && 'loc' in value; +} + +export function createESTreeSerializer(): Serializer { + return function serializer( + data, + _key, + processValue, + ): ASTViewerModel | undefined { + if (isESTreeNode(data)) { + return { + range: { + start: data.loc.start, + end: data.loc.end, + }, + type: 'object', + name: String(data.type), + value: processValue( + Object.entries(data).filter(item => !propsToFilter.includes(item[0])), + ), + }; + } + return undefined; + }; +} diff --git a/packages/website/src/components/ast/serializer/serializerScope.ts b/packages/website/src/components/ast/serializer/serializerScope.ts new file mode 100644 index 000000000000..176f49f92c5c --- /dev/null +++ b/packages/website/src/components/ast/serializer/serializerScope.ts @@ -0,0 +1,203 @@ +import type { ASTViewerModel, Serializer, SelectedRange } from '../types'; +import type { TSESTree } from '@typescript-eslint/website-eslint'; +import { isRecord } from '../utils'; + +function isESTreeNode( + value: unknown, +): value is Record & TSESTree.Node { + return Boolean(value) && isRecord(value) && 'type' in value && 'loc' in value; +} + +function getClassName(value: Record): string { + // eslint-disable-next-line @typescript-eslint/ban-types + return (Object.getPrototypeOf(value) as Object).constructor.name.replace( + /\$[0-9]+$/, + '', + ); +} + +function getNodeName( + className: string, + data: Record, +): string | undefined { + const id = data.$id != null ? `$${String(data.$id)}` : ''; + + if (className === 'ImplicitLibVariable' && data.name === 'const') { + className = 'ImplicitGlobalConstTypeVariable'; + } + + return `${className}${id}`; +} + +function getRange(value: Record): SelectedRange | undefined { + if (isESTreeNode(value.block)) { + return { + start: value.block.loc.start, + end: value.block.loc.end, + }; + } else if (isESTreeNode(value.identifier)) { + return { + start: { ...value.identifier.loc.start }, + end: { ...value.identifier.loc.end }, + }; + } else if (isESTreeNode(value.node)) { + return { + start: { ...value.node.loc.start }, + end: { ...value.node.loc.end }, + }; + } else if ( + Array.isArray(value.identifiers) && + value.identifiers.length > 0 && + isESTreeNode(value.identifiers[0]) + ) { + return { + start: { ...value.identifiers[0].loc.start }, + end: { ...value.identifiers[0].loc.end }, + }; + } + + return undefined; +} + +type NodeType = + | 'Scope' + | 'Definition' + | 'Variable' + | 'ScopeManager' + | 'Reference'; + +function getNodeType(nodeName: string | undefined): NodeType | undefined { + if (nodeName) { + if (nodeName === 'ScopeManager') { + return 'ScopeManager'; + } else if (nodeName.endsWith('Scope')) { + return 'Scope'; + } else if (nodeName.endsWith('Definition')) { + return 'Definition'; + } else if (nodeName === 'Variable' || nodeName === 'ImplicitLibVariable') { + return 'Variable'; + } else if (nodeName === 'Reference') { + return 'Reference'; + } + } + return undefined; +} + +function getProps(nodeType: NodeType | undefined): string[] | undefined { + switch (nodeType) { + case 'ScopeManager': + return ['scopes', 'globalScope', 'variables']; + case 'Scope': + return [ + 'block', + 'isStrict', + 'references', + 'through', + 'set', + 'type', + 'variables', + 'variableScope', + 'functionExpressionScope', + 'childScopes', + 'upper', + ]; + case 'Definition': + return [ + 'name', + 'type', + 'node', + 'isTypeDefinition', + 'isVariableDefinition', + 'rest', + 'parent', + ]; + case 'Reference': + return [ + 'init', + 'identifier', + 'from', + 'isTypeReference', + 'isValueReference', + 'maybeImplicitGlobal', + 'isRead', + 'isWrite', + 'resolved', + 'writeExpr', + ]; + case 'Variable': + return [ + 'name', + 'identifiers', + 'references', + 'defs', + 'eslintUsed', + 'tainted', + 'scope', + 'isValueVariable', + 'isTypeVariable', + 'writeable', + ]; + } + return undefined; +} + +export function createScopeSerializer(): Serializer { + const SEEN_THINGS = new Map(); + + return function serializer( + data, + _key, + processValue, + ): ASTViewerModel | undefined { + const className = getClassName(data); + + if (className !== 'Object') { + const nodeName = getNodeName(className, data); + const nodeType = getNodeType(className); + const value = data.name != null ? `<"${String(data.name)}">` : ''; + + const uniqName = `${nodeName}${value}`; + + if (SEEN_THINGS.has(uniqName)) { + return SEEN_THINGS.get(uniqName); + } + + const result: ASTViewerModel = { + range: getRange(data), + type: 'object', + name: nodeName, + value: [], + }; + SEEN_THINGS.set(uniqName, result); + + let values: [string, unknown][]; + + const props = getProps(nodeType); + if (props) { + values = props.map(key => { + const res = data[key]; + return [key, typeof res === 'function' ? res.bind(data) : res]; + }); + } else { + values = Object.entries(data); + } + + result.value = processValue(values); + return result; + } + + if (isESTreeNode(data)) { + return { + type: 'ref', + name: data.type, + range: { + start: { ...data.loc.start }, + end: { ...data.loc.end }, + }, + value: data.type === 'Identifier' ? `<"${data.name}">` : '', + }; + } + + return undefined; + }; +} diff --git a/packages/website/src/components/ast/serializer/serializerTS.ts b/packages/website/src/components/ast/serializer/serializerTS.ts new file mode 100644 index 000000000000..e1a86f054a75 --- /dev/null +++ b/packages/website/src/components/ast/serializer/serializerTS.ts @@ -0,0 +1,57 @@ +import type { ASTViewerModel, Serializer, SelectedPosition } from '../types'; +import type { SourceFile, Node } from 'typescript'; +import { isRecord } from '../utils'; + +export function getLineAndCharacterFor( + pos: number, + ast: SourceFile, +): SelectedPosition { + const loc = ast.getLineAndCharacterOfPosition(pos); + return { + line: loc.line + 1, + column: loc.character, + }; +} + +export const propsToFilter = [ + 'parent', + 'jsDoc', + 'lineMap', + 'externalModuleIndicator', + 'bindDiagnostics', + 'transformFlags', + 'resolvedModules', + 'imports', +]; + +function isTsNode(value: unknown): value is Node { + return isRecord(value) && typeof value.kind === 'number'; +} + +export function createTsSerializer( + root: SourceFile, + syntaxKind: Record, +): Serializer { + return function serializer( + data, + _key, + processValue, + ): ASTViewerModel | undefined { + if (root && isTsNode(data)) { + const nodeName = syntaxKind[data.kind]; + + return { + range: { + start: getLineAndCharacterFor(data.pos, root), + end: getLineAndCharacterFor(data.end, root), + }, + type: 'object', + name: nodeName, + value: processValue( + Object.entries(data).filter(item => !propsToFilter.includes(item[0])), + ), + }; + } + return undefined; + }; +} diff --git a/packages/website/src/components/ast/types.ts b/packages/website/src/components/ast/types.ts index 8b27865e3428..1d5976424d2d 100644 --- a/packages/website/src/components/ast/types.ts +++ b/packages/website/src/components/ast/types.ts @@ -1,37 +1,68 @@ import type { SelectedPosition, SelectedRange } from '../types'; -import { TSESTree } from '@typescript-eslint/website-eslint'; import Monaco from 'monaco-editor'; -export type GetNodeNameFn = (data: unknown) => string | undefined; -export type GetTooltipFn = (key: string, data: unknown) => string | undefined; -export type GetRangeFn = (data: unknown) => SelectedRange | undefined; +export type GetTooltipFn = (data: ASTViewerModelMap) => string | undefined; export type OnSelectNodeFn = (node: SelectedRange | null) => void; -export type FilterPropsFn = (item: [string, unknown]) => boolean; + +export type ASTViewerModelTypeSimple = + | 'ref' + | 'string' + | 'number' + | 'class' + | 'boolean' + | 'bigint' + | 'regexp' + | 'undefined'; + +export type ASTViewerModelTypeComplex = 'object' | 'array'; + +export interface ASTViewerModelBase { + name?: string; + range?: SelectedRange; +} + +export interface ASTViewerModelSimple extends ASTViewerModelBase { + type: ASTViewerModelTypeSimple; + value: string; +} + +export interface ASTViewerModelComplex extends ASTViewerModelBase { + type: ASTViewerModelTypeComplex; + value: ASTViewerModelMap[]; +} + +export type ASTViewerModel = ASTViewerModelSimple | ASTViewerModelComplex; + +export interface ASTViewerModelMap { + key?: string; + model: T; +} + +export type ASTViewerModelMapSimple = ASTViewerModelMap; +export type ASTViewerModelMapComplex = ASTViewerModelMap; export interface GenericParams { - readonly propName?: string; - readonly value: V; + readonly data: V; readonly level: string; readonly selection?: SelectedPosition | null; readonly onSelectNode?: OnSelectNodeFn; - readonly getNodeName: GetNodeNameFn; readonly getTooltip?: GetTooltipFn; - readonly filterProps: FilterPropsFn; - readonly getRange: GetRangeFn; - readonly isArray?: boolean; } export interface ASTViewerBaseProps { - readonly value: Record | TSESTree.Node | string; readonly position?: Monaco.Position | null; readonly onSelectNode?: OnSelectNodeFn; } export interface ASTViewerProps extends ASTViewerBaseProps { - readonly getNodeName: GetNodeNameFn; readonly getTooltip?: GetTooltipFn; - readonly getRange: GetRangeFn; - readonly filterProps: FilterPropsFn; + readonly value: ASTViewerModelMap | string; } +export type Serializer = ( + data: Record, + key: string | undefined, + processValue: (data: [string, unknown][]) => ASTViewerModelMap[], +) => ASTViewerModel | undefined; + export type { SelectedPosition, SelectedRange }; diff --git a/packages/website/src/components/ast/utils.ts b/packages/website/src/components/ast/utils.ts index a06436e9c356..bfe21860afd4 100644 --- a/packages/website/src/components/ast/utils.ts +++ b/packages/website/src/components/ast/utils.ts @@ -1,5 +1,5 @@ import type { SelectedPosition, SelectedRange } from './types'; -import { GetRangeFn } from './types'; +import { ASTViewerModel, ASTViewerModelComplex } from './types'; export function isWithinRange( loc: SelectedPosition, @@ -30,42 +30,35 @@ export function isRecord(value: unknown): value is Record { export function isInRange( position: SelectedPosition | null | undefined, - value: unknown, - getRange: GetRangeFn, + value: ASTViewerModel, ): boolean { - if (!position) { + if (!position || !value.range) { return false; } - const range = getRange(value); - if (!range) { - return false; - } - return isWithinRange(position, range); + return isWithinRange(position, value.range); } export function isArrayInRange( position: SelectedPosition | null | undefined, - value: unknown, - getRange: GetRangeFn, + value: ASTViewerModelComplex, ): boolean { return Boolean( - position && - Array.isArray(value) && - value.some(item => isInRange(position, item, getRange)), + position && value.value.some(item => isInRange(position, item.model)), ); } export function hasChildInRange( position: SelectedPosition | null | undefined, - value: [string, unknown][], - getRange: GetRangeFn, + value: ASTViewerModelComplex, ): boolean { return Boolean( position && - value.some( - ([, item]) => - isInRange(position, item, getRange) || - isArrayInRange(position, item, getRange), + value.value.some(item => + item.model.type === 'object' + ? isInRange(position, item.model) + : item.model.type === 'array' + ? isArrayInRange(position, item.model) + : false, ), ); } diff --git a/packages/website/src/components/editor/LoadedEditor.tsx b/packages/website/src/components/editor/LoadedEditor.tsx index 5a2180ba0fdc..a3e8395bc3d7 100644 --- a/packages/website/src/components/editor/LoadedEditor.tsx +++ b/packages/website/src/components/editor/LoadedEditor.tsx @@ -22,6 +22,7 @@ export const LoadedEditor: React.FC = ({ jsx, main, onEsASTChange, + onScopeChange, onTsASTChange, onChange, onSelect, @@ -65,6 +66,7 @@ export const LoadedEditor: React.FC = ({ onEsASTChange(fatalMessage ?? webLinter.getAst()); onTsASTChange(fatalMessage ?? webLinter.getTsAst()); + onScopeChange(fatalMessage ?? webLinter.getScope()); onSelect(sandboxInstance.editor.getPosition()); }, 500), [code, jsx, sandboxInstance, rules, sourceType, webLinter], diff --git a/packages/website/src/components/editor/types.ts b/packages/website/src/components/editor/types.ts index 56048321473f..edcbcf842d38 100644 --- a/packages/website/src/components/editor/types.ts +++ b/packages/website/src/components/editor/types.ts @@ -1,12 +1,14 @@ import type Monaco from 'monaco-editor'; import type { ConfigModel, SelectedRange } from '../types'; import type { TSESTree } from '@typescript-eslint/website-eslint'; +import type { SourceFile } from 'typescript'; export interface CommonEditorProps extends ConfigModel { readonly darkTheme: boolean; readonly decoration: SelectedRange | null; readonly onChange: (value: string) => void; - readonly onTsASTChange: (value: string | Record) => void; + readonly onTsASTChange: (value: string | SourceFile) => void; readonly onEsASTChange: (value: string | TSESTree.Program) => void; + readonly onScopeChange: (value: string | Record) => void; readonly onSelect: (position: Monaco.Position | null) => void; } diff --git a/packages/website/src/components/hooks/useHashState.ts b/packages/website/src/components/hooks/useHashState.ts index 9c495facc591..f8b7e1270171 100644 --- a/packages/website/src/components/hooks/useHashState.ts +++ b/packages/website/src/components/hooks/useHashState.ts @@ -15,12 +15,14 @@ function readQueryParam(value: string | null, fallback: string): string { : fallback; } -function readShowAST(value: string | null): 'ts' | 'es' | boolean { +function readShowAST(value: string | null): 'ts' | 'scope' | 'es' | boolean { switch (value) { case 'es': return 'es'; case 'ts': return 'ts'; + case 'scope': + return 'scope'; } return Boolean(value); } diff --git a/packages/website/src/components/types.ts b/packages/website/src/components/types.ts index 7830baa224c5..5e1e3a721950 100644 --- a/packages/website/src/components/types.ts +++ b/packages/website/src/components/types.ts @@ -42,7 +42,7 @@ export interface ConfigModel { tsConfig?: CompilerFlags; code: string; ts: string; - showAST?: boolean | 'ts' | 'es'; + showAST?: boolean | 'ts' | 'es' | 'scope'; } export interface SelectedPosition { diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json index a689b00a6f5e..3488d04f2e95 100644 --- a/packages/website/tsconfig.json +++ b/packages/website/tsconfig.json @@ -6,7 +6,7 @@ "allowJs": true, "esModuleInterop": true, "jsx": "react", - "lib": ["DOM"], + "lib": ["DOM", "ESNext"], "noEmit": true, "noImplicitAny": false, "resolveJsonModule": true, From ba0b1e3c52b47fad28a942dd09eb1a818817f2ff Mon Sep 17 00:00:00 2001 From: Armano Date: Thu, 23 Dec 2021 19:02:51 +0100 Subject: [PATCH 3/6] docs(website): use json5 library to parse config in playground (#4341) --- packages/website/package.json | 1 + .../src/components/config/ConfigEditor.tsx | 5 +- yarn.lock | 356 +----------------- 3 files changed, 17 insertions(+), 345 deletions(-) diff --git a/packages/website/package.json b/packages/website/package.json index 334148c6ca37..090324a66074 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -29,6 +29,7 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "remark-docusaurus-tabs": "^0.2.0", + "json5": "^2.2.0", "typescript": "*" }, "devDependencies": { diff --git a/packages/website/src/components/config/ConfigEditor.tsx b/packages/website/src/components/config/ConfigEditor.tsx index 0880ff7e6e70..062e1ac21fde 100644 --- a/packages/website/src/components/config/ConfigEditor.tsx +++ b/packages/website/src/components/config/ConfigEditor.tsx @@ -1,5 +1,6 @@ import React, { useCallback, useEffect, useReducer, useState } from 'react'; import clsx from 'clsx'; +import { parse } from 'json5'; import styles from './ConfigEditor.module.css'; @@ -79,7 +80,7 @@ function reducerObject( } case 'json': { try { - const parsed: unknown = JSON.parse(action.code); + const parsed: unknown = parse(action.code); if (isRecord(parsed)) { const item = parsed[action.field]; if (item && isRecord(item)) { @@ -93,8 +94,6 @@ function reducerObject( return state; } } - // @ts-expect-error: Safeguard - throw new Error(); } function filterConfig( diff --git a/yarn.lock b/yarn.lock index 97b2cd1acbcc..6e6be599b811 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2035,16 +2035,6 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.4.2.tgz#03efabce528dbb09bffd3ec7e39bb0f3f7475cc2" - integrity sha512-uSljKxh/rGlHlmhyeG4ZoVK9hOec+EPBkwTHkHKQ2EqDu5K+MaG9uJZ8o1CbRsSdZqSuhXvJCYhBWsORPPg6qw== - dependencies: - "@jest/fake-timers" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - jest-mock "^27.4.2" - "@jest/environment@^27.4.4": version "27.4.4" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.4.4.tgz#66ebebc79673d84aad29d2bb70a8c51e6c29bb4d" @@ -2067,15 +2057,6 @@ jest-mock "^27.4.2" jest-util "^27.4.2" -"@jest/globals@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.2.tgz#56a402c5ebf22eba1d34e900772147f5126ea2d8" - integrity sha512-KkfaHEttlGpXYAQTZHgrESiEPx2q/DKAFLGLFda1uGVrqc17snd3YVPhOxlXOHIzVPs+lQ/SDB2EIvxyGzb3Ew== - dependencies: - "@jest/environment" "^27.4.2" - "@jest/types" "^27.4.2" - expect "^27.4.2" - "@jest/globals@^27.4.4": version "27.4.4" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.4.tgz#fe501a80c23ea2dab585c42be2a519bb5e38530d" @@ -2175,17 +2156,7 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.2.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.4.2.tgz#94bb7e5412d59ae2a8a4b8f9925bb16b6dc82b4c" - integrity sha512-HmHp5mlh9f9GyNej5yCS1JZIFfUGnP9+jEOH5zoq5EmsuZeYD+dGULqyvGDPtuzzbyAFJ6R4+z4SS0VvnFwwGQ== - dependencies: - "@jest/test-result" "^27.4.2" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.2" - jest-runtime "^27.4.2" - -"@jest/test-sequencer@^27.4.5": +"@jest/test-sequencer@^27.2.2", "@jest/test-sequencer@^27.4.5": version "27.4.5" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.4.5.tgz#1d7e026844d343b60d2ca7fd82c579a17b445d7d" integrity sha512-n5woIn/1v+FT+9hniymHPARA9upYUmfi5Pw9ewVwXCDlK4F5/Gkees9v8vdjGdAIJ2MPHLHodiajLpZZanWzEQ== @@ -2195,49 +2166,7 @@ jest-haste-map "^27.4.5" jest-runtime "^27.4.5" -"@jest/transform@^27.2.2", "@jest/transform@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.2.tgz#459885e96de2e21fc68b8b371e90aa653966dd0d" - integrity sha512-RTKcPZllfcmLfnlxBya7aypofhdz05+E6QITe55Ex0rxyerkgjmmpMlvVn11V0cP719Ps6WcDYCnDzxnnJUwKg== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.4.2" - babel-plugin-istanbul "^6.0.0" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.2" - jest-regex-util "^27.4.0" - jest-util "^27.4.2" - micromatch "^4.0.4" - pirates "^4.0.1" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/transform@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.4.tgz#347e39402730879ba88c6ea6982db0d88640aa78" - integrity sha512-7U/nDSrGsGzL7+X8ScNFV71w8u8knJQWSa9C2xsrrKLMOgb+rWuCG4VAyWke/53BU96GnT+Ka81xCAHA5gk6zA== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.4.2" - babel-plugin-istanbul "^6.0.0" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.4" - jest-regex-util "^27.4.0" - jest-util "^27.4.2" - micromatch "^4.0.4" - pirates "^4.0.1" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/transform@^27.4.5": +"@jest/transform@^27.2.2", "@jest/transform@^27.4.5": version "27.4.5" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.5.tgz#3dfe2e3680cd4aa27356172bf25617ab5b94f195" integrity sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew== @@ -4568,21 +4497,7 @@ axobject-query@^2.2.0: resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== -babel-jest@^27.2.2: - version "27.4.4" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.4.tgz#a012441f8a155df909839543a09510ab3477aa11" - integrity sha512-+6RVutZxOQgJkt4svgTHPFtOQlVe9dUg3wrimIAM38pY6hL/nsL8glfFSUjD9jNVjaVjzkCzj6loFFecrjr9Qw== - dependencies: - "@jest/transform" "^27.4.4" - "@jest/types" "^27.4.2" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^27.4.0" - chalk "^4.0.0" - graceful-fs "^4.2.4" - slash "^3.0.0" - -babel-jest@^27.4.5: +babel-jest@^27.2.2, babel-jest@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.5.tgz#d38bd0be8ea71d8b97853a5fc9f76deeb095c709" integrity sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA== @@ -8818,12 +8733,7 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.2.tgz#36786d4d82aad2ea5911007e255e2da6b5f80d86" - integrity sha512-o5+eTUYzCJ11/+JhW5/FUCdfsdoYVdQ/8I/OveE2XsjehYn5DdeSnNQAbjYaO8gQ6hvGTN6GM6ddQqpTVG5j8g== - -istanbul-lib-coverage@^3.2.0: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== @@ -8894,32 +8804,7 @@ jest-changed-files@^27.4.2: execa "^5.0.0" throat "^6.0.1" -jest-circus@^27.2.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.2.tgz#466f482207ca9f323b78416c28f4d1fa7588159a" - integrity sha512-2ePUSru1BGMyzxsMvRfu+tNb+PW60rUyMLJBfw1Nrh5zC8RoTPfF+zbE0JToU31a6ZVe4nnrNKWYRzlghAbL0A== - dependencies: - "@jest/environment" "^27.4.2" - "@jest/test-result" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - expect "^27.4.2" - is-generator-fn "^2.0.0" - jest-each "^27.4.2" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-runtime "^27.4.2" - jest-snapshot "^27.4.2" - jest-util "^27.4.2" - pretty-format "^27.4.2" - slash "^3.0.0" - stack-utils "^2.0.3" - throat "^6.0.1" - -jest-circus@^27.4.5: +jest-circus@^27.2.2, jest-circus@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.5.tgz#70bfb78e0200cab9b84747bf274debacaa538467" integrity sha512-eTNWa9wsvBwPykhMMShheafbwyakcdHZaEYh5iRrQ0PFJxkDP/e3U/FvzGuKWu2WpwUA3C3hPlfpuzvOdTVqnw== @@ -9045,20 +8930,7 @@ jest-each@^27.4.2: jest-util "^27.4.2" pretty-format "^27.4.2" -jest-environment-jsdom@^27.2.2, jest-environment-jsdom@^27.4.3: - version "27.4.3" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.4.3.tgz#74198285f6284888ca9c7486c4e5e67add75aa53" - integrity sha512-x1AUVz3G14LpEJs7KIFUaTINT2n0unOUmvdAby3s/sldUpJJetOJifHo1O/EUQC5fNBowggwJbVulko18y6OWw== - dependencies: - "@jest/environment" "^27.4.2" - "@jest/fake-timers" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - jest-mock "^27.4.2" - jest-util "^27.4.2" - jsdom "^16.6.0" - -jest-environment-jsdom@^27.4.4: +jest-environment-jsdom@^27.2.2, jest-environment-jsdom@^27.4.4: version "27.4.4" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz#94f738e99514d7a880e8ed8e03e3a321d43b49db" integrity sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA== @@ -9071,19 +8943,7 @@ jest-environment-jsdom@^27.4.4: jest-util "^27.4.2" jsdom "^16.6.0" -jest-environment-node@^27.2.2, jest-environment-node@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.4.2.tgz#bf5586a0924a8d21c13838121ac0941638c7d15e" - integrity sha512-nzTZ5nJ+FabuZPH2YVci7SZIHpvtNRHPt8+vipLkCnAgXGjVzHm7XJWdnNqXbAkExIgiKeVEkVMNZOZE/LeiIg== - dependencies: - "@jest/environment" "^27.4.2" - "@jest/fake-timers" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - jest-mock "^27.4.2" - jest-util "^27.4.2" - -jest-environment-node@^27.4.4: +jest-environment-node@^27.2.2, jest-environment-node@^27.4.4: version "27.4.4" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.4.4.tgz#42fe5e3b224cb69b99811ebf6f5eaa5a59618514" integrity sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA== @@ -9100,47 +8960,7 @@ jest-get-type@^27.0.6, jest-get-type@^27.4.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== -jest-haste-map@^27.2.2, jest-haste-map@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.2.tgz#7fc7d5e568cca704284f4850885b74a0b8b87587" - integrity sha512-foiyAEePORUN2eeJnOtcM1y8qW0ShEd9kTjWVL4sVaMcuCJM6gtHegvYPBRT0mpI/bs4ueThM90+Eoj2ncoNsA== - dependencies: - "@jest/types" "^27.4.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^27.4.0" - jest-serializer "^27.4.0" - jest-util "^27.4.2" - jest-worker "^27.4.2" - micromatch "^4.0.4" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.3.2" - -jest-haste-map@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.4.tgz#ec6013845368a155372e25e42e2b77e6ecc5019f" - integrity sha512-kvspmHmgPIZoDaqUsvsJFTaspuxhATvdO6wsFNGNSi8kfdiOCEEvECNbht8xG+eE5Ol88JyJmp2D7RF4dYo85Q== - dependencies: - "@jest/types" "^27.4.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^27.4.0" - jest-serializer "^27.4.0" - jest-util "^27.4.2" - jest-worker "^27.4.4" - micromatch "^4.0.4" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.3.2" - -jest-haste-map@^27.4.5: +jest-haste-map@^27.2.2, jest-haste-map@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.5.tgz#c2921224a59223f91e03ec15703905978ef0cc1a" integrity sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q== @@ -9160,31 +8980,7 @@ jest-haste-map@^27.4.5: optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.2.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.4.2.tgz#c956c88b9c05ca22afdc779deebc2890cb891797" - integrity sha512-VO/fyAJSH9u0THjbteFiL8qc93ufU+yW+bdieDc8tzTCWwlWzO53UHS5nFK1qmE8izb5Smkn+XHlVt6/l06MKQ== - dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.4.2" - "@jest/source-map" "^27.4.0" - "@jest/test-result" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.4.2" - is-generator-fn "^2.0.0" - jest-each "^27.4.2" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-runtime "^27.4.2" - jest-snapshot "^27.4.2" - jest-util "^27.4.2" - pretty-format "^27.4.2" - throat "^6.0.1" - -jest-jasmine2@^27.4.5: +jest-jasmine2@^27.2.2, jest-jasmine2@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.4.5.tgz#ff79d11561679ff6c89715b0cd6b1e8c0dfbc6dc" integrity sha512-oUnvwhJDj2LhOiUB1kdnJjkx8C5PwgUZQb9urF77mELH9DGR4e2GqpWQKBOYXWs5+uTN9BGDqRz3Aeg5Wts7aw== @@ -9284,23 +9080,7 @@ jest-resolve@27.2.2: resolve "^1.20.0" slash "^3.0.0" -jest-resolve@^27.2.2, jest-resolve@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.4.2.tgz#d3e4cbee7acb4a4f8c8bfc270767bec34d2aefaf" - integrity sha512-d/zqPjxCzMqHlOdRTg8cTpO9jY+1/T74KazT8Ws/LwmwxV5sRMWOkiLjmzUCDj/5IqA5XHNK4Hkmlq9Kdpb9Sg== - dependencies: - "@jest/types" "^27.4.2" - chalk "^4.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.2" - jest-pnp-resolver "^1.2.2" - jest-util "^27.4.2" - jest-validate "^27.4.2" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - -jest-resolve@^27.4.5: +jest-resolve@^27.2.2, jest-resolve@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.4.5.tgz#8dc44f5065fb8d58944c20f932cb7b9fe9760cca" integrity sha512-xU3z1BuOz/hUhVUL+918KqUgK+skqOuUsAi7A+iwoUldK6/+PW+utK8l8cxIWT9AW7IAhGNXjSAh1UYmjULZZw== @@ -9316,35 +9096,7 @@ jest-resolve@^27.4.5: resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^27.2.2: - version "27.4.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.4.3.tgz#9f05d4733829787778e8a143ade913834d0828dc" - integrity sha512-JgR6Om/j22Fd6ZUUIGTWNcCtuZVYbNrecb4k89W4UyFJoRtHpo2zMKWkmFFFJoqwWGrfrcPLnVBIgkJiTV3cyA== - dependencies: - "@jest/console" "^27.4.2" - "@jest/environment" "^27.4.2" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-docblock "^27.4.0" - jest-environment-jsdom "^27.4.3" - jest-environment-node "^27.4.2" - jest-haste-map "^27.4.2" - jest-leak-detector "^27.4.2" - jest-message-util "^27.4.2" - jest-resolve "^27.4.2" - jest-runtime "^27.4.2" - jest-util "^27.4.2" - jest-worker "^27.4.2" - source-map-support "^0.5.6" - throat "^6.0.1" - -jest-runner@^27.4.5: +jest-runner@^27.2.2, jest-runner@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.4.5.tgz#daba2ba71c8f34137dc7ac45616add35370a681e" integrity sha512-/irauncTfmY1WkTaRQGRWcyQLzK1g98GYG/8QvIPviHgO1Fqz1JYeEIsSfF+9mc/UTA6S+IIHFgKyvUrtiBIZg== @@ -9372,38 +9124,6 @@ jest-runner@^27.4.5: source-map-support "^0.5.6" throat "^6.0.1" -jest-runtime@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.4.2.tgz#d72da8a0e97366c16ad515a2c437191a72600d38" - integrity sha512-eqPgcBaUNaw6j8T5M+dnfAEh6MIrh2YmtskCr9sl50QYpD22Sg+QqHw3J3nmaLzVMbBtOMHFFxLF0Qx8MsZVFQ== - dependencies: - "@jest/console" "^27.4.2" - "@jest/environment" "^27.4.2" - "@jest/globals" "^27.4.2" - "@jest/source-map" "^27.4.0" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.4" - jest-haste-map "^27.4.2" - jest-message-util "^27.4.2" - jest-mock "^27.4.2" - jest-regex-util "^27.4.0" - jest-resolve "^27.4.2" - jest-snapshot "^27.4.2" - jest-util "^27.4.2" - jest-validate "^27.4.2" - slash "^3.0.0" - strip-bom "^4.0.0" - yargs "^16.2.0" - jest-runtime@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.4.5.tgz#97703ad2a1799d4f50ab59049bd21a9ceaed2813" @@ -9444,37 +9164,7 @@ jest-serializer@^27.4.0: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^27.0.2, jest-snapshot@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.4.2.tgz#bd1ea04a8fab402e5ab18b788809fa597ddff532" - integrity sha512-DI7lJlNIu6WSQ+esqhnJzEzU70+dV+cNjoF1c+j5FagWEd3KtOyZvVliAH0RWNQ6KSnAAnKSU0qxJ8UXOOhuUQ== - dependencies: - "@babel/core" "^7.7.2" - "@babel/generator" "^7.7.2" - "@babel/parser" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.4.2" - "@jest/types" "^27.4.2" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^27.4.2" - graceful-fs "^4.2.4" - jest-diff "^27.4.2" - jest-get-type "^27.4.0" - jest-haste-map "^27.4.2" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-resolve "^27.4.2" - jest-util "^27.4.2" - natural-compare "^1.4.0" - pretty-format "^27.4.2" - semver "^7.3.2" - -jest-snapshot@^27.4.5: +jest-snapshot@^27.0.2, jest-snapshot@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.4.5.tgz#2ea909b20aac0fe62504bc161331f730b8a7ecc7" integrity sha512-eCi/iM1YJFrJWiT9de4+RpWWWBqsHiYxFG9V9o/n0WXs6GpW4lUt4FAHAgFPTLPqCUVzrMQmSmTZSgQzwqR7IQ== @@ -9560,25 +9250,7 @@ jest-watcher@^27.4.2: jest-util "^27.4.2" string-length "^4.0.1" -jest-worker@^27.0.2, jest-worker@^27.0.6, jest-worker@^27.2.2, jest-worker@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.2.tgz#0fb123d50955af1a450267787f340a1bf7e12bc4" - integrity sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest-worker@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.4.tgz#9390a97c013a54d07f5c2ad2b5f6109f30c4966d" - integrity sha512-jfwxYJvfua1b1XkyuyPh01ATmgg4e5fPM/muLmhy9Qc6dmiwacQB0MLHaU6IjEsv/+nAixHGxTn8WllA27Pn0w== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest-worker@^27.4.5: +jest-worker@^27.0.2, jest-worker@^27.0.6, jest-worker@^27.2.2, jest-worker@^27.4.5: version "27.4.5" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242" integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg== @@ -9729,7 +9401,7 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@2.x, json5@^2.1.2: +json5@2.x, json5@^2.1.2, json5@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== From 6edebcda00053eecf7b3e55eeb3fe5d7fb9e7db7 Mon Sep 17 00:00:00 2001 From: Armano Date: Mon, 27 Dec 2021 07:03:07 +0100 Subject: [PATCH 4/6] fix(eslint-plugin): [consistent-indexed-object-style] do not report for circular references (#4347) --- .../rules/consistent-indexed-object-style.ts | 35 +++++++++++- .../consistent-indexed-object-style.test.ts | 55 +++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts b/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts index 8c2081adebfe..2c00dfd43eb3 100644 --- a/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts +++ b/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts @@ -34,7 +34,8 @@ export default createRule({ function checkMembers( members: TSESTree.TypeElement[], - node: TSESTree.Node, + node: TSESTree.TSTypeLiteral | TSESTree.TSInterfaceDeclaration, + parentId: TSESTree.Identifier | undefined, prefix: string, postfix: string, safeFix = true, @@ -67,6 +68,22 @@ export default createRule({ return; } + if (parentId) { + const scope = context.getScope(); + const superVar = scope.set.get(parentId.name); + if (superVar) { + const isCircular = superVar.references.some( + item => + item.isTypeReference && + node.range[0] <= item.identifier.range[0] && + node.range[1] >= item.identifier.range[1], + ); + if (isCircular) { + return; + } + } + } + context.report({ node, messageId: 'preferRecord', @@ -112,7 +129,8 @@ export default createRule({ }), ...(mode === 'record' && { TSTypeLiteral(node): void { - checkMembers(node.members, node, '', ''); + const parent = findParentDeclaration(node); + checkMembers(node.members, node, parent?.id, '', ''); }, TSInterfaceDeclaration(node): void { let genericTypes = ''; @@ -126,6 +144,7 @@ export default createRule({ checkMembers( node.body.body, node, + node.id, `type ${node.id.name}${genericTypes} = `, ';', !node.extends?.length, @@ -135,3 +154,15 @@ export default createRule({ }; }, }); + +function findParentDeclaration( + node: TSESTree.Node, +): TSESTree.TSTypeAliasDeclaration | undefined { + if (node.parent && node.parent.type !== AST_NODE_TYPES.TSTypeAnnotation) { + if (node.parent.type === AST_NODE_TYPES.TSTypeAliasDeclaration) { + return node.parent; + } + return findParentDeclaration(node.parent); + } + return undefined; +} diff --git a/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts b/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts index eb7e5cc8d1f6..9c92f1a2eac9 100644 --- a/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts @@ -30,6 +30,15 @@ interface Foo { bar: string; } `, + // circular + 'type Foo = { [key: string]: string | Foo };', + 'type Foo = { [key: string]: Foo };', + 'type Foo = { [key: string]: Foo } | Foo;', + ` +interface Foo { + [key: string]: Foo; +} + `, // Type literal 'type Foo = {};', @@ -287,6 +296,52 @@ type Foo = Readonly>; errors: [{ messageId: 'preferIndexSignature', line: 1, column: 15 }], }, + // Circular + { + code: 'type Foo = { [k: string]: A.Foo };', + output: 'type Foo = Record;', + errors: [{ messageId: 'preferRecord', line: 1, column: 12 }], + }, + { + code: 'type Foo = { [key: string]: AnotherFoo };', + output: 'type Foo = Record;', + errors: [{ messageId: 'preferRecord', line: 1, column: 12 }], + }, + { + code: 'type Foo = { [key: string]: { [key: string]: Foo } };', + output: 'type Foo = { [key: string]: Record };', + errors: [{ messageId: 'preferRecord', line: 1, column: 29 }], + }, + { + code: 'type Foo = { [key: string]: string } | Foo;', + output: 'type Foo = Record | Foo;', + errors: [{ messageId: 'preferRecord', line: 1, column: 12 }], + }, + { + code: ` +interface Foo { + [k: string]: A.Foo; +} + `, + output: ` +type Foo = Record; + `, + errors: [{ messageId: 'preferRecord', line: 2, column: 1 }], + }, + { + code: ` +interface Foo { + [k: string]: { [key: string]: Foo }; +} + `, + output: ` +interface Foo { + [k: string]: Record; +} + `, + errors: [{ messageId: 'preferRecord', line: 3, column: 16 }], + }, + // Generic { code: 'type Foo = Generic>;', From d31ec264fe5f5cd27e8f522a485e106889f2d380 Mon Sep 17 00:00:00 2001 From: Taeheon Kim Date: Mon, 27 Dec 2021 15:04:21 +0900 Subject: [PATCH 5/6] fix(eslint-plugin): [padding-line-between-statements] make function overloading is also processed (#4345) --- .../rules/padding-line-between-statements.ts | 2 ++ .../padding-line-between-statements.test.ts | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts index f64122aaea38..aab53cbba4ac 100644 --- a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts +++ b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts @@ -803,7 +803,9 @@ export default util.createRule({ ':statement': verify, SwitchCase: verifyThenEnterScope, + TSDeclareFunction: verifyThenEnterScope, 'SwitchCase:exit': exitScope, + 'TSDeclareFunction:exit': exitScope, }; }, }); diff --git a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts index 4fd71fa1eece..93b01ce6f333 100644 --- a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts +++ b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts @@ -2799,6 +2799,20 @@ var a = 1 { blankLine: 'always', prev: 'block-like', next: 'block-like' }, ], }, + { + code: 'export function foo(arg1: string): number;\nexport function foo(arg2: number) {\n return arg2;\n}', + options: [ + { blankLine: 'always', prev: '*', next: 'block-like' }, + { blankLine: 'never', prev: '*', next: 'export' }, + ], + }, + { + code: 'function foo(arg1: string): number;\nfunction foo(arg2: number) {\n return arg2;\n}', + options: [ + { blankLine: 'always', prev: '*', next: 'block-like' }, + { blankLine: 'never', prev: '*', next: 'function' }, + ], + }, ], invalid: [ //---------------------------------------------------------------------- @@ -5101,5 +5115,19 @@ declare namespace Types { { messageId: 'expectedBlankLine' }, ], }, + { + code: 'export function foo(arg1: string): number;\nexport function foo(arg2: number) {\n return arg2;\n}', + output: + 'export function foo(arg1: string): number;\n\nexport function foo(arg2: number) {\n return arg2;\n}', + options: [{ blankLine: 'always', prev: '*', next: 'block-like' }], + errors: [{ messageId: 'expectedBlankLine' }], + }, + { + code: 'function foo(arg1: string): number;\nfunction foo(arg2: number) {\n return arg2;\n}', + output: + 'function foo(arg1: string): number;\n\nfunction foo(arg2: number) {\n return arg2;\n}', + options: [{ blankLine: 'always', prev: '*', next: 'block-like' }], + errors: [{ messageId: 'expectedBlankLine' }], + }, ], }); From b4046d435189ded3a1ab315f41bbe857c7130cf7 Mon Sep 17 00:00:00 2001 From: James Henry Date: Mon, 27 Dec 2021 18:01:43 +0000 Subject: [PATCH 6/6] chore: publish v5.8.1 --- CHANGELOG.md | 13 +++++++++++++ lerna.json | 2 +- packages/ast-spec/CHANGELOG.md | 8 ++++++++ packages/ast-spec/package.json | 2 +- packages/eslint-plugin-internal/CHANGELOG.md | 8 ++++++++ packages/eslint-plugin-internal/package.json | 6 +++--- packages/eslint-plugin-tslint/CHANGELOG.md | 8 ++++++++ packages/eslint-plugin-tslint/package.json | 6 +++--- packages/eslint-plugin/CHANGELOG.md | 13 +++++++++++++ packages/eslint-plugin/package.json | 6 +++--- packages/experimental-utils/CHANGELOG.md | 8 ++++++++ packages/experimental-utils/package.json | 8 ++++---- packages/parser/CHANGELOG.md | 8 ++++++++ packages/parser/package.json | 8 ++++---- packages/scope-manager/CHANGELOG.md | 8 ++++++++ packages/scope-manager/package.json | 8 ++++---- packages/shared-fixtures/CHANGELOG.md | 8 ++++++++ packages/shared-fixtures/package.json | 2 +- packages/types/CHANGELOG.md | 8 ++++++++ packages/types/package.json | 2 +- packages/typescript-estree/CHANGELOG.md | 8 ++++++++ packages/typescript-estree/package.json | 8 ++++---- packages/visitor-keys/CHANGELOG.md | 8 ++++++++ packages/visitor-keys/package.json | 4 ++-- packages/website-eslint/CHANGELOG.md | 8 ++++++++ packages/website-eslint/package.json | 16 ++++++++-------- packages/website/CHANGELOG.md | 8 ++++++++ packages/website/package.json | 6 +++--- 28 files changed, 164 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff7ef7d506d7..055234ca9a85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + + +### Bug Fixes + +* **eslint-plugin:** [consistent-indexed-object-style] do not report for circular references ([#4347](https://github.com/typescript-eslint/typescript-eslint/issues/4347)) ([6edebcd](https://github.com/typescript-eslint/typescript-eslint/commit/6edebcda00053eecf7b3e55eeb3fe5d7fb9e7db7)) +* **eslint-plugin:** [consistent-type-definitions] correct fixer with declare keyword ([#4334](https://github.com/typescript-eslint/typescript-eslint/issues/4334)) ([0cd911a](https://github.com/typescript-eslint/typescript-eslint/commit/0cd911a916805d3b1f8043584e4685f3edd5c427)) +* **eslint-plugin:** [padding-line-between-statements] make function overloading is also processed ([#4345](https://github.com/typescript-eslint/typescript-eslint/issues/4345)) ([d31ec26](https://github.com/typescript-eslint/typescript-eslint/commit/d31ec264fe5f5cd27e8f522a485e106889f2d380)) + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) diff --git a/lerna.json b/lerna.json index cdc09c29cde4..1db17c7a68fb 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "5.8.0", + "version": "5.8.1", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/packages/ast-spec/CHANGELOG.md b/packages/ast-spec/CHANGELOG.md index fc6ee3ba176c..2da2ffc8abf9 100644 --- a/packages/ast-spec/CHANGELOG.md +++ b/packages/ast-spec/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/ast-spec + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/ast-spec diff --git a/packages/ast-spec/package.json b/packages/ast-spec/package.json index d5746ab5b5b0..ccc9be45e274 100644 --- a/packages/ast-spec/package.json +++ b/packages/ast-spec/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/ast-spec", - "version": "5.8.0", + "version": "5.8.1", "description": "TypeScript-ESTree AST spec", "private": true, "keywords": [ diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index 1b03deeb6e2b..77572fc52ed7 100644 --- a/packages/eslint-plugin-internal/CHANGELOG.md +++ b/packages/eslint-plugin-internal/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index eb15bd52370d..a443fd6334f4 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-internal", - "version": "5.8.0", + "version": "5.8.1", "private": true, "main": "dist/index.js", "scripts": { @@ -14,8 +14,8 @@ }, "dependencies": { "@types/prettier": "*", - "@typescript-eslint/experimental-utils": "5.8.0", - "@typescript-eslint/scope-manager": "5.8.0", + "@typescript-eslint/experimental-utils": "5.8.1", + "@typescript-eslint/scope-manager": "5.8.1", "prettier": "*" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index 98640bdebddc..cc25451dad13 100644 --- a/packages/eslint-plugin-tslint/CHANGELOG.md +++ b/packages/eslint-plugin-tslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index 3603c4ab5a16..6e6afaf619b6 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-tslint", - "version": "5.8.0", + "version": "5.8.1", "main": "dist/index.js", "typings": "src/index.ts", "description": "TSLint wrapper plugin for ESLint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "5.8.0", + "@typescript-eslint/experimental-utils": "5.8.1", "lodash": "^4.17.21" }, "peerDependencies": { @@ -48,6 +48,6 @@ }, "devDependencies": { "@types/lodash": "*", - "@typescript-eslint/parser": "5.8.0" + "@typescript-eslint/parser": "5.8.1" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index d480713307e1..71eef25b4ba7 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + + +### Bug Fixes + +* **eslint-plugin:** [consistent-indexed-object-style] do not report for circular references ([#4347](https://github.com/typescript-eslint/typescript-eslint/issues/4347)) ([6edebcd](https://github.com/typescript-eslint/typescript-eslint/commit/6edebcda00053eecf7b3e55eeb3fe5d7fb9e7db7)) +* **eslint-plugin:** [consistent-type-definitions] correct fixer with declare keyword ([#4334](https://github.com/typescript-eslint/typescript-eslint/issues/4334)) ([0cd911a](https://github.com/typescript-eslint/typescript-eslint/commit/0cd911a916805d3b1f8043584e4685f3edd5c427)) +* **eslint-plugin:** [padding-line-between-statements] make function overloading is also processed ([#4345](https://github.com/typescript-eslint/typescript-eslint/issues/4345)) ([d31ec26](https://github.com/typescript-eslint/typescript-eslint/commit/d31ec264fe5f5cd27e8f522a485e106889f2d380)) + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index d3dfdc2cc7d0..d813840aff43 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "5.8.0", + "version": "5.8.1", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -44,8 +44,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "5.8.0", - "@typescript-eslint/scope-manager": "5.8.0", + "@typescript-eslint/experimental-utils": "5.8.1", + "@typescript-eslint/scope-manager": "5.8.1", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index 22d58330b076..9a67454c04b5 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index 823bab80838c..0842982c8670 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "5.8.0", + "version": "5.8.1", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -40,9 +40,9 @@ }, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.8.0", - "@typescript-eslint/types": "5.8.0", - "@typescript-eslint/typescript-estree": "5.8.0", + "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/typescript-estree": "5.8.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 2a7a69f3affd..f4133fca9cd8 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/parser diff --git a/packages/parser/package.json b/packages/parser/package.json index 7d446a5aca1b..4bb03576b7c8 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "5.8.0", + "version": "5.8.1", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -44,9 +44,9 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "dependencies": { - "@typescript-eslint/scope-manager": "5.8.0", - "@typescript-eslint/types": "5.8.0", - "@typescript-eslint/typescript-estree": "5.8.0", + "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/typescript-estree": "5.8.1", "debug": "^4.3.2" }, "devDependencies": { diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index 136a826aed62..cf01cabe6dbd 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/scope-manager + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/scope-manager diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 49bbb79dbaa7..64fdb12ceedd 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "5.8.0", + "version": "5.8.1", "description": "TypeScript scope analyser for ESLint", "keywords": [ "eslint", @@ -39,12 +39,12 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "5.8.0", - "@typescript-eslint/visitor-keys": "5.8.0" + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/visitor-keys": "5.8.1" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/typescript-estree": "5.8.0", + "@typescript-eslint/typescript-estree": "5.8.1", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index 71e090cec20b..e0450e58c48e 100644 --- a/packages/shared-fixtures/CHANGELOG.md +++ b/packages/shared-fixtures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/shared-fixtures diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index f729016e4fd4..d957d2677a22 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,5 +1,5 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "5.8.0", + "version": "5.8.1", "private": true } diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index c0faa61a8606..872b4db197b2 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/types + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/types diff --git a/packages/types/package.json b/packages/types/package.json index efa012300705..5c40bf8f4b14 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "5.8.0", + "version": "5.8.1", "description": "Types for the TypeScript-ESTree AST spec", "keywords": [ "eslint", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index 7eeac95bcfd1..9f5f9be7566b 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/typescript-estree + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/typescript-estree diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 7c2c413ee1fa..22f17a188c64 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "5.8.0", + "version": "5.8.1", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -41,8 +41,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "5.8.0", - "@typescript-eslint/visitor-keys": "5.8.0", + "@typescript-eslint/types": "5.8.1", + "@typescript-eslint/visitor-keys": "5.8.1", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -59,7 +59,7 @@ "@types/is-glob": "*", "@types/semver": "*", "@types/tmp": "*", - "@typescript-eslint/shared-fixtures": "5.8.0", + "@typescript-eslint/shared-fixtures": "5.8.1", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index c1b97c28aef0..0c0dd43802c2 100644 --- a/packages/visitor-keys/CHANGELOG.md +++ b/packages/visitor-keys/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/visitor-keys + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/visitor-keys diff --git a/packages/visitor-keys/package.json b/packages/visitor-keys/package.json index f93087488834..ef4d2344f82f 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "5.8.0", + "version": "5.8.1", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "keywords": [ "eslint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "5.8.0", + "@typescript-eslint/types": "5.8.1", "eslint-visitor-keys": "^3.0.0" }, "devDependencies": { diff --git a/packages/website-eslint/CHANGELOG.md b/packages/website-eslint/CHANGELOG.md index 070c2dda72ea..29d30d757163 100644 --- a/packages/website-eslint/CHANGELOG.md +++ b/packages/website-eslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package @typescript-eslint/website-eslint + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package @typescript-eslint/website-eslint diff --git a/packages/website-eslint/package.json b/packages/website-eslint/package.json index 39664fd146e3..10a2949e90ab 100644 --- a/packages/website-eslint/package.json +++ b/packages/website-eslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/website-eslint", - "version": "5.8.0", + "version": "5.8.1", "private": true, "description": "ESLint which works in browsers.", "engines": { @@ -16,19 +16,19 @@ "format": "prettier --write \"./**/*.{ts,js,json,md}\" --ignore-path ../../.prettierignore" }, "dependencies": { - "@typescript-eslint/experimental-utils": "5.8.0", - "@typescript-eslint/types": "5.8.0" + "@typescript-eslint/experimental-utils": "5.8.1", + "@typescript-eslint/types": "5.8.1" }, "devDependencies": { "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.0.6", "@rollup/pluginutils": "^4.1.1", - "@typescript-eslint/eslint-plugin": "5.8.0", - "@typescript-eslint/parser": "5.8.0", - "@typescript-eslint/scope-manager": "5.8.0", - "@typescript-eslint/typescript-estree": "5.8.0", - "@typescript-eslint/visitor-keys": "5.8.0", + "@typescript-eslint/eslint-plugin": "5.8.1", + "@typescript-eslint/parser": "5.8.1", + "@typescript-eslint/scope-manager": "5.8.1", + "@typescript-eslint/typescript-estree": "5.8.1", + "@typescript-eslint/visitor-keys": "5.8.1", "eslint": "*", "rollup": "^2.59.0", "semver": "^7.3.5" diff --git a/packages/website/CHANGELOG.md b/packages/website/CHANGELOG.md index 3ba594738f05..ef2349b95d51 100644 --- a/packages/website/CHANGELOG.md +++ b/packages/website/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.8.1](https://github.com/typescript-eslint/typescript-eslint/compare/v5.8.0...v5.8.1) (2021-12-27) + +**Note:** Version bump only for package website + + + + + # [5.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.7.0...v5.8.0) (2021-12-20) **Note:** Version bump only for package website diff --git a/packages/website/package.json b/packages/website/package.json index 090324a66074..a47a71afd09b 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "website", - "version": "5.8.0", + "version": "5.8.1", "private": true, "scripts": { "build": "docusaurus build", @@ -21,15 +21,15 @@ "@docusaurus/theme-classic": "^2.0.0-beta.13", "@docusaurus/theme-search-algolia": "^2.0.0-beta.13", "@mdx-js/react": "1.6.22", - "@typescript-eslint/website-eslint": "5.8.0", + "@typescript-eslint/website-eslint": "5.8.1", "clsx": "^1.1.1", "eslint": "*", + "json5": "^2.2.0", "konamimojisplosion": "^0.5.1", "lzstring.ts": "^2.0.2", "react": "^17.0.2", "react-dom": "^17.0.2", "remark-docusaurus-tabs": "^0.2.0", - "json5": "^2.2.0", "typescript": "*" }, "devDependencies": {