Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ const options = {
default: false,
description: 'Should specifiers be sorted?',
},
importOrderSortByLength: {
type: 'choice',
category: 'Global',
default: null,
choices: [
{value: 'asc', description: 'will sort from shortest to longest'},
{value: 'desc', description: 'will sort from longest to shortest'},
{value: null, description: 'will disable sorting based on length'}
],
description: 'Should imports be sorted by their string length'
}
};

module.exports = {
Expand Down
2 changes: 2 additions & 0 deletions src/preprocessors/preprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function preprocessor(code: string, options: PrettierOptions) {
importOrderSeparation,
importOrderGroupNamespaceSpecifiers,
importOrderSortSpecifiers,
importOrderSortByLength
} = options;

const parserOptions: ParserOptions = {
Expand All @@ -40,6 +41,7 @@ export function preprocessor(code: string, options: PrettierOptions) {
importOrderSeparation,
importOrderGroupNamespaceSpecifiers,
importOrderSortSpecifiers,
importOrderSortByLength
});

return getCodeFromAst(allImports, directives, code, interpreter);
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export type GetSortedNodes = (
| 'importOrderSeparation'
| 'importOrderGroupNamespaceSpecifiers'
| 'importOrderSortSpecifiers'
| 'importOrderSortByLength'
>,
) => ImportOrLine[];
1 change: 1 addition & 0 deletions src/utils/__tests__/get-all-comments-from-nodes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const getSortedImportNodes = (code: string, options?: ParserOptions) => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
});
};

Expand Down
1 change: 1 addition & 0 deletions src/utils/__tests__/get-code-from-ast.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import a from 'a';
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
});
const formatted = getCodeFromAst(sortedNodes, [], code, null);
expect(format(formatted, { parser: 'babel' })).toEqual(
Expand Down
58 changes: 58 additions & 0 deletions src/utils/__tests__/get-sorted-nodes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ test('it returns all sorted nodes', () => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
}) as ImportDeclaration[];

expect(getSortedNodesNames(sorted)).toEqual([
Expand Down Expand Up @@ -72,6 +73,7 @@ test('it returns all sorted nodes case-insensitive', () => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
}) as ImportDeclaration[];

expect(getSortedNodesNames(sorted)).toEqual([
Expand Down Expand Up @@ -116,6 +118,7 @@ test('it returns all sorted nodes with sort order', () => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
}) as ImportDeclaration[];

expect(getSortedNodesNames(sorted)).toEqual([
Expand Down Expand Up @@ -160,6 +163,7 @@ test('it returns all sorted nodes with sort order case-insensitive', () => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
}) as ImportDeclaration[];
expect(getSortedNodesNames(sorted)).toEqual([
'c',
Expand Down Expand Up @@ -203,6 +207,7 @@ test('it returns all sorted import nodes with sorted import specifiers', () => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: true,
importOrderSortByLength: null
}) as ImportDeclaration[];
expect(getSortedNodesNames(sorted)).toEqual([
'XY',
Expand Down Expand Up @@ -246,6 +251,7 @@ test('it returns all sorted import nodes with sorted import specifiers with case
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: true,
importOrderSortByLength: null
}) as ImportDeclaration[];
expect(getSortedNodesNames(sorted)).toEqual([
'c',
Expand Down Expand Up @@ -289,6 +295,7 @@ test('it returns all sorted nodes with custom third party modules', () => {
importOrderCaseInsensitive: true,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
}) as ImportDeclaration[];
expect(getSortedNodesNames(sorted)).toEqual([
'a',
Expand All @@ -313,6 +320,7 @@ test('it returns all sorted nodes with namespace specifiers at the top', () => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: true,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
}) as ImportDeclaration[];

expect(getSortedNodesNames(sorted)).toEqual([
Expand All @@ -329,3 +337,53 @@ test('it returns all sorted nodes with namespace specifiers at the top', () => {
'z',
]);
});

test('it returns all sorted nodes, sorted shortest to longest', () => {
const result = getImportNodes(code)
const sorted = getSortedNodes(result, {
importOrder: [],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: 'asc'
}) as ImportDeclaration[];
expect(getSortedNodesNames(sorted)).toEqual([
'g',
'z',
'Ba',
'BY',
'Xa',
'XY',
'a',
'x',
'c',
'k',
't',
]);
})

test('it returns all sorted nodes, sorted longest to shortest', () => {
const result = getImportNodes(code)
const sorted = getSortedNodes(result, {
importOrder: [],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: 'desc'
}) as ImportDeclaration[];
expect(getSortedNodesNames(sorted)).toEqual([
't',
'k',
'c',
'a',
'x',
'Ba',
'BY',
'Xa',
'XY',
'g',
'z'
]);
})
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ test('it should remove nodes from the original code', () => {
importOrderSeparation: false,
importOrderGroupNamespaceSpecifiers: false,
importOrderSortSpecifiers: false,
importOrderSortByLength: null
});
const allCommentsFromImports = getAllCommentsFromNodes(sortedNodes);

Expand Down
13 changes: 11 additions & 2 deletions src/utils/get-sorted-nodes-group.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { Import, ImportDeclaration } from '@babel/types';
import { ImportDeclaration } from '@babel/types';
import { naturalSort } from '../natural-sort';
import { PrettierOptions } from '../types';

export const getSortedNodesGroup = (
imports: ImportDeclaration[],
options: Pick<PrettierOptions, 'importOrderGroupNamespaceSpecifiers'>,
options: Pick<PrettierOptions, 'importOrderGroupNamespaceSpecifiers' | 'importOrderSortByLength'>,
) => {
return imports.sort((a, b) => {
const aLength = (a.end || 0) - (a.start || 0)
const bLength = (b.end || 0) - (b.start || 0)

if (options.importOrderGroupNamespaceSpecifiers) {
const diff = namespaceSpecifierSort(a, b);
if (diff !== 0) return diff;
}

if (options.importOrderSortByLength === 'asc')
return aLength - bLength || a.source.value.localeCompare(b.source.value)

if (options.importOrderSortByLength === 'desc')
return bLength - aLength || a.source.value.localeCompare(b.source.value)

return naturalSort(a.source.value, b.source.value);
});
};
Expand Down
3 changes: 2 additions & 1 deletion src/utils/get-sorted-nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const getSortedNodes: GetSortedNodes = (nodes, options) => {
const {
importOrderSeparation,
importOrderSortSpecifiers,
importOrderGroupNamespaceSpecifiers,
importOrderGroupNamespaceSpecifiers,importOrderSortByLength

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
importOrderGroupNamespaceSpecifiers,importOrderSortByLength
importOrderGroupNamespaceSpecifiers,
importOrderSortByLength

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be in now, im gonna go through and check it still works as the merge may not be ok given how long its been

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're still around, latest commit should fix any tests, update docs / types and work

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, I really appreciate the effort. Hopefully some maintainer is able to merge this wonderful PR! 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you approve the pr again, we can get it in. Unless Github is leading me astray telling me it needs you to review.. if not the wait goes on 😅

} = options;

const originalNodes = nodes.map(clone);
Expand Down Expand Up @@ -58,6 +58,7 @@ export const getSortedNodes: GetSortedNodes = (nodes, options) => {

const sortedInsideGroup = getSortedNodesGroup(groupNodes, {
importOrderGroupNamespaceSpecifiers,
importOrderSortByLength
});

// Sort the import specifiers
Expand Down
18 changes: 13 additions & 5 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,21 @@ export interface PluginConfig {
/**
* A boolean value to enable case-insensitivity in the sorting algorithm
used to order imports within each match group.
*
*
* For example, when false (or not specified):
*
*
* ```js
* import ExampleView from './ExampleView';
* import ExamplesList from './ExamplesList';
* ```
*
*
* compared with `"importOrderCaseInsensitive": true`:
*
*
* ```js
* import ExamplesList from './ExamplesList';
* import ExampleView from './ExampleView';
* ```
*
*
* @default false
*/
importOrderCaseInsensitive?: boolean;
Expand Down Expand Up @@ -92,6 +92,14 @@ used to order imports within each match group.
* @default ["typescript", "jsx"]
*/
importOrderParserPlugins?: ImportOrderParserPlugin[];

/**
* A choice value to enable sorting imports within their groups based on their string lengths, the two options being ascending and descending.
* Leaving the value blank or setting it to null will result in length being ignored
*
* @default undefined
*/
importOrderSortByLength?: 'asc' | 'desc' | null
}

export type PrettierConfig = PluginConfig & Config;