prettier-plugin-sort 0.0.3 → 0.1.1
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 +2 -2
- package/README.zh.md +9 -9
- package/dist/index.js +110 -117
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ import react from 'react';
|
|
|
56
56
|
import App from './App.tsx';
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
Each import belongs to a group. For example, `node:fs` is a `builtin` (covers Node.js
|
|
59
|
+
Each import belongs to a group. For example, `node:fs` is a `builtin` (covers Node.js and Bun **runtime** built-ins), while `react` and `lodash` are `external` npm packages. The plugin first classifies each import by group, then sorts alphabetically within each group.
|
|
60
60
|
|
|
61
61
|
Grouping and ordering follow the conventions of [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import)'s [import/order](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md) rule.
|
|
62
62
|
|
|
@@ -76,7 +76,7 @@ Group matchers:
|
|
|
76
76
|
|
|
77
77
|
| Group | Matches | Examples |
|
|
78
78
|
| ---------- | ----------------------------------------------------------- | ---------------------------------- |
|
|
79
|
-
| `builtin` | `node:*`, `bun:*`, `
|
|
79
|
+
| `builtin` | `node:*`, `bun:*`, `bun`, and unprefixed Node built-ins | `node:fs`, `path`, `bun` |
|
|
80
80
|
| `external` | npm packages, and anything that doesn't match another group | `react`, `@scope/pkg` |
|
|
81
81
|
| `internal` | Project absolute paths and aliases | `/utils`, `~/app`, `@/shared` |
|
|
82
82
|
| `parent` | Parent-relative paths | `../Button` |
|
package/README.zh.md
CHANGED
|
@@ -56,7 +56,7 @@ import react from 'react';
|
|
|
56
56
|
import App from './App.tsx';
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
import 的模块一般可以按其来源分为不同的类别,例如上面的示例代码,'node:fs' 就属于 builtin 分类,该分类涵盖 Node.js
|
|
59
|
+
import 的模块一般可以按其来源分为不同的类别,例如上面的示例代码,'node:fs' 就属于 builtin 分类,该分类涵盖 Node.js 和 Bun **运行时**的内置模块。而像 react 和 lodash 这种直接从 npm 下载的依赖模块,属于 external 分类。
|
|
60
60
|
|
|
61
61
|
插件会先根据不同的模块进行分类,然后在模块内部基于字母顺序进行排列。
|
|
62
62
|
|
|
@@ -76,14 +76,14 @@ import 的模块一般可以按其来源分为不同的类别,例如上面的
|
|
|
76
76
|
|
|
77
77
|
各分组的匹配规则如下:
|
|
78
78
|
|
|
79
|
-
| 分组 | 匹配内容
|
|
80
|
-
| ---------- |
|
|
81
|
-
| `builtin` | `node:*`、`bun:*`、`
|
|
82
|
-
| `external` | npm 包,以及不属于其他分组的模块
|
|
83
|
-
| `internal` | 项目绝对路径与别名
|
|
84
|
-
| `parent` | 向上跳级的相对路径
|
|
85
|
-
| `sibling` | 同级相对路径(不包含 index)
|
|
86
|
-
| `index` | 当前目录的 index 模块
|
|
79
|
+
| 分组 | 匹配内容 | 示例 |
|
|
80
|
+
| ---------- | ---------------------------------------------------- | ---------------------------------- |
|
|
81
|
+
| `builtin` | `node:*`、`bun:*`、`bun`,以及无前缀的 Node 内置模块 | `node:fs`、`path`、`bun` |
|
|
82
|
+
| `external` | npm 包,以及不属于其他分组的模块 | `react`、`@scope/pkg` |
|
|
83
|
+
| `internal` | 项目绝对路径与别名 | `/utils`、`~/app`、`@/shared` |
|
|
84
|
+
| `parent` | 向上跳级的相对路径 | `../Button` |
|
|
85
|
+
| `sibling` | 同级相对路径(不包含 index) | `./Icon` |
|
|
86
|
+
| `index` | 当前目录的 index 模块 | `.`、`./`、`./index`、`./index.ts` |
|
|
87
87
|
|
|
88
88
|
> **关于 `internal` 的检测方式:** 插件目前通过说明符的前缀硬编码(`/`、`~`、`@/`)来判断,不会读取 tsconfig `paths` 或任何构建工具的配置。后续版本可能会提供 `importOrderInternalPatterns` 选项,支持自定义正则匹配。
|
|
89
89
|
|
package/dist/index.js
CHANGED
|
@@ -27,26 +27,24 @@ var VALID_TYPE_STYLES = new Set([
|
|
|
27
27
|
"inline-last",
|
|
28
28
|
"mixed"
|
|
29
29
|
]);
|
|
30
|
-
var isValidImportGroup = (
|
|
31
|
-
var isValidTypeStyle = (
|
|
30
|
+
var isValidImportGroup = (value) => typeof value === "string" && VALID_IMPORT_GROUPS.has(value);
|
|
31
|
+
var isValidTypeStyle = (value) => typeof value === "string" && VALID_TYPE_STYLES.has(value);
|
|
32
|
+
function resolveBoolean(rawOptions, key) {
|
|
33
|
+
const raw = rawOptions[key];
|
|
34
|
+
return typeof raw === "boolean" ? raw : DEFAULT_SORT_OPTIONS[key];
|
|
35
|
+
}
|
|
32
36
|
function resolveSortOptions(rawOptions) {
|
|
33
37
|
const groups = Array.isArray(rawOptions.importOrderGroups) ? rawOptions.importOrderGroups.filter(isValidImportGroup) : [];
|
|
34
|
-
const excludeKeys = Array.isArray(rawOptions.packageJsonOrderExcludeKeys) ? rawOptions.packageJsonOrderExcludeKeys.filter((
|
|
35
|
-
const importOrder = typeof rawOptions.importOrder === "boolean" ? rawOptions.importOrder : DEFAULT_SORT_OPTIONS.importOrder;
|
|
36
|
-
const importOrderGroups = groups.length > 0 ? groups : [...DEFAULT_SORT_OPTIONS.importOrderGroups];
|
|
37
|
-
const importOrderSeparation = typeof rawOptions.importOrderSeparation === "boolean" ? rawOptions.importOrderSeparation : DEFAULT_SORT_OPTIONS.importOrderSeparation;
|
|
38
|
+
const excludeKeys = Array.isArray(rawOptions.packageJsonOrderExcludeKeys) ? rawOptions.packageJsonOrderExcludeKeys.filter((key) => typeof key === "string") : [];
|
|
38
39
|
const importOrderTypeImports = isValidTypeStyle(rawOptions.importOrderTypeImports) ? rawOptions.importOrderTypeImports : DEFAULT_SORT_OPTIONS.importOrderTypeImports;
|
|
39
|
-
const importOrderMergeDuplicates = typeof rawOptions.importOrderMergeDuplicates === "boolean" ? rawOptions.importOrderMergeDuplicates : DEFAULT_SORT_OPTIONS.importOrderMergeDuplicates;
|
|
40
|
-
const exportOrder = typeof rawOptions.exportOrder === "boolean" ? rawOptions.exportOrder : DEFAULT_SORT_OPTIONS.exportOrder;
|
|
41
|
-
const packageJsonOrder = typeof rawOptions.packageJsonOrder === "boolean" ? rawOptions.packageJsonOrder : DEFAULT_SORT_OPTIONS.packageJsonOrder;
|
|
42
40
|
return {
|
|
43
|
-
importOrder,
|
|
44
|
-
importOrderGroups,
|
|
45
|
-
importOrderSeparation,
|
|
41
|
+
importOrder: resolveBoolean(rawOptions, "importOrder"),
|
|
42
|
+
importOrderGroups: groups.length > 0 ? groups : [...DEFAULT_SORT_OPTIONS.importOrderGroups],
|
|
43
|
+
importOrderSeparation: resolveBoolean(rawOptions, "importOrderSeparation"),
|
|
46
44
|
importOrderTypeImports,
|
|
47
|
-
importOrderMergeDuplicates,
|
|
48
|
-
exportOrder,
|
|
49
|
-
packageJsonOrder,
|
|
45
|
+
importOrderMergeDuplicates: resolveBoolean(rawOptions, "importOrderMergeDuplicates"),
|
|
46
|
+
exportOrder: resolveBoolean(rawOptions, "exportOrder"),
|
|
47
|
+
packageJsonOrder: resolveBoolean(rawOptions, "packageJsonOrder"),
|
|
50
48
|
packageJsonOrderExcludeKeys: excludeKeys
|
|
51
49
|
};
|
|
52
50
|
}
|
|
@@ -123,26 +121,26 @@ var options = {
|
|
|
123
121
|
|
|
124
122
|
// src/utils.ts
|
|
125
123
|
function splitTopLevel(input, separator) {
|
|
126
|
-
const
|
|
127
|
-
let
|
|
124
|
+
const segments = [];
|
|
125
|
+
let current = "";
|
|
128
126
|
let depth = 0;
|
|
129
|
-
for (const
|
|
130
|
-
if (
|
|
127
|
+
for (const char of input) {
|
|
128
|
+
if (char === "{" || char === "(" || char === "[") {
|
|
131
129
|
depth++;
|
|
132
|
-
} else if (
|
|
130
|
+
} else if (char === "}" || char === ")" || char === "]") {
|
|
133
131
|
depth--;
|
|
134
132
|
}
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
if (char === separator && depth === 0) {
|
|
134
|
+
segments.push(current);
|
|
135
|
+
current = "";
|
|
138
136
|
continue;
|
|
139
137
|
}
|
|
140
|
-
|
|
138
|
+
current += char;
|
|
141
139
|
}
|
|
142
|
-
if (
|
|
143
|
-
|
|
140
|
+
if (current.length > 0) {
|
|
141
|
+
segments.push(current);
|
|
144
142
|
}
|
|
145
|
-
return
|
|
143
|
+
return segments.map((segment) => segment.trim()).filter((segment) => segment.length > 0);
|
|
146
144
|
}
|
|
147
145
|
|
|
148
146
|
// src/sort-exports.ts
|
|
@@ -159,8 +157,8 @@ function sortExports(text, rawOptions) {
|
|
|
159
157
|
const sorted = [...members].sort((a, b) => stripTypePrefix(a).localeCompare(stripTypePrefix(b), "en", {
|
|
160
158
|
sensitivity: "base"
|
|
161
159
|
}));
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
160
|
+
const unchanged = sorted.every((member, index) => member === members[index]);
|
|
161
|
+
if (unchanged) {
|
|
164
162
|
return match;
|
|
165
163
|
}
|
|
166
164
|
const prefix = typeKeyword ? `export${typeKeyword}` : "export";
|
|
@@ -175,7 +173,7 @@ function stripTypePrefix(member) {
|
|
|
175
173
|
import { builtinModules } from "node:module";
|
|
176
174
|
var NODE_BUILTINS = new Set(builtinModules);
|
|
177
175
|
function detectGroup(source) {
|
|
178
|
-
if (source
|
|
176
|
+
if (source === "bun" || source.startsWith("bun:") || source.startsWith("node:")) {
|
|
179
177
|
return "builtin";
|
|
180
178
|
}
|
|
181
179
|
const slashIndex = source.indexOf("/");
|
|
@@ -197,20 +195,19 @@ function detectGroup(source) {
|
|
|
197
195
|
}
|
|
198
196
|
return "external";
|
|
199
197
|
}
|
|
198
|
+
var TYPE_PREFIX = /^type\s+(.+)$/s;
|
|
200
199
|
function splitMembers(inner) {
|
|
201
200
|
return splitTopLevel(inner, ",").map((part) => {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
return { name, isType };
|
|
201
|
+
const match = TYPE_PREFIX.exec(part);
|
|
202
|
+
return match ? { name: match[1].trim(), isType: true } : { name: part, isType: false };
|
|
205
203
|
});
|
|
206
204
|
}
|
|
207
|
-
function parseImport(
|
|
208
|
-
const trimmed =
|
|
209
|
-
const leadingComments =
|
|
205
|
+
function parseImport(statement) {
|
|
206
|
+
const trimmed = statement.raw.trim();
|
|
207
|
+
const leadingComments = statement.leadingComments;
|
|
210
208
|
const sideEffect = /^import\s*(['"])([^'"]+)\1(?:\s+with\s*(\{[^}]*\}))?\s*;?$/.exec(trimmed);
|
|
211
209
|
if (sideEffect) {
|
|
212
210
|
return {
|
|
213
|
-
raw: trimmed,
|
|
214
211
|
source: sideEffect[2] ?? "",
|
|
215
212
|
typeClause: false,
|
|
216
213
|
sideEffect: true,
|
|
@@ -221,14 +218,14 @@ function parseImport(stmt) {
|
|
|
221
218
|
leadingComments
|
|
222
219
|
};
|
|
223
220
|
}
|
|
224
|
-
const
|
|
225
|
-
if (!
|
|
221
|
+
const match = /^import\s+(type\s+)?([\s\S]+?)\s*from\s*(['"])([^'"]+)\3(?:\s+with\s*(\{[^}]*\}))?\s*;?$/.exec(trimmed);
|
|
222
|
+
if (!match) {
|
|
226
223
|
return null;
|
|
227
224
|
}
|
|
228
|
-
const typeClause = Boolean(
|
|
229
|
-
const clause = (
|
|
230
|
-
const source =
|
|
231
|
-
const attributes =
|
|
225
|
+
const typeClause = Boolean(match[1]);
|
|
226
|
+
const clause = (match[2] ?? "").trim();
|
|
227
|
+
const source = match[4] ?? "";
|
|
228
|
+
const attributes = match[5] ?? null;
|
|
232
229
|
let defaultSpec = null;
|
|
233
230
|
let namespaceSpec = null;
|
|
234
231
|
let members = null;
|
|
@@ -243,7 +240,6 @@ function parseImport(stmt) {
|
|
|
243
240
|
}
|
|
244
241
|
}
|
|
245
242
|
return {
|
|
246
|
-
raw: trimmed,
|
|
247
243
|
source,
|
|
248
244
|
typeClause,
|
|
249
245
|
sideEffect: false,
|
|
@@ -255,7 +251,7 @@ function parseImport(stmt) {
|
|
|
255
251
|
};
|
|
256
252
|
}
|
|
257
253
|
function extractImportBlock(text) {
|
|
258
|
-
const firstRe = /(?:^|\n)(?:[ \t]*(?:\/\/[^\n]*|\/\*[\s\S]*?\*\/)[ \t]*\n)*[ \t]*import\b/;
|
|
254
|
+
const firstRe = /(?:^|\n)(?:[ \t]*(?:\/\/[^\n]*|\/\*[\s\S]*?\*\/)[ \t]*\n)*[ \t]*import\b(?![.(])/;
|
|
259
255
|
const first = firstRe.exec(text);
|
|
260
256
|
if (!first) {
|
|
261
257
|
return null;
|
|
@@ -263,17 +259,21 @@ function extractImportBlock(text) {
|
|
|
263
259
|
const start = first.index + (text[first.index] === `
|
|
264
260
|
` ? 1 : 0);
|
|
265
261
|
const statements = [];
|
|
262
|
+
const skipRe = /(?:[ \t]*(?:\/\/[^\n]*|\/\*[\s\S]*?\*\/)?[ \t]*\n)*/y;
|
|
263
|
+
const importRe = /[ \t]*(import\b(?![.(])[\s\S]*?(?:from\s*(['"])[^'"]+\2|(['"])[^'"]+\3)(?:\s+with\s*\{[^}]*\})?\s*;?)/y;
|
|
266
264
|
let cursor = start;
|
|
267
265
|
while (cursor < text.length) {
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
const
|
|
271
|
-
const
|
|
266
|
+
skipRe.lastIndex = cursor;
|
|
267
|
+
const skipMatch = skipRe.exec(text);
|
|
268
|
+
const skipped = skipMatch ? skipMatch[0] : "";
|
|
269
|
+
const afterSkip = cursor + skipped.length;
|
|
270
|
+
importRe.lastIndex = afterSkip;
|
|
271
|
+
const importMatch = importRe.exec(text);
|
|
272
272
|
if (!importMatch) {
|
|
273
273
|
break;
|
|
274
274
|
}
|
|
275
|
-
const normalised =
|
|
276
|
-
`) ?
|
|
275
|
+
const normalised = skipped.endsWith(`
|
|
276
|
+
`) ? skipped.slice(0, -1) : skipped;
|
|
277
277
|
const commentLines = normalised.length > 0 ? normalised.split(`
|
|
278
278
|
`) : [];
|
|
279
279
|
const leadingLines = [];
|
|
@@ -305,28 +305,23 @@ function extractImportBlock(text) {
|
|
|
305
305
|
function renderMembers(members) {
|
|
306
306
|
return members.map((member) => member.isType ? `type ${member.name}` : member.name).join(", ");
|
|
307
307
|
}
|
|
308
|
+
function renderSpecifiers(importDecl) {
|
|
309
|
+
const parts = [];
|
|
310
|
+
if (importDecl.defaultSpec) {
|
|
311
|
+
parts.push(importDecl.defaultSpec);
|
|
312
|
+
}
|
|
313
|
+
if (importDecl.namespaceSpec) {
|
|
314
|
+
parts.push(importDecl.namespaceSpec);
|
|
315
|
+
}
|
|
316
|
+
if (importDecl.members) {
|
|
317
|
+
parts.push(`{ ${renderMembers(importDecl.members)} }`);
|
|
318
|
+
}
|
|
319
|
+
return parts.join(", ");
|
|
320
|
+
}
|
|
308
321
|
function renderImport(importDecl) {
|
|
309
322
|
const suffix = importDecl.attributes ? ` with ${importDecl.attributes}` : "";
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
return `import '${importDecl.source}'${suffix};`;
|
|
313
|
-
}
|
|
314
|
-
if (importDecl.typeClause) {
|
|
315
|
-
const inner = importDecl.members ? `{ ${renderMembers(importDecl.members)} }` : "";
|
|
316
|
-
return `import type ${inner} from '${importDecl.source}'${suffix};`;
|
|
317
|
-
}
|
|
318
|
-
const leftParts = [];
|
|
319
|
-
if (importDecl.defaultSpec) {
|
|
320
|
-
leftParts.push(importDecl.defaultSpec);
|
|
321
|
-
}
|
|
322
|
-
if (importDecl.namespaceSpec) {
|
|
323
|
-
leftParts.push(importDecl.namespaceSpec);
|
|
324
|
-
}
|
|
325
|
-
if (importDecl.members) {
|
|
326
|
-
leftParts.push(`{ ${renderMembers(importDecl.members)} }`);
|
|
327
|
-
}
|
|
328
|
-
return `import ${leftParts.join(", ")} from '${importDecl.source}'${suffix};`;
|
|
329
|
-
})();
|
|
323
|
+
const source = `'${importDecl.source}'`;
|
|
324
|
+
const body = importDecl.sideEffect ? `import ${source}${suffix};` : importDecl.typeClause ? `import type ${renderSpecifiers(importDecl)} from ${source}${suffix};` : `import ${renderSpecifiers(importDecl)} from ${source}${suffix};`;
|
|
330
325
|
return importDecl.leadingComments + body;
|
|
331
326
|
}
|
|
332
327
|
function sortMembersAlpha(members) {
|
|
@@ -343,30 +338,30 @@ function normalizeTypeClause(importDecl) {
|
|
|
343
338
|
};
|
|
344
339
|
}
|
|
345
340
|
function mergeImportsFromSameSource(imports) {
|
|
346
|
-
const
|
|
341
|
+
const indexByKey = new Map;
|
|
347
342
|
const result = [];
|
|
348
|
-
for (const
|
|
349
|
-
const importDecl = normalizeTypeClause(
|
|
350
|
-
if (importDecl.sideEffect) {
|
|
343
|
+
for (const rawImport of imports) {
|
|
344
|
+
const importDecl = normalizeTypeClause(rawImport);
|
|
345
|
+
if (importDecl.sideEffect || importDecl.typeClause) {
|
|
351
346
|
result.push(importDecl);
|
|
352
347
|
continue;
|
|
353
348
|
}
|
|
354
|
-
const
|
|
349
|
+
const mergeKey = `${importDecl.source}\x00${importDecl.attributes ?? ""}`;
|
|
350
|
+
const existingIndex = indexByKey.get(mergeKey);
|
|
355
351
|
if (existingIndex === undefined) {
|
|
356
|
-
|
|
352
|
+
indexByKey.set(mergeKey, result.length);
|
|
357
353
|
result.push(importDecl);
|
|
358
354
|
continue;
|
|
359
355
|
}
|
|
360
356
|
const existing = result[existingIndex];
|
|
361
357
|
result[existingIndex] = {
|
|
362
|
-
raw: "",
|
|
363
358
|
source: existing.source,
|
|
364
359
|
typeClause: false,
|
|
365
360
|
sideEffect: false,
|
|
366
361
|
defaultSpec: existing.defaultSpec ?? importDecl.defaultSpec,
|
|
367
362
|
namespaceSpec: existing.namespaceSpec ?? importDecl.namespaceSpec,
|
|
368
363
|
members: existing.members === null && importDecl.members === null ? null : [...existing.members ?? [], ...importDecl.members ?? []],
|
|
369
|
-
attributes: existing.attributes
|
|
364
|
+
attributes: existing.attributes,
|
|
370
365
|
leadingComments: existing.leadingComments
|
|
371
366
|
};
|
|
372
367
|
}
|
|
@@ -385,7 +380,6 @@ function applyTypeImports(importDecl, style) {
|
|
|
385
380
|
const out = [];
|
|
386
381
|
if (typeMembers2.length > 0) {
|
|
387
382
|
out.push({
|
|
388
|
-
raw: "",
|
|
389
383
|
source: importDecl.source,
|
|
390
384
|
typeClause: true,
|
|
391
385
|
sideEffect: false,
|
|
@@ -406,7 +400,7 @@ function applyTypeImports(importDecl, style) {
|
|
|
406
400
|
}
|
|
407
401
|
return out.length > 0 ? out : [importDecl];
|
|
408
402
|
}
|
|
409
|
-
const
|
|
403
|
+
const inlineBase = importDecl.typeClause ? {
|
|
410
404
|
...importDecl,
|
|
411
405
|
typeClause: false,
|
|
412
406
|
members: importDecl.members.map((member) => ({
|
|
@@ -415,14 +409,14 @@ function applyTypeImports(importDecl, style) {
|
|
|
415
409
|
}))
|
|
416
410
|
} : { ...importDecl, members: importDecl.members };
|
|
417
411
|
if (style === "mixed") {
|
|
418
|
-
return [{ ...
|
|
412
|
+
return [{ ...inlineBase, members: sortMembersAlpha(inlineBase.members) }];
|
|
419
413
|
}
|
|
420
|
-
const typeMembers =
|
|
421
|
-
const valueMembers =
|
|
414
|
+
const typeMembers = inlineBase.members.filter((member) => member.isType);
|
|
415
|
+
const valueMembers = inlineBase.members.filter((member) => !member.isType);
|
|
422
416
|
const sortedTypes = sortMembersAlpha(typeMembers);
|
|
423
417
|
const sortedValues = sortMembersAlpha(valueMembers);
|
|
424
418
|
const ordered = style === "inline-first" ? [...sortedTypes, ...sortedValues] : [...sortedValues, ...sortedTypes];
|
|
425
|
-
return [{ ...
|
|
419
|
+
return [{ ...inlineBase, members: ordered }];
|
|
426
420
|
}
|
|
427
421
|
function sortSegment(imports, options2, groupIndex, fallback) {
|
|
428
422
|
if (imports.length === 0) {
|
|
@@ -432,7 +426,7 @@ function sortSegment(imports, options2, groupIndex, fallback) {
|
|
|
432
426
|
const deduped = options2.importOrderMergeDuplicates ? mergeImportsFromSameSource(imports) : imports;
|
|
433
427
|
const rewritten = deduped.flatMap((importDecl) => applyTypeImports(importDecl, style));
|
|
434
428
|
const decorated = rewritten.map((importDecl, index) => ({
|
|
435
|
-
|
|
429
|
+
importDecl,
|
|
436
430
|
group: detectGroup(importDecl.source),
|
|
437
431
|
originalIndex: index
|
|
438
432
|
}));
|
|
@@ -442,24 +436,24 @@ function sortSegment(imports, options2, groupIndex, fallback) {
|
|
|
442
436
|
if (groupOrderA !== groupOrderB) {
|
|
443
437
|
return groupOrderA - groupOrderB;
|
|
444
438
|
}
|
|
445
|
-
const sourceA = a.
|
|
446
|
-
const sourceB = b.
|
|
439
|
+
const sourceA = a.importDecl.source.toLowerCase();
|
|
440
|
+
const sourceB = b.importDecl.source.toLowerCase();
|
|
447
441
|
if (sourceA !== sourceB) {
|
|
448
442
|
return sourceA < sourceB ? -1 : 1;
|
|
449
443
|
}
|
|
450
|
-
if (a.
|
|
451
|
-
return a.
|
|
444
|
+
if (a.importDecl.typeClause !== b.importDecl.typeClause) {
|
|
445
|
+
return a.importDecl.typeClause ? -1 : 1;
|
|
452
446
|
}
|
|
453
447
|
return a.originalIndex - b.originalIndex;
|
|
454
448
|
});
|
|
455
449
|
const lines = [];
|
|
456
|
-
let
|
|
450
|
+
let previousGroup = null;
|
|
457
451
|
for (const item of decorated) {
|
|
458
|
-
if (options2.importOrderSeparation &&
|
|
452
|
+
if (options2.importOrderSeparation && previousGroup !== null && item.group !== previousGroup) {
|
|
459
453
|
lines.push("");
|
|
460
454
|
}
|
|
461
|
-
lines.push(renderImport(item.
|
|
462
|
-
|
|
455
|
+
lines.push(renderImport(item.importDecl));
|
|
456
|
+
previousGroup = item.group;
|
|
463
457
|
}
|
|
464
458
|
return lines;
|
|
465
459
|
}
|
|
@@ -472,7 +466,7 @@ function sortImports(text, rawOptions) {
|
|
|
472
466
|
if (!block || block.statements.length === 0) {
|
|
473
467
|
return text;
|
|
474
468
|
}
|
|
475
|
-
const parsed = block.statements.map((
|
|
469
|
+
const parsed = block.statements.map((rawStatement) => parseImport(rawStatement)).filter((importDecl) => importDecl !== null);
|
|
476
470
|
if (parsed.length === 0) {
|
|
477
471
|
return text;
|
|
478
472
|
}
|
|
@@ -485,31 +479,30 @@ function sortImports(text, rawOptions) {
|
|
|
485
479
|
let currentSegment = [];
|
|
486
480
|
for (const importDecl of parsed) {
|
|
487
481
|
if (importDecl.sideEffect) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
482
|
+
if (currentSegment.length > 0) {
|
|
483
|
+
chunks.push({ kind: "segment", imports: currentSegment });
|
|
484
|
+
currentSegment = [];
|
|
485
|
+
}
|
|
486
|
+
chunks.push({ kind: "side-effect", importDecl });
|
|
491
487
|
} else {
|
|
492
488
|
currentSegment.push(importDecl);
|
|
493
489
|
}
|
|
494
490
|
}
|
|
495
|
-
|
|
491
|
+
if (currentSegment.length > 0) {
|
|
492
|
+
chunks.push({ kind: "segment", imports: currentSegment });
|
|
493
|
+
}
|
|
496
494
|
const allLines = [];
|
|
495
|
+
let previousKind = null;
|
|
497
496
|
for (const chunk of chunks) {
|
|
497
|
+
if (previousKind !== null && previousKind !== chunk.kind && options2.importOrderSeparation) {
|
|
498
|
+
allLines.push("");
|
|
499
|
+
}
|
|
498
500
|
if (chunk.kind === "segment") {
|
|
499
|
-
|
|
500
|
-
continue;
|
|
501
|
-
}
|
|
502
|
-
const segmentLines = sortSegment(chunk.imports, options2, groupIndex, fallback);
|
|
503
|
-
if (allLines.length > 0 && options2.importOrderSeparation) {
|
|
504
|
-
allLines.push("");
|
|
505
|
-
}
|
|
506
|
-
allLines.push(...segmentLines);
|
|
501
|
+
allLines.push(...sortSegment(chunk.imports, options2, groupIndex, fallback));
|
|
507
502
|
} else {
|
|
508
|
-
|
|
509
|
-
allLines.push("");
|
|
510
|
-
}
|
|
511
|
-
allLines.push(renderImport(chunk.stmt));
|
|
503
|
+
allLines.push(renderImport(chunk.importDecl));
|
|
512
504
|
}
|
|
505
|
+
previousKind = chunk.kind;
|
|
513
506
|
}
|
|
514
507
|
const replacement = allLines.join(`
|
|
515
508
|
`);
|
|
@@ -666,15 +659,15 @@ function sortObjectKeysByOrder(record, order) {
|
|
|
666
659
|
rest.push(entry);
|
|
667
660
|
}
|
|
668
661
|
}
|
|
669
|
-
known.sort(([
|
|
670
|
-
rest.sort(([
|
|
662
|
+
known.sort(([a], [b]) => (orderIndex.get(a) ?? 0) - (orderIndex.get(b) ?? 0));
|
|
663
|
+
rest.sort(([a], [b]) => a.localeCompare(b, "en"));
|
|
671
664
|
return Object.fromEntries([...known, ...rest]);
|
|
672
665
|
}
|
|
673
666
|
function sortObjectKeysAlpha(value) {
|
|
674
667
|
if (!isPlainObject(value)) {
|
|
675
668
|
return value;
|
|
676
669
|
}
|
|
677
|
-
return Object.fromEntries(Object.entries(value).sort(([
|
|
670
|
+
return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b, "en")));
|
|
678
671
|
}
|
|
679
672
|
function sortStringArrayAlpha(value) {
|
|
680
673
|
return [...value].sort((a, b) => a.localeCompare(b, "en"));
|
|
@@ -704,7 +697,7 @@ function sortPackageJson(text, rawOptions) {
|
|
|
704
697
|
if (!isPlainObject(parsed)) {
|
|
705
698
|
return text;
|
|
706
699
|
}
|
|
707
|
-
let result =
|
|
700
|
+
let result = parsed;
|
|
708
701
|
for (const field of DEPENDENCY_FIELDS) {
|
|
709
702
|
const dependencyMap = result[field];
|
|
710
703
|
if (dependencyMap !== undefined && !exclude.has(field)) {
|
|
@@ -735,8 +728,8 @@ function wrap(parser, ...transforms) {
|
|
|
735
728
|
...parser,
|
|
736
729
|
async preprocess(text, parserOptions) {
|
|
737
730
|
let source = parser.preprocess ? await parser.preprocess(text, parserOptions) : text;
|
|
738
|
-
for (const
|
|
739
|
-
source =
|
|
731
|
+
for (const transform of transforms) {
|
|
732
|
+
source = transform(source, parserOptions);
|
|
740
733
|
}
|
|
741
734
|
return source;
|
|
742
735
|
}
|