diff --git a/README.md b/README.md index 6762e95..0a1f583 100644 --- a/README.md +++ b/README.md @@ -253,6 +253,12 @@ import b from 'b' import c from 'c' ``` +### `importOrderSortGroups` +**type**: `boolean` +**default value**: `true` + +By default, the plugin sorts imports within groups. If you need to keep ordering within groups consistent, set this option to false. + ### Ignoring import ordering diff --git a/src/index.ts b/src/index.ts index b449bfd..2a1050d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -93,6 +93,12 @@ const options: Options = { default: 'with', description: 'Provide a keyword for import attributes', }, + importOrderSortGroups: { + type: 'boolean', + category: 'Global', + default: true, + description: 'Should imports be sorted within groups?', + }, }; export default { diff --git a/src/preprocessors/preprocessor.ts b/src/preprocessors/preprocessor.ts index 27563a9..0433205 100644 --- a/src/preprocessors/preprocessor.ts +++ b/src/preprocessors/preprocessor.ts @@ -22,6 +22,7 @@ export function preprocessor(code: string, options: PrettierOptions) { importOrderSideEffects, importOrderImportAttributesKeyword, importOrderExclude, + importOrderSortGroups, filepath, } = options; @@ -62,6 +63,7 @@ export function preprocessor(code: string, options: PrettierOptions) { importOrderSortSpecifiers, importOrderSortByLength, importOrderSideEffects, + importOrderSortGroups, }); return getCodeFromAst(allImports, code, injectIdx, { diff --git a/src/types.ts b/src/types.ts index 799e4e0..36b80b6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,8 +4,7 @@ import { RequiredOptions } from 'prettier'; import { PluginConfig } from '../types'; export interface PrettierOptions - extends Required, - RequiredOptions {} + extends Required, RequiredOptions {} export type ImportGroups = Record; export type ImportOrLine = ImportDeclaration | ExpressionStatement; @@ -21,6 +20,7 @@ export type GetSortedNodes = ( | 'importOrderSortSpecifiers' | 'importOrderSortByLength' | 'importOrderSideEffects' + | 'importOrderSortGroups' >, ) => ImportOrLine[]; diff --git a/src/utils/__tests__/assemble-updated-code.spec.ts b/src/utils/__tests__/assemble-updated-code.spec.ts index 7620486..6786b3f 100644 --- a/src/utils/__tests__/assemble-updated-code.spec.ts +++ b/src/utils/__tests__/assemble-updated-code.spec.ts @@ -29,6 +29,7 @@ test('it should remove nodes from the original code', async () => { importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }); const allCommentsFromImports = getAllCommentsFromNodes(sortedNodes); @@ -57,6 +58,7 @@ test('it should inject the generated code at the correct location', async () => importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }); const allCommentsFromImports = getAllCommentsFromNodes(sortedNodes); diff --git a/src/utils/__tests__/get-all-comments-from-nodes.spec.ts b/src/utils/__tests__/get-all-comments-from-nodes.spec.ts index 4455d55..225471e 100644 --- a/src/utils/__tests__/get-all-comments-from-nodes.spec.ts +++ b/src/utils/__tests__/get-all-comments-from-nodes.spec.ts @@ -16,6 +16,7 @@ const getSortedImportNodes = (code: string, options?: ParserOptions) => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }); }; diff --git a/src/utils/__tests__/get-code-from-ast.spec.ts b/src/utils/__tests__/get-code-from-ast.spec.ts index 7c238b5..c2393ef 100644 --- a/src/utils/__tests__/get-code-from-ast.spec.ts +++ b/src/utils/__tests__/get-code-from-ast.spec.ts @@ -23,6 +23,7 @@ import a from 'a'; importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }); const formatted = getCodeFromAst(sortedNodes, code); diff --git a/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts b/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts index ff9e8dd..724f404 100644 --- a/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts +++ b/src/utils/__tests__/get-sorted-nodes-by-import-order.spec.ts @@ -32,6 +32,7 @@ test('it returns all sorted nodes', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -78,6 +79,7 @@ test('it returns all sorted nodes case-insensitive', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -124,6 +126,7 @@ test('it returns all sorted nodes with sort order', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -170,6 +173,7 @@ test('it returns all sorted nodes with sort order case-insensitive', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -215,6 +219,7 @@ test('it returns all sorted import nodes with sorted import specifiers', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: true, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -260,6 +265,7 @@ test('it returns all sorted import nodes with sorted import specifiers with case importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: true, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -305,6 +311,7 @@ test('it returns all sorted nodes with custom third party modules', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -331,6 +338,7 @@ test('it returns all sorted nodes with namespace specifiers at the top', () => { importOrderGroupNamespaceSpecifiers: true, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -367,6 +375,7 @@ test('it returns the default separations if `importOrderSeparation` is false', ( importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }); expect(getSeparationData(sorted)).toEqual([ { type: 'ImportDeclaration', value: 'XY' }, @@ -394,6 +403,7 @@ test('it returns default import module separations', () => { importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }); expect(getSeparationData(sorted)).toEqual([ { type: 'ImportDeclaration', value: 'XY' }, @@ -426,6 +436,7 @@ test('it returns targeted import module separations', () => { importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }); expect(getSeparationData(sorted)).toEqual([ { type: 'ImportDeclaration', value: 'XY' }, @@ -459,6 +470,7 @@ test('it never returns a separation at the top of the list (leading separator)', importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }); expect(getSeparationData(sorted)).toEqual([ { type: 'ImportDeclaration', value: './test' }, @@ -480,6 +492,7 @@ test('it never returns a separation at the top of the list (zero preceding impor importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }); expect(getSeparationData(sorted)).toEqual([ { type: 'ImportDeclaration', value: './test' }, diff --git a/src/utils/__tests__/get-sorted-nodes-group.spec.ts b/src/utils/__tests__/get-sorted-nodes-group.spec.ts new file mode 100644 index 0000000..c7c96da --- /dev/null +++ b/src/utils/__tests__/get-sorted-nodes-group.spec.ts @@ -0,0 +1,288 @@ +import { ImportDeclaration } from '@babel/types'; +import { describe, expect, it } from 'vitest'; + +import { getSortedNodesGroup } from '../get-sorted-nodes-group.js'; + +const createImportDeclaration = ( + source: string, + start: number, + end: number, + specifierType: + | 'ImportDefaultSpecifier' + | 'ImportNamespaceSpecifier' + | 'ImportSpecifier' = 'ImportDefaultSpecifier', +): ImportDeclaration => + ({ + type: 'ImportDeclaration', + source: { value: source }, + start, + end, + specifiers: [{ type: specifierType }], + }) as unknown as ImportDeclaration; + +describe('getSortedNodesGroup', () => { + describe('when importOrderSortGroups is false', () => { + it('should not sort imports', () => { + const imports = [ + createImportDeclaration('zod', 0, 20), + createImportDeclaration('axios', 0, 25), + createImportDeclaration('react', 0, 22), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: false, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: null, + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'zod', + 'axios', + 'react', + ]); + }); + }); + + describe('when importOrderSortGroups is true', () => { + it('should sort imports alphabetically using natural sort', () => { + const imports = [ + createImportDeclaration('zod', 0, 20), + createImportDeclaration('axios', 0, 25), + createImportDeclaration('react', 0, 22), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: null, + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'axios', + 'react', + 'zod', + ]); + }); + + it('should handle numeric suffixes with natural sort', () => { + const imports = [ + createImportDeclaration('file10', 0, 20), + createImportDeclaration('file2', 0, 20), + createImportDeclaration('file1', 0, 20), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: null, + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'file1', + 'file2', + 'file10', + ]); + }); + }); + + describe('when importOrderSortByLength is "asc"', () => { + it('should sort imports by length ascending', () => { + const imports = [ + createImportDeclaration('react', 0, 30), + createImportDeclaration('zod', 0, 15), + createImportDeclaration('axios', 0, 25), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: 'asc', + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'zod', + 'axios', + 'react', + ]); + }); + + it('should use localeCompare as tiebreaker when lengths are equal', () => { + const imports = [ + createImportDeclaration('zod', 0, 20), + createImportDeclaration('aaa', 0, 20), + createImportDeclaration('bbb', 0, 20), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: 'asc', + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'aaa', + 'bbb', + 'zod', + ]); + }); + }); + + describe('when importOrderSortByLength is "desc"', () => { + it('should sort imports by length descending', () => { + const imports = [ + createImportDeclaration('zod', 0, 15), + createImportDeclaration('react', 0, 30), + createImportDeclaration('axios', 0, 25), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: 'desc', + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'react', + 'axios', + 'zod', + ]); + }); + + it('should use localeCompare as tiebreaker when lengths are equal', () => { + const imports = [ + createImportDeclaration('zod', 0, 20), + createImportDeclaration('aaa', 0, 20), + createImportDeclaration('bbb', 0, 20), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: 'desc', + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'aaa', + 'bbb', + 'zod', + ]); + }); + }); + + describe('when importOrderGroupNamespaceSpecifiers is true', () => { + it('should prioritize namespace specifiers', () => { + const imports = [ + createImportDeclaration( + 'axios', + 0, + 25, + 'ImportDefaultSpecifier', + ), + createImportDeclaration( + 'react', + 0, + 22, + 'ImportNamespaceSpecifier', + ), + createImportDeclaration('zod', 0, 20, 'ImportDefaultSpecifier'), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: true, + importOrderSortByLength: null, + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'react', + 'axios', + 'zod', + ]); + }); + + it('should sort namespace specifiers among themselves', () => { + const imports = [ + createImportDeclaration( + 'zod', + 0, + 20, + 'ImportNamespaceSpecifier', + ), + createImportDeclaration( + 'axios', + 0, + 25, + 'ImportNamespaceSpecifier', + ), + createImportDeclaration( + 'react', + 0, + 22, + 'ImportDefaultSpecifier', + ), + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: true, + importOrderSortByLength: null, + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'axios', + 'zod', + 'react', + ]); + }); + }); + + describe('edge cases', () => { + it('should handle empty imports array', () => { + const result = getSortedNodesGroup([], { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: null, + }); + + expect(result).toEqual([]); + }); + + it('should handle single import', () => { + const imports = [createImportDeclaration('react', 0, 22)]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: null, + }); + + expect(result.map((i) => i.source.value)).toEqual(['react']); + }); + + it('should handle imports with undefined start/end', () => { + const imports = [ + { + type: 'ImportDeclaration', + source: { value: 'react' }, + specifiers: [], + } as unknown as ImportDeclaration, + { + type: 'ImportDeclaration', + source: { value: 'axios' }, + specifiers: [], + } as unknown as ImportDeclaration, + ]; + + const result = getSortedNodesGroup(imports, { + importOrderSortGroups: true, + importOrderGroupNamespaceSpecifiers: false, + importOrderSortByLength: 'asc', + }); + + expect(result.map((i) => i.source.value)).toEqual([ + 'axios', + 'react', + ]); + }); + }); +}); diff --git a/src/utils/__tests__/get-sorted-nodes.spec.ts b/src/utils/__tests__/get-sorted-nodes.spec.ts index fb9ac6a..ec762a5 100644 --- a/src/utils/__tests__/get-sorted-nodes.spec.ts +++ b/src/utils/__tests__/get-sorted-nodes.spec.ts @@ -48,6 +48,7 @@ test('it returns all sorted nodes', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -94,6 +95,7 @@ test('it returns all sorted nodes case-insensitive', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -140,6 +142,7 @@ test('it returns all sorted nodes with sort order', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -186,6 +189,7 @@ test('it returns all sorted nodes with sort order case-insensitive', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -231,6 +235,7 @@ test('it returns all sorted import nodes with sorted import specifiers', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: true, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -276,6 +281,7 @@ test('it returns all sorted import nodes with sorted import specifiers with case importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: true, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -321,6 +327,7 @@ test('it returns all sorted nodes with custom third party modules', () => { importOrderGroupNamespaceSpecifiers: false, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ @@ -347,6 +354,7 @@ test('it returns all sorted nodes with namespace specifiers at the top', () => { importOrderGroupNamespaceSpecifiers: true, importOrderSortSpecifiers: false, importOrderSortByLength: null, + importOrderSortGroups: true, importOrderSideEffects: true, }) as ImportDeclaration[]; @@ -375,6 +383,7 @@ test('it returns all sorted nodes, sorted shortest to longest', () => { importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: 'asc', + importOrderSortGroups: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ 'g', @@ -401,6 +410,7 @@ test('it returns all sorted nodes, sorted longest to shortest', () => { importOrderSortSpecifiers: false, importOrderSideEffects: false, importOrderSortByLength: 'desc', + importOrderSortGroups: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ 't', @@ -429,6 +439,7 @@ test('it returns all sorted nodes with types', () => { importOrderSortSpecifiers: false, importOrderSideEffects: true, importOrderSortByLength: null, + importOrderSortGroups: true, }) as ImportDeclaration[]; expect(getSortedNodesNames(sorted)).toEqual([ diff --git a/src/utils/get-sorted-nodes-by-import-order.ts b/src/utils/get-sorted-nodes-by-import-order.ts index e0f663a..9a2377f 100644 --- a/src/utils/get-sorted-nodes-by-import-order.ts +++ b/src/utils/get-sorted-nodes-by-import-order.ts @@ -27,6 +27,7 @@ export const getSortedNodesByImportOrder: GetSortedNodes = (nodes, options) => { importOrderSeparation, importOrderSortSpecifiers, importOrderGroupNamespaceSpecifiers, + importOrderSortGroups, } = options; const originalNodes = nodes.map(clone); @@ -74,6 +75,7 @@ export const getSortedNodesByImportOrder: GetSortedNodes = (nodes, options) => { const sortedInsideGroup = getSortedNodesGroup(groupNodes, { importOrderGroupNamespaceSpecifiers, importOrderSortByLength, + importOrderSortGroups, }); // Sort the import specifiers diff --git a/src/utils/get-sorted-nodes-group.ts b/src/utils/get-sorted-nodes-group.ts index 759a044..f46e182 100644 --- a/src/utils/get-sorted-nodes-group.ts +++ b/src/utils/get-sorted-nodes-group.ts @@ -7,10 +7,16 @@ export const getSortedNodesGroup = ( imports: ImportDeclaration[], options: Pick< PrettierOptions, - 'importOrderGroupNamespaceSpecifiers' | 'importOrderSortByLength' + | 'importOrderGroupNamespaceSpecifiers' + | 'importOrderSortByLength' + | 'importOrderSortGroups' >, ) => { return imports.sort((a, b) => { + if (options.importOrderSortGroups === false) { + return 0; + } + const aLength = (a.end || 0) - (a.start || 0); const bLength = (b.end || 0) - (b.start || 0); diff --git a/tests/ImportGroupsNotSorted/__snapshots__/ppsi.spec.mjs.snap b/tests/ImportGroupsNotSorted/__snapshots__/ppsi.spec.mjs.snap new file mode 100644 index 0000000..177a9f6 --- /dev/null +++ b/tests/ImportGroupsNotSorted/__snapshots__/ppsi.spec.mjs.snap @@ -0,0 +1,34 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`import-groups-not-sorted.ts - typescript-verify > import-groups-not-sorted.ts 1`] = ` +// I am top level comment in this file. +import thirdParty0 from "third-party0"; +import something3 from "@core/something3"; +import thirdDisco0 from "third-disco0"; +import otherthing3 from "@core/otherthing3"; +import { a } from "b" with { type: "json" }; + +import anotherSameLevelRelativePath3 from "./anotherSameLevelRelativePath3"; +import something0 from "@core/something0"; + +import { b } from "r" with { type: "json" }; + + +function add(a,b) { + return a + b; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// I am top level comment in this file. +import thirdParty0 from "third-party0"; +import thirdDisco0 from "third-disco0"; +import { a } from "b" with { type: "json" }; +import { b } from "r" with { type: "json" }; +import something3 from "@core/something3"; +import otherthing3 from "@core/otherthing3"; +import something0 from "@core/something0"; +import anotherSameLevelRelativePath3 from "./anotherSameLevelRelativePath3"; + +function add(a, b) { + return a + b; +} + +`; diff --git a/tests/ImportGroupsNotSorted/import-groups-not-sorted.ts b/tests/ImportGroupsNotSorted/import-groups-not-sorted.ts new file mode 100644 index 0000000..afc468d --- /dev/null +++ b/tests/ImportGroupsNotSorted/import-groups-not-sorted.ts @@ -0,0 +1,16 @@ +// I am top level comment in this file. +import thirdParty0 from "third-party0"; +import something3 from "@core/something3"; +import thirdDisco0 from "third-disco0"; +import otherthing3 from "@core/otherthing3"; +import { a } from "b" with { type: "json" }; + +import anotherSameLevelRelativePath3 from "./anotherSameLevelRelativePath3"; +import something0 from "@core/something0"; + +import { b } from "r" with { type: "json" }; + + +function add(a,b) { + return a + b; +} \ No newline at end of file diff --git a/tests/ImportGroupsNotSorted/ppsi.spec.mjs b/tests/ImportGroupsNotSorted/ppsi.spec.mjs new file mode 100644 index 0000000..7a5b37e --- /dev/null +++ b/tests/ImportGroupsNotSorted/ppsi.spec.mjs @@ -0,0 +1,4 @@ +run_spec(__dirname, ["typescript"], { + importOrder: ['^@core/(.*)$', '^@server/(.*)', '^@ui/(.*)$', '^[./]'], + importOrderSortGroups: false, +}); diff --git a/types/index.d.ts b/types/index.d.ts index 8019b88..b17a44e 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -133,6 +133,13 @@ used to order imports within each match group. * @default [] */ importOrderExclude?: string[]; + + /** + * A boolean value to enable or disable sorting imports within their groups. + * + * @default true + */ + importOrderSortGroups?: boolean; } export type PrettierConfig = PluginConfig & Config;