Skip to content

Commit b329506

Browse files
robmisasirobmisasi-syk
authored andcommitted
Copy changes from import-js#3196.
1 parent 01c9eb0 commit b329506

File tree

4 files changed

+96
-8
lines changed

4 files changed

+96
-8
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
66

77
## [Unreleased]
88

9+
### Added
10+
- [`order`]: add `orderByFullPathString` option
11+
912
## [2.32.0] - 2025-06-20
1013

1114
### Added

docs/rules/order.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,10 @@ Imports are associated with a [`PathGroup`][13] based on path matching against t
193193

194194
| property | required | type | description |
195195
| :--------------: | :------: | :--------------------: | ------------------------------------------------------------------------------------------------------------------------------- |
196-
| `pattern` | ☑️ | `string` | [Minimatch pattern][16] for specifier matching |
196+
| `pattern` | ☑️ | `string` | [Minimatch pattern][16] for specifier matching |
197197
| `patternOptions` | | `object` | [Minimatch options][17]; default: `{nocomment: true}` |
198-
| `group` | ☑️ | [predefined group][18] | One of the [predefined groups][18] to which matching imports will be positioned relatively |
199-
| `position` | | `"after" \| "before"` | Where, in relation to `group`, matching imports will be positioned; default: same position as `group` (neither before or after) |
198+
| `group` | ☑️ | [predefined group][18] | One of the [predefined groups][18] to which matching imports will be positioned relatively |
199+
| `position` | | `"after" \| "before"` | Where, in relation to `group`, matching imports will be positioned; default: same position as `group` (neither before or after) |
200200

201201
#### Example
202202

@@ -367,8 +367,8 @@ import index from './';
367367

368368
### `alphabetize`
369369

370-
Valid values: `{ order?: "asc" | "desc" | "ignore", orderImportKind?: "asc" | "desc" | "ignore", caseInsensitive?: boolean }` \
371-
Default: `{ order: "ignore", orderImportKind: "ignore", caseInsensitive: false }`
370+
Valid values: `{ order?: "asc" | "desc" | "ignore", orderImportKind?: "asc" | "desc" | "ignore", caseInsensitive?: boolean, orderByFullPathString?: boolean }` \
371+
Default: `{ order: "ignore", orderImportKind: "ignore", caseInsensitive: false, orderByFullPathString: false }`
372372

373373
Determine the sort order of imports within each [predefined group][18] or [`PathGroup`][8] alphabetically based on specifier.
374374

@@ -385,6 +385,11 @@ Valid properties and their values include:
385385

386386
- **`caseInsensitive`**: use `true` to ignore case and `false` to consider case when sorting
387387

388+
- **`orderByFullPathString`**: use `true` to sort by the full un-split path string and `false` to split by paths and sort by each one
389+
- Enabling this flag may better align with the sort algorithm used by certain IDE's and applications, e.g.
390+
- The Organize Imports action in JetBrains IDE's sorts by the full path string
391+
- Microsoft's accessibility-insights-web application is [reported](https://github.com/microsoft/accessibility-insights-web/pull/6846) to sort by the full path string as well
392+
388393
#### Example
389394

390395
Given the following settings:
@@ -394,7 +399,8 @@ Given the following settings:
394399
"import/order": ["error", {
395400
"alphabetize": {
396401
"order": "asc",
397-
"caseInsensitive": true
402+
"caseInsensitive": true,
403+
"orderByFullPathString": true,
398404
}
399405
}]
400406
}
@@ -408,6 +414,8 @@ import aTypes from 'prop-types';
408414
import { compose, apply } from 'xcompose';
409415
import * as classnames from 'classnames';
410416
import blist from 'BList';
417+
import timeUtils1 from '../utils/time'
418+
import timeUtils2 from '../utils-time'
411419
```
412420

413421
While this will pass:
@@ -418,6 +426,11 @@ import * as classnames from 'classnames';
418426
import aTypes from 'prop-types';
419427
import React, { PureComponent } from 'react';
420428
import { compose, apply } from 'xcompose';
429+
// Below the '../utils-time' and '../utils/time' path are not split before ordering ("orderByFullPathString": true).
430+
// Instead, during comparison the "-" in "../utils-time" occurs lexicographically before the
431+
// second "/" in "../utils/time"
432+
import timeUtils2 from '../utils-time'
433+
import timeUtils1 from '../utils/time'
421434
```
422435

423436
### `named`

src/rules/order.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,10 @@ function getSorter(alphabetizeOptions) {
433433
const importB = getNormalizedValue(nodeB, alphabetizeOptions.caseInsensitive);
434434
let result = 0;
435435

436-
if (!includes(importA, '/') && !includes(importB, '/')) {
436+
if (
437+
alphabetizeOptions.orderByFullPathString === true
438+
|| !includes(importA, '/') && !includes(importB, '/')
439+
) {
437440
result = compareString(importA, importB);
438441
} else {
439442
const A = importA.split('/');
@@ -831,8 +834,9 @@ function getAlphabetizeConfig(options) {
831834
const order = alphabetize.order || 'ignore';
832835
const orderImportKind = alphabetize.orderImportKind || 'ignore';
833836
const caseInsensitive = alphabetize.caseInsensitive || false;
837+
const orderByFullPathString = alphabetize.orderByFullPathString || false;
834838

835-
return { order, orderImportKind, caseInsensitive };
839+
return { order, orderImportKind, caseInsensitive, orderByFullPathString };
836840
}
837841

838842
// TODO, semver-major: Change the default of "distinctGroup" from true to false
@@ -962,6 +966,10 @@ module.exports = {
962966
enum: ['ignore', 'asc', 'desc'],
963967
default: 'ignore',
964968
},
969+
orderByFullPathString: {
970+
type: 'boolean',
971+
default: false,
972+
},
965973
},
966974
additionalProperties: false,
967975
},

tests/src/rules/order.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,48 @@ ruleTester.run('order', rule, {
780780
alphabetize: { order: 'desc' },
781781
}],
782782
}),
783+
// Option alphabetize: {order: 'asc'} with orderByFullPathString: true`
784+
test({
785+
code: `
786+
import a from "foo";
787+
import b from "foo-bar";
788+
import c from "foo/bar";
789+
import d from "foo/barfoo";
790+
`,
791+
options: [{ alphabetize: { order: 'asc' }, orderByFullPathString: true }],
792+
}),
793+
// Option alphabetize: {order: 'asc'} with orderByFullPathString: true
794+
test({
795+
code: `
796+
import a from "foo";
797+
import b from "foo-bar";
798+
import c from "foo/foobar/bar";
799+
import d from "foo/foobar/barfoo";
800+
`,
801+
options: [{ alphabetize: { order: 'asc' }, orderByFullPathString: true }],
802+
}),
803+
// Option alphabetize: {order: 'desc'} with orderByFullPathString: true
804+
test({
805+
code: `
806+
import d from "foo/barfoo";
807+
import c from "foo/bar";
808+
import b from "foo-bar";
809+
import a from "foo";
810+
`,
811+
options: [{ alphabetize: { order: 'desc' }, orderByFullPathString: true }],
812+
}),
813+
// Option alphabetize: {order: 'desc'} with orderByFullPathString: true and file names having non-alphanumeric characters.
814+
test({
815+
code: `
816+
import d from "foo/barfoo";
817+
import b from "foo-bar";
818+
import c from "foo,bar";
819+
import a from "foo";`,
820+
options: [{
821+
alphabetize: { order: 'desc' },
822+
orderByFullPathString: true,
823+
}],
824+
}),
783825
// Option alphabetize with newlines-between: {order: 'asc', newlines-between: 'always'}
784826
test({
785827
code: `
@@ -2646,6 +2688,28 @@ ruleTester.run('order', rule, {
26462688
message: '`foo-bar` import should occur after import of `foo/barfoo`',
26472689
}],
26482690
}),
2691+
// Option alphabetize: {order: 'asc'} with orderByFullPathString: true
2692+
test({
2693+
code: `
2694+
import a from "foo";
2695+
import c from "foo/bar";
2696+
import d from "foo/barfoo";
2697+
import b from "foo-bar";
2698+
`,
2699+
options: [{
2700+
alphabetize: { order: 'asc' },
2701+
orderByFullPathString: true,
2702+
}],
2703+
output: `
2704+
import a from "foo";
2705+
import b from "foo-bar";
2706+
import c from "foo/bar";
2707+
import d from "foo/barfoo";
2708+
`,
2709+
errors: [{
2710+
message: '`foo/barfoo` import should occur after import of `foo-bar`',
2711+
}],
2712+
}),
26492713
// Option alphabetize {order: 'asc': caseInsensitive: true}
26502714
test({
26512715
code: `

0 commit comments

Comments
 (0)