Skip to content

Commit

Permalink
feat: support arbitrary module identifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
azat-io committed Oct 18, 2024
1 parent 11c902f commit 43f218d
Show file tree
Hide file tree
Showing 9 changed files with 661 additions and 474 deletions.
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
"eslint": ">=8.0.0"
},
"dependencies": {
"@typescript-eslint/types": "^8.9.0",
"@typescript-eslint/utils": "^8.9.0",
"@typescript-eslint/types": "^8.10.0",
"@typescript-eslint/utils": "^8.10.0",
"minimatch": "^9.0.5",
"natural-compare-lite": "^1.4.0"
},
Expand All @@ -74,35 +74,35 @@
"@shikijs/transformers": "^1.22.0",
"@types/mdast": "^4.0.4",
"@types/natural-compare-lite": "^1.4.2",
"@types/node": "^22.7.5",
"@types/node": "^22.7.6",
"@types/unist": "^3.0.3",
"@typescript-eslint/eslint-plugin": "^8.9.0",
"@typescript-eslint/parser": "^8.9.0",
"@typescript-eslint/rule-tester": "^8.9.0",
"@typescript-eslint/eslint-plugin": "^8.10.0",
"@typescript-eslint/parser": "^8.10.0",
"@typescript-eslint/rule-tester": "^8.10.0",
"@typescript-eslint/types": "^6.13.0",
"@vercel/og": "^0.6.3",
"@vitest/coverage-v8": "^2.1.3",
"astro": "^4.16.4",
"astro": "^4.16.6",
"astro-eslint-parser": "^1.0.3",
"browserslist": "^4.24.0",
"changelogen": "^0.5.7",
"clean-publish": "^5.0.0",
"cspell": "^8.15.2",
"cspell": "^8.15.3",
"eslint": "^9.12.0",
"eslint-plugin-astro": "^1.3.0",
"eslint-plugin-eslint-plugin": "^6.2.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-n": "^17.11.1",
"eslint-plugin-node-import": "^1.0.4",
"eslint-plugin-perfectionist": "^3.8.0",
"eslint-plugin-perfectionist": "^3.9.1",
"eslint-plugin-prefer-arrow": "^1.2.3",
"eslint-plugin-prefer-let": "^4.0.0",
"eslint-plugin-promise": "^7.1.0",
"eslint-plugin-sonarjs": "2.0.3",
"eslint-plugin-unicorn": "^56.0.0",
"eslint-plugin-vitest": "^0.5.4",
"execa": "^9.4.0",
"execa": "^9.4.1",
"keyux": "^0.9.0",
"lightningcss": "^1.27.0",
"nanostores": "^0.11.3",
Expand All @@ -122,7 +122,7 @@
"stylelint-plugin-logical-css": "^1.2.1",
"svelte": "5.0.0-next.221",
"svelte-check": "^4.0.5",
"svelte-eslint-parser": "^0.41.1",
"svelte-eslint-parser": "^0.42.0",
"svgo": "^3.3.2",
"ts-dedent": "^2.2.0",
"typescript": "^5.6.3",
Expand Down
899 changes: 501 additions & 398 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

62 changes: 31 additions & 31 deletions rules/sort-intersection-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,62 +193,62 @@ export default createEslintRule<Options, MESSAGE_ID>({
let { getGroup, defineGroup } = useGroups(options)

switch (type.type) {
case 'TSConditionalType':
defineGroup('conditional')
break
case 'TSConstructorType':
case 'TSFunctionType':
defineGroup('function')
case 'TSTemplateLiteralType':
case 'TSLiteralType':
defineGroup('literal')
break
case 'TSImportType':
defineGroup('import')
case 'TSIndexedAccessType':
case 'TSTypeReference':
case 'TSQualifiedName':
case 'TSArrayType':
case 'TSInferType':
defineGroup('named')
break
case 'TSIntersectionType':
defineGroup('intersection')
break
case 'TSAnyKeyword':
case 'TSBigIntKeyword':
case 'TSIntrinsicKeyword':
case 'TSBooleanKeyword':
case 'TSNeverKeyword':
case 'TSUnknownKeyword':
case 'TSBigIntKeyword':
case 'TSNumberKeyword':
case 'TSObjectKeyword':
case 'TSStringKeyword':
case 'TSSymbolKeyword':
case 'TSNeverKeyword':
case 'TSAnyKeyword':
case 'TSThisType':
case 'TSUnknownKeyword':
case 'TSIntrinsicKeyword':
defineGroup('keyword')
break
case 'TSLiteralType':
case 'TSTemplateLiteralType':
defineGroup('literal')
case 'TSUndefinedKeyword':
case 'TSNullKeyword':
case 'TSVoidKeyword':
defineGroup('nullish')
break
case 'TSArrayType':
case 'TSIndexedAccessType':
case 'TSInferType':
case 'TSTypeReference':
case 'TSQualifiedName':
defineGroup('named')
case 'TSConditionalType':
defineGroup('conditional')
break
case 'TSMappedType':
case 'TSTypeLiteral':
defineGroup('object')
case 'TSConstructorType':
case 'TSFunctionType':
defineGroup('function')
break
case 'TSTypeQuery':
case 'TSTypeOperator':
case 'TSTypeQuery':
defineGroup('operator')
break
case 'TSTypeLiteral':
case 'TSMappedType':
defineGroup('object')
break
case 'TSImportType':
defineGroup('import')
break
case 'TSTupleType':
defineGroup('tuple')
break
case 'TSUnionType':
defineGroup('union')
break
case 'TSNullKeyword':
case 'TSUndefinedKeyword':
case 'TSVoidKeyword':
defineGroup('nullish')
break
}

let lastSortingNode = accumulator.at(-1)?.at(-1)
Expand Down
10 changes: 9 additions & 1 deletion rules/sort-named-exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,20 @@ export default createEslintRule<Options, MESSAGE_ID>({
group = 'value'
}

let name: string

if (specifier.exported.type === 'Identifier') {
;({ name } = specifier.exported)
} else {
name = specifier.exported.value
}

let lastSortingNode = formattedMembers.at(-1)?.at(-1)
let sortingNode: SortingNode = {
size: rangeToDiff(specifier.range),
name: specifier.local.name,
node: specifier,
group,
name,
}
if (
(partitionComment &&
Expand Down
6 changes: 5 additions & 1 deletion rules/sort-named-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,11 @@ export default createEslintRule<Options, MESSAGE_ID>({
let { name } = specifier.local

if (specifier.type === 'ImportSpecifier' && options.ignoreAlias) {
;({ name } = specifier.imported)
if (specifier.imported.type === 'Identifier') {
;({ name } = specifier.imported)
} else {
name = specifier.imported.value
}
}

if (
Expand Down
62 changes: 31 additions & 31 deletions rules/sort-union-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,62 +191,62 @@ export default createEslintRule<Options, MESSAGE_ID>({
let { getGroup, defineGroup } = useGroups(options)

switch (type.type) {
case 'TSConditionalType':
defineGroup('conditional')
break
case 'TSConstructorType':
case 'TSFunctionType':
defineGroup('function')
case 'TSTemplateLiteralType':
case 'TSLiteralType':
defineGroup('literal')
break
case 'TSImportType':
defineGroup('import')
case 'TSIndexedAccessType':
case 'TSTypeReference':
case 'TSQualifiedName':
case 'TSArrayType':
case 'TSInferType':
defineGroup('named')
break
case 'TSIntersectionType':
defineGroup('intersection')
break
case 'TSAnyKeyword':
case 'TSBigIntKeyword':
case 'TSIntrinsicKeyword':
case 'TSBooleanKeyword':
case 'TSNeverKeyword':
case 'TSUnknownKeyword':
case 'TSBigIntKeyword':
case 'TSNumberKeyword':
case 'TSObjectKeyword':
case 'TSStringKeyword':
case 'TSSymbolKeyword':
case 'TSNeverKeyword':
case 'TSAnyKeyword':
case 'TSThisType':
case 'TSUnknownKeyword':
case 'TSIntrinsicKeyword':
defineGroup('keyword')
break
case 'TSLiteralType':
case 'TSTemplateLiteralType':
defineGroup('literal')
case 'TSUndefinedKeyword':
case 'TSNullKeyword':
case 'TSVoidKeyword':
defineGroup('nullish')
break
case 'TSArrayType':
case 'TSIndexedAccessType':
case 'TSInferType':
case 'TSTypeReference':
case 'TSQualifiedName':
defineGroup('named')
case 'TSConditionalType':
defineGroup('conditional')
break
case 'TSMappedType':
case 'TSTypeLiteral':
defineGroup('object')
case 'TSConstructorType':
case 'TSFunctionType':
defineGroup('function')
break
case 'TSTypeQuery':
case 'TSTypeOperator':
case 'TSTypeQuery':
defineGroup('operator')
break
case 'TSTypeLiteral':
case 'TSMappedType':
defineGroup('object')
break
case 'TSImportType':
defineGroup('import')
break
case 'TSTupleType':
defineGroup('tuple')
break
case 'TSUnionType':
defineGroup('union')
break
case 'TSNullKeyword':
case 'TSUndefinedKeyword':
case 'TSVoidKeyword':
defineGroup('nullish')
break
}

let lastSortingNode = accumulator.at(-1)?.at(-1)
Expand Down
31 changes: 31 additions & 0 deletions test/sort-named-exports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,37 @@ describe(ruleName, () => {
invalid: [],
},
)

ruleTester.run(`${ruleName}(${type}): works with arbitrary names`, rule, {
valid: [
{
code: dedent`
export { a as "A", b as "B" };
`,
options: [options],
},
],
invalid: [
{
code: dedent`
export { b as "B", a as "A" };
`,
output: dedent`
export { a as "A", b as "B" };
`,
options: [options],
errors: [
{
messageId: 'unexpectedNamedExportsOrder',
data: {
left: 'B',
right: 'A',
},
},
],
},
],
})
})

describe(`${ruleName}: sorting by natural order`, () => {
Expand Down
41 changes: 41 additions & 0 deletions test/sort-named-imports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,47 @@ describe(ruleName, () => {
invalid: [],
},
)

ruleTester.run(`${ruleName}(${type}): works with arbitrary names`, rule, {
valid: [
{
code: dedent`
import { "A" as a, "B" as b } from 'module';
`,
options: [
{
...options,
ignoreAlias: true,
},
],
},
],
invalid: [
{
code: dedent`
import { "B" as b, "A" as a } from 'module';
`,
output: dedent`
import { "A" as a, "B" as b } from 'module';
`,
options: [
{
...options,
ignoreAlias: true,
},
],
errors: [
{
messageId: 'unexpectedNamedImportsOrder',
data: {
left: 'B',
right: 'A',
},
},
],
},
],
})
})

describe(`${ruleName}: sorting by natural order`, () => {
Expand Down
2 changes: 1 addition & 1 deletion utils/is-member-optional.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { AST_NODE_TYPES } from '@typescript-eslint/types'

export let isMemberOptional = (node: TSESTree.Node): boolean => {
switch (node.type) {
case AST_NODE_TYPES.TSMethodSignature:
case AST_NODE_TYPES.TSPropertySignature:
case AST_NODE_TYPES.TSMethodSignature:
return node.optional
}

Expand Down

0 comments on commit 43f218d

Please sign in to comment.