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/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: ["builtin", "external", "parent", "sibling", "index"],
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 resolveSortOptions(prettierOptions) {
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
- packageSort: resolveBooleanSortOption(prettierOptions, "packageSort")
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 package.json fields using the sort-package-json community convention."
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
- function compareText(leftText, rightText) {
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 (!isParserJsonAstNode(rootNode)) {
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) || !isParserJsonAstNode(propertyValueNode)) {
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 = compareText) {
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 compareText(leftKey, rightKey);
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) => compareText(getJsonString(leftValue), getJsonString(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 = fieldOrderIndexes.get(leftFieldName);
682
- const rightIndex = fieldOrderIndexes.get(rightFieldName);
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 compareText(leftFieldName, rightFieldName);
737
+ return compareStringsCaseSensitive(leftFieldName, rightFieldName);
700
738
  });
701
739
  }
702
- function isNpmDependencyOrderPreferred(packageJson) {
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, packageJson) {
727
- return sortJsonObjectValue(fieldValue, (dependencyObject) => sortDependencyObject(dependencyObject, packageJson));
743
+ function sortDependencyValue(fieldValue) {
744
+ return sortJsonObjectValue(fieldValue, sortDependencyObject);
728
745
  }
729
- function sortWorkspacesValue(fieldValue, packageJson) {
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, packageJson);
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(compareText);
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(compareText).flatMap((scriptGroupName) => {
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(compareText);
872
+ return groupedScriptNames.sort(compareStringsCaseSensitive);
856
873
  }
857
- const directScriptNames = groupedScriptNames.filter((scriptName) => scriptName === scriptGroupName || !scriptName.startsWith(`${scriptGroupName}:`)).sort(compareText);
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 [nameAndVersion = packageSelector] = packageSelector.split(">");
916
- const versionSeparatorIndex = nameAndVersion.lastIndexOf("@");
917
- if (versionSeparatorIndex <= 0) {
918
- return { name: packageSelector, versionRange: null };
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 compareText(leftPackage.versionRange, rightPackage.versionRange);
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) => compareText(getDependencyName(leftIdentifier), getDependencyName(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) || !resolveSortOptions(prettierOptions).packageSort) {
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 (!isParserJsonAstNode(parserJsonAst)) {
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 classifyImportGroup(moduleSpecifier) {
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 (moduleSpecifier.startsWith("/") || moduleSpecifier.startsWith("~") || moduleSpecifier.startsWith("@/") || moduleSpecifier.startsWith("#")) {
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.namedSpecifiers ?? [],
1569
- ...candidateImportDeclaration.namedSpecifiers ?? []
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: false,
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 originalImportDeclaration of importDeclarations) {
1617
- const importDeclaration = normalizeNamedTypeOnlyImport(originalImportDeclaration);
2005
+ for (const importDeclaration of importDeclarations) {
1618
2006
  const importRequestKey = getImportRequestKey(importDeclaration);
1619
- const bindingCounts = bindingCountsByImportDeclaration.get(originalImportDeclaration) ?? {
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
- if (typeSpecifiers2.length > 0 && (importDeclaration.importAttributes !== null || importDeclaration.leadingCommentsText.trim() !== "" || importDeclaration.trailingCommentsText !== "")) {
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
- ...inlineImportDeclaration,
1705
- namedSpecifiers: sortNamedImportSpecifiers(inlineImportDeclaration.namedSpecifiers)
2082
+ ...importDeclaration,
2083
+ namedSpecifiers: sortNamedImportSpecifiers(namedSpecifiers)
1706
2084
  }
1707
2085
  ];
1708
2086
  }
1709
- const typeSpecifiers = sortNamedImportSpecifiers(inlineImportDeclaration.namedSpecifiers.filter((importSpecifier) => importSpecifier.isTypeOnly));
1710
- const valueSpecifiers = sortNamedImportSpecifiers(inlineImportDeclaration.namedSpecifiers.filter((importSpecifier) => !importSpecifier.isTypeOnly));
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 [{ ...inlineImportDeclaration, namedSpecifiers: orderedSpecifiers }];
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 sortImportSegment(importDeclarations, sortOptions, importGroupOrder) {
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 renderedImportLines = [];
2134
+ const renderedImports = [];
1757
2135
  for (const { importDeclaration, importGroup } of rankedImportDeclarations) {
1758
2136
  if (sortOptions.esmImportSeparation && previousImportGroup !== null && importGroup !== previousImportGroup) {
1759
- renderedImportLines.push("");
2137
+ renderedImports.push("");
1760
2138
  }
1761
- renderedImportLines.push(renderImportDeclaration(importDeclaration));
2139
+ renderedImports.push(renderImportDeclaration(importDeclaration));
1762
2140
  previousImportGroup = importGroup;
1763
2141
  }
1764
- return renderedImportLines;
2142
+ return renderedImports;
1765
2143
  }
1766
- function renderSortedImportLines(importDeclarations, sortOptions) {
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 renderedImportLines = [];
2172
+ const renderedImports = [];
1795
2173
  for (const importChunk of importDeclarationChunks) {
1796
2174
  if (sortOptions.esmImportSeparation && previousChunkKind !== null && previousChunkKind !== importChunk.kind) {
1797
- renderedImportLines.push("");
2175
+ renderedImports.push("");
1798
2176
  }
1799
2177
  if (importChunk.kind === "sortable") {
1800
- renderedImportLines.push(...sortImportSegment(importChunk.importDeclarations, sortOptions, importGroupOrder));
2178
+ renderedImports.push(...renderSortedImportSegment(importChunk.importDeclarations, sortOptions, pathPatterns, importGroupOrder));
1801
2179
  } else {
1802
- renderedImportLines.push(renderImportDeclaration(importChunk.importDeclaration));
2180
+ renderedImports.push(renderImportDeclaration(importChunk.importDeclaration));
1803
2181
  }
1804
2182
  previousChunkKind = importChunk.kind;
1805
2183
  }
1806
- return renderedImportLines;
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 = renderSortedImportLines(importEntries.map((importEntry) => importEntry.parsedImportDeclaration), sortOptions).join(lineEnding);
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 = resolveSortOptions(prettierOptions);
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
- sortingEdits.push(...buildImportSortingEdits(sourceText, programStatements, sortedComments, sortOptions, isPrettierFilePragmaPresent));
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, preprocessPackageJson),
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)