Skip to content

Commit

Permalink
fix(#123): make no-named-as-default ignores TS namespace (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
SukkaW committed Aug 29, 2024
1 parent ceb8e65 commit 757ffa9
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 50 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-paws-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-import-x": patch
---

Fix #123 where the rule `no-named-as-default` will confuse TypeScript namespace exports with actual exports.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"@types/is-glob": "^4.0.4",
"@types/jest": "^29.5.12",
"@types/json-schema": "^7.0.15",
"@types/klaw-sync": "^6.0.5",
"@types/node": "^20.11.30",
"@typescript-eslint/eslint-plugin": "^8.1.0",
"@typescript-eslint/parser": "^8.1.0",
Expand All @@ -114,13 +115,15 @@
"eslint9": "npm:eslint@^9.8.0",
"hermes-eslint": "^0.23.1",
"jest": "^29.7.0",
"klaw-sync": "^6.0.0",
"npm-run-all2": "^6.1.2",
"prettier": "^3.2.5",
"redux": "^5.0.1",
"rimraf": "^5.0.10",
"svelte": "^4.2.12",
"ts-node": "^10.9.2",
"type-fest": "^4.14.0",
"typescript": "^5.5.4"
"typescript": "^5.5.4",
"zod": "^3.23.8"
}
}
67 changes: 37 additions & 30 deletions src/rules/no-named-as-default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,44 +21,51 @@ export = createRule<[], MessageId>({
},
defaultOptions: [],
create(context) {
function checkDefault(
nameKey: 'local' | 'exported',
defaultSpecifier: TSESTree.ImportDefaultSpecifier,
// | TSESTree.ExportDefaultSpecifier,
) {
// #566: default is a valid specifier
// @ts-expect-error - ExportDefaultSpecifier is unavailable yet
const nameValue = defaultSpecifier[nameKey].name as string
function createCheckDefault(nameKey: 'local' | 'exported') {
return function checkDefault(
defaultSpecifier: TSESTree.ImportDefaultSpecifier,
// | TSESTree.ExportDefaultSpecifier,
) {
// #566: default is a valid specifier
// @ts-expect-error - ExportDefaultSpecifier is unavailable yet
const nameValue = defaultSpecifier[nameKey].name as string

if (nameValue === 'default') {
return
}
if (nameValue === 'default') {
return
}

const declaration = importDeclaration(context, defaultSpecifier)
const declaration = importDeclaration(context, defaultSpecifier)

const imports = ExportMap.get(declaration.source.value, context)
if (imports == null) {
return
}
const exportMapOfImported = ExportMap.get(
declaration.source.value,
context,
)
if (exportMapOfImported == null) {
return
}

if (imports.errors.length > 0) {
imports.reportErrors(context, declaration)
return
}
if (exportMapOfImported.errors.length > 0) {
exportMapOfImported.reportErrors(context, declaration)
return
}

if (imports.has('default') && imports.has(nameValue)) {
context.report({
node: defaultSpecifier,
messageId: 'default',
data: {
name: nameValue,
},
})
if (
exportMapOfImported.exports.has('default') &&
exportMapOfImported.exports.has(nameValue)
) {
context.report({
node: defaultSpecifier,
messageId: 'default',
data: {
name: nameValue,
},
})
}
}
}
return {
ImportDefaultSpecifier: checkDefault.bind(null, 'local'),
ExportDefaultSpecifier: checkDefault.bind(null, 'exported'),
ImportDefaultSpecifier: createCheckDefault('local'),
ExportDefaultSpecifier: createCheckDefault('exported'),
}
},
})
4 changes: 2 additions & 2 deletions src/utils/export-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ export class ExportMap {
return
}
case 'ExportAllDeclaration': {
m.exports.set(s.exported!.name, n)
m.exports.set(getValue(s.exported!), n)
m.namespace.set(
getValue(s.exported!),
addNamespace(exportMeta, s.exported!),
Expand All @@ -293,7 +293,7 @@ export class ExportMap {
}
case 'ExportSpecifier': {
if (!('source' in n && n.source)) {
m.exports.set(s.exported!.name, n)
m.exports.set(getValue(s.exported!), n)
m.namespace.set(
getValue(s.exported),
addNamespace(exportMeta, s.local),
Expand Down
1 change: 0 additions & 1 deletion test/package.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ describe('package', () => {
continue
}
for (const rule of Object.keys(config.rules)) {
console.log({ rule, preamble })
expect(() =>
require(getRulePath(rule.slice(preamble.length))),
).not.toThrow()
Expand Down
55 changes: 51 additions & 4 deletions test/rules/no-named-as-default.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,54 @@ import rule from 'eslint-plugin-import-x/rules/no-named-as-default'

const ruleTester = new TSESLintRuleTester()

console.log({ babel: require(parsers.BABEL) })

ruleTester.run('no-named-as-default', rule, {
valid: [
// https://github.com/un-ts/eslint-plugin-import-x/issues/123
test({
code: `/** TypeScript */ import klawSync from "klaw-sync";`,
settings: {
'import-x/extensions': [
'.ts',
'.cts',
'.mts',
'.tsx',
'.js',
'.cjs',
'.mjs',
'.jsx',
],
'import-x/external-module-folders': [
'node_modules',
'node_modules/@types',
],
'import-x/parsers': {
'@typescript-eslint/parser': ['.ts', '.cts', '.mts', '.tsx'],
},
'import-x/resolver': {
typescript: true,
node: {
extensions: [
'.ts',
'.cts',
'.mts',
'.tsx',
'.js',
'.cjs',
'.mjs',
'.jsx',
],
},
},
},
}),

test({
code: 'import "./malformed.js"',
languageOptions: { parser: require(parsers.ESPREE) },
}),

test({ code: 'import bar, { foo } from "./bar";' }),
test({ code: 'import bar, { foo } from "./empty-folder";' }),
'import bar, { foo } from "./bar";',
'import bar, { foo } from "./empty-folder";',

// es7
test({
Expand Down Expand Up @@ -133,5 +170,15 @@ ruleTester.run('no-named-as-default', rule, {
parserOptions: { ecmaVersion: 2022 },
},
}),

test({
code: `import z from 'zod';`,
errors: [
{
message: "Using exported name 'z' as identifier for default export.",
type: 'ImportDefaultSpecifier',
},
],
}),
],
})
24 changes: 12 additions & 12 deletions test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,29 +109,29 @@ export function testContext(settings?: PluginSettings) {
* to crash at runtime
*/
export const SYNTAX_CASES = [
test({ code: 'for (let { foo, bar } of baz) {}' }),
test({ code: 'for (let [ foo, bar ] of baz) {}' }),
'for (let { foo, bar } of baz) {}',
'for (let [ foo, bar ] of baz) {}',

test({ code: 'const { x, y } = bar' }),
'const { x, y } = bar',
test({
code: 'const { x, y, ...z } = bar',
languageOptions: { parser: require(parsers.BABEL) },
}),

// all the exports
test({ code: 'let x; export { x }' }),
test({ code: 'let x; export { x as y }' }),
'let x; export { x }',
'let x; export { x as y }',

// not sure about these since they reference a file
// test({ code: 'export { x } from "./y.js"'}),
// test({ code: 'export * as y from "./y.js"', languageOptions: { parser: require(parsers.BABEL) } }),
// 'export { x } from "./y.js"'}),
// 'export * as y from "./y.js"', languageOptions: { parser: require(parsers.BABEL) } }),

test({ code: 'export const x = null' }),
test({ code: 'export var x = null' }),
test({ code: 'export let x = null' }),
'export const x = null',
'export var x = null',
'export let x = null',

test({ code: 'export default x' }),
test({ code: 'export default class x {}' }),
'export default x',
'export default class x {}',

// issue #267: parser opt-in extension list
test({
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2285,6 +2285,13 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==

"@types/klaw-sync@^6.0.5":
version "6.0.5"
resolved "https://registry.yarnpkg.com/@types/klaw-sync/-/klaw-sync-6.0.5.tgz#0a87fa0762673a1a1d2e7b08a51d5d65f0c842cd"
integrity sha512-xlavCRyu5ibDjsOc7PSgeUbwOBZdnJsND8gFUVfBilplbBIWhLZVjwtqbZq0327ny3jNt7oviEh5NS9a4LudeQ==
dependencies:
"@types/node" "*"

"@types/minimist@^1.2.0":
version "1.2.5"
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e"
Expand Down Expand Up @@ -7121,3 +7128,8 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==

zod@^3.23.8:
version "3.23.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==

0 comments on commit 757ffa9

Please sign in to comment.