From 18450ecfeacd334bc7300482e8f0ab1153937870 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Sat, 25 Feb 2023 01:53:16 +0100 Subject: [PATCH 1/2] format --- .changeset/lazy-rabbits-wink.md | 10 ++++++++++ .eslintrc.js | 1 + packages/codemirror-graphql/src/results/mode.ts | 3 +-- packages/codemirror-graphql/src/utils/mode-indent.ts | 3 +-- packages/codemirror-graphql/src/variables/mode.ts | 3 +-- .../src/explorer/components/doc-explorer.tsx | 4 ++-- .../graphiql-react/src/explorer/components/search.tsx | 4 ++-- packages/graphiql-react/src/explorer/context.tsx | 2 +- packages/graphiql-toolkit/src/storage/query.ts | 2 +- packages/graphql-language-service-cli/src/client.ts | 3 +-- .../src/MessageProcessor.ts | 2 +- .../src/parseDocument.ts | 2 +- .../src/parser/onlineParser.ts | 4 ++-- 13 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 .changeset/lazy-rabbits-wink.md diff --git a/.changeset/lazy-rabbits-wink.md b/.changeset/lazy-rabbits-wink.md new file mode 100644 index 00000000000..408267b612e --- /dev/null +++ b/.changeset/lazy-rabbits-wink.md @@ -0,0 +1,10 @@ +--- +'codemirror-graphql': patch +'@graphiql/react': patch +'@graphiql/toolkit': patch +'graphql-language-service': patch +'graphql-language-service-cli': patch +'graphql-language-service-server': patch +--- + +Prefer .at() method for index access diff --git a/.eslintrc.js b/.eslintrc.js index 2394e895bc4..34dceb647e8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -245,6 +245,7 @@ module.exports = { { extensions: ['.tsx', '.jsx'], allow: 'as-needed' }, ], + 'unicorn/prefer-at': 'error', 'unicorn/consistent-destructuring': 'error', 'prefer-destructuring': ['error', { VariableDeclarator: { object: true } }], 'promise/no-multiple-resolved': 'error', diff --git a/packages/codemirror-graphql/src/results/mode.ts b/packages/codemirror-graphql/src/results/mode.ts index 0e7e0b654bb..aff296baf09 100644 --- a/packages/codemirror-graphql/src/results/mode.ts +++ b/packages/codemirror-graphql/src/results/mode.ts @@ -58,8 +58,7 @@ function indent( const level = !levels || levels.length === 0 ? indentLevel - : levels[levels.length - 1] - - (this.electricInput?.test(textAfter) ? 1 : 0); + : levels.at(-1) - (this.electricInput?.test(textAfter) ? 1 : 0); return (level || 0) * (this.config?.indentUnit || 0); } diff --git a/packages/codemirror-graphql/src/utils/mode-indent.ts b/packages/codemirror-graphql/src/utils/mode-indent.ts index 615e08c5d4d..18f28550e52 100644 --- a/packages/codemirror-graphql/src/utils/mode-indent.ts +++ b/packages/codemirror-graphql/src/utils/mode-indent.ts @@ -25,7 +25,6 @@ export default function indent( const level = !levels || levels.length === 0 ? indentLevel - : levels[levels.length - 1] - - (this.electricInput?.test(textAfter) ? 1 : 0); + : levels.at(-1) - (this.electricInput?.test(textAfter) ? 1 : 0); return (level || 0) * (this.config?.indentUnit || 0); } diff --git a/packages/codemirror-graphql/src/variables/mode.ts b/packages/codemirror-graphql/src/variables/mode.ts index 03bb909837f..3d278eb586d 100644 --- a/packages/codemirror-graphql/src/variables/mode.ts +++ b/packages/codemirror-graphql/src/variables/mode.ts @@ -59,8 +59,7 @@ function indent( const level = !levels || levels.length === 0 ? indentLevel - : levels[levels.length - 1] - - (this.electricInput?.test(textAfter) ? 1 : 0); + : levels.at(-1) - (this.electricInput?.test(textAfter) ? 1 : 0); return (level || 0) * (this.config?.indentUnit || 0); } diff --git a/packages/graphiql-react/src/explorer/components/doc-explorer.tsx b/packages/graphiql-react/src/explorer/components/doc-explorer.tsx index 026e7ff5ae7..c40e619b9d3 100644 --- a/packages/graphiql-react/src/explorer/components/doc-explorer.tsx +++ b/packages/graphiql-react/src/explorer/components/doc-explorer.tsx @@ -21,7 +21,7 @@ export function DocExplorer() { caller: DocExplorer, }); - const navItem = explorerNavStack[explorerNavStack.length - 1]; + const navItem = explorerNavStack.at(-1); let content: ReactNode = null; if (fetchError) { @@ -55,7 +55,7 @@ export function DocExplorer() { let prevName; if (explorerNavStack.length > 1) { - prevName = explorerNavStack[explorerNavStack.length - 2].name; + prevName = explorerNavStack.at(-2).name; } return ( diff --git a/packages/graphiql-react/src/explorer/components/search.tsx b/packages/graphiql-react/src/explorer/components/search.tsx index bb8c8eff540..3a0c27d3d42 100644 --- a/packages/graphiql-react/src/explorer/components/search.tsx +++ b/packages/graphiql-react/src/explorer/components/search.tsx @@ -58,7 +58,7 @@ export function Search() { return () => window.removeEventListener('keydown', handleKeyDown); }, []); - const navItem = explorerNavStack[explorerNavStack.length - 1]; + const navItem = explorerNavStack.at(-1); const shouldSearchBoxAppear = explorerNavStack.length === 1 || @@ -198,7 +198,7 @@ export function useSearchResults(caller?: Function) { caller: caller || useSearchResults, }); - const navItem = explorerNavStack[explorerNavStack.length - 1]; + const navItem = explorerNavStack.at(-1); return useCallback( (searchValue: string) => { diff --git a/packages/graphiql-react/src/explorer/context.tsx b/packages/graphiql-react/src/explorer/context.tsx index 7fd0617aa0c..b43c4dc7f25 100644 --- a/packages/graphiql-react/src/explorer/context.tsx +++ b/packages/graphiql-react/src/explorer/context.tsx @@ -83,7 +83,7 @@ export function ExplorerContextProvider(props: ExplorerContextProviderProps) { const push = useCallback((item: ExplorerNavStackItem) => { setNavStack(currentState => { - const lastItem = currentState[currentState.length - 1]; + const lastItem = currentState.at(-1); return lastItem.def === item.def ? // Avoid pushing duplicate items currentState diff --git a/packages/graphiql-toolkit/src/storage/query.ts b/packages/graphiql-toolkit/src/storage/query.ts index 45701830976..86040e1621a 100644 --- a/packages/graphiql-toolkit/src/storage/query.ts +++ b/packages/graphiql-toolkit/src/storage/query.ts @@ -63,7 +63,7 @@ export class QueryStore { } fetchRecent() { - return this.items[this.items.length - 1]; + return this.items.at(-1); } fetchAll() { diff --git a/packages/graphql-language-service-cli/src/client.ts b/packages/graphql-language-service-cli/src/client.ts index 6b60f47c618..09e157022a9 100644 --- a/packages/graphql-language-service-cli/src/client.ts +++ b/packages/graphql-language-service-cli/src/client.ts @@ -56,8 +56,7 @@ export default function main( case 'autocomplete': const lines = text.split('\n'); const row = parseInt(argv.row, 10) || lines.length - 1; - const column = - parseInt(argv.column, 10) || lines[lines.length - 1].length; + const column = parseInt(argv.column, 10) || lines.at(-1).length; const point = new Position(row, column); exitCode = _getAutocompleteSuggestions(text, point, schemaPath); break; diff --git a/packages/graphql-language-service-server/src/MessageProcessor.ts b/packages/graphql-language-service-server/src/MessageProcessor.ts index 12fadaa1cdb..d010827069f 100644 --- a/packages/graphql-language-service-server/src/MessageProcessor.ts +++ b/packages/graphql-language-service-server/src/MessageProcessor.ts @@ -434,7 +434,7 @@ export class MessageProcessor { const project = this._graphQLCache.getProjectForFile(uri); try { const { contentChanges } = params; - const contentChange = contentChanges[contentChanges.length - 1]; + const contentChange = contentChanges.at(-1); // As `contentChanges` is an array, and we just want the // latest update to the text, grab the last entry from the array. diff --git a/packages/graphql-language-service-server/src/parseDocument.ts b/packages/graphql-language-service-server/src/parseDocument.ts index e92beb2c7cc..add652031d6 100644 --- a/packages/graphql-language-service-server/src/parseDocument.ts +++ b/packages/graphql-language-service-server/src/parseDocument.ts @@ -68,7 +68,7 @@ export function parseDocument( const lines = query.split('\n'); const range = new Range( new Position(0, 0), - new Position(lines.length - 1, lines[lines.length - 1].length - 1), + new Position(lines.length - 1, lines.at(-1).length - 1), ); return [{ query, range }]; } diff --git a/packages/graphql-language-service/src/parser/onlineParser.ts b/packages/graphql-language-service/src/parser/onlineParser.ts index dd9ae1100af..26bbfc97f93 100644 --- a/packages/graphql-language-service/src/parser/onlineParser.ts +++ b/packages/graphql-language-service/src/parser/onlineParser.ts @@ -148,9 +148,9 @@ function getToken( if ( state.indentLevel && levels.length > 0 && - levels[levels.length - 1] < state.indentLevel + levels.at(-1) < state.indentLevel ) { - state.indentLevel = levels[levels.length - 1]; + state.indentLevel = levels.at(-1); } } } From 6f4e6d27bb1f090a444cb1acb6a7021c4d576462 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Sat, 25 Feb 2023 02:10:13 +0100 Subject: [PATCH 2/2] fixes --- .../codemirror-graphql/src/results/mode.ts | 28 ++----------------- .../src/utils/mode-indent.ts | 2 +- .../codemirror-graphql/src/variables/mode.ts | 19 +------------ .../src/explorer/components/doc-explorer.tsx | 4 +-- .../src/explorer/components/search.tsx | 4 +-- .../graphiql-react/src/explorer/context.tsx | 2 +- .../src/client.ts | 2 +- .../src/MessageProcessor.ts | 12 ++------ .../src/parseDocument.ts | 2 +- .../src/parser/onlineParser.ts | 2 +- 10 files changed, 15 insertions(+), 62 deletions(-) diff --git a/packages/codemirror-graphql/src/results/mode.ts b/packages/codemirror-graphql/src/results/mode.ts index aff296baf09..369ed8ecf83 100644 --- a/packages/codemirror-graphql/src/results/mode.ts +++ b/packages/codemirror-graphql/src/results/mode.ts @@ -9,14 +9,8 @@ import CodeMirror from 'codemirror'; -import { - list, - t, - onlineParser, - p, - State, - Token, -} from 'graphql-language-service'; +import { list, t, onlineParser, p, Token } from 'graphql-language-service'; +import indent from '../utils/mode-indent'; /** * This mode defines JSON, but provides a data-laden parser state to enable @@ -44,24 +38,6 @@ CodeMirror.defineMode('graphql-results', config => { }; }); -function indent( - this: CodeMirror.Mode & { - electricInput?: RegExp; - config?: CodeMirror.EditorConfiguration; - }, - state: State, - textAfter: string, -) { - const { levels, indentLevel } = state; - // If there is no stack of levels, use the current level. - // Otherwise, use the top level, preemptively dedenting for close braces. - const level = - !levels || levels.length === 0 - ? indentLevel - : levels.at(-1) - (this.electricInput?.test(textAfter) ? 1 : 0); - return (level || 0) * (this.config?.indentUnit || 0); -} - /** * The lexer rules. These are exactly as described by the spec. */ diff --git a/packages/codemirror-graphql/src/utils/mode-indent.ts b/packages/codemirror-graphql/src/utils/mode-indent.ts index 18f28550e52..10c417df99f 100644 --- a/packages/codemirror-graphql/src/utils/mode-indent.ts +++ b/packages/codemirror-graphql/src/utils/mode-indent.ts @@ -25,6 +25,6 @@ export default function indent( const level = !levels || levels.length === 0 ? indentLevel - : levels.at(-1) - (this.electricInput?.test(textAfter) ? 1 : 0); + : levels.at(-1)! - (this.electricInput?.test(textAfter) ? 1 : 0); return (level || 0) * (this.config?.indentUnit || 0); } diff --git a/packages/codemirror-graphql/src/variables/mode.ts b/packages/codemirror-graphql/src/variables/mode.ts index 3d278eb586d..393fa8a835c 100644 --- a/packages/codemirror-graphql/src/variables/mode.ts +++ b/packages/codemirror-graphql/src/variables/mode.ts @@ -18,6 +18,7 @@ import { State, Token, } from 'graphql-language-service'; +import indent from '../utils/mode-indent'; /** * This mode defines JSON, but provides a data-laden parser state to enable @@ -45,24 +46,6 @@ CodeMirror.defineMode('graphql-variables', config => { }; }); -function indent( - this: CodeMirror.Mode & { - electricInput?: RegExp; - config?: CodeMirror.EditorConfiguration; - }, - state: State, - textAfter: string, -) { - const { levels, indentLevel } = state; - // If there is no stack of levels, use the current level. - // Otherwise, use the top level, preemptively dedenting for close braces. - const level = - !levels || levels.length === 0 - ? indentLevel - : levels.at(-1) - (this.electricInput?.test(textAfter) ? 1 : 0); - return (level || 0) * (this.config?.indentUnit || 0); -} - /** * The lexer rules. These are exactly as described by the spec. */ diff --git a/packages/graphiql-react/src/explorer/components/doc-explorer.tsx b/packages/graphiql-react/src/explorer/components/doc-explorer.tsx index c40e619b9d3..43a1b3c803a 100644 --- a/packages/graphiql-react/src/explorer/components/doc-explorer.tsx +++ b/packages/graphiql-react/src/explorer/components/doc-explorer.tsx @@ -21,7 +21,7 @@ export function DocExplorer() { caller: DocExplorer, }); - const navItem = explorerNavStack.at(-1); + const navItem = explorerNavStack.at(-1)!; let content: ReactNode = null; if (fetchError) { @@ -55,7 +55,7 @@ export function DocExplorer() { let prevName; if (explorerNavStack.length > 1) { - prevName = explorerNavStack.at(-2).name; + prevName = explorerNavStack.at(-2)!.name; } return ( diff --git a/packages/graphiql-react/src/explorer/components/search.tsx b/packages/graphiql-react/src/explorer/components/search.tsx index 3a0c27d3d42..8876397a02e 100644 --- a/packages/graphiql-react/src/explorer/components/search.tsx +++ b/packages/graphiql-react/src/explorer/components/search.tsx @@ -58,7 +58,7 @@ export function Search() { return () => window.removeEventListener('keydown', handleKeyDown); }, []); - const navItem = explorerNavStack.at(-1); + const navItem = explorerNavStack.at(-1)!; const shouldSearchBoxAppear = explorerNavStack.length === 1 || @@ -198,7 +198,7 @@ export function useSearchResults(caller?: Function) { caller: caller || useSearchResults, }); - const navItem = explorerNavStack.at(-1); + const navItem = explorerNavStack.at(-1)!; return useCallback( (searchValue: string) => { diff --git a/packages/graphiql-react/src/explorer/context.tsx b/packages/graphiql-react/src/explorer/context.tsx index b43c4dc7f25..cf545334306 100644 --- a/packages/graphiql-react/src/explorer/context.tsx +++ b/packages/graphiql-react/src/explorer/context.tsx @@ -83,7 +83,7 @@ export function ExplorerContextProvider(props: ExplorerContextProviderProps) { const push = useCallback((item: ExplorerNavStackItem) => { setNavStack(currentState => { - const lastItem = currentState.at(-1); + const lastItem = currentState.at(-1)!; return lastItem.def === item.def ? // Avoid pushing duplicate items currentState diff --git a/packages/graphql-language-service-cli/src/client.ts b/packages/graphql-language-service-cli/src/client.ts index 09e157022a9..bde89aa6eec 100644 --- a/packages/graphql-language-service-cli/src/client.ts +++ b/packages/graphql-language-service-cli/src/client.ts @@ -56,7 +56,7 @@ export default function main( case 'autocomplete': const lines = text.split('\n'); const row = parseInt(argv.row, 10) || lines.length - 1; - const column = parseInt(argv.column, 10) || lines.at(-1).length; + const column = parseInt(argv.column, 10) || lines.at(-1)!.length; const point = new Position(row, column); exitCode = _getAutocompleteSuggestions(text, point, schemaPath); break; diff --git a/packages/graphql-language-service-server/src/MessageProcessor.ts b/packages/graphql-language-service-server/src/MessageProcessor.ts index d010827069f..54410c6e082 100644 --- a/packages/graphql-language-service-server/src/MessageProcessor.ts +++ b/packages/graphql-language-service-server/src/MessageProcessor.ts @@ -419,22 +419,16 @@ export class MessageProcessor { // with version information up-to-date, so that the textDocument contents // may be used during performing language service features, // e.g. auto-completions. - if ( - !params || - !params.textDocument || - !params.contentChanges || - !params.textDocument.uri - ) { + if (!params?.textDocument?.uri || !params.contentChanges) { throw new Error( '`textDocument`, `textDocument.uri`, and `contentChanges` arguments are required.', ); } - const { textDocument } = params; + const { textDocument, contentChanges } = params; const { uri } = textDocument; const project = this._graphQLCache.getProjectForFile(uri); try { - const { contentChanges } = params; - const contentChange = contentChanges.at(-1); + const contentChange = contentChanges.at(-1)!; // As `contentChanges` is an array, and we just want the // latest update to the text, grab the last entry from the array. diff --git a/packages/graphql-language-service-server/src/parseDocument.ts b/packages/graphql-language-service-server/src/parseDocument.ts index add652031d6..a9b809af1c7 100644 --- a/packages/graphql-language-service-server/src/parseDocument.ts +++ b/packages/graphql-language-service-server/src/parseDocument.ts @@ -68,7 +68,7 @@ export function parseDocument( const lines = query.split('\n'); const range = new Range( new Position(0, 0), - new Position(lines.length - 1, lines.at(-1).length - 1), + new Position(lines.length - 1, lines.at(-1)!.length - 1), ); return [{ query, range }]; } diff --git a/packages/graphql-language-service/src/parser/onlineParser.ts b/packages/graphql-language-service/src/parser/onlineParser.ts index 26bbfc97f93..37c9cb98458 100644 --- a/packages/graphql-language-service/src/parser/onlineParser.ts +++ b/packages/graphql-language-service/src/parser/onlineParser.ts @@ -148,7 +148,7 @@ function getToken( if ( state.indentLevel && levels.length > 0 && - levels.at(-1) < state.indentLevel + levels.at(-1)! < state.indentLevel ) { state.indentLevel = levels.at(-1); }