prettier-plugin-sort 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -113
- package/README.zh.md +167 -115
- package/dist/index.d.ts +2 -2
- package/dist/index.js +540 -145
- package/dist/options.d.ts +71 -7
- package/dist/parser-ast.d.ts +11 -3
- package/dist/sort-exports.d.ts +2 -2
- package/dist/sort-imports.d.ts +4 -4
- package/dist/sort-tsconfig.d.ts +6 -0
- package/dist/utils/package-rules.d.ts +1 -0
- package/dist/utils/tsconfig-rules.d.ts +16 -0
- package/package.json +16 -10
package/dist/index.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined")
|
|
5
|
+
return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
1
9
|
// src/index.ts
|
|
2
10
|
import acornPlugin from "prettier/plugins/acorn";
|
|
3
11
|
import babelPlugin from "prettier/plugins/babel";
|
|
@@ -8,12 +16,21 @@ import typescriptPlugin from "prettier/plugins/typescript";
|
|
|
8
16
|
// src/options.ts
|
|
9
17
|
var DEFAULT_SORT_OPTIONS = {
|
|
10
18
|
esmImportSort: true,
|
|
11
|
-
esmImportGroups: [
|
|
19
|
+
esmImportGroups: [
|
|
20
|
+
"builtin",
|
|
21
|
+
"external",
|
|
22
|
+
"internal",
|
|
23
|
+
"parent",
|
|
24
|
+
"sibling",
|
|
25
|
+
"index"
|
|
26
|
+
],
|
|
12
27
|
esmImportSeparation: true,
|
|
13
28
|
esmImportTypeStyle: "separate",
|
|
14
29
|
esmImportMerge: true,
|
|
15
30
|
esmExportSpecifierSort: true,
|
|
16
|
-
packageSort: true
|
|
31
|
+
packageSort: true,
|
|
32
|
+
tsconfigSort: true,
|
|
33
|
+
tsconfigSeparation: true
|
|
17
34
|
};
|
|
18
35
|
var VALID_IMPORT_GROUPS = new Set([
|
|
19
36
|
"builtin",
|
|
@@ -38,7 +55,7 @@ function resolveBooleanSortOption(prettierOptions, optionName) {
|
|
|
38
55
|
}
|
|
39
56
|
return DEFAULT_SORT_OPTIONS[optionName];
|
|
40
57
|
}
|
|
41
|
-
function
|
|
58
|
+
function resolveEsmOptions(prettierOptions) {
|
|
42
59
|
const configuredImportGroups = Array.isArray(prettierOptions.esmImportGroups) ? [...new Set(prettierOptions.esmImportGroups.filter(isValidImportGroup))] : [];
|
|
43
60
|
const remainingDefaultImportGroups = DEFAULT_SORT_OPTIONS.esmImportGroups.filter((importGroup) => !configuredImportGroups.includes(importGroup));
|
|
44
61
|
const resolvedImportGroups = configuredImportGroups.length > 0 ? [...configuredImportGroups, ...remainingDefaultImportGroups] : [...DEFAULT_SORT_OPTIONS.esmImportGroups];
|
|
@@ -49,8 +66,16 @@ function resolveSortOptions(prettierOptions) {
|
|
|
49
66
|
esmImportSeparation: resolveBooleanSortOption(prettierOptions, "esmImportSeparation"),
|
|
50
67
|
esmImportTypeStyle: resolvedTypeImportStyle,
|
|
51
68
|
esmImportMerge: resolveBooleanSortOption(prettierOptions, "esmImportMerge"),
|
|
52
|
-
esmExportSpecifierSort: resolveBooleanSortOption(prettierOptions, "esmExportSpecifierSort")
|
|
53
|
-
|
|
69
|
+
esmExportSpecifierSort: resolveBooleanSortOption(prettierOptions, "esmExportSpecifierSort")
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function isPackageSortEnabled(prettierOptions) {
|
|
73
|
+
return resolveBooleanSortOption(prettierOptions, "packageSort");
|
|
74
|
+
}
|
|
75
|
+
function resolveTsconfigOptions(prettierOptions) {
|
|
76
|
+
return {
|
|
77
|
+
tsconfigSort: resolveBooleanSortOption(prettierOptions, "tsconfigSort"),
|
|
78
|
+
tsconfigSeparation: resolveBooleanSortOption(prettierOptions, "tsconfigSeparation")
|
|
54
79
|
};
|
|
55
80
|
}
|
|
56
81
|
var options = {
|
|
@@ -77,7 +102,7 @@ var options = {
|
|
|
77
102
|
type: "choice",
|
|
78
103
|
default: DEFAULT_SORT_OPTIONS.esmImportTypeStyle,
|
|
79
104
|
category: "ES Module Imports",
|
|
80
|
-
description: "Format named type imports as separate declarations or inline specifiers.",
|
|
105
|
+
description: "Format named type imports as separate declarations or inline specifiers without changing runtime module requests.",
|
|
81
106
|
choices: [
|
|
82
107
|
{
|
|
83
108
|
value: "separate",
|
|
@@ -113,14 +138,30 @@ var options = {
|
|
|
113
138
|
type: "boolean",
|
|
114
139
|
default: DEFAULT_SORT_OPTIONS.packageSort,
|
|
115
140
|
category: "package.json",
|
|
116
|
-
description: "Sort
|
|
141
|
+
description: "Sort fields in package.json."
|
|
142
|
+
},
|
|
143
|
+
tsconfigSort: {
|
|
144
|
+
type: "boolean",
|
|
145
|
+
default: DEFAULT_SORT_OPTIONS.tsconfigSort,
|
|
146
|
+
category: "tsconfig.json",
|
|
147
|
+
description: "Sort fields in tsconfig.json."
|
|
148
|
+
},
|
|
149
|
+
tsconfigSeparation: {
|
|
150
|
+
type: "boolean",
|
|
151
|
+
default: DEFAULT_SORT_OPTIONS.tsconfigSeparation,
|
|
152
|
+
category: "tsconfig.json",
|
|
153
|
+
description: "Add blank lines between TypeScript 5.8 compilerOptions categories."
|
|
117
154
|
}
|
|
118
155
|
};
|
|
119
156
|
|
|
120
157
|
// src/sort-package.ts
|
|
121
158
|
import findMinimumSemanticVersion from "semver/ranges/min-version.js";
|
|
159
|
+
import getValidSemanticVersionRange from "semver/ranges/valid.js";
|
|
122
160
|
|
|
123
161
|
// src/parser-ast.ts
|
|
162
|
+
function isParserAstNode(value) {
|
|
163
|
+
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
|
|
164
|
+
}
|
|
124
165
|
function getAstNodeTextRange(node) {
|
|
125
166
|
if (!node) {
|
|
126
167
|
return null;
|
|
@@ -478,7 +519,8 @@ class JsonSourceLiteral {
|
|
|
478
519
|
}
|
|
479
520
|
}
|
|
480
521
|
var SEQUENTIAL_SCRIPT_PATTERN = /(?<=^|[\s&;<>|(])(?:run-s|npm-run-all2? .*(?:--sequential|--serial|-s))(?=$|[\s&;<>|)])/;
|
|
481
|
-
|
|
522
|
+
var PACKAGE_JSON_FIELD_INDEXES = new Map(PACKAGE_JSON_FIELD_ORDER.map((fieldName, index) => [fieldName, index]));
|
|
523
|
+
function compareStringsCaseSensitive(leftText, rightText) {
|
|
482
524
|
if (leftText === rightText) {
|
|
483
525
|
return 0;
|
|
484
526
|
}
|
|
@@ -502,13 +544,10 @@ function getJsonString(jsonValue) {
|
|
|
502
544
|
function isJsonStringValue(jsonValue) {
|
|
503
545
|
return getJsonString(jsonValue) !== null;
|
|
504
546
|
}
|
|
505
|
-
function isParserJsonAstNode(value) {
|
|
506
|
-
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
|
|
507
|
-
}
|
|
508
547
|
function preserveJsonSourceLiterals(jsonValue, parserJsonNode, sourceText, fieldNameSourceTexts, jsonPath = []) {
|
|
509
548
|
if (parserJsonNode.type === "JsonRoot") {
|
|
510
549
|
const rootNode = parserJsonNode.node;
|
|
511
|
-
if (!
|
|
550
|
+
if (!isParserAstNode(rootNode)) {
|
|
512
551
|
return;
|
|
513
552
|
}
|
|
514
553
|
return preserveJsonSourceLiterals(jsonValue, rootNode, sourceText, fieldNameSourceTexts, jsonPath);
|
|
@@ -534,7 +573,7 @@ function preserveJsonSourceLiterals(jsonValue, parserJsonNode, sourceText, field
|
|
|
534
573
|
const propertyName = getAstNodeName(propertyNode.key);
|
|
535
574
|
const propertyNameRange = getAstNodeTextRange(propertyNode.key);
|
|
536
575
|
const propertyValueNode = propertyNode.value;
|
|
537
|
-
if (propertyNode.type !== "ObjectProperty" || propertyName === null || !propertyNameRange || propertyNames.has(propertyName) || !Object.hasOwn(jsonValue, propertyName) || !
|
|
576
|
+
if (propertyNode.type !== "ObjectProperty" || propertyName === null || !propertyNameRange || propertyNames.has(propertyName) || !Object.hasOwn(jsonValue, propertyName) || !isParserAstNode(propertyValueNode)) {
|
|
538
577
|
return;
|
|
539
578
|
}
|
|
540
579
|
propertyNames.add(propertyName);
|
|
@@ -616,7 +655,7 @@ function deduplicateStringValues(stringValues) {
|
|
|
616
655
|
}
|
|
617
656
|
return [...uniqueStringValues.values()];
|
|
618
657
|
}
|
|
619
|
-
function sortJsonObject(jsonObject, compareKeys =
|
|
658
|
+
function sortJsonObject(jsonObject, compareKeys = compareStringsCaseSensitive) {
|
|
620
659
|
return Object.fromEntries(Object.entries(jsonObject).sort(([leftKey], [rightKey]) => compareKeys(leftKey, rightKey)));
|
|
621
660
|
}
|
|
622
661
|
function sortJsonObjectByKeyOrder(jsonObject, keyOrder) {
|
|
@@ -635,7 +674,7 @@ function sortJsonObjectByKeyOrder(jsonObject, keyOrder) {
|
|
|
635
674
|
if (isRightKeyKnown) {
|
|
636
675
|
return 1;
|
|
637
676
|
}
|
|
638
|
-
return
|
|
677
|
+
return compareStringsCaseSensitive(leftKey, rightKey);
|
|
639
678
|
});
|
|
640
679
|
}
|
|
641
680
|
function sortJsonObjectRecursively(jsonObject, sortObject = sortJsonObject) {
|
|
@@ -661,7 +700,7 @@ function sortUniqueStringArrayValue(fieldValue) {
|
|
|
661
700
|
if (!isStringArray(fieldValue)) {
|
|
662
701
|
return fieldValue;
|
|
663
702
|
}
|
|
664
|
-
return deduplicateStringValues(fieldValue).sort((leftValue, rightValue) =>
|
|
703
|
+
return deduplicateStringValues(fieldValue).sort((leftValue, rightValue) => compareStringsCaseSensitive(getJsonString(leftValue), getJsonString(rightValue)));
|
|
665
704
|
}
|
|
666
705
|
function deduplicateStringArrayValue(fieldValue) {
|
|
667
706
|
return isStringArray(fieldValue) ? deduplicateStringValues(fieldValue) : fieldValue;
|
|
@@ -676,10 +715,9 @@ function sortPeopleArrayValue(fieldValue) {
|
|
|
676
715
|
return fieldValue.map((person) => sortPersonValue(person));
|
|
677
716
|
}
|
|
678
717
|
function sortPackageJsonFields(packageJson) {
|
|
679
|
-
const fieldOrderIndexes = new Map(PACKAGE_JSON_FIELD_ORDER.map((fieldName, index) => [fieldName, index]));
|
|
680
718
|
return sortJsonObject(packageJson, (leftFieldName, rightFieldName) => {
|
|
681
|
-
const leftIndex =
|
|
682
|
-
const rightIndex =
|
|
719
|
+
const leftIndex = PACKAGE_JSON_FIELD_INDEXES.get(leftFieldName);
|
|
720
|
+
const rightIndex = PACKAGE_JSON_FIELD_INDEXES.get(rightFieldName);
|
|
683
721
|
const isLeftFieldKnown = leftIndex !== undefined;
|
|
684
722
|
const isRightFieldKnown = rightIndex !== undefined;
|
|
685
723
|
if (isLeftFieldKnown && isRightFieldKnown) {
|
|
@@ -696,37 +734,16 @@ function sortPackageJsonFields(packageJson) {
|
|
|
696
734
|
if (isLeftFieldPrivate !== isRightFieldPrivate) {
|
|
697
735
|
return isLeftFieldPrivate ? 1 : -1;
|
|
698
736
|
}
|
|
699
|
-
return
|
|
737
|
+
return compareStringsCaseSensitive(leftFieldName, rightFieldName);
|
|
700
738
|
});
|
|
701
739
|
}
|
|
702
|
-
function
|
|
703
|
-
const packageManager = getJsonString(packageJson.packageManager);
|
|
704
|
-
if (packageManager !== null) {
|
|
705
|
-
return packageManager.startsWith("npm@");
|
|
706
|
-
}
|
|
707
|
-
const devEngines = packageJson.devEngines;
|
|
708
|
-
if (isJsonObject(devEngines)) {
|
|
709
|
-
const devPackageManager = devEngines.packageManager;
|
|
710
|
-
const devPackageManagerName = isJsonObject(devPackageManager) ? getJsonString(devPackageManager.name) : null;
|
|
711
|
-
if (devPackageManagerName !== null) {
|
|
712
|
-
return devPackageManagerName === "npm";
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
if (isJsonObject(packageJson.pnpm)) {
|
|
716
|
-
return false;
|
|
717
|
-
}
|
|
718
|
-
return true;
|
|
719
|
-
}
|
|
720
|
-
function sortDependencyObject(dependencyObject, packageJson) {
|
|
721
|
-
if (!isNpmDependencyOrderPreferred(packageJson)) {
|
|
722
|
-
return sortJsonObject(dependencyObject);
|
|
723
|
-
}
|
|
740
|
+
function sortDependencyObject(dependencyObject) {
|
|
724
741
|
return sortJsonObject(dependencyObject, (leftName, rightName) => leftName.localeCompare(rightName, "en"));
|
|
725
742
|
}
|
|
726
|
-
function sortDependencyValue(fieldValue
|
|
727
|
-
return sortJsonObjectValue(fieldValue,
|
|
743
|
+
function sortDependencyValue(fieldValue) {
|
|
744
|
+
return sortJsonObjectValue(fieldValue, sortDependencyObject);
|
|
728
745
|
}
|
|
729
|
-
function sortWorkspacesValue(fieldValue
|
|
746
|
+
function sortWorkspacesValue(fieldValue) {
|
|
730
747
|
if (!isJsonObject(fieldValue)) {
|
|
731
748
|
return fieldValue;
|
|
732
749
|
}
|
|
@@ -739,7 +756,7 @@ function sortWorkspacesValue(fieldValue, packageJson) {
|
|
|
739
756
|
sortedWorkspaces.packages = sortUniqueStringArrayValue(workspacePackages);
|
|
740
757
|
}
|
|
741
758
|
if (isJsonObject(sortedWorkspaces.catalog)) {
|
|
742
|
-
sortedWorkspaces.catalog = sortDependencyObject(sortedWorkspaces.catalog
|
|
759
|
+
sortedWorkspaces.catalog = sortDependencyObject(sortedWorkspaces.catalog);
|
|
743
760
|
}
|
|
744
761
|
return sortedWorkspaces;
|
|
745
762
|
}
|
|
@@ -769,7 +786,7 @@ function sortEslintConfigValue(fieldValue) {
|
|
|
769
786
|
return sortJsonObjectValue(fieldValue, sortEslintConfigObject);
|
|
770
787
|
}
|
|
771
788
|
function sortPrettierConfigObject(prettierConfig) {
|
|
772
|
-
const keyOrder = Object.keys(prettierConfig).filter((key) => key !== "overrides").sort(
|
|
789
|
+
const keyOrder = Object.keys(prettierConfig).filter((key) => key !== "overrides").sort(compareStringsCaseSensitive);
|
|
773
790
|
if (Object.hasOwn(prettierConfig, "overrides")) {
|
|
774
791
|
keyOrder.push("overrides");
|
|
775
792
|
}
|
|
@@ -848,13 +865,13 @@ function sortScriptNames(scriptNames, namespacePrefix = "") {
|
|
|
848
865
|
groupedScriptNames.push(scriptName);
|
|
849
866
|
scriptGroups.set(scriptGroupName, groupedScriptNames);
|
|
850
867
|
}
|
|
851
|
-
return [...scriptGroups.keys()].sort(
|
|
868
|
+
return [...scriptGroups.keys()].sort(compareStringsCaseSensitive).flatMap((scriptGroupName) => {
|
|
852
869
|
const groupedScriptNames = scriptGroups.get(scriptGroupName);
|
|
853
870
|
const isNestedGroup = groupedScriptNames.length > 1 && groupedScriptNames.some((scriptName) => scriptName !== scriptGroupName && scriptName.startsWith(`${scriptGroupName}:`));
|
|
854
871
|
if (!isNestedGroup) {
|
|
855
|
-
return groupedScriptNames.sort(
|
|
872
|
+
return groupedScriptNames.sort(compareStringsCaseSensitive);
|
|
856
873
|
}
|
|
857
|
-
const directScriptNames = groupedScriptNames.filter((scriptName) => scriptName === scriptGroupName || !scriptName.startsWith(`${scriptGroupName}:`)).sort(
|
|
874
|
+
const directScriptNames = groupedScriptNames.filter((scriptName) => scriptName === scriptGroupName || !scriptName.startsWith(`${scriptGroupName}:`)).sort(compareStringsCaseSensitive);
|
|
858
875
|
const nestedScriptNames = groupedScriptNames.filter((scriptName) => scriptName.startsWith(`${scriptGroupName}:`));
|
|
859
876
|
return [
|
|
860
877
|
...directScriptNames,
|
|
@@ -911,11 +928,38 @@ function getDependencyName(dependencyIdentifier) {
|
|
|
911
928
|
const versionSeparatorIndex = dependencyIdentifier.indexOf("@", dependencyIdentifier.startsWith("@") ? 1 : 0);
|
|
912
929
|
return versionSeparatorIndex < 0 ? dependencyIdentifier : dependencyIdentifier.slice(0, versionSeparatorIndex);
|
|
913
930
|
}
|
|
931
|
+
function getPackageVersionSeparatorIndex(packageSelector) {
|
|
932
|
+
return packageSelector.indexOf("@", packageSelector.startsWith("@") ? 1 : 0);
|
|
933
|
+
}
|
|
934
|
+
function isCompletePackageSelector(packageSelector) {
|
|
935
|
+
const versionSeparatorIndex = getPackageVersionSeparatorIndex(packageSelector);
|
|
936
|
+
if (versionSeparatorIndex < 0) {
|
|
937
|
+
return packageSelector !== "";
|
|
938
|
+
}
|
|
939
|
+
const name = packageSelector.slice(0, versionSeparatorIndex);
|
|
940
|
+
const versionRange = packageSelector.slice(versionSeparatorIndex + 1);
|
|
941
|
+
return name !== "" && versionRange.trim() !== "" && !versionRange.trimEnd().endsWith("||") && getValidSemanticVersionRange(versionRange) !== null;
|
|
942
|
+
}
|
|
943
|
+
function findPnpmDependencySeparator(packageSelector) {
|
|
944
|
+
for (let separatorIndex = packageSelector.indexOf(">");separatorIndex >= 0; separatorIndex = packageSelector.indexOf(">", separatorIndex + 1)) {
|
|
945
|
+
const isSemverComparator = packageSelector[separatorIndex - 1]?.trim() === "";
|
|
946
|
+
if (isSemverComparator) {
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
const parentSelector = packageSelector.slice(0, separatorIndex);
|
|
950
|
+
const dependencySelector = packageSelector.slice(separatorIndex + 1);
|
|
951
|
+
if (dependencySelector.trim() !== "" && isCompletePackageSelector(parentSelector)) {
|
|
952
|
+
return separatorIndex;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
return -1;
|
|
956
|
+
}
|
|
914
957
|
function parsePackageSelector(packageSelector) {
|
|
915
|
-
const
|
|
916
|
-
const
|
|
917
|
-
|
|
918
|
-
|
|
958
|
+
const dependencySeparatorIndex = findPnpmDependencySeparator(packageSelector);
|
|
959
|
+
const nameAndVersion = dependencySeparatorIndex < 0 ? packageSelector : packageSelector.slice(0, dependencySeparatorIndex);
|
|
960
|
+
const versionSeparatorIndex = getPackageVersionSeparatorIndex(nameAndVersion);
|
|
961
|
+
if (versionSeparatorIndex < 0) {
|
|
962
|
+
return { name: nameAndVersion, versionRange: null };
|
|
919
963
|
}
|
|
920
964
|
return {
|
|
921
965
|
name: nameAndVersion.slice(0, versionSeparatorIndex),
|
|
@@ -947,7 +991,7 @@ function comparePnpmOverrideSelectors(leftSelector, rightSelector) {
|
|
|
947
991
|
const leftVersion = getMinimumSemanticVersion(leftPackage.versionRange);
|
|
948
992
|
const rightVersion = getMinimumSemanticVersion(rightPackage.versionRange);
|
|
949
993
|
if (!leftVersion && !rightVersion) {
|
|
950
|
-
return
|
|
994
|
+
return compareStringsCaseSensitive(leftPackage.versionRange, rightPackage.versionRange);
|
|
951
995
|
}
|
|
952
996
|
if (!leftVersion) {
|
|
953
997
|
return 1;
|
|
@@ -959,7 +1003,7 @@ function comparePnpmOverrideSelectors(leftSelector, rightSelector) {
|
|
|
959
1003
|
}
|
|
960
1004
|
function sortDependencyMetadataValue(fieldValue) {
|
|
961
1005
|
return sortJsonObjectValue(fieldValue, (dependencyMetadata) => {
|
|
962
|
-
const compareDependencyIdentifiers = (leftIdentifier, rightIdentifier) =>
|
|
1006
|
+
const compareDependencyIdentifiers = (leftIdentifier, rightIdentifier) => compareStringsCaseSensitive(getDependencyName(leftIdentifier), getDependencyName(rightIdentifier));
|
|
963
1007
|
return sortJsonObjectRecursively(dependencyMetadata, (jsonObject) => sortJsonObject(jsonObject, compareDependencyIdentifiers));
|
|
964
1008
|
});
|
|
965
1009
|
}
|
|
@@ -1075,7 +1119,7 @@ function isPackageJsonFile(filePath) {
|
|
|
1075
1119
|
return filePath?.split(/[\\/]/).at(-1) === "package.json";
|
|
1076
1120
|
}
|
|
1077
1121
|
async function preprocessPackageJson(sourceText, prettierOptions, parser) {
|
|
1078
|
-
if (!isPackageJsonFile(prettierOptions.filepath) || !
|
|
1122
|
+
if (!isPackageJsonFile(prettierOptions.filepath) || !isPackageSortEnabled(prettierOptions)) {
|
|
1079
1123
|
return sourceText;
|
|
1080
1124
|
}
|
|
1081
1125
|
try {
|
|
@@ -1084,7 +1128,7 @@ async function preprocessPackageJson(sourceText, prettierOptions, parser) {
|
|
|
1084
1128
|
return sourceText;
|
|
1085
1129
|
}
|
|
1086
1130
|
const parserJsonAst = await parser.parse(sourceText, prettierOptions);
|
|
1087
|
-
if (!
|
|
1131
|
+
if (!isParserAstNode(parserJsonAst)) {
|
|
1088
1132
|
return sourceText;
|
|
1089
1133
|
}
|
|
1090
1134
|
const fieldNameSourceTexts = new Map;
|
|
@@ -1098,6 +1142,367 @@ async function preprocessPackageJson(sourceText, prettierOptions, parser) {
|
|
|
1098
1142
|
}
|
|
1099
1143
|
}
|
|
1100
1144
|
|
|
1145
|
+
// src/utils/source-text.ts
|
|
1146
|
+
function applySourceTextEdits(sourceText, sourceTextEdits) {
|
|
1147
|
+
if (sourceTextEdits.length === 0) {
|
|
1148
|
+
return sourceText;
|
|
1149
|
+
}
|
|
1150
|
+
let previousEditEnd = 0;
|
|
1151
|
+
const ascendingEdits = [...sourceTextEdits].sort((left, right) => left.start - right.start || left.end - right.end);
|
|
1152
|
+
for (const sourceTextEdit of ascendingEdits) {
|
|
1153
|
+
const { start, end } = sourceTextEdit;
|
|
1154
|
+
const isSourceTextEditValid = [start, end].every(Number.isSafeInteger) && start >= previousEditEnd && end >= start && end <= sourceText.length;
|
|
1155
|
+
if (!isSourceTextEditValid) {
|
|
1156
|
+
return null;
|
|
1157
|
+
}
|
|
1158
|
+
previousEditEnd = end;
|
|
1159
|
+
}
|
|
1160
|
+
let editedText = sourceText;
|
|
1161
|
+
for (const sourceTextEdit of ascendingEdits.reverse()) {
|
|
1162
|
+
editedText = editedText.slice(0, sourceTextEdit.start) + sourceTextEdit.replacementText + editedText.slice(sourceTextEdit.end);
|
|
1163
|
+
}
|
|
1164
|
+
return editedText;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// src/utils/tsconfig-rules.ts
|
|
1168
|
+
var TSCONFIG_ROOT_FIRST_FIELDS = ["$schema", "extends"];
|
|
1169
|
+
var TSCONFIG_ROOT_LAST_FIELDS = [
|
|
1170
|
+
"files",
|
|
1171
|
+
"include",
|
|
1172
|
+
"exclude"
|
|
1173
|
+
];
|
|
1174
|
+
var COMPILER_OPTION_FIELD_GROUPS = [
|
|
1175
|
+
[
|
|
1176
|
+
"incremental",
|
|
1177
|
+
"composite",
|
|
1178
|
+
"tsBuildInfoFile",
|
|
1179
|
+
"disableSourceOfProjectReferenceRedirect",
|
|
1180
|
+
"disableSolutionSearching",
|
|
1181
|
+
"disableReferencedProjectLoad"
|
|
1182
|
+
],
|
|
1183
|
+
[
|
|
1184
|
+
"target",
|
|
1185
|
+
"lib",
|
|
1186
|
+
"jsx",
|
|
1187
|
+
"libReplacement",
|
|
1188
|
+
"experimentalDecorators",
|
|
1189
|
+
"emitDecoratorMetadata",
|
|
1190
|
+
"jsxFactory",
|
|
1191
|
+
"jsxFragmentFactory",
|
|
1192
|
+
"jsxImportSource",
|
|
1193
|
+
"reactNamespace",
|
|
1194
|
+
"noLib",
|
|
1195
|
+
"useDefineForClassFields",
|
|
1196
|
+
"moduleDetection"
|
|
1197
|
+
],
|
|
1198
|
+
[
|
|
1199
|
+
"module",
|
|
1200
|
+
"rootDir",
|
|
1201
|
+
"moduleResolution",
|
|
1202
|
+
"baseUrl",
|
|
1203
|
+
"paths",
|
|
1204
|
+
"rootDirs",
|
|
1205
|
+
"typeRoots",
|
|
1206
|
+
"types",
|
|
1207
|
+
"allowUmdGlobalAccess",
|
|
1208
|
+
"moduleSuffixes",
|
|
1209
|
+
"allowImportingTsExtensions",
|
|
1210
|
+
"rewriteRelativeImportExtensions",
|
|
1211
|
+
"resolvePackageJsonExports",
|
|
1212
|
+
"resolvePackageJsonImports",
|
|
1213
|
+
"customConditions",
|
|
1214
|
+
"noUncheckedSideEffectImports",
|
|
1215
|
+
"resolveJsonModule",
|
|
1216
|
+
"allowArbitraryExtensions",
|
|
1217
|
+
"noResolve"
|
|
1218
|
+
],
|
|
1219
|
+
["allowJs", "checkJs", "maxNodeModuleJsDepth"],
|
|
1220
|
+
[
|
|
1221
|
+
"declaration",
|
|
1222
|
+
"declarationMap",
|
|
1223
|
+
"emitDeclarationOnly",
|
|
1224
|
+
"sourceMap",
|
|
1225
|
+
"inlineSourceMap",
|
|
1226
|
+
"noEmit",
|
|
1227
|
+
"outFile",
|
|
1228
|
+
"outDir",
|
|
1229
|
+
"removeComments",
|
|
1230
|
+
"importHelpers",
|
|
1231
|
+
"downlevelIteration",
|
|
1232
|
+
"sourceRoot",
|
|
1233
|
+
"mapRoot",
|
|
1234
|
+
"inlineSources",
|
|
1235
|
+
"emitBOM",
|
|
1236
|
+
"newLine",
|
|
1237
|
+
"stripInternal",
|
|
1238
|
+
"noEmitHelpers",
|
|
1239
|
+
"noEmitOnError",
|
|
1240
|
+
"preserveConstEnums",
|
|
1241
|
+
"declarationDir"
|
|
1242
|
+
],
|
|
1243
|
+
[
|
|
1244
|
+
"isolatedModules",
|
|
1245
|
+
"verbatimModuleSyntax",
|
|
1246
|
+
"isolatedDeclarations",
|
|
1247
|
+
"erasableSyntaxOnly",
|
|
1248
|
+
"allowSyntheticDefaultImports",
|
|
1249
|
+
"esModuleInterop",
|
|
1250
|
+
"preserveSymlinks",
|
|
1251
|
+
"forceConsistentCasingInFileNames"
|
|
1252
|
+
],
|
|
1253
|
+
[
|
|
1254
|
+
"strict",
|
|
1255
|
+
"noImplicitAny",
|
|
1256
|
+
"strictNullChecks",
|
|
1257
|
+
"strictFunctionTypes",
|
|
1258
|
+
"strictBindCallApply",
|
|
1259
|
+
"strictPropertyInitialization",
|
|
1260
|
+
"strictBuiltinIteratorReturn",
|
|
1261
|
+
"noImplicitThis",
|
|
1262
|
+
"useUnknownInCatchVariables",
|
|
1263
|
+
"alwaysStrict",
|
|
1264
|
+
"noUnusedLocals",
|
|
1265
|
+
"noUnusedParameters",
|
|
1266
|
+
"exactOptionalPropertyTypes",
|
|
1267
|
+
"noImplicitReturns",
|
|
1268
|
+
"noFallthroughCasesInSwitch",
|
|
1269
|
+
"noUncheckedIndexedAccess",
|
|
1270
|
+
"noImplicitOverride",
|
|
1271
|
+
"noPropertyAccessFromIndexSignature",
|
|
1272
|
+
"allowUnusedLabels",
|
|
1273
|
+
"allowUnreachableCode"
|
|
1274
|
+
],
|
|
1275
|
+
["skipDefaultLibCheck", "skipLibCheck"],
|
|
1276
|
+
["preserveWatchOutput", "pretty", "noErrorTruncation"],
|
|
1277
|
+
[
|
|
1278
|
+
"listFiles",
|
|
1279
|
+
"explainFiles",
|
|
1280
|
+
"listEmittedFiles",
|
|
1281
|
+
"traceResolution",
|
|
1282
|
+
"diagnostics",
|
|
1283
|
+
"extendedDiagnostics",
|
|
1284
|
+
"generateCpuProfile",
|
|
1285
|
+
"generateTrace",
|
|
1286
|
+
"noCheck"
|
|
1287
|
+
],
|
|
1288
|
+
["assumeChangesOnlyAffectDirectDependencies"],
|
|
1289
|
+
[
|
|
1290
|
+
"importsNotUsedAsValues",
|
|
1291
|
+
"out",
|
|
1292
|
+
"charset",
|
|
1293
|
+
"noImplicitUseStrict",
|
|
1294
|
+
"suppressExcessPropertyErrors",
|
|
1295
|
+
"suppressImplicitAnyIndexErrors",
|
|
1296
|
+
"noStrictGenericChecks",
|
|
1297
|
+
"preserveValueImports",
|
|
1298
|
+
"keyofStringsOnly"
|
|
1299
|
+
],
|
|
1300
|
+
["disableSizeLimit", "plugins"]
|
|
1301
|
+
];
|
|
1302
|
+
|
|
1303
|
+
// src/sort-tsconfig.ts
|
|
1304
|
+
function createFieldIndexes(fieldNames) {
|
|
1305
|
+
return new Map(fieldNames.map((fieldName, fieldIndex) => [fieldName, fieldIndex]));
|
|
1306
|
+
}
|
|
1307
|
+
var COMPILER_OPTION_FIELD_INDEXES = createFieldIndexes(COMPILER_OPTION_FIELD_GROUPS.flat());
|
|
1308
|
+
var COMPILER_OPTION_FIELD_GROUP_INDEXES = new Map(COMPILER_OPTION_FIELD_GROUPS.flatMap((fieldGroup, groupIndex) => fieldGroup.map((fieldName) => [fieldName, groupIndex])));
|
|
1309
|
+
var ROOT_FIRST_FIELD_INDEXES = createFieldIndexes(TSCONFIG_ROOT_FIRST_FIELDS);
|
|
1310
|
+
var ROOT_LAST_FIELD_INDEXES = createFieldIndexes(TSCONFIG_ROOT_LAST_FIELDS);
|
|
1311
|
+
function getTsconfigRootNode(parserAst) {
|
|
1312
|
+
if (parserAst.type === "ObjectExpression") {
|
|
1313
|
+
return parserAst;
|
|
1314
|
+
}
|
|
1315
|
+
return parserAst.type === "JsonRoot" && parserAst.node?.type === "ObjectExpression" ? parserAst.node : null;
|
|
1316
|
+
}
|
|
1317
|
+
function getCompilerOptionsNode(rootNode) {
|
|
1318
|
+
const propertyNodes = rootNode.properties;
|
|
1319
|
+
if (!Array.isArray(propertyNodes)) {
|
|
1320
|
+
return null;
|
|
1321
|
+
}
|
|
1322
|
+
const compilerOptions = propertyNodes.filter((propertyNode) => getAstNodeName(propertyNode.key) === "compilerOptions");
|
|
1323
|
+
if (compilerOptions.length !== 1) {
|
|
1324
|
+
return null;
|
|
1325
|
+
}
|
|
1326
|
+
const property = compilerOptions[0];
|
|
1327
|
+
const value = property?.value;
|
|
1328
|
+
return property?.type === "ObjectProperty" && isParserAstNode(value) && value.type === "ObjectExpression" ? { property, value } : null;
|
|
1329
|
+
}
|
|
1330
|
+
function hasDirectComments(objectNode, propertyNodes, sortedComments) {
|
|
1331
|
+
const objectRange = getAstNodeTextRange(objectNode);
|
|
1332
|
+
const propertyRanges = propertyNodes.map(getAstNodeTextRange);
|
|
1333
|
+
if (!objectRange || propertyRanges.some((propertyRange) => !propertyRange)) {
|
|
1334
|
+
return true;
|
|
1335
|
+
}
|
|
1336
|
+
return sortedComments.some(({ textRange: commentRange }) => {
|
|
1337
|
+
if (commentRange.start < objectRange.start || commentRange.end > objectRange.end) {
|
|
1338
|
+
return false;
|
|
1339
|
+
}
|
|
1340
|
+
return !propertyRanges.some((propertyRange) => propertyRange && propertyRange.start <= commentRange.start && propertyRange.end >= commentRange.end);
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
function sortRenderedProperties(renderedProperties, fieldIndexes, lastFieldIndexes) {
|
|
1344
|
+
return [...renderedProperties].sort((left, right) => {
|
|
1345
|
+
const leftFieldIndex = fieldIndexes.get(left.name);
|
|
1346
|
+
const rightFieldIndex = fieldIndexes.get(right.name);
|
|
1347
|
+
if (leftFieldIndex !== undefined && rightFieldIndex !== undefined) {
|
|
1348
|
+
return leftFieldIndex - rightFieldIndex;
|
|
1349
|
+
}
|
|
1350
|
+
if (leftFieldIndex !== undefined) {
|
|
1351
|
+
return -1;
|
|
1352
|
+
}
|
|
1353
|
+
if (rightFieldIndex !== undefined) {
|
|
1354
|
+
return 1;
|
|
1355
|
+
}
|
|
1356
|
+
const leftLastFieldIndex = lastFieldIndexes?.get(left.name);
|
|
1357
|
+
const rightLastFieldIndex = lastFieldIndexes?.get(right.name);
|
|
1358
|
+
if (leftLastFieldIndex !== undefined && rightLastFieldIndex !== undefined) {
|
|
1359
|
+
return leftLastFieldIndex - rightLastFieldIndex;
|
|
1360
|
+
}
|
|
1361
|
+
if (leftLastFieldIndex !== undefined) {
|
|
1362
|
+
return 1;
|
|
1363
|
+
}
|
|
1364
|
+
if (rightLastFieldIndex !== undefined) {
|
|
1365
|
+
return -1;
|
|
1366
|
+
}
|
|
1367
|
+
return left.originalIndex - right.originalIndex;
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
function getPropertySeparator(property, shouldSeparateCategories, previousProperty) {
|
|
1371
|
+
if (!previousProperty) {
|
|
1372
|
+
return "";
|
|
1373
|
+
}
|
|
1374
|
+
if (!shouldSeparateCategories) {
|
|
1375
|
+
return ",";
|
|
1376
|
+
}
|
|
1377
|
+
const previousGroupIndex = COMPILER_OPTION_FIELD_GROUP_INDEXES.get(previousProperty.name);
|
|
1378
|
+
const groupIndex = COMPILER_OPTION_FIELD_GROUP_INDEXES.get(property.name);
|
|
1379
|
+
return previousGroupIndex !== undefined && groupIndex !== undefined && previousGroupIndex !== groupIndex ? `,
|
|
1380
|
+
|
|
1381
|
+
` : ",";
|
|
1382
|
+
}
|
|
1383
|
+
function renderProperty(sourceText, propertyNode, originalIndex, replacementText) {
|
|
1384
|
+
const propertyName = getAstNodeName(propertyNode.key);
|
|
1385
|
+
const propertyRange = getAstNodeTextRange(propertyNode);
|
|
1386
|
+
const propertyValue = propertyNode.value;
|
|
1387
|
+
if (propertyNode.type !== "ObjectProperty" || propertyName === null || !propertyRange || !isParserAstNode(propertyValue)) {
|
|
1388
|
+
return null;
|
|
1389
|
+
}
|
|
1390
|
+
return {
|
|
1391
|
+
name: propertyName,
|
|
1392
|
+
originalIndex,
|
|
1393
|
+
sourceText: replacementText ?? sourceText.slice(propertyRange.start, propertyRange.end)
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
function replacePropertyValue(sourceText, propertyNode, valueNode, replacementText) {
|
|
1397
|
+
const propertyRange = getAstNodeTextRange(propertyNode);
|
|
1398
|
+
const valueRange = getAstNodeTextRange(valueNode);
|
|
1399
|
+
if (!propertyRange || !valueRange || valueRange.start < propertyRange.start || valueRange.end > propertyRange.end) {
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1402
|
+
return sourceText.slice(propertyRange.start, valueRange.start) + replacementText + sourceText.slice(valueRange.end, propertyRange.end);
|
|
1403
|
+
}
|
|
1404
|
+
function renderObject(sourceText, objectNode, sortedComments, fieldIndexes, shouldSeparateCategories, propertyReplacements, lastFieldIndexes) {
|
|
1405
|
+
const objectRange = getAstNodeTextRange(objectNode);
|
|
1406
|
+
const propertyNodes = objectNode.properties;
|
|
1407
|
+
if (objectNode.type !== "ObjectExpression" || !objectRange || !Array.isArray(propertyNodes)) {
|
|
1408
|
+
return null;
|
|
1409
|
+
}
|
|
1410
|
+
const objectSource = sourceText.slice(objectRange.start, objectRange.end);
|
|
1411
|
+
if (propertyNodes.length === 0) {
|
|
1412
|
+
return { hasOrderChanged: false, sourceText: objectSource };
|
|
1413
|
+
}
|
|
1414
|
+
if (hasDirectComments(objectNode, propertyNodes, sortedComments)) {
|
|
1415
|
+
return null;
|
|
1416
|
+
}
|
|
1417
|
+
const propertyNames = new Set;
|
|
1418
|
+
const renderedProperties = [];
|
|
1419
|
+
for (const [propertyIndex, propertyNode] of propertyNodes.entries()) {
|
|
1420
|
+
const renderedProperty = renderProperty(sourceText, propertyNode, propertyIndex, propertyReplacements?.get(propertyNode));
|
|
1421
|
+
if (!renderedProperty || propertyNames.has(renderedProperty.name)) {
|
|
1422
|
+
return null;
|
|
1423
|
+
}
|
|
1424
|
+
propertyNames.add(renderedProperty.name);
|
|
1425
|
+
renderedProperties.push(renderedProperty);
|
|
1426
|
+
}
|
|
1427
|
+
const sortedProperties = sortRenderedProperties(renderedProperties, fieldIndexes, lastFieldIndexes);
|
|
1428
|
+
const hasOrderChanged = sortedProperties.some((renderedProperty, propertyIndex) => renderedProperty.originalIndex !== propertyIndex);
|
|
1429
|
+
return {
|
|
1430
|
+
hasOrderChanged,
|
|
1431
|
+
sourceText: `{${sortedProperties.map((renderedProperty, propertyIndex) => getPropertySeparator(renderedProperty, shouldSeparateCategories, sortedProperties[propertyIndex - 1]) + renderedProperty.sourceText).join("")}}`
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
function isTsconfigFile(filePath) {
|
|
1435
|
+
const fileName = filePath?.split(/[\\/]/).at(-1);
|
|
1436
|
+
return fileName ? /^tsconfig(?:\..+)?\.json$/.test(fileName) : false;
|
|
1437
|
+
}
|
|
1438
|
+
async function preprocessTsconfig(sourceText, prettierOptions, parser) {
|
|
1439
|
+
if (!isTsconfigFile(prettierOptions.filepath)) {
|
|
1440
|
+
return sourceText;
|
|
1441
|
+
}
|
|
1442
|
+
const { tsconfigSeparation, tsconfigSort } = resolveTsconfigOptions(prettierOptions);
|
|
1443
|
+
if (!tsconfigSort) {
|
|
1444
|
+
return sourceText;
|
|
1445
|
+
}
|
|
1446
|
+
try {
|
|
1447
|
+
const parserAst = await parser.parse(sourceText, prettierOptions);
|
|
1448
|
+
if (!isParserAstNode(parserAst)) {
|
|
1449
|
+
return sourceText;
|
|
1450
|
+
}
|
|
1451
|
+
const rootNode = getTsconfigRootNode(parserAst);
|
|
1452
|
+
if (!rootNode) {
|
|
1453
|
+
return sourceText;
|
|
1454
|
+
}
|
|
1455
|
+
const sortedComments = getSortedAstCommentsWithTextRanges(getProgramComments(parserAst));
|
|
1456
|
+
const rootRange = getAstNodeTextRange(rootNode);
|
|
1457
|
+
if (!rootRange || isPrettierIgnored(sourceText, rootRange, sortedComments)) {
|
|
1458
|
+
return sourceText;
|
|
1459
|
+
}
|
|
1460
|
+
let compilerOptionsEdit;
|
|
1461
|
+
let propertyReplacements;
|
|
1462
|
+
const compilerOptions = getCompilerOptionsNode(rootNode);
|
|
1463
|
+
if (compilerOptions) {
|
|
1464
|
+
const propertyRange = getAstNodeTextRange(compilerOptions.property);
|
|
1465
|
+
const valueRange = getAstNodeTextRange(compilerOptions.value);
|
|
1466
|
+
if (propertyRange && valueRange && !isPrettierIgnored(sourceText, propertyRange, sortedComments)) {
|
|
1467
|
+
const renderedCompilerOptions = renderObject(sourceText, compilerOptions.value, sortedComments, COMPILER_OPTION_FIELD_INDEXES, tsconfigSeparation);
|
|
1468
|
+
const renderedProperty = renderedCompilerOptions ? replacePropertyValue(sourceText, compilerOptions.property, compilerOptions.value, renderedCompilerOptions.sourceText) : null;
|
|
1469
|
+
if (renderedCompilerOptions && renderedProperty) {
|
|
1470
|
+
compilerOptionsEdit = {
|
|
1471
|
+
start: valueRange.start,
|
|
1472
|
+
end: valueRange.end,
|
|
1473
|
+
replacementText: renderedCompilerOptions.sourceText
|
|
1474
|
+
};
|
|
1475
|
+
propertyReplacements = new Map([
|
|
1476
|
+
[compilerOptions.property, renderedProperty]
|
|
1477
|
+
]);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
const renderedRoot = renderObject(sourceText, rootNode, sortedComments, ROOT_FIRST_FIELD_INDEXES, false, propertyReplacements, ROOT_LAST_FIELD_INDEXES);
|
|
1482
|
+
const sourceTextEdits = [];
|
|
1483
|
+
if (renderedRoot && (renderedRoot.hasOrderChanged || propertyReplacements)) {
|
|
1484
|
+
sourceTextEdits.push({
|
|
1485
|
+
start: rootRange.start,
|
|
1486
|
+
end: rootRange.end,
|
|
1487
|
+
replacementText: renderedRoot.sourceText
|
|
1488
|
+
});
|
|
1489
|
+
} else if (compilerOptionsEdit) {
|
|
1490
|
+
sourceTextEdits.push(compilerOptionsEdit);
|
|
1491
|
+
}
|
|
1492
|
+
if (sourceTextEdits.length === 0) {
|
|
1493
|
+
return sourceText;
|
|
1494
|
+
}
|
|
1495
|
+
const editedSourceText = applySourceTextEdits(sourceText, sourceTextEdits);
|
|
1496
|
+
if (editedSourceText === null) {
|
|
1497
|
+
return sourceText;
|
|
1498
|
+
}
|
|
1499
|
+
await parser.parse(editedSourceText, prettierOptions);
|
|
1500
|
+
return editedSourceText;
|
|
1501
|
+
} catch {
|
|
1502
|
+
return sourceText;
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1101
1506
|
// src/sort-exports.ts
|
|
1102
1507
|
function buildExportSortingEdits(sourceText, programStatements, sortedComments) {
|
|
1103
1508
|
const sortingEdits = [];
|
|
@@ -1162,28 +1567,6 @@ function buildExportSortingEdits(sourceText, programStatements, sortedComments)
|
|
|
1162
1567
|
return sortingEdits;
|
|
1163
1568
|
}
|
|
1164
1569
|
|
|
1165
|
-
// src/utils/source-text.ts
|
|
1166
|
-
function applySourceTextEdits(sourceText, sourceTextEdits) {
|
|
1167
|
-
if (sourceTextEdits.length === 0) {
|
|
1168
|
-
return sourceText;
|
|
1169
|
-
}
|
|
1170
|
-
let previousEditEnd = 0;
|
|
1171
|
-
const ascendingEdits = [...sourceTextEdits].sort((left, right) => left.start - right.start || left.end - right.end);
|
|
1172
|
-
for (const sourceTextEdit of ascendingEdits) {
|
|
1173
|
-
const { start, end } = sourceTextEdit;
|
|
1174
|
-
const isSourceTextEditValid = [start, end].every(Number.isSafeInteger) && start >= previousEditEnd && end >= start && end <= sourceText.length;
|
|
1175
|
-
if (!isSourceTextEditValid) {
|
|
1176
|
-
return null;
|
|
1177
|
-
}
|
|
1178
|
-
previousEditEnd = end;
|
|
1179
|
-
}
|
|
1180
|
-
let editedText = sourceText;
|
|
1181
|
-
for (const sourceTextEdit of ascendingEdits.reverse()) {
|
|
1182
|
-
editedText = editedText.slice(0, sourceTextEdit.start) + sourceTextEdit.replacementText + editedText.slice(sourceTextEdit.end);
|
|
1183
|
-
}
|
|
1184
|
-
return editedText;
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
1570
|
// src/sort-imports.ts
|
|
1188
1571
|
var INDEX_MODULE_PATTERN = /^\.\/index(?:\.[^/]+)*$/;
|
|
1189
1572
|
var PRETTIER_FILE_PRAGMA_DIRECTIVES = ["@format", "@prettier"];
|
|
@@ -1266,7 +1649,19 @@ function getPrettierFilePragmaComment(sortedComments, isPrettierFilePragmaPresen
|
|
|
1266
1649
|
}
|
|
1267
1650
|
return sortedComments.find(({ comment }) => getCommentLines(comment).some((commentLine) => hasCommentDirective(commentLine.trim(), PRETTIER_FILE_PRAGMA_DIRECTIVES)))?.comment ?? null;
|
|
1268
1651
|
}
|
|
1269
|
-
function
|
|
1652
|
+
function matchesPathPattern(moduleSpecifier, pathPattern) {
|
|
1653
|
+
const wildcardIndex = pathPattern.indexOf("*");
|
|
1654
|
+
if (wildcardIndex < 0) {
|
|
1655
|
+
return moduleSpecifier === pathPattern;
|
|
1656
|
+
}
|
|
1657
|
+
if (pathPattern === "*" || wildcardIndex !== pathPattern.lastIndexOf("*")) {
|
|
1658
|
+
return false;
|
|
1659
|
+
}
|
|
1660
|
+
const prefix = pathPattern.slice(0, wildcardIndex);
|
|
1661
|
+
const suffix = pathPattern.slice(wildcardIndex + 1);
|
|
1662
|
+
return moduleSpecifier.length >= prefix.length + suffix.length && moduleSpecifier.startsWith(prefix) && moduleSpecifier.endsWith(suffix);
|
|
1663
|
+
}
|
|
1664
|
+
function classifyImportGroup(moduleSpecifier, pathPatterns) {
|
|
1270
1665
|
if (moduleSpecifier === "bun" || moduleSpecifier.startsWith("bun:") || moduleSpecifier.startsWith("node:")) {
|
|
1271
1666
|
return "builtin";
|
|
1272
1667
|
}
|
|
@@ -1279,7 +1674,7 @@ function classifyImportGroup(moduleSpecifier) {
|
|
|
1279
1674
|
if (moduleSpecifier.startsWith("./")) {
|
|
1280
1675
|
return "sibling";
|
|
1281
1676
|
}
|
|
1282
|
-
if (
|
|
1677
|
+
if (pathPatterns.some((pathPattern) => matchesPathPattern(moduleSpecifier, pathPattern))) {
|
|
1283
1678
|
return "internal";
|
|
1284
1679
|
}
|
|
1285
1680
|
return "external";
|
|
@@ -1532,19 +1927,6 @@ function getLocalBindingNames(importDeclaration) {
|
|
|
1532
1927
|
}
|
|
1533
1928
|
return localBindingNames;
|
|
1534
1929
|
}
|
|
1535
|
-
function normalizeNamedTypeOnlyImport(importDeclaration) {
|
|
1536
|
-
if (!importDeclaration.isTypeOnly || !importDeclaration.namedSpecifiers || importDeclaration.defaultBinding || importDeclaration.namespaceBinding || importDeclaration.verbatimDeclaration !== null) {
|
|
1537
|
-
return importDeclaration;
|
|
1538
|
-
}
|
|
1539
|
-
return {
|
|
1540
|
-
...importDeclaration,
|
|
1541
|
-
isTypeOnly: false,
|
|
1542
|
-
namedSpecifiers: importDeclaration.namedSpecifiers.map((importSpecifier) => ({
|
|
1543
|
-
...importSpecifier,
|
|
1544
|
-
isTypeOnly: true
|
|
1545
|
-
}))
|
|
1546
|
-
};
|
|
1547
|
-
}
|
|
1548
1930
|
function getImportRequestKey(importDeclaration) {
|
|
1549
1931
|
return `${importDeclaration.moduleSpecifier}\x00${importDeclaration.importAttributes ?? ""}`;
|
|
1550
1932
|
}
|
|
@@ -1564,9 +1946,10 @@ function isImportDeclarationMergeSafe(targetImportDeclaration, candidateImportDe
|
|
|
1564
1946
|
}
|
|
1565
1947
|
function mergeImportDeclarations(targetImportDeclaration, candidateImportDeclaration) {
|
|
1566
1948
|
let namedSpecifiers = null;
|
|
1949
|
+
const isTypeOnly = targetImportDeclaration.isTypeOnly && candidateImportDeclaration.isTypeOnly;
|
|
1567
1950
|
const mergedNamedSpecifiers = [
|
|
1568
|
-
...targetImportDeclaration
|
|
1569
|
-
...candidateImportDeclaration
|
|
1951
|
+
...getNamedSpecifiersForMerge(targetImportDeclaration, isTypeOnly),
|
|
1952
|
+
...getNamedSpecifiersForMerge(candidateImportDeclaration, isTypeOnly)
|
|
1570
1953
|
];
|
|
1571
1954
|
if (mergedNamedSpecifiers.length > 0) {
|
|
1572
1955
|
namedSpecifiers = mergedNamedSpecifiers;
|
|
@@ -1574,7 +1957,7 @@ function mergeImportDeclarations(targetImportDeclaration, candidateImportDeclara
|
|
|
1574
1957
|
return {
|
|
1575
1958
|
moduleSpecifier: targetImportDeclaration.moduleSpecifier,
|
|
1576
1959
|
moduleSpecifierText: targetImportDeclaration.moduleSpecifierText,
|
|
1577
|
-
isTypeOnly
|
|
1960
|
+
isTypeOnly,
|
|
1578
1961
|
isSideEffectOnly: false,
|
|
1579
1962
|
defaultBinding: targetImportDeclaration.defaultBinding ?? candidateImportDeclaration.defaultBinding,
|
|
1580
1963
|
namespaceBinding: targetImportDeclaration.namespaceBinding ?? candidateImportDeclaration.namespaceBinding,
|
|
@@ -1586,6 +1969,12 @@ function mergeImportDeclarations(targetImportDeclaration, candidateImportDeclara
|
|
|
1586
1969
|
isMergeBoundary: false
|
|
1587
1970
|
};
|
|
1588
1971
|
}
|
|
1972
|
+
function getNamedSpecifiersForMerge(importDeclaration, isMergedTypeOnly) {
|
|
1973
|
+
return (importDeclaration.namedSpecifiers ?? []).map((importSpecifier) => ({
|
|
1974
|
+
...importSpecifier,
|
|
1975
|
+
isTypeOnly: !isMergedTypeOnly && (importDeclaration.isTypeOnly || importSpecifier.isTypeOnly)
|
|
1976
|
+
}));
|
|
1977
|
+
}
|
|
1589
1978
|
function mergeCompatibleImports(importDeclarations) {
|
|
1590
1979
|
const bindingCountsByImportDeclaration = new Map;
|
|
1591
1980
|
const currentBindingCountsByRequest = new Map;
|
|
@@ -1613,10 +2002,9 @@ function mergeCompatibleImports(importDeclarations) {
|
|
|
1613
2002
|
bindingCountsByImportDeclaration.set(importDeclaration, bindingCounts);
|
|
1614
2003
|
}
|
|
1615
2004
|
const mergedImportDeclarations = [];
|
|
1616
|
-
for (const
|
|
1617
|
-
const importDeclaration = normalizeNamedTypeOnlyImport(originalImportDeclaration);
|
|
2005
|
+
for (const importDeclaration of importDeclarations) {
|
|
1618
2006
|
const importRequestKey = getImportRequestKey(importDeclaration);
|
|
1619
|
-
const bindingCounts = bindingCountsByImportDeclaration.get(
|
|
2007
|
+
const bindingCounts = bindingCountsByImportDeclaration.get(importDeclaration) ?? {
|
|
1620
2008
|
defaultBindingCount: 0,
|
|
1621
2009
|
namespaceBindingCount: 0
|
|
1622
2010
|
};
|
|
@@ -1638,18 +2026,19 @@ function applyTypeImportStyle(importDeclaration, typeImportStyle) {
|
|
|
1638
2026
|
return [importDeclaration];
|
|
1639
2027
|
}
|
|
1640
2028
|
const namedSpecifiers = importDeclaration.namedSpecifiers;
|
|
2029
|
+
if (importDeclaration.isTypeOnly) {
|
|
2030
|
+
return [
|
|
2031
|
+
{
|
|
2032
|
+
...importDeclaration,
|
|
2033
|
+
namedSpecifiers: sortNamedImportSpecifiers(namedSpecifiers)
|
|
2034
|
+
}
|
|
2035
|
+
];
|
|
2036
|
+
}
|
|
1641
2037
|
if (typeImportStyle === "separate") {
|
|
1642
|
-
if (importDeclaration.isTypeOnly) {
|
|
1643
|
-
return [
|
|
1644
|
-
{
|
|
1645
|
-
...importDeclaration,
|
|
1646
|
-
namedSpecifiers: sortNamedImportSpecifiers(namedSpecifiers)
|
|
1647
|
-
}
|
|
1648
|
-
];
|
|
1649
|
-
}
|
|
1650
2038
|
const typeSpecifiers2 = namedSpecifiers.filter((importSpecifier) => importSpecifier.isTypeOnly);
|
|
1651
2039
|
const valueSpecifiers2 = namedSpecifiers.filter((importSpecifier) => !importSpecifier.isTypeOnly);
|
|
1652
|
-
|
|
2040
|
+
const hasValueBinding = valueSpecifiers2.length > 0 || importDeclaration.defaultBinding !== null || importDeclaration.namespaceBinding !== null;
|
|
2041
|
+
if (typeSpecifiers2.length > 0 && (!hasValueBinding || importDeclaration.importAttributes !== null || importDeclaration.leadingCommentsText.trim() !== "" || importDeclaration.trailingCommentsText !== "")) {
|
|
1653
2042
|
return [
|
|
1654
2043
|
{
|
|
1655
2044
|
...importDeclaration,
|
|
@@ -1687,32 +2076,21 @@ function applyTypeImportStyle(importDeclaration, typeImportStyle) {
|
|
|
1687
2076
|
}
|
|
1688
2077
|
return styledImportDeclarations;
|
|
1689
2078
|
}
|
|
1690
|
-
let inlineImportDeclaration = { ...importDeclaration, namedSpecifiers };
|
|
1691
|
-
if (importDeclaration.isTypeOnly) {
|
|
1692
|
-
inlineImportDeclaration = {
|
|
1693
|
-
...importDeclaration,
|
|
1694
|
-
isTypeOnly: false,
|
|
1695
|
-
namedSpecifiers: namedSpecifiers.map((importSpecifier) => ({
|
|
1696
|
-
...importSpecifier,
|
|
1697
|
-
isTypeOnly: true
|
|
1698
|
-
}))
|
|
1699
|
-
};
|
|
1700
|
-
}
|
|
1701
2079
|
if (typeImportStyle === "mixed") {
|
|
1702
2080
|
return [
|
|
1703
2081
|
{
|
|
1704
|
-
...
|
|
1705
|
-
namedSpecifiers: sortNamedImportSpecifiers(
|
|
2082
|
+
...importDeclaration,
|
|
2083
|
+
namedSpecifiers: sortNamedImportSpecifiers(namedSpecifiers)
|
|
1706
2084
|
}
|
|
1707
2085
|
];
|
|
1708
2086
|
}
|
|
1709
|
-
const typeSpecifiers = sortNamedImportSpecifiers(
|
|
1710
|
-
const valueSpecifiers = sortNamedImportSpecifiers(
|
|
2087
|
+
const typeSpecifiers = sortNamedImportSpecifiers(namedSpecifiers.filter((importSpecifier) => importSpecifier.isTypeOnly));
|
|
2088
|
+
const valueSpecifiers = sortNamedImportSpecifiers(namedSpecifiers.filter((importSpecifier) => !importSpecifier.isTypeOnly));
|
|
1711
2089
|
let orderedSpecifiers = [...valueSpecifiers, ...typeSpecifiers];
|
|
1712
2090
|
if (typeImportStyle === "inline-first") {
|
|
1713
2091
|
orderedSpecifiers = [...typeSpecifiers, ...valueSpecifiers];
|
|
1714
2092
|
}
|
|
1715
|
-
return [{ ...
|
|
2093
|
+
return [{ ...importDeclaration, namedSpecifiers: orderedSpecifiers }];
|
|
1716
2094
|
}
|
|
1717
2095
|
function getImportBindingShapeRank(importDeclaration) {
|
|
1718
2096
|
if (importDeclaration.defaultBinding !== null) {
|
|
@@ -1723,7 +2101,7 @@ function getImportBindingShapeRank(importDeclaration) {
|
|
|
1723
2101
|
}
|
|
1724
2102
|
return 2;
|
|
1725
2103
|
}
|
|
1726
|
-
function
|
|
2104
|
+
function renderSortedImportSegment(importDeclarations, sortOptions, pathPatterns, importGroupOrder) {
|
|
1727
2105
|
let mergedImportDeclarations = [...importDeclarations];
|
|
1728
2106
|
if (sortOptions.esmImportMerge) {
|
|
1729
2107
|
mergedImportDeclarations = mergeCompatibleImports(importDeclarations);
|
|
@@ -1732,7 +2110,7 @@ function sortImportSegment(importDeclarations, sortOptions, importGroupOrder) {
|
|
|
1732
2110
|
const unlistedGroupRank = sortOptions.esmImportGroups.length;
|
|
1733
2111
|
const rankedImportDeclarations = styledImportDeclarations.map((importDeclaration, originalIndex) => ({
|
|
1734
2112
|
importDeclaration,
|
|
1735
|
-
importGroup: classifyImportGroup(importDeclaration.moduleSpecifier),
|
|
2113
|
+
importGroup: classifyImportGroup(importDeclaration.moduleSpecifier, pathPatterns),
|
|
1736
2114
|
originalIndex
|
|
1737
2115
|
}));
|
|
1738
2116
|
rankedImportDeclarations.sort((left, right) => {
|
|
@@ -1753,17 +2131,17 @@ function sortImportSegment(importDeclarations, sortOptions, importGroupOrder) {
|
|
|
1753
2131
|
return getImportBindingShapeRank(left.importDeclaration) - getImportBindingShapeRank(right.importDeclaration) || left.originalIndex - right.originalIndex;
|
|
1754
2132
|
});
|
|
1755
2133
|
let previousImportGroup = null;
|
|
1756
|
-
const
|
|
2134
|
+
const renderedImports = [];
|
|
1757
2135
|
for (const { importDeclaration, importGroup } of rankedImportDeclarations) {
|
|
1758
2136
|
if (sortOptions.esmImportSeparation && previousImportGroup !== null && importGroup !== previousImportGroup) {
|
|
1759
|
-
|
|
2137
|
+
renderedImports.push("");
|
|
1760
2138
|
}
|
|
1761
|
-
|
|
2139
|
+
renderedImports.push(renderImportDeclaration(importDeclaration));
|
|
1762
2140
|
previousImportGroup = importGroup;
|
|
1763
2141
|
}
|
|
1764
|
-
return
|
|
2142
|
+
return renderedImports;
|
|
1765
2143
|
}
|
|
1766
|
-
function
|
|
2144
|
+
function renderSortedImports(importDeclarations, sortOptions, pathPatterns) {
|
|
1767
2145
|
let currentSortableImportDeclarations = [];
|
|
1768
2146
|
const importGroupOrder = new Map(sortOptions.esmImportGroups.map((importGroup, groupIndex) => [
|
|
1769
2147
|
importGroup,
|
|
@@ -1791,19 +2169,19 @@ function renderSortedImportLines(importDeclarations, sortOptions) {
|
|
|
1791
2169
|
});
|
|
1792
2170
|
}
|
|
1793
2171
|
let previousChunkKind = null;
|
|
1794
|
-
const
|
|
2172
|
+
const renderedImports = [];
|
|
1795
2173
|
for (const importChunk of importDeclarationChunks) {
|
|
1796
2174
|
if (sortOptions.esmImportSeparation && previousChunkKind !== null && previousChunkKind !== importChunk.kind) {
|
|
1797
|
-
|
|
2175
|
+
renderedImports.push("");
|
|
1798
2176
|
}
|
|
1799
2177
|
if (importChunk.kind === "sortable") {
|
|
1800
|
-
|
|
2178
|
+
renderedImports.push(...renderSortedImportSegment(importChunk.importDeclarations, sortOptions, pathPatterns, importGroupOrder));
|
|
1801
2179
|
} else {
|
|
1802
|
-
|
|
2180
|
+
renderedImports.push(renderImportDeclaration(importChunk.importDeclaration));
|
|
1803
2181
|
}
|
|
1804
2182
|
previousChunkKind = importChunk.kind;
|
|
1805
2183
|
}
|
|
1806
|
-
return
|
|
2184
|
+
return renderedImports;
|
|
1807
2185
|
}
|
|
1808
2186
|
function isCommentPresentWithinRange(sortedComments, start, end) {
|
|
1809
2187
|
const firstCommentIndex = findCommentIndexAtOrAfter(sortedComments, start);
|
|
@@ -1822,13 +2200,13 @@ function hasPositionSensitiveEslintCommentWithinRange(sourceText, sortedComments
|
|
|
1822
2200
|
}
|
|
1823
2201
|
return false;
|
|
1824
2202
|
}
|
|
1825
|
-
function buildImportSegmentEdits(sourceText, importEntries, sortOptions, lineEnding, isBlankLineRequired) {
|
|
2203
|
+
function buildImportSegmentEdits(sourceText, importEntries, sortOptions, pathPatterns, lineEnding, isBlankLineRequired) {
|
|
1826
2204
|
const [firstImportEntry] = importEntries;
|
|
1827
2205
|
if (!firstImportEntry) {
|
|
1828
2206
|
return null;
|
|
1829
2207
|
}
|
|
1830
2208
|
let trailingLineBreaks = lineEnding;
|
|
1831
|
-
const replacementText =
|
|
2209
|
+
const replacementText = renderSortedImports(importEntries.map((importEntry) => importEntry.parsedImportDeclaration), sortOptions, pathPatterns).join(lineEnding);
|
|
1832
2210
|
const removalEdits = importEntries.slice(1).map((importEntry) => ({
|
|
1833
2211
|
start: importEntry.start,
|
|
1834
2212
|
end: importEntry.end,
|
|
@@ -1853,7 +2231,7 @@ function buildImportSegmentEdits(sourceText, importEntries, sortOptions, lineEnd
|
|
|
1853
2231
|
...removalEdits
|
|
1854
2232
|
];
|
|
1855
2233
|
}
|
|
1856
|
-
function buildImportSortingEdits(sourceText, programStatements, sortedComments, sortOptions, isPrettierFilePragmaPresent) {
|
|
2234
|
+
function buildImportSortingEdits(sourceText, programStatements, sortedComments, sortOptions, pathPatterns, isPrettierFilePragmaPresent) {
|
|
1857
2235
|
const importDeclarationNodes = programStatements.filter((statement) => statement.type === "ImportDeclaration");
|
|
1858
2236
|
if (importDeclarationNodes.length === 0) {
|
|
1859
2237
|
return [];
|
|
@@ -1919,7 +2297,7 @@ function buildImportSortingEdits(sourceText, programStatements, sortedComments,
|
|
|
1919
2297
|
const lastImportDeclarationNode = importDeclarationNodes.at(-1);
|
|
1920
2298
|
for (const sortableSegment of sortableSegments) {
|
|
1921
2299
|
const isLastImportSegment = sortableSegment.at(-1)?.importDeclarationNode === lastImportDeclarationNode;
|
|
1922
|
-
const importSegmentEdits = buildImportSegmentEdits(sourceText, sortableSegment, sortOptions, lineEnding, isLastImportSegment);
|
|
2300
|
+
const importSegmentEdits = buildImportSegmentEdits(sourceText, sortableSegment, sortOptions, pathPatterns, lineEnding, isLastImportSegment);
|
|
1923
2301
|
if (importSegmentEdits === null) {
|
|
1924
2302
|
return [];
|
|
1925
2303
|
}
|
|
@@ -1929,8 +2307,20 @@ function buildImportSortingEdits(sourceText, programStatements, sortedComments,
|
|
|
1929
2307
|
}
|
|
1930
2308
|
|
|
1931
2309
|
// src/sort-typescript.ts
|
|
2310
|
+
async function getTsconfigPathPatterns(filePath) {
|
|
2311
|
+
if (!filePath) {
|
|
2312
|
+
return [];
|
|
2313
|
+
}
|
|
2314
|
+
try {
|
|
2315
|
+
const { getTsconfig } = await import("get-tsconfig");
|
|
2316
|
+
const paths = getTsconfig(filePath)?.config.compilerOptions?.paths;
|
|
2317
|
+
return paths ? Object.keys(paths) : [];
|
|
2318
|
+
} catch {
|
|
2319
|
+
return [];
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
1932
2322
|
async function sortTypeScript(sourceText, prettierOptions, parser) {
|
|
1933
|
-
const sortOptions =
|
|
2323
|
+
const sortOptions = resolveEsmOptions(prettierOptions);
|
|
1934
2324
|
if (!sortOptions.esmImportSort && !sortOptions.esmExportSpecifierSort) {
|
|
1935
2325
|
return sourceText;
|
|
1936
2326
|
}
|
|
@@ -1945,7 +2335,8 @@ async function sortTypeScript(sourceText, prettierOptions, parser) {
|
|
|
1945
2335
|
const sortingEdits = [];
|
|
1946
2336
|
if (sortOptions.esmImportSort) {
|
|
1947
2337
|
const isPrettierFilePragmaPresent = parser.hasPragma?.(sourceText) ?? false;
|
|
1948
|
-
|
|
2338
|
+
const pathPatterns = programStatements.some((statement) => statement.type === "ImportDeclaration") ? await getTsconfigPathPatterns(prettierOptions.filepath) : [];
|
|
2339
|
+
sortingEdits.push(...buildImportSortingEdits(sourceText, programStatements, sortedComments, sortOptions, pathPatterns, isPrettierFilePragmaPresent));
|
|
1949
2340
|
}
|
|
1950
2341
|
if (sortOptions.esmExportSpecifierSort) {
|
|
1951
2342
|
sortingEdits.push(...buildExportSortingEdits(sourceText, programStatements, sortedComments));
|
|
@@ -1975,6 +2366,10 @@ function wrapParserPreprocess(parser, preprocessTransform) {
|
|
|
1975
2366
|
}
|
|
1976
2367
|
};
|
|
1977
2368
|
}
|
|
2369
|
+
async function preprocessJson(sourceText, prettierOptions, parser) {
|
|
2370
|
+
const packagePreprocessedText = await preprocessPackageJson(sourceText, prettierOptions, parser);
|
|
2371
|
+
return preprocessTsconfig(packagePreprocessedText, prettierOptions, parser);
|
|
2372
|
+
}
|
|
1978
2373
|
var sortPlugin = {
|
|
1979
2374
|
options,
|
|
1980
2375
|
parsers: {
|
|
@@ -1984,7 +2379,7 @@ var sortPlugin = {
|
|
|
1984
2379
|
"babel-ts": wrapParserPreprocess(babelPlugin.parsers["babel-ts"], sortTypeScript),
|
|
1985
2380
|
espree: wrapParserPreprocess(acornPlugin.parsers.espree, sortTypeScript),
|
|
1986
2381
|
flow: wrapParserPreprocess(flowPlugin.parsers.flow, sortTypeScript),
|
|
1987
|
-
json: wrapParserPreprocess(babelPlugin.parsers.json,
|
|
2382
|
+
json: wrapParserPreprocess(babelPlugin.parsers.json, preprocessJson),
|
|
1988
2383
|
"json-stringify": wrapParserPreprocess(babelPlugin.parsers["json-stringify"], preprocessPackageJson),
|
|
1989
2384
|
meriyah: wrapParserPreprocess(meriyahPlugin.parsers.meriyah, sortTypeScript),
|
|
1990
2385
|
typescript: wrapParserPreprocess(typescriptPlugin.parsers.typescript, sortTypeScript)
|