diff --git a/README.md b/README.md index f472bf2..839c853 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ Since then more critical features & fixes have been added, and the options have - [How does import sort work?](#how-does-import-sort-work) - [Options](#options) - [`importOrder`](#importorder) - - [`importOrderSortSpecifiers`](#importordersortspecifiers) - [`importOrderMergeDuplicateImports`](#importordermergeduplicateimports) - [`importOrderCombineTypeAndValueImports`](#importordercombinetypeandvalueimports) - [`importOrderParserPlugins`](#importorderparserplugins) @@ -133,7 +132,6 @@ module.exports = { importOrderParserPlugins: ['typescript', 'jsx', 'decorators-legacy'], importOrderMergeDuplicateImports: true, importOrderCombineTypeAndValueImports: true, - importOrderSortSpecifiers: true, }; ``` @@ -221,26 +219,6 @@ _Note:_ If you want to separate some groups from others, you can add an empty st ], ``` -#### `importOrderSortSpecifiers` - -**type**: `boolean` - -**default value:** `false` - -A boolean value to enable or disable sorting of the specifiers in an import declarations. If enabled, type imports will be sorted after value imports. - -Before: - -```ts -import Default, {type Bravo, delta as echo, charlie, type Alpha} from 'source'; -``` - -After: - -```ts -import Default, {charlie, delta as echo, type Alpha, type Bravo} from 'source'; -``` - #### `importOrderMergeDuplicateImports` **type**: `boolean` diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md index 5c7bbb0..c8d2aa4 100644 --- a/docs/MIGRATION.md +++ b/docs/MIGRATION.md @@ -8,6 +8,7 @@ - The `importOrderSeparation` option has been removed. Use empty quotes in your `importOrder` to control the placement of blank lines. - The `importOrderCaseInsensitive` option has been removed, and imports will always be sorted case-insensitive. - The `importOrderGroupNamespaceSpecifiers` option has been removed. +- The `importOrderSortSpecifiers` option has been removed, and specifiers are now always sorted (previous `true` setting) #### `importOrderSeparation` removed diff --git a/prettier.config.js b/prettier.config.js index 9a80358..3528228 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -7,5 +7,4 @@ module.exports = { semi: true, plugins: [require('./lib/src/index.js')], importOrder: ['', '', '', '^[./]'], - importOrderSortSpecifiers: true, }; diff --git a/src/index.ts b/src/index.ts index d8ac92a..f034434 100644 --- a/src/index.ts +++ b/src/index.ts @@ -37,12 +37,6 @@ export const options: Record< default: [{ value: ['typescript', 'jsx'] }], description: 'Provide a list of plugins for special syntax', }, - importOrderSortSpecifiers: { - type: 'boolean', - category: 'Global', - default: false, - description: 'Should specifiers be sorted?', - }, importOrderMergeDuplicateImports: { type: 'boolean', category: 'Global', diff --git a/src/preprocessors/preprocessor.ts b/src/preprocessors/preprocessor.ts index a4e6898..e6bb97b 100644 --- a/src/preprocessors/preprocessor.ts +++ b/src/preprocessors/preprocessor.ts @@ -13,7 +13,6 @@ export function preprocessor(code: string, options: PrettierOptions): string { importOrderParserPlugins, importOrder, importOrderMergeDuplicateImports, - importOrderSortSpecifiers, } = options; let { importOrderCombineTypeAndValueImports } = options; @@ -68,7 +67,6 @@ export function preprocessor(code: string, options: PrettierOptions): string { importOrder, importOrderMergeDuplicateImports, importOrderCombineTypeAndValueImports, - importOrderSortSpecifiers, }); return getCodeFromAst({ diff --git a/src/types.ts b/src/types.ts index bb537bc..40d4381 100644 --- a/src/types.ts +++ b/src/types.ts @@ -37,7 +37,6 @@ export type GetSortedNodes = ( | 'importOrder' | 'importOrderMergeDuplicateImports' | 'importOrderCombineTypeAndValueImports' - | 'importOrderSortSpecifiers' >, ) => ImportOrLine[]; 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 a907c08..1fdccb1 100644 --- a/src/utils/__tests__/get-all-comments-from-nodes.spec.ts +++ b/src/utils/__tests__/get-all-comments-from-nodes.spec.ts @@ -13,7 +13,6 @@ const getSortedImportNodes = (code: string, options?: ParserOptions) => { importOrder: [], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }); }; diff --git a/src/utils/__tests__/get-code-from-ast.spec.ts b/src/utils/__tests__/get-code-from-ast.spec.ts index 2a5f415..e96239f 100644 --- a/src/utils/__tests__/get-code-from-ast.spec.ts +++ b/src/utils/__tests__/get-code-from-ast.spec.ts @@ -20,7 +20,6 @@ import a from 'a'; importOrder: [], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }); const formatted = getCodeFromAst({ nodesToOutput: sortedNodes, @@ -58,7 +57,6 @@ import type {See} from 'c'; importOrder: [], importOrderMergeDuplicateImports: true, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }); const formatted = getCodeFromAst({ nodesToOutput: sortedNodes, 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 ccbc95a..8a956d2 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 @@ -31,7 +31,6 @@ test('it returns all sorted nodes', () => { importOrder: ['^[./]'], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }) as ImportDeclaration[]; expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ @@ -66,59 +65,8 @@ test('it returns all sorted nodes', () => { ['BY'], ['c', 'cD'], ['g'], - ['k', 'kE', 'kB'], - ['tC', 'tA', 'tB'], - ['x'], - ['Xa'], - ['XY'], - ['z'], - ['local'], - ]); -}); - -test('it returns all sorted nodes case-insensitive', () => { - const result = getImportNodes(code); - const sorted = getSortedNodesByImportOrder(result, { - importOrder: ['^[./]'], - importOrderMergeDuplicateImports: false, - importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, - }) as ImportDeclaration[]; - - expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ - 'node:fs/promises', - 'node:url', - 'path', - 'a', - 'Ba', - 'BY', - 'c', - 'g', - 'k', - 't', - 'x', - 'Xa', - 'XY', - 'z', - './local', - ]); - expect( - sorted - .filter((node) => node.type === 'ImportDeclaration') - .map((importDeclaration) => - getSortedNodesModulesNames(importDeclaration.specifiers), - ), - ).toEqual([ - ['fs'], - ['url'], // `node:url` comes before `path` - ['path'], - ['a'], - ['Ba'], - ['BY'], - ['c', 'cD'], - ['g'], - ['k', 'kE', 'kB'], - ['tC', 'tA', 'tB'], + ['k', 'kB', 'kE'], + ['tA', 'tB', 'tC'], ['x'], ['Xa'], ['XY'], @@ -133,107 +81,6 @@ test('it returns all sorted nodes with sort order', () => { importOrder: ['^a$', '^t$', '^k$', '^B', '^[./]'], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, - }) as ImportDeclaration[]; - expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ - 'node:fs/promises', - 'node:url', - 'path', - 'c', - 'g', - 'x', - 'Xa', - 'XY', - 'z', - 'a', - 't', - 'k', - 'Ba', - 'BY', - './local', - ]); - expect( - sorted - .filter((node) => node.type === 'ImportDeclaration') - .map((importDeclaration) => - getSortedNodesModulesNames(importDeclaration.specifiers), - ), - ).toEqual([ - ['fs'], - ['url'], // `node:url` comes before `path` - ['path'], - ['c', 'cD'], - ['g'], - ['x'], - ['Xa'], - ['XY'], - ['z'], - ['a'], - ['tC', 'tA', 'tB'], - ['k', 'kE', 'kB'], - ['Ba'], - ['BY'], - ['local'], - ]); -}); - -test('it returns all sorted nodes with sort order case-insensitive', () => { - const result = getImportNodes(code); - const sorted = getSortedNodesByImportOrder(result, { - importOrder: ['^a$', '^t$', '^k$', '^B', '^[./]'], - importOrderMergeDuplicateImports: false, - importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, - }) as ImportDeclaration[]; - expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ - 'node:fs/promises', - 'node:url', - 'path', - 'c', - 'g', - 'x', - 'Xa', - 'XY', - 'z', - 'a', - 't', - 'k', - 'Ba', - 'BY', - './local', - ]); - expect( - sorted - .filter((node) => node.type === 'ImportDeclaration') - .map((importDeclaration) => - getSortedNodesModulesNames(importDeclaration.specifiers), - ), - ).toEqual([ - ['fs'], - ['url'], // `node:url` comes before `path` - ['path'], - ['c', 'cD'], - ['g'], - ['x'], - ['Xa'], - ['XY'], - ['z'], - ['a'], - ['tC', 'tA', 'tB'], - ['k', 'kE', 'kB'], - ['Ba'], - ['BY'], - ['local'], - ]); -}); - -test('it returns all sorted import nodes with sorted import specifiers', () => { - const result = getImportNodes(code); - const sorted = getSortedNodesByImportOrder(result, { - importOrder: ['^a$', '^t$', '^k$', '^B', '^[./]'], - importOrderMergeDuplicateImports: false, - importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: true, }) as ImportDeclaration[]; expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ 'node:fs/promises', @@ -277,31 +124,22 @@ test('it returns all sorted import nodes with sorted import specifiers', () => { ]); }); -test('it returns all sorted import nodes with sorted import specifiers with case-insensitive ', () => { - const result = getImportNodes(code); +test('it returns all sorted import nodes with sorted import specifiers', () => { + const code = ` +import { tC, tA, tB } from 't'; +import k, { kE, kB } from 'k'; +import {type B, A} from 'z'; +`; + + const result = getImportNodes(code, { + plugins: ['typescript'], + }); const sorted = getSortedNodesByImportOrder(result, { - importOrder: ['^a$', '^t$', '^k$', '^B', '^[./]'], + importOrder: ['^[./]'], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: true, }) as ImportDeclaration[]; - expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ - 'node:fs/promises', - 'node:url', - 'path', - 'c', - 'g', - 'x', - 'Xa', - 'XY', - 'z', - 'a', - 't', - 'k', - 'Ba', - 'BY', - './local', - ]); + expect(getSortedNodesNamesAndNewlines(sorted)).toEqual(['k', 't', 'z']); expect( sorted .filter((node) => node.type === 'ImportDeclaration') @@ -309,21 +147,9 @@ test('it returns all sorted import nodes with sorted import specifiers with case getSortedNodesModulesNames(importDeclaration.specifiers), ), ).toEqual([ - ['fs'], - ['url'], // `node:url` comes before `path` - ['path'], - ['c', 'cD'], - ['g'], - ['x'], - ['Xa'], - ['XY'], - ['z'], - ['a'], - ['tA', 'tB', 'tC'], ['k', 'kB', 'kE'], - ['Ba'], - ['BY'], - ['local'], + ['tA', 'tB', 'tC'], + ['A', 'B'], ]); }); @@ -333,7 +159,6 @@ test('it returns all sorted nodes with builtin specifiers at the top', () => { importOrder: ['^[./]'], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }) as ImportDeclaration[]; expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ @@ -361,7 +186,6 @@ test('it returns all sorted nodes with custom third party modules and builtins a importOrder: ['^a$', '', '^t$', '^k$', '^[./]'], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }) as ImportDeclaration[]; expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ 'node:fs/promises', @@ -395,7 +219,6 @@ test('it returns all sorted nodes with custom separation', () => { ], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }) as ImportDeclaration[]; expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ 'node:fs/promises', @@ -432,7 +255,6 @@ test('it does not add multiple custom import separators', () => { ], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }) as ImportDeclaration[]; expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ 'node:fs/promises', diff --git a/src/utils/__tests__/get-sorted-nodes.spec.ts b/src/utils/__tests__/get-sorted-nodes.spec.ts index e49f285..ce40548 100644 --- a/src/utils/__tests__/get-sorted-nodes.spec.ts +++ b/src/utils/__tests__/get-sorted-nodes.spec.ts @@ -32,7 +32,6 @@ test('it returns all sorted nodes, preserving the order side effect nodes', () = importOrder: [], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }) as ImportDeclaration[]; expect(getSortedNodesNamesAndNewlines(sorted)).toEqual([ 'se3', @@ -63,8 +62,8 @@ test('it returns all sorted nodes, preserving the order side effect nodes', () = [], ['c', 'cD'], ['g'], - ['k', 'kE', 'kB'], - ['tC', 'tA', 'tB'], + ['k', 'kB', 'kE'], + ['tA', 'tB', 'tC'], ['z'], [], [], diff --git a/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts b/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts index 116b2e8..344182e 100644 --- a/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts +++ b/src/utils/__tests__/merge-nodes-with-matching-flavors.spec.ts @@ -9,7 +9,6 @@ const defaultOptions = { importOrder: [''], // Separate side-effect and ignored chunks, for easier test readability importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: true, }; test('should merge duplicate imports within a given chunk', () => { diff --git a/src/utils/__tests__/remove-nodes-from-original-code.spec.ts b/src/utils/__tests__/remove-nodes-from-original-code.spec.ts index 486f441..459dec3 100644 --- a/src/utils/__tests__/remove-nodes-from-original-code.spec.ts +++ b/src/utils/__tests__/remove-nodes-from-original-code.spec.ts @@ -26,7 +26,6 @@ test('it should remove nodes from the original code', () => { importOrder: [], importOrderMergeDuplicateImports: false, importOrderCombineTypeAndValueImports: false, - importOrderSortSpecifiers: false, }); const allCommentsFromImports = getAllCommentsFromNodes(sortedNodes); diff --git a/src/utils/get-sorted-nodes-by-import-order.ts b/src/utils/get-sorted-nodes-by-import-order.ts index 90ee35f..6c153dc 100644 --- a/src/utils/get-sorted-nodes-by-import-order.ts +++ b/src/utils/get-sorted-nodes-by-import-order.ts @@ -22,7 +22,6 @@ export const getSortedNodesByImportOrder: GetSortedNodes = (nodes, options) => { naturalSort.insensitive = true; let { importOrder } = options; - const { importOrderSortSpecifiers } = options; const originalNodes = nodes.map(clone); const finalNodes: ImportOrLine[] = []; @@ -84,11 +83,7 @@ export const getSortedNodesByImportOrder: GetSortedNodes = (nodes, options) => { const sortedInsideGroup = getSortedNodesGroup(groupNodes); // Sort the import specifiers - if (importOrderSortSpecifiers) { - sortedInsideGroup.forEach((node) => - getSortedImportSpecifiers(node), - ); - } + sortedInsideGroup.forEach((node) => getSortedImportSpecifiers(node)); finalNodes.push(...sortedInsideGroup); } diff --git a/tests/IgnoreComments/__snapshots__/ppsi.spec.ts.snap b/tests/IgnoreComments/__snapshots__/ppsi.spec.ts.snap index 482e96b..e4c793e 100644 --- a/tests/IgnoreComments/__snapshots__/ppsi.spec.ts.snap +++ b/tests/IgnoreComments/__snapshots__/ppsi.spec.ts.snap @@ -70,7 +70,7 @@ import { type h, h2 } from "h"; // prettier-ignore import { g, type g2 } from "g"; import { d1, type d, type d2 } from "d"; -import { type e, e2 } from "e"; +import { e2, type e } from "e"; import { f, type f2 } from "f"; export const foo = 42; diff --git a/tests/TypesSpecialWord/__snapshots__/ppsi.spec.ts.snap b/tests/TypesSpecialWord/__snapshots__/ppsi.spec.ts.snap index 36d5790..c918634 100644 --- a/tests/TypesSpecialWord/__snapshots__/ppsi.spec.ts.snap +++ b/tests/TypesSpecialWord/__snapshots__/ppsi.spec.ts.snap @@ -7,7 +7,7 @@ import value, {tp} from 'third-party'; import {specifier, type ThirdPartyType} from 'third-party'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ import type { ThirdPartyType } from "third-party"; -import value, { tp, specifier } from "third-party"; +import value, { specifier, tp } from "third-party"; import a from "./local-file"; import type Another from "./another-local-file"; import type { LocalType } from "./local-file"; diff --git a/tests/Typescript/__snapshots__/ppsi.spec.ts.snap b/tests/Typescript/__snapshots__/ppsi.spec.ts.snap index 9d92487..71572bc 100644 --- a/tests/Typescript/__snapshots__/ppsi.spec.ts.snap +++ b/tests/Typescript/__snapshots__/ppsi.spec.ts.snap @@ -212,7 +212,7 @@ export class AppComponent { } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ import { Component } from "@angular/core"; -import { isEmpty, concat, flatten } from "lodash-es"; +import { concat, flatten, isEmpty } from "lodash-es"; import thirdParty from "third-party"; import z from "z"; import abc from "@core/abc"; @@ -222,17 +222,17 @@ import component from "@ui/hello"; import xyz from "@ui/xyz"; import fourLevelRelativePath from "../../../../fourLevelRelativePath"; import threeLevelRelativePathA, { - nonDefaultModuleC, nonDefaultModuleA, nonDefaultModuleB, + nonDefaultModuleC, } from "../../../threeLevelRelativePathA"; import * as allThreeLevelRelativePathBModules from "../../../threeLevelRelativePathB"; import threeLevelRelativePathC, { - nonDefaultModuleC as nonConflictingModuleNameC, nonDefaultModuleA as nonConflictingModuleNameA, nonDefaultModuleB as nonConflictingModuleNameB, - nonDefaultModuleE, + nonDefaultModuleC as nonConflictingModuleNameC, nonDefaultModuleD, + nonDefaultModuleE, } from "../../../threeLevelRelativePathC"; import twoLevelRelativePath from "../../twoLevelRelativePath"; import oneLevelRelativePath from "../oneLevelRelativePath"; diff --git a/types/index.d.ts b/types/index.d.ts index b2466d9..889d14f 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -66,13 +66,6 @@ export interface PluginConfig { */ importOrderCombineTypeAndValueImports?: boolean; - /** - * A boolean value to enable or disable sorting of the specifiers in an import declarations. - * - * @default false - */ - importOrderSortSpecifiers?: boolean; - /** * A collection of plugins for babel parser. The plugin passes this list to babel parser, so it can understand the syntaxes * used in the file being formatted. The plugin uses prettier itself to figure out the parser it needs to use but if that fails,