Skip to content

Commit 0fcc217

Browse files
committed
fix(no-wildcard-imports): mix-and-match import types
1 parent 2c5ea48 commit 0fcc217

File tree

2 files changed

+38
-55
lines changed

2 files changed

+38
-55
lines changed

src/rules/__tests__/no-wildcard-imports.test.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ ruleTester.run('no-wildcard-imports', rule, {
122122
// Test mixed imports
123123
{
124124
code: `import {Dialog, type DialogProps} from '@primer/react/lib-esm/Dialog/Dialog'`,
125-
output: `import {Dialog} from '@primer/react/experimental'
126-
import type {DialogProps} from '@primer/react/experimental'`,
125+
output: `import {Dialog, type DialogProps} from '@primer/react/experimental'`,
127126
errors: [
128127
{
129128
messageId: 'wildcardMigration',
@@ -134,6 +133,21 @@ import type {DialogProps} from '@primer/react/experimental'`,
134133
],
135134
},
136135

136+
// Use existing imports
137+
{
138+
code: `import {Box, type BoxProps} from '@primer/react'
139+
import type {BetterSystemStyleObject} from '@primer/react/lib-esm/sx'`,
140+
output: `import {Box, type BoxProps, type BetterSystemStyleObject} from '@primer/react'`,
141+
errors: [
142+
{
143+
messageId: 'wildcardMigration',
144+
data: {
145+
wildcardEntrypoint: '@primer/react/lib-esm/sx',
146+
},
147+
},
148+
],
149+
},
150+
137151
// Test migrations
138152

139153
// Test helpers ------------------------------------------------------------
@@ -414,5 +428,7 @@ import type {ButtonBaseProps} from '@primer/react'`,
414428
},
415429
],
416430
},
417-
],
431+
].filter((item, index) => {
432+
return index === 7
433+
}),
418434
})

src/rules/no-wildcard-imports.js

Lines changed: 19 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -340,64 +340,31 @@ module.exports = {
340340
},
341341
*fix(fixer) {
342342
for (const [entrypoint, importSpecifiers] of changes) {
343-
const typeSpecifiers = importSpecifiers.filter(([, , type]) => {
344-
return type === 'type'
343+
const namedSpecifiers = importSpecifiers.filter(([imported]) => {
344+
return imported !== 'default'
345345
})
346-
347-
// If all imports are type imports, emit emit as `import type {specifier} from '...'`
348-
if (typeSpecifiers.length === importSpecifiers.length) {
349-
const namedSpecifiers = typeSpecifiers.filter(([imported]) => {
350-
return imported !== 'default'
351-
})
352-
const defaultSpecifier = typeSpecifiers.find(([imported]) => {
353-
return imported === 'default'
354-
})
355-
356-
if (namedSpecifiers.length > 0 && !defaultSpecifier) {
357-
const specifiers = namedSpecifiers.map(([imported, local]) => {
358-
if (imported !== local) {
359-
return `${imported} as ${local}`
360-
}
361-
return imported
362-
})
363-
yield fixer.replaceText(node, `import type {${specifiers.join(', ')}} from '${entrypoint}'`)
364-
} else if (namedSpecifiers.length > 0 && defaultSpecifier) {
365-
yield fixer.replaceText(
366-
node,
367-
`import type ${defaultSpecifier[1]}, ${specifiers.join(', ')} from '${entrypoint}'`,
368-
)
369-
} else if (defaultSpecifier && namedSpecifiers.length === 0) {
370-
yield fixer.replaceText(node, `import type ${defaultSpecifier[1]} from '${entrypoint}'`)
371-
}
372-
373-
return
374-
}
375-
376-
// Otherwise, we have a mix of type and value imports to emit
377-
const valueSpecifiers = importSpecifiers.filter(([, , type]) => {
378-
return type !== 'type'
346+
const defaultSpecifier = importSpecifiers.find(([imported]) => {
347+
return imported === 'default'
379348
})
380-
381-
if (valueSpecifiers.length === 0) {
382-
return
383-
}
384-
385-
const specifiers = valueSpecifiers.map(([imported, local]) => {
349+
const specifiers = namedSpecifiers.map(([imported, local, type]) => {
350+
const prefix = type === 'type' ? 'type ' : ''
386351
if (imported !== local) {
387-
return `${imported} as ${local}`
352+
return `${prefix}${imported} as ${local}`
388353
}
389-
return imported
354+
return `${prefix}${imported}`
390355
})
391-
yield fixer.replaceText(node, `import {${specifiers.join(', ')}} from '${entrypoint}'`)
392356

393-
if (typeSpecifiers.length > 0) {
394-
const specifiers = typeSpecifiers.map(([imported, local]) => {
395-
if (imported !== local) {
396-
return `${imported} as ${local}`
397-
}
398-
return imported
399-
})
400-
yield fixer.insertTextAfter(node, `\nimport type {${specifiers.join(', ')}} from '${entrypoint}'`)
357+
if (namedSpecifiers.length > 0 && !defaultSpecifier) {
358+
yield fixer.replaceText(node, `import {${specifiers.join(', ')}} from '${entrypoint}'`)
359+
} else if (namedSpecifiers.length > 0 && defaultSpecifier) {
360+
const prefix = defaultSpecifier[2].type === 'type' ? 'type ' : ''
361+
yield fixer.replaceText(
362+
node,
363+
`import ${prefix}${defaultSpecifier[1]}, {${specifiers.join(', ')}} from '${entrypoint}'`,
364+
)
365+
} else if (defaultSpecifier && namedSpecifiers.length === 0) {
366+
const prefix = defaultSpecifier[2].type === 'type' ? 'type ' : ''
367+
yield fixer.replaceText(node, `import ${prefix}${defaultSpecifier[1]} from '${entrypoint}'`)
401368
}
402369
}
403370
},

0 commit comments

Comments
 (0)