prettier-plugin-sort 0.0.0 → 0.0.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/dist/index.js ADDED
@@ -0,0 +1,732 @@
1
+ // src/index.ts
2
+ import { parsers as babelParsers } from "prettier/plugins/babel";
3
+ import { parsers as typescriptParsers } from "prettier/plugins/typescript";
4
+
5
+ // src/options.ts
6
+ var DEFAULT_SORT_OPTIONS = {
7
+ importOrder: true,
8
+ importOrderGroups: ["builtin", "external", "parent", "sibling", "index"],
9
+ importOrderSeparation: true,
10
+ importOrderTypeImports: "separate",
11
+ importOrderMergeDuplicates: true,
12
+ exportOrder: true,
13
+ packageJsonOrder: true,
14
+ packageJsonOrderExcludeKeys: []
15
+ };
16
+ var VALID_IMPORT_GROUPS = new Set([
17
+ "builtin",
18
+ "external",
19
+ "internal",
20
+ "parent",
21
+ "sibling",
22
+ "index"
23
+ ]);
24
+ var VALID_TYPE_STYLES = new Set([
25
+ "separate",
26
+ "inline-first",
27
+ "inline-last",
28
+ "mixed"
29
+ ]);
30
+ var isValidImportGroup = (g) => typeof g === "string" && VALID_IMPORT_GROUPS.has(g);
31
+ var isValidTypeStyle = (s) => typeof s === "string" && VALID_TYPE_STYLES.has(s);
32
+ function resolveSortOptions(rawOptions) {
33
+ const groups = Array.isArray(rawOptions.importOrderGroups) ? rawOptions.importOrderGroups.filter(isValidImportGroup) : [];
34
+ const excludeKeys = Array.isArray(rawOptions.packageJsonOrderExcludeKeys) ? rawOptions.packageJsonOrderExcludeKeys.filter((k) => typeof k === "string") : [];
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 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
+ return {
43
+ importOrder,
44
+ importOrderGroups,
45
+ importOrderSeparation,
46
+ importOrderTypeImports,
47
+ importOrderMergeDuplicates,
48
+ exportOrder,
49
+ packageJsonOrder,
50
+ packageJsonOrderExcludeKeys: excludeKeys
51
+ };
52
+ }
53
+ var options = {
54
+ importOrder: {
55
+ type: "boolean",
56
+ default: DEFAULT_SORT_OPTIONS.importOrder,
57
+ category: "SortImports",
58
+ description: "Sort `import` declarations in JS/TS files."
59
+ },
60
+ importOrderGroups: {
61
+ type: "string",
62
+ array: true,
63
+ default: [{ value: [...DEFAULT_SORT_OPTIONS.importOrderGroups] }],
64
+ category: "SortImports",
65
+ description: 'Ordered list of import groups. Valid values: "builtin", "external", "internal", "parent", "sibling", "index". Each group is sorted alphabetically; unknown groups are ignored.'
66
+ },
67
+ importOrderSeparation: {
68
+ type: "boolean",
69
+ default: DEFAULT_SORT_OPTIONS.importOrderSeparation,
70
+ category: "SortImports",
71
+ description: "Insert a blank line between adjacent import groups."
72
+ },
73
+ importOrderTypeImports: {
74
+ type: "choice",
75
+ default: DEFAULT_SORT_OPTIONS.importOrderTypeImports,
76
+ category: "SortImports",
77
+ description: "How to place `type` imports relative to value imports.",
78
+ choices: [
79
+ {
80
+ value: "separate",
81
+ description: "Keep `import type { … }` as its own statement."
82
+ },
83
+ {
84
+ value: "inline-first",
85
+ description: "Inline inside braces, type specifiers before value specifiers."
86
+ },
87
+ {
88
+ value: "inline-last",
89
+ description: "Inline inside braces, type specifiers after value specifiers."
90
+ },
91
+ {
92
+ value: "mixed",
93
+ description: "Inline inside braces, alphabetical without distinguishing type from value."
94
+ }
95
+ ]
96
+ },
97
+ importOrderMergeDuplicates: {
98
+ type: "boolean",
99
+ default: DEFAULT_SORT_OPTIONS.importOrderMergeDuplicates,
100
+ category: "SortImports",
101
+ description: "Merge multiple `import` statements from the same source into one. Side-effect imports are never merged."
102
+ },
103
+ exportOrder: {
104
+ type: "boolean",
105
+ default: DEFAULT_SORT_OPTIONS.exportOrder,
106
+ category: "SortExports",
107
+ description: "Sort named specifiers inside `export { … }` alphabetically. Does not reorder export statements."
108
+ },
109
+ packageJsonOrder: {
110
+ type: "boolean",
111
+ default: DEFAULT_SORT_OPTIONS.packageJsonOrder,
112
+ category: "SortPackageJson",
113
+ description: "Sort top-level keys and string-array values inside `package.json`. Dependency maps are always alphabetised regardless of this option."
114
+ },
115
+ packageJsonOrderExcludeKeys: {
116
+ type: "string",
117
+ array: true,
118
+ default: [{ value: [...DEFAULT_SORT_OPTIONS.packageJsonOrderExcludeKeys] }],
119
+ category: "SortPackageJson",
120
+ description: "Top-level `package.json` keys to leave untouched (no key reordering or array sorting). Takes priority over `packageJsonOrder`."
121
+ }
122
+ };
123
+
124
+ // src/sort-exports.ts
125
+ function sortExports(text, rawOptions) {
126
+ const options2 = resolveSortOptions(rawOptions);
127
+ if (!options2.exportOrder) {
128
+ return text;
129
+ }
130
+ return text.replace(/export(\s+type)?\s*\{([^}]*)\}/g, (match, typeKeyword, inner) => {
131
+ const members = splitTopLevel(inner, ",");
132
+ if (members.length <= 1) {
133
+ return match;
134
+ }
135
+ const sorted = [...members].sort((a, b) => stripTypePrefix(a).localeCompare(stripTypePrefix(b), "en", {
136
+ sensitivity: "base"
137
+ }));
138
+ const same = sorted.every((m, i) => m === members[i]);
139
+ if (same) {
140
+ return match;
141
+ }
142
+ const prefix = typeKeyword ? `export${typeKeyword}` : "export";
143
+ return `${prefix} { ${sorted.join(", ")} }`;
144
+ });
145
+ }
146
+ function splitTopLevel(input, separator) {
147
+ const out = [];
148
+ let buf = "";
149
+ let depth = 0;
150
+ for (const ch of input) {
151
+ if (ch === "{" || ch === "(" || ch === "[") {
152
+ depth++;
153
+ } else if (ch === "}" || ch === ")" || ch === "]") {
154
+ depth--;
155
+ }
156
+ if (ch === separator && depth === 0) {
157
+ out.push(buf);
158
+ buf = "";
159
+ continue;
160
+ }
161
+ buf += ch;
162
+ }
163
+ if (buf.length > 0) {
164
+ out.push(buf);
165
+ }
166
+ return out.map((s) => s.trim()).filter((s) => s.length > 0);
167
+ }
168
+ function stripTypePrefix(member) {
169
+ return member.replace(/^type\s+/, "");
170
+ }
171
+
172
+ // src/sort-imports.ts
173
+ import { builtinModules } from "node:module";
174
+ var NODE_BUILTINS = new Set(builtinModules);
175
+ function detectGroup(source) {
176
+ if (source.startsWith("node:") || source.startsWith("bun:") || source.startsWith("deno:")) {
177
+ return "builtin";
178
+ }
179
+ const slashIndex = source.indexOf("/");
180
+ const head = slashIndex === -1 ? source : source.slice(0, slashIndex);
181
+ if (head && NODE_BUILTINS.has(head)) {
182
+ return "builtin";
183
+ }
184
+ if (source === "." || source === "./" || /^\.\/index(\.[a-z]+)?$/.test(source)) {
185
+ return "index";
186
+ }
187
+ if (source.startsWith("../") || source === "..") {
188
+ return "parent";
189
+ }
190
+ if (source.startsWith("./")) {
191
+ return "sibling";
192
+ }
193
+ if (source.startsWith("/") || source.startsWith("~") || source.startsWith("@/")) {
194
+ return "internal";
195
+ }
196
+ return "external";
197
+ }
198
+ function splitTopLevel2(input, separator) {
199
+ const out = [];
200
+ let buf = "";
201
+ let depth = 0;
202
+ for (const ch of input) {
203
+ if (ch === "{" || ch === "(" || ch === "[") {
204
+ depth++;
205
+ } else if (ch === "}" || ch === ")" || ch === "]") {
206
+ depth--;
207
+ }
208
+ if (ch === separator && depth === 0) {
209
+ out.push(buf);
210
+ buf = "";
211
+ continue;
212
+ }
213
+ buf += ch;
214
+ }
215
+ if (buf.length > 0) {
216
+ out.push(buf);
217
+ }
218
+ return out.map((s) => s.trim()).filter((s) => s.length > 0);
219
+ }
220
+ function splitMembers(inner) {
221
+ return splitTopLevel2(inner, ",").map((part) => {
222
+ const isType = /^type\s+/.test(part);
223
+ const name = isType ? part.replace(/^type\s+/, "").trim() : part;
224
+ return { name, isType };
225
+ });
226
+ }
227
+ function parseImport(stmt) {
228
+ const trimmed = stmt.raw.trim();
229
+ const leadingComments = stmt.leadingComments;
230
+ const sideEffect = /^import\s*(['"])([^'"]+)\1\s*;?$/.exec(trimmed);
231
+ if (sideEffect) {
232
+ return {
233
+ raw: trimmed,
234
+ source: sideEffect[2] ?? "",
235
+ typeClause: false,
236
+ sideEffect: true,
237
+ defaultSpec: null,
238
+ namespaceSpec: null,
239
+ members: null,
240
+ leadingComments
241
+ };
242
+ }
243
+ const m = /^import\s+(type\s+)?([\s\S]+?)\s+from\s*(['"])([^'"]+)\3\s*;?$/.exec(trimmed);
244
+ if (!m) {
245
+ return null;
246
+ }
247
+ const typeClause = Boolean(m[1]);
248
+ const clause = (m[2] ?? "").trim();
249
+ const source = m[4] ?? "";
250
+ let defaultSpec = null;
251
+ let namespaceSpec = null;
252
+ let members = null;
253
+ for (const part of splitTopLevel2(clause, ",")) {
254
+ if (part.startsWith("{")) {
255
+ const inner = part.slice(1, part.lastIndexOf("}")).trim();
256
+ members = inner ? splitMembers(inner) : [];
257
+ } else if (part.startsWith("*")) {
258
+ namespaceSpec = part;
259
+ } else {
260
+ defaultSpec = part;
261
+ }
262
+ }
263
+ return {
264
+ raw: trimmed,
265
+ source,
266
+ typeClause,
267
+ sideEffect: false,
268
+ defaultSpec,
269
+ namespaceSpec,
270
+ members,
271
+ leadingComments
272
+ };
273
+ }
274
+ function extractImportBlock(text) {
275
+ const firstRe = /(?:^|\n)(?:[ \t]*(?:\/\/[^\n]*|\/\*[\s\S]*?\*\/)[ \t]*\n)*[ \t]*import\b/;
276
+ const first = firstRe.exec(text);
277
+ if (!first) {
278
+ return null;
279
+ }
280
+ const start = first.index + (text[first.index] === `
281
+ ` ? 1 : 0);
282
+ const statements = [];
283
+ let cursor = start;
284
+ while (cursor < text.length) {
285
+ const chunkMatch = /^(?:[ \t]*(?:\/\/[^\n]*|\/\*[\s\S]*?\*\/)?[ \t]*\n)*/.exec(text.slice(cursor));
286
+ const chunk = chunkMatch ? chunkMatch[0] : "";
287
+ const afterSkip = cursor + chunk.length;
288
+ const importMatch = /^[ \t]*(import\b[\s\S]*?(?:from\s*(['"])[^'"]+\2|(['"])[^'"]+\3)\s*;?)/.exec(text.slice(afterSkip));
289
+ if (!importMatch) {
290
+ break;
291
+ }
292
+ const normalised = chunk.endsWith(`
293
+ `) ? chunk.slice(0, -1) : chunk;
294
+ const commentLines = normalised.length > 0 ? normalised.split(`
295
+ `) : [];
296
+ const leadingLines = [];
297
+ for (let i = commentLines.length - 1;i >= 0; i--) {
298
+ const line = commentLines[i];
299
+ if (line === undefined) {
300
+ continue;
301
+ }
302
+ if (line.trim() === "") {
303
+ break;
304
+ }
305
+ leadingLines.unshift(line);
306
+ }
307
+ const leadingComments = leadingLines.length > 0 ? leadingLines.join(`
308
+ `) + `
309
+ ` : "";
310
+ const statement = importMatch[1];
311
+ if (!statement) {
312
+ break;
313
+ }
314
+ statements.push({ raw: statement.trim(), leadingComments });
315
+ cursor = afterSkip + importMatch[0].length;
316
+ }
317
+ if (statements.length === 0) {
318
+ return null;
319
+ }
320
+ return { start, end: cursor, statements };
321
+ }
322
+ function renderMembers(members) {
323
+ return members.map((member) => member.isType ? `type ${member.name}` : member.name).join(", ");
324
+ }
325
+ function renderImport(importDecl) {
326
+ const body = (() => {
327
+ if (importDecl.sideEffect) {
328
+ return `import '${importDecl.source}';`;
329
+ }
330
+ if (importDecl.typeClause) {
331
+ const inner = importDecl.members ? `{ ${renderMembers(importDecl.members)} }` : "";
332
+ return `import type ${inner} from '${importDecl.source}';`;
333
+ }
334
+ const leftParts = [];
335
+ if (importDecl.defaultSpec) {
336
+ leftParts.push(importDecl.defaultSpec);
337
+ }
338
+ if (importDecl.namespaceSpec) {
339
+ leftParts.push(importDecl.namespaceSpec);
340
+ }
341
+ if (importDecl.members) {
342
+ leftParts.push(`{ ${renderMembers(importDecl.members)} }`);
343
+ }
344
+ return `import ${leftParts.join(", ")} from '${importDecl.source}';`;
345
+ })();
346
+ return importDecl.leadingComments + body;
347
+ }
348
+ function sortMembersAlpha(members) {
349
+ return [...members].sort((a, b) => a.name.localeCompare(b.name, "en", { sensitivity: "base" }));
350
+ }
351
+ function normalizeTypeClause(importDecl) {
352
+ if (!importDecl.typeClause || importDecl.members === null) {
353
+ return importDecl;
354
+ }
355
+ return {
356
+ ...importDecl,
357
+ typeClause: false,
358
+ members: importDecl.members.map((member) => ({ ...member, isType: true }))
359
+ };
360
+ }
361
+ function mergeImportsFromSameSource(imports) {
362
+ const indexBySource = new Map;
363
+ const result = [];
364
+ for (const raw of imports) {
365
+ const importDecl = normalizeTypeClause(raw);
366
+ if (importDecl.sideEffect) {
367
+ result.push(importDecl);
368
+ continue;
369
+ }
370
+ const existingIndex = indexBySource.get(importDecl.source);
371
+ if (existingIndex === undefined) {
372
+ indexBySource.set(importDecl.source, result.length);
373
+ result.push(importDecl);
374
+ continue;
375
+ }
376
+ const existing = result[existingIndex];
377
+ result[existingIndex] = {
378
+ raw: "",
379
+ source: existing.source,
380
+ typeClause: false,
381
+ sideEffect: false,
382
+ defaultSpec: existing.defaultSpec ?? importDecl.defaultSpec,
383
+ namespaceSpec: existing.namespaceSpec ?? importDecl.namespaceSpec,
384
+ members: existing.members === null && importDecl.members === null ? null : [...existing.members ?? [], ...importDecl.members ?? []],
385
+ leadingComments: existing.leadingComments
386
+ };
387
+ }
388
+ return result;
389
+ }
390
+ function applyTypeImports(importDecl, style) {
391
+ if (importDecl.sideEffect || !importDecl.members) {
392
+ return [importDecl];
393
+ }
394
+ if (style === "separate") {
395
+ if (importDecl.typeClause) {
396
+ return [importDecl];
397
+ }
398
+ const typeMembers2 = importDecl.members.filter((member) => member.isType);
399
+ const valueMembers2 = importDecl.members.filter((member) => !member.isType);
400
+ const out = [];
401
+ if (typeMembers2.length > 0) {
402
+ out.push({
403
+ raw: "",
404
+ source: importDecl.source,
405
+ typeClause: true,
406
+ sideEffect: false,
407
+ defaultSpec: null,
408
+ namespaceSpec: null,
409
+ members: sortMembersAlpha(typeMembers2.map((member) => ({ ...member, isType: false }))),
410
+ leadingComments: importDecl.leadingComments
411
+ });
412
+ }
413
+ const hasValueBody = valueMembers2.length > 0 || importDecl.defaultSpec !== null || importDecl.namespaceSpec !== null;
414
+ if (hasValueBody) {
415
+ out.push({
416
+ ...importDecl,
417
+ members: valueMembers2.length > 0 ? sortMembersAlpha(valueMembers2) : null,
418
+ leadingComments: typeMembers2.length > 0 ? "" : importDecl.leadingComments
419
+ });
420
+ }
421
+ return out.length > 0 ? out : [importDecl];
422
+ }
423
+ const base = importDecl.typeClause ? {
424
+ ...importDecl,
425
+ typeClause: false,
426
+ members: importDecl.members.map((member) => ({
427
+ ...member,
428
+ isType: true
429
+ }))
430
+ } : { ...importDecl, members: importDecl.members };
431
+ if (style === "mixed") {
432
+ return [{ ...base, members: sortMembersAlpha(base.members) }];
433
+ }
434
+ const typeMembers = base.members.filter((m) => m.isType);
435
+ const valueMembers = base.members.filter((m) => !m.isType);
436
+ const sortedTypes = sortMembersAlpha(typeMembers);
437
+ const sortedValues = sortMembersAlpha(valueMembers);
438
+ const ordered = style === "inline-first" ? [...sortedTypes, ...sortedValues] : [...sortedValues, ...sortedTypes];
439
+ return [{ ...base, members: ordered }];
440
+ }
441
+ function sortImports(text, rawOptions) {
442
+ const options2 = resolveSortOptions(rawOptions);
443
+ if (!options2.importOrder) {
444
+ return text;
445
+ }
446
+ const block = extractImportBlock(text);
447
+ if (!block || block.statements.length === 0) {
448
+ return text;
449
+ }
450
+ const parsed = block.statements.map((rawStmt) => parseImport(rawStmt)).filter((decl) => decl !== null);
451
+ if (parsed.length === 0) {
452
+ return text;
453
+ }
454
+ const style = options2.importOrderTypeImports;
455
+ const deduped = options2.importOrderMergeDuplicates ? mergeImportsFromSameSource(parsed) : parsed;
456
+ const rewritten = deduped.flatMap((importDecl) => applyTypeImports(importDecl, style));
457
+ const groupIndex = new Map(options2.importOrderGroups.map((group, index) => [
458
+ group,
459
+ index
460
+ ]));
461
+ const fallback = options2.importOrderGroups.length;
462
+ const decorated = rewritten.map((importDecl, index) => ({
463
+ stmt: importDecl,
464
+ group: detectGroup(importDecl.source),
465
+ originalIndex: index
466
+ }));
467
+ decorated.sort((a, b) => {
468
+ const groupOrderA = groupIndex.get(a.group) ?? fallback;
469
+ const groupOrderB = groupIndex.get(b.group) ?? fallback;
470
+ if (groupOrderA !== groupOrderB) {
471
+ return groupOrderA - groupOrderB;
472
+ }
473
+ const sourceA = a.stmt.source.toLowerCase();
474
+ const sourceB = b.stmt.source.toLowerCase();
475
+ if (sourceA !== sourceB) {
476
+ return sourceA < sourceB ? -1 : 1;
477
+ }
478
+ if (a.stmt.typeClause !== b.stmt.typeClause) {
479
+ return a.stmt.typeClause ? -1 : 1;
480
+ }
481
+ return a.originalIndex - b.originalIndex;
482
+ });
483
+ const lines = [];
484
+ let prevGroup = null;
485
+ for (const item of decorated) {
486
+ if (options2.importOrderSeparation && prevGroup !== null && item.group !== prevGroup) {
487
+ lines.push("");
488
+ }
489
+ lines.push(renderImport(item.stmt));
490
+ prevGroup = item.group;
491
+ }
492
+ const replacement = lines.join(`
493
+ `);
494
+ return text.slice(0, block.start) + replacement + text.slice(block.end);
495
+ }
496
+
497
+ // src/sort-package.ts
498
+ import path from "node:path";
499
+
500
+ // src/order-package.ts
501
+ var PACKAGE_JSON_TOP_LEVEL_ORDER = [
502
+ "$schema",
503
+ "name",
504
+ "displayName",
505
+ "version",
506
+ "stableVersion",
507
+ "private",
508
+ "description",
509
+ "categories",
510
+ "keywords",
511
+ "homepage",
512
+ "bugs",
513
+ "repository",
514
+ "funding",
515
+ "license",
516
+ "qna",
517
+ "author",
518
+ "maintainers",
519
+ "contributors",
520
+ "publisher",
521
+ "sideEffects",
522
+ "type",
523
+ "imports",
524
+ "exports",
525
+ "main",
526
+ "svelte",
527
+ "umd:main",
528
+ "jsdelivr",
529
+ "unpkg",
530
+ "module",
531
+ "source",
532
+ "jsnext:main",
533
+ "browser",
534
+ "react-native",
535
+ "types",
536
+ "typesVersions",
537
+ "typings",
538
+ "style",
539
+ "example",
540
+ "examplestyle",
541
+ "assets",
542
+ "bin",
543
+ "man",
544
+ "directories",
545
+ "files",
546
+ "workspaces",
547
+ "binary",
548
+ "scripts",
549
+ "betterScripts",
550
+ "l10n",
551
+ "contributes",
552
+ "activationEvents",
553
+ "husky",
554
+ "simple-git-hooks",
555
+ "pre-commit",
556
+ "commitlint",
557
+ "lint-staged",
558
+ "nano-staged",
559
+ "config",
560
+ "nodemonConfig",
561
+ "browserify",
562
+ "babel",
563
+ "browserslist",
564
+ "xo",
565
+ "prettier",
566
+ "eslintConfig",
567
+ "eslintIgnore",
568
+ "npmpkgjsonlint",
569
+ "npmPackageJsonLintConfig",
570
+ "npmpackagejsonlint",
571
+ "release",
572
+ "remarkConfig",
573
+ "stylelint",
574
+ "ava",
575
+ "jest",
576
+ "jest-junit",
577
+ "jest-stare",
578
+ "mocha",
579
+ "nyc",
580
+ "c8",
581
+ "tap",
582
+ "oclif",
583
+ "resolutions",
584
+ "overrides",
585
+ "dependencies",
586
+ "devDependencies",
587
+ "dependenciesMeta",
588
+ "peerDependencies",
589
+ "peerDependenciesMeta",
590
+ "optionalDependencies",
591
+ "bundledDependencies",
592
+ "bundleDependencies",
593
+ "extensionPack",
594
+ "extensionDependencies",
595
+ "flat",
596
+ "packageManager",
597
+ "engines",
598
+ "engineStrict",
599
+ "devEngines",
600
+ "volta",
601
+ "languageName",
602
+ "os",
603
+ "cpu",
604
+ "preferGlobal",
605
+ "publishConfig",
606
+ "icon",
607
+ "badges",
608
+ "galleryBanner",
609
+ "preview",
610
+ "markdown",
611
+ "pnpm"
612
+ ];
613
+ var DEPENDENCY_FIELDS = [
614
+ "dependencies",
615
+ "devDependencies",
616
+ "peerDependencies",
617
+ "optionalDependencies",
618
+ "bundledDependencies",
619
+ "bundleDependencies",
620
+ "resolutions",
621
+ "overrides"
622
+ ];
623
+
624
+ // src/sort-package.ts
625
+ function isPlainObject(value) {
626
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
627
+ }
628
+ function isStringArray(value) {
629
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
630
+ }
631
+ function sortObjectKeysByOrder(record, order) {
632
+ const orderIndex = new Map(order.map((key, index) => [key, index]));
633
+ const known = [];
634
+ const rest = [];
635
+ for (const entry of Object.entries(record)) {
636
+ const [key] = entry;
637
+ if (orderIndex.has(key)) {
638
+ known.push(entry);
639
+ } else {
640
+ rest.push(entry);
641
+ }
642
+ }
643
+ known.sort(([left], [right]) => (orderIndex.get(left) ?? 0) - (orderIndex.get(right) ?? 0));
644
+ rest.sort(([left], [right]) => left.localeCompare(right, "en"));
645
+ return Object.fromEntries([...known, ...rest]);
646
+ }
647
+ function sortObjectKeysAlpha(value) {
648
+ if (!isPlainObject(value)) {
649
+ return value;
650
+ }
651
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right, "en")));
652
+ }
653
+ function sortStringArrayAlpha(value) {
654
+ return [...value].sort((a, b) => a.localeCompare(b, "en"));
655
+ }
656
+ function isPackageJson(filepath) {
657
+ if (!filepath) {
658
+ return false;
659
+ }
660
+ return path.basename(filepath) === "package.json";
661
+ }
662
+ function detectIndent(source) {
663
+ const match = /\n([ \t]+)\S/.exec(source);
664
+ return match ? match[1] ?? " " : " ";
665
+ }
666
+ function sortPackageJson(text, rawOptions) {
667
+ if (!isPackageJson(rawOptions.filepath)) {
668
+ return text;
669
+ }
670
+ const options2 = resolveSortOptions(rawOptions);
671
+ const exclude = new Set(options2.packageJsonOrderExcludeKeys);
672
+ let parsed;
673
+ try {
674
+ parsed = JSON.parse(text);
675
+ } catch {
676
+ return text;
677
+ }
678
+ if (!isPlainObject(parsed)) {
679
+ return text;
680
+ }
681
+ let result = { ...parsed };
682
+ for (const field of DEPENDENCY_FIELDS) {
683
+ const dependencyMap = result[field];
684
+ if (dependencyMap !== undefined && !exclude.has(field)) {
685
+ result[field] = sortObjectKeysAlpha(dependencyMap);
686
+ }
687
+ }
688
+ if (options2.packageJsonOrder) {
689
+ result = sortObjectKeysByOrder(result, PACKAGE_JSON_TOP_LEVEL_ORDER);
690
+ for (const [key, value] of Object.entries(result)) {
691
+ if (exclude.has(key)) {
692
+ continue;
693
+ }
694
+ if (isStringArray(value)) {
695
+ result[key] = sortStringArrayAlpha(value);
696
+ }
697
+ }
698
+ }
699
+ const indent = detectIndent(text);
700
+ const output = JSON.stringify(result, null, indent);
701
+ return text.endsWith(`
702
+ `) ? output + `
703
+ ` : output;
704
+ }
705
+
706
+ // src/index.ts
707
+ function wrap(parser, ...transforms) {
708
+ return {
709
+ ...parser,
710
+ async preprocess(text, parserOptions) {
711
+ let source = parser.preprocess ? await parser.preprocess(text, parserOptions) : text;
712
+ for (const fn of transforms) {
713
+ source = fn(source, parserOptions);
714
+ }
715
+ return source;
716
+ }
717
+ };
718
+ }
719
+ var plugin = {
720
+ options,
721
+ parsers: {
722
+ babel: wrap(babelParsers.babel, sortImports, sortExports),
723
+ "babel-ts": wrap(babelParsers["babel-ts"], sortImports, sortExports),
724
+ typescript: wrap(typescriptParsers.typescript, sortImports, sortExports),
725
+ "json-stringify": wrap(babelParsers["json-stringify"], sortPackageJson)
726
+ }
727
+ };
728
+ var src_default = plugin;
729
+ export {
730
+ options,
731
+ src_default as default
732
+ };