From 80f6ba5684678cb9b53c2a0edfba85fe8f03a7a9 Mon Sep 17 00:00:00 2001 From: Maxim Stykow Date: Sat, 19 Oct 2024 18:43:11 +0200 Subject: [PATCH 1/5] feat(typescript-eslint): improve undefined extension handling Addresses #10176 by checking if any of the extensions are undefined and throwing a helpful error if true. Signed-off-by: Maxim Stykow --- packages/typescript-eslint/src/config-helper.ts | 5 +++++ packages/typescript-eslint/tests/configs.test.ts | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/typescript-eslint/src/config-helper.ts b/packages/typescript-eslint/src/config-helper.ts index 77085838c76a..bd4f177b73e1 100644 --- a/packages/typescript-eslint/src/config-helper.ts +++ b/packages/typescript-eslint/src/config-helper.ts @@ -90,6 +90,11 @@ export function config( if (extendsArr == null || extendsArr.length === 0) { return config; } + if (!extendsArr.every(Boolean)) { + throw new Error( + 'Some of your extensions are undefined, likely due to a problem with their import path.', + ); + } return [ ...extendsArr.map(extension => { diff --git a/packages/typescript-eslint/tests/configs.test.ts b/packages/typescript-eslint/tests/configs.test.ts index 63bf079e1b79..fae4845204ff 100644 --- a/packages/typescript-eslint/tests/configs.test.ts +++ b/packages/typescript-eslint/tests/configs.test.ts @@ -368,6 +368,19 @@ describe('config helper', () => { ]); }); + it('throws error when some extensions are undefined', () => { + expect(() => + plugin.config({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + extends: [undefined as any], + files: ['common-file'], + ignores: ['common-ignored'], + name: 'my-config', + rules: { rule: 'error' }, + }), + ).toThrow('Some of your extensions are undefined'); + }); + it('flattens extended configs with config name', () => { expect( plugin.config({ From 75c0c840ae399ac30dda68a0273d78d588f6076a Mon Sep 17 00:00:00 2001 From: Maxim Stykow Date: Tue, 22 Oct 2024 10:51:44 +0200 Subject: [PATCH 2/5] feat(typescript-eslint): improve error message to include indices Signed-off-by: Maxim Stykow --- .../typescript-eslint/src/config-helper.ts | 21 ++++++++++-- .../typescript-eslint/tests/configs.test.ts | 33 ++++++++++++++----- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/packages/typescript-eslint/src/config-helper.ts b/packages/typescript-eslint/src/config-helper.ts index bd4f177b73e1..7b4d234a229d 100644 --- a/packages/typescript-eslint/src/config-helper.ts +++ b/packages/typescript-eslint/src/config-helper.ts @@ -85,14 +85,29 @@ export interface ConfigWithExtends extends TSESLint.FlatConfig.Config { export function config( ...configs: ConfigWithExtends[] ): TSESLint.FlatConfig.ConfigArray { - return configs.flatMap(configWithExtends => { + return configs.flatMap((configWithExtends, configIndex) => { const { extends: extendsArr, ...config } = configWithExtends; if (extendsArr == null || extendsArr.length === 0) { return config; } - if (!extendsArr.every(Boolean)) { + const undefinedExtensions = extendsArr.reduce( + (acc, extension, extensionIndex) => { + const maybeExtension = extension as + | TSESLint.FlatConfig.Config + | undefined; + if (!maybeExtension) { + acc.push(extensionIndex); + } + return acc; + }, + [], + ); + if (undefinedExtensions.length) { throw new Error( - 'Some of your extensions are undefined, likely due to a problem with their import path.', + `Your config at index ${configIndex} contains undefined extensions ` + + `at the following indices: ${undefinedExtensions.join(', ')}.\n` + + 'This is likely due to a problem with how you are specifying your ' + + "extension's import path.", ); } diff --git a/packages/typescript-eslint/tests/configs.test.ts b/packages/typescript-eslint/tests/configs.test.ts index fae4845204ff..044c11b4a41f 100644 --- a/packages/typescript-eslint/tests/configs.test.ts +++ b/packages/typescript-eslint/tests/configs.test.ts @@ -1,3 +1,4 @@ +import type { TSESLint } from '@typescript-eslint/utils'; import type { FlatConfig, RuleRecommendation, @@ -369,16 +370,30 @@ describe('config helper', () => { }); it('throws error when some extensions are undefined', () => { + const extension: TSESLint.FlatConfig.Config = { rules: { rule1: 'error' } }; + expect(() => - plugin.config({ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - extends: [undefined as any], - files: ['common-file'], - ignores: ['common-ignored'], - name: 'my-config', - rules: { rule: 'error' }, - }), - ).toThrow('Some of your extensions are undefined'); + plugin.config( + { + extends: [extension], + files: ['common-file'], + ignores: ['common-ignored'], + name: 'my-config', + rules: { rule: 'error' }, + }, + { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + extends: [undefined as any, extension, undefined as any], + files: ['common-file'], + ignores: ['common-ignored'], + name: 'my-config', + rules: { rule: 'error' }, + }, + ), + ).toThrow( + 'Your config at index 1 contains undefined extensions at the following' + + ' indices: 0, 2', + ); }); it('flattens extended configs with config name', () => { From d3bd7aaed742b3531e6565ee0231a2c336bc07cc Mon Sep 17 00:00:00 2001 From: Maxim Stykow Date: Tue, 22 Oct 2024 17:17:14 +0200 Subject: [PATCH 3/5] feat(typescript-eslint): minor rewording Signed-off-by: Maxim Stykow --- packages/typescript-eslint/src/config-helper.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/typescript-eslint/src/config-helper.ts b/packages/typescript-eslint/src/config-helper.ts index 7b4d234a229d..68ecbfcb4304 100644 --- a/packages/typescript-eslint/src/config-helper.ts +++ b/packages/typescript-eslint/src/config-helper.ts @@ -106,8 +106,7 @@ export function config( throw new Error( `Your config at index ${configIndex} contains undefined extensions ` + `at the following indices: ${undefinedExtensions.join(', ')}.\n` + - 'This is likely due to a problem with how you are specifying your ' + - "extension's import path.", + 'This is likely due to a problem with extension import paths.', ); } From 900f45d35d6fb6fc46a818654261ebdb05427ce5 Mon Sep 17 00:00:00 2001 From: Maxim Stykow Date: Wed, 23 Oct 2024 23:37:02 +0200 Subject: [PATCH 4/5] feat(typescript-eslint): add config name to error message Signed-off-by: Maxim Stykow --- .../typescript-eslint/src/config-helper.ts | 12 ++++--- .../typescript-eslint/tests/configs.test.ts | 36 ++++++++++++++++--- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/typescript-eslint/src/config-helper.ts b/packages/typescript-eslint/src/config-helper.ts index 68ecbfcb4304..b09a8309a913 100644 --- a/packages/typescript-eslint/src/config-helper.ts +++ b/packages/typescript-eslint/src/config-helper.ts @@ -95,7 +95,7 @@ export function config( const maybeExtension = extension as | TSESLint.FlatConfig.Config | undefined; - if (!maybeExtension) { + if (maybeExtension == null) { acc.push(extensionIndex); } return acc; @@ -103,10 +103,14 @@ export function config( [], ); if (undefinedExtensions.length) { + const configName = + configWithExtends.name != null + ? `, named "${configWithExtends.name},"` + : ' (anonymous)'; + const extensionIndices = undefinedExtensions.join(', '); throw new Error( - `Your config at index ${configIndex} contains undefined extensions ` + - `at the following indices: ${undefinedExtensions.join(', ')}.\n` + - 'This is likely due to a problem with extension import paths.', + `Your config at index ${configIndex}${configName} contains undefined` + + ` extensions at the following indices: ${extensionIndices}.`, ); } diff --git a/packages/typescript-eslint/tests/configs.test.ts b/packages/typescript-eslint/tests/configs.test.ts index 044c11b4a41f..292f543e7309 100644 --- a/packages/typescript-eslint/tests/configs.test.ts +++ b/packages/typescript-eslint/tests/configs.test.ts @@ -369,7 +369,7 @@ describe('config helper', () => { ]); }); - it('throws error when some extensions are undefined', () => { + it('throws error containing config name when some extensions are undefined', () => { const extension: TSESLint.FlatConfig.Config = { rules: { rule1: 'error' } }; expect(() => @@ -378,7 +378,7 @@ describe('config helper', () => { extends: [extension], files: ['common-file'], ignores: ['common-ignored'], - name: 'my-config', + name: 'my-config-1', rules: { rule: 'error' }, }, { @@ -386,13 +386,39 @@ describe('config helper', () => { extends: [undefined as any, extension, undefined as any], files: ['common-file'], ignores: ['common-ignored'], - name: 'my-config', + name: 'my-config-2', rules: { rule: 'error' }, }, ), ).toThrow( - 'Your config at index 1 contains undefined extensions at the following' + - ' indices: 0, 2', + 'Your config at index 1, named "my-config-2," contains undefined ' + + 'extensions at the following indices: 0, 2', + ); + }); + + it('throws error without config name when some extensions are undefined', () => { + const extension: TSESLint.FlatConfig.Config = { rules: { rule1: 'error' } }; + + expect(() => + plugin.config( + { + extends: [extension], + files: ['common-file'], + ignores: ['common-ignored'], + name: 'my-config-1', + rules: { rule: 'error' }, + }, + { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + extends: [undefined as any, extension, undefined as any], + files: ['common-file'], + ignores: ['common-ignored'], + rules: { rule: 'error' }, + }, + ), + ).toThrow( + 'Your config at index 1 (anonymous) contains undefined extensions at ' + + 'the following indices: 0, 2', ); }); From 4d6ad8ba37b3fc1bc26985643e5864a792bc5b76 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Wed, 23 Oct 2024 16:46:10 -0600 Subject: [PATCH 5/5] quotes around what is quoted --- packages/typescript-eslint/src/config-helper.ts | 2 +- packages/typescript-eslint/tests/configs.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typescript-eslint/src/config-helper.ts b/packages/typescript-eslint/src/config-helper.ts index b09a8309a913..58866686d13c 100644 --- a/packages/typescript-eslint/src/config-helper.ts +++ b/packages/typescript-eslint/src/config-helper.ts @@ -105,7 +105,7 @@ export function config( if (undefinedExtensions.length) { const configName = configWithExtends.name != null - ? `, named "${configWithExtends.name},"` + ? `, named "${configWithExtends.name}",` : ' (anonymous)'; const extensionIndices = undefinedExtensions.join(', '); throw new Error( diff --git a/packages/typescript-eslint/tests/configs.test.ts b/packages/typescript-eslint/tests/configs.test.ts index 292f543e7309..e020dba758b5 100644 --- a/packages/typescript-eslint/tests/configs.test.ts +++ b/packages/typescript-eslint/tests/configs.test.ts @@ -391,7 +391,7 @@ describe('config helper', () => { }, ), ).toThrow( - 'Your config at index 1, named "my-config-2," contains undefined ' + + 'Your config at index 1, named "my-config-2", contains undefined ' + 'extensions at the following indices: 0, 2', ); }); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy