@1adybug/prettier-plugin-sort-imports 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,464 @@
1
+ import { createRequire } from "module";
2
+ import { parse } from "@babel/parser";
3
+ import traverse from "@babel/traverse";
4
+ function analyzeUsedIdentifiers(code) {
5
+ const usedIdentifiers = new Set();
6
+ try {
7
+ const ast = parse(code, {
8
+ sourceType: "module",
9
+ plugins: [
10
+ "typescript",
11
+ "jsx"
12
+ ],
13
+ errorRecovery: true
14
+ });
15
+ traverse(ast, {
16
+ Identifier (path) {
17
+ const node = path.node;
18
+ const parent = path.parent;
19
+ if (path.isBindingIdentifier()) return;
20
+ if (parent?.type === "ObjectProperty" && parent.key === node && !parent.computed) return;
21
+ usedIdentifiers.add(node.name);
22
+ },
23
+ JSXIdentifier (path) {
24
+ const node = path.node;
25
+ if (path.parent?.type === "JSXOpeningElement" || path.parent?.type === "JSXClosingElement") usedIdentifiers.add(node.name);
26
+ },
27
+ TSTypeReference (path) {
28
+ const node = path.node;
29
+ if ("Identifier" === node.typeName.type) usedIdentifiers.add(node.typeName.name);
30
+ else if ("TSQualifiedName" === node.typeName.type) {
31
+ let current = node.typeName;
32
+ while("TSQualifiedName" === current.type)current = current.left;
33
+ if ("Identifier" === current.type) usedIdentifiers.add(current.name);
34
+ }
35
+ },
36
+ ExportNamedDeclaration (path) {
37
+ const node = path.node;
38
+ if (!node.source && node.specifiers) {
39
+ for (const specifier of node.specifiers)if ("ExportSpecifier" === specifier.type) {
40
+ if ("Identifier" === specifier.local.type) usedIdentifiers.add(specifier.local.name);
41
+ }
42
+ }
43
+ }
44
+ });
45
+ } catch (error) {
46
+ console.error("Failed to analyze used identifiers:", error);
47
+ }
48
+ return usedIdentifiers;
49
+ }
50
+ function filterUnusedImports(importStatement, usedIdentifiers) {
51
+ if (importStatement.isSideEffect || importStatement.isExport) return importStatement;
52
+ const usedContents = [];
53
+ for (const content of importStatement.importContents){
54
+ const usedName = content.alias ?? content.name;
55
+ if ("default" === content.name || "*" === content.name) {
56
+ if (content.alias && usedIdentifiers.has(content.alias)) usedContents.push(content);
57
+ } else if (usedIdentifiers.has(usedName)) usedContents.push(content);
58
+ }
59
+ return {
60
+ ...importStatement,
61
+ importContents: usedContents,
62
+ isSideEffect: 0 === usedContents.length
63
+ };
64
+ }
65
+ function removeUnusedImportsFromStatements(importStatements, code) {
66
+ const usedIdentifiers = analyzeUsedIdentifiers(code);
67
+ const filteredStatements = [];
68
+ for (const statement of importStatements){
69
+ const filteredStatement = filterUnusedImports(statement, usedIdentifiers);
70
+ if (statement.isSideEffect || !filteredStatement.isSideEffect || 0 !== filteredStatement.importContents.length) filteredStatements.push(filteredStatement);
71
+ }
72
+ return filteredStatements;
73
+ }
74
+ function formatImportStatement(statement) {
75
+ const { path, isExport, isSideEffect, importContents, leadingComments } = statement;
76
+ const lines = [];
77
+ if (leadingComments && leadingComments.length > 0) lines.push(...leadingComments);
78
+ if (isSideEffect) {
79
+ if (isExport) lines.push(`export * from "${path}"`);
80
+ else lines.push(`import "${path}"`);
81
+ return lines.join("\n");
82
+ }
83
+ const parts = [];
84
+ const namedParts = [];
85
+ for (const content of importContents){
86
+ if ("default" === content.name) {
87
+ parts.push(content.alias ?? "default");
88
+ continue;
89
+ }
90
+ if ("*" === content.name) {
91
+ parts.push(`* as ${content.alias ?? "namespace"}`);
92
+ continue;
93
+ }
94
+ const typePrefix = "type" === content.type ? "type " : "";
95
+ if (content.alias) namedParts.push(`${typePrefix}${content.name} as ${content.alias}`);
96
+ else namedParts.push(`${typePrefix}${content.name}`);
97
+ }
98
+ if (namedParts.length > 0) parts.push(`{ ${namedParts.join(", ")} }`);
99
+ const importClause = parts.join(", ");
100
+ if (isExport) lines.push(`export ${importClause} from "${path}"`);
101
+ else lines.push(`import ${importClause} from "${path}"`);
102
+ return lines.join("\n");
103
+ }
104
+ function formatGroups(groups, config) {
105
+ const lines = [];
106
+ const separator = config.separator;
107
+ for(let i = 0; i < groups.length; i++){
108
+ const group = groups[i];
109
+ if (void 0 !== separator) {
110
+ let separatorStr;
111
+ separatorStr = "string" == typeof separator ? separator : separator(group, i);
112
+ if (void 0 !== separatorStr) {
113
+ lines.push("");
114
+ if ("" !== separatorStr) lines.push(separatorStr);
115
+ }
116
+ }
117
+ for (const statement of group.importStatements)lines.push(formatImportStatement(statement));
118
+ }
119
+ return lines.join("\n");
120
+ }
121
+ function formatImportStatements(statements) {
122
+ return statements.map(formatImportStatement).join("\n");
123
+ }
124
+ function parseImports(code) {
125
+ const ast = parse(code, {
126
+ sourceType: "module",
127
+ plugins: [
128
+ "typescript",
129
+ "jsx"
130
+ ],
131
+ errorRecovery: true
132
+ });
133
+ const importStatements = [];
134
+ const { body } = ast.program;
135
+ for (const node of body)if ("ImportDeclaration" === node.type || "ExportNamedDeclaration" === node.type && node.source || "ExportAllDeclaration" === node.type) {
136
+ const statement = parseImportNode(node, ast.comments ?? []);
137
+ importStatements.push(statement);
138
+ } else break;
139
+ return importStatements;
140
+ }
141
+ function parseImportNode(node, comments) {
142
+ node.type;
143
+ const source = node.source?.value ?? "";
144
+ const leadingComments = [];
145
+ let start = node.start ?? 0;
146
+ if (node.leadingComments) {
147
+ const firstComment = node.leadingComments[0];
148
+ if (null !== firstComment.start && void 0 !== firstComment.start) start = firstComment.start;
149
+ for (const comment of node.leadingComments)if ("CommentLine" === comment.type) leadingComments.push(`//${comment.value}`);
150
+ else if ("CommentBlock" === comment.type) leadingComments.push(`/*${comment.value}*/`);
151
+ }
152
+ const end = node.end ?? 0;
153
+ if ("ImportDeclaration" === node.type) {
154
+ const importContents = parseImportSpecifiers(node);
155
+ const isSideEffect = 0 === importContents.length;
156
+ return {
157
+ path: source,
158
+ isExport: false,
159
+ isSideEffect,
160
+ importContents,
161
+ leadingComments: leadingComments.length > 0 ? leadingComments : void 0,
162
+ start,
163
+ end
164
+ };
165
+ }
166
+ if ("ExportAllDeclaration" === node.type) return {
167
+ path: source,
168
+ isExport: true,
169
+ isSideEffect: false,
170
+ importContents: [],
171
+ leadingComments: leadingComments.length > 0 ? leadingComments : void 0,
172
+ start,
173
+ end
174
+ };
175
+ const importContents = parseExportSpecifiers(node);
176
+ return {
177
+ path: source,
178
+ isExport: true,
179
+ isSideEffect: false,
180
+ importContents,
181
+ leadingComments: leadingComments.length > 0 ? leadingComments : void 0,
182
+ start,
183
+ end
184
+ };
185
+ }
186
+ function parseImportSpecifiers(node) {
187
+ const contents = [];
188
+ for (const specifier of node.specifiers)if ("ImportDefaultSpecifier" === specifier.type) contents.push({
189
+ name: "default",
190
+ alias: specifier.local.name,
191
+ type: "variable"
192
+ });
193
+ else if ("ImportNamespaceSpecifier" === specifier.type) contents.push({
194
+ name: "*",
195
+ alias: specifier.local.name,
196
+ type: "variable"
197
+ });
198
+ else if ("ImportSpecifier" === specifier.type) {
199
+ const importedName = "Identifier" === specifier.imported.type ? specifier.imported.name : specifier.imported.value;
200
+ const localName = specifier.local.name;
201
+ const isTypeImport = "type" === specifier.importKind;
202
+ contents.push({
203
+ name: importedName,
204
+ alias: importedName !== localName ? localName : void 0,
205
+ type: isTypeImport ? "type" : "variable"
206
+ });
207
+ }
208
+ return contents;
209
+ }
210
+ function parseExportSpecifiers(node) {
211
+ const contents = [];
212
+ if (!node.specifiers) return contents;
213
+ for (const specifier of node.specifiers)if ("ExportSpecifier" === specifier.type) {
214
+ const localName = "Identifier" === specifier.local.type ? specifier.local.name : specifier.local.value;
215
+ const exportedName = "Identifier" === specifier.exported.type ? specifier.exported.name : specifier.exported.value;
216
+ const isTypeExport = "type" === specifier.exportKind;
217
+ contents.push({
218
+ name: localName,
219
+ alias: localName !== exportedName ? exportedName : void 0,
220
+ type: isTypeExport ? "type" : "variable"
221
+ });
222
+ }
223
+ return contents;
224
+ }
225
+ function defaultGetGroup() {
226
+ return "default";
227
+ }
228
+ function defaultSortGroup(a, b) {
229
+ return a.name.localeCompare(b.name);
230
+ }
231
+ function getImportType(path) {
232
+ if (path.startsWith("./") || path.startsWith("../")) return "relative";
233
+ if (path.startsWith("@/") || path.startsWith("~/") || path.startsWith("#/")) return "alias";
234
+ if (path.startsWith("/")) return "alias";
235
+ return "module";
236
+ }
237
+ function getImportTypePriority(type) {
238
+ switch(type){
239
+ case "module":
240
+ return 0;
241
+ case "alias":
242
+ return 1;
243
+ case "relative":
244
+ return 2;
245
+ }
246
+ }
247
+ function defaultSortImportStatement(a, b) {
248
+ const aType = getImportType(a.path);
249
+ const bType = getImportType(b.path);
250
+ const aPriority = getImportTypePriority(aType);
251
+ const bPriority = getImportTypePriority(bType);
252
+ if (aPriority !== bPriority) return aPriority - bPriority;
253
+ return a.path.localeCompare(b.path);
254
+ }
255
+ function defaultSortImportContent(a, b) {
256
+ if ("type" === a.type && "type" !== b.type) return -1;
257
+ if ("type" !== a.type && "type" === b.type) return 1;
258
+ const aName = a.alias ?? a.name;
259
+ const bName = b.alias ?? b.name;
260
+ return aName.localeCompare(bName);
261
+ }
262
+ const DEFAULT_CONFIG = {
263
+ getGroup: defaultGetGroup,
264
+ sortGroup: defaultSortGroup,
265
+ sortImportStatement: defaultSortImportStatement,
266
+ sortImportContent: defaultSortImportContent,
267
+ sortSideEffect: false
268
+ };
269
+ function mergeConfig(userConfig) {
270
+ return {
271
+ getGroup: userConfig.getGroup ?? DEFAULT_CONFIG.getGroup,
272
+ sortGroup: userConfig.sortGroup ?? DEFAULT_CONFIG.sortGroup,
273
+ sortImportStatement: userConfig.sortImportStatement ?? DEFAULT_CONFIG.sortImportStatement,
274
+ sortImportContent: userConfig.sortImportContent ?? DEFAULT_CONFIG.sortImportContent,
275
+ separator: userConfig.separator,
276
+ sortSideEffect: userConfig.sortSideEffect ?? DEFAULT_CONFIG.sortSideEffect,
277
+ removeUnusedImports: userConfig.removeUnusedImports ?? false
278
+ };
279
+ }
280
+ function sortImports(imports, userConfig) {
281
+ const config = mergeConfig(userConfig);
282
+ if (!config.sortSideEffect) return sortImportsWithSideEffectSeparators(imports, config);
283
+ const groups = groupImports(imports, config);
284
+ const sortedGroups = sortGroups(groups, config);
285
+ const result = [];
286
+ for (const group of sortedGroups){
287
+ const sortedStatements = sortImportStatements(group.importStatements, config);
288
+ for (const statement of sortedStatements){
289
+ const sortedContents = sortImportContents(statement.importContents, config);
290
+ result.push({
291
+ ...statement,
292
+ importContents: sortedContents
293
+ });
294
+ }
295
+ }
296
+ return result;
297
+ }
298
+ function sortImportsWithSideEffectSeparators(imports, config) {
299
+ const result = [];
300
+ const chunks = [];
301
+ let currentChunk = [];
302
+ for (const statement of imports)if (statement.isSideEffect) {
303
+ if (currentChunk.length > 0) {
304
+ chunks.push(currentChunk);
305
+ currentChunk = [];
306
+ }
307
+ chunks.push([
308
+ statement
309
+ ]);
310
+ } else currentChunk.push(statement);
311
+ if (currentChunk.length > 0) chunks.push(currentChunk);
312
+ for (const chunk of chunks){
313
+ if (1 === chunk.length && chunk[0].isSideEffect) {
314
+ result.push(chunk[0]);
315
+ continue;
316
+ }
317
+ const groups = groupImports(chunk, config);
318
+ const sortedGroups = sortGroups(groups, config);
319
+ for (const group of sortedGroups){
320
+ const sortedStatements = sortImportStatements(group.importStatements, config);
321
+ for (const statement of sortedStatements){
322
+ const sortedContents = sortImportContents(statement.importContents, config);
323
+ result.push({
324
+ ...statement,
325
+ importContents: sortedContents
326
+ });
327
+ }
328
+ }
329
+ }
330
+ return result;
331
+ }
332
+ function groupImports(imports, userConfig) {
333
+ const config = mergeConfig(userConfig);
334
+ const groupMap = new Map();
335
+ for (const statement of imports){
336
+ const groupName = config.getGroup(statement);
337
+ const statements = groupMap.get(groupName) ?? [];
338
+ statements.push(statement);
339
+ groupMap.set(groupName, statements);
340
+ }
341
+ const groups = [];
342
+ for (const [name, statements] of Array.from(groupMap.entries())){
343
+ const isSideEffect = statements.every((s)=>s.isSideEffect);
344
+ groups.push({
345
+ name,
346
+ isSideEffect,
347
+ importStatements: statements
348
+ });
349
+ }
350
+ return groups;
351
+ }
352
+ function sortGroups(groups, userConfig) {
353
+ const config = mergeConfig(userConfig);
354
+ return [
355
+ ...groups
356
+ ].sort(config.sortGroup);
357
+ }
358
+ function sortImportStatements(statements, userConfig) {
359
+ const config = mergeConfig(userConfig);
360
+ return [
361
+ ...statements
362
+ ].sort(config.sortImportStatement);
363
+ }
364
+ function sortImportContents(contents, userConfig) {
365
+ const config = mergeConfig(userConfig);
366
+ if (userConfig.sortImportContent) return [
367
+ ...contents
368
+ ].sort(config.sortImportContent);
369
+ const defaultImport = contents.filter((c)=>"default" === c.name);
370
+ const namespaceImport = contents.filter((c)=>"*" === c.name);
371
+ const namedImports = contents.filter((c)=>"default" !== c.name && "*" !== c.name);
372
+ return [
373
+ ...defaultImport,
374
+ ...namespaceImport,
375
+ ...namedImports.sort(config.sortImportContent)
376
+ ];
377
+ }
378
+ const src_require = createRequire(import.meta.url);
379
+ let src_userConfig = {};
380
+ function preprocessImports(text, options) {
381
+ try {
382
+ const imports = parseImports(text);
383
+ if (0 === imports.length) return text;
384
+ const config = {
385
+ getGroup: src_userConfig.getGroup ?? options.getGroup,
386
+ sortGroup: src_userConfig.sortGroup ?? options.sortGroup,
387
+ sortImportStatement: src_userConfig.sortImportStatement ?? options.sortImportStatement,
388
+ sortImportContent: src_userConfig.sortImportContent ?? options.sortImportContent,
389
+ separator: src_userConfig.separator ?? options.importSortSeparator ?? options.separator,
390
+ sortSideEffect: src_userConfig.sortSideEffect ?? options.importSortSideEffect ?? false,
391
+ removeUnusedImports: src_userConfig.removeUnusedImports ?? options.importSortRemoveUnused ?? false
392
+ };
393
+ let processedImports = imports;
394
+ if (config.removeUnusedImports) {
395
+ const lastImport = imports[imports.length - 1];
396
+ const codeAfterImports = text.slice(lastImport.end ?? 0);
397
+ processedImports = removeUnusedImportsFromStatements(imports, codeAfterImports);
398
+ }
399
+ const sortedImports = sortImports(processedImports, config);
400
+ let formattedImports;
401
+ if (config.getGroup) {
402
+ const groups = groupImports(sortedImports, config);
403
+ const sortedGroups = sortGroups(groups, config);
404
+ formattedImports = formatGroups(sortedGroups, config);
405
+ } else formattedImports = formatImportStatements(sortedImports);
406
+ const firstImport = imports[0];
407
+ const lastImport = imports[imports.length - 1];
408
+ const startIndex = firstImport.start ?? 0;
409
+ const endIndex = lastImport.end ?? text.length;
410
+ const beforeImports = text.slice(0, startIndex);
411
+ const afterImports = text.slice(endIndex);
412
+ return beforeImports + formattedImports + "\n" + afterImports;
413
+ } catch (error) {
414
+ console.error("Failed to sort imports:", error);
415
+ return text;
416
+ }
417
+ }
418
+ const babelParser = src_require("prettier/parser-babel").parsers.babel;
419
+ const typescriptParser = src_require("prettier/parser-typescript").parsers.typescript;
420
+ const babelTsParser = src_require("prettier/parser-babel").parsers["babel-ts"];
421
+ function createPluginInstance() {
422
+ return {
423
+ parsers: {
424
+ babel: {
425
+ ...babelParser,
426
+ preprocess: preprocessImports
427
+ },
428
+ typescript: {
429
+ ...typescriptParser,
430
+ preprocess: preprocessImports
431
+ },
432
+ "babel-ts": {
433
+ ...babelTsParser,
434
+ preprocess: preprocessImports
435
+ }
436
+ },
437
+ options: {
438
+ importSortSeparator: {
439
+ type: "string",
440
+ category: "Import Sort",
441
+ description: "分组之间的分隔符"
442
+ },
443
+ importSortSideEffect: {
444
+ type: "boolean",
445
+ category: "Import Sort",
446
+ description: "是否对副作用导入进行排序",
447
+ default: false
448
+ },
449
+ importSortRemoveUnused: {
450
+ type: "boolean",
451
+ category: "Import Sort",
452
+ description: "是否删除未使用的导入",
453
+ default: false
454
+ }
455
+ }
456
+ };
457
+ }
458
+ const src_plugin = createPluginInstance();
459
+ function createPlugin(config = {}) {
460
+ src_userConfig = config;
461
+ return createPluginInstance();
462
+ }
463
+ const src = src_plugin;
464
+ export { createPlugin, src as default };
@@ -0,0 +1,3 @@
1
+ import { ImportStatement } from "./types";
2
+ /** 解析导入语句 */
3
+ export declare function parseImports(code: string): ImportStatement[];
@@ -0,0 +1,16 @@
1
+ import { Group, ImportContent, ImportStatement, PluginConfig } from "./types";
2
+ /** 合并后的配置 */
3
+ export interface MergedConfig extends Omit<Required<PluginConfig>, "separator" | "removeUnusedImports"> {
4
+ separator: PluginConfig["separator"];
5
+ removeUnusedImports: boolean;
6
+ }
7
+ /** 对导入语句进行排序 */
8
+ export declare function sortImports(imports: ImportStatement[], userConfig: PluginConfig): ImportStatement[];
9
+ /** 对导入语句进行分组 */
10
+ export declare function groupImports(imports: ImportStatement[], userConfig: PluginConfig): Group[];
11
+ /** 对分组进行排序 */
12
+ export declare function sortGroups(groups: Group[], userConfig: PluginConfig): Group[];
13
+ /** 对导入语句进行排序 */
14
+ export declare function sortImportStatements(statements: ImportStatement[], userConfig: PluginConfig): ImportStatement[];
15
+ /** 对导入内容进行排序 */
16
+ export declare function sortImportContents(contents: ImportContent[], userConfig: PluginConfig): ImportContent[];
@@ -0,0 +1,62 @@
1
+ /** 导入内容 */
2
+ export interface ImportContent {
3
+ /** 导入的内容的名称 */
4
+ name: string;
5
+ /** 导入的内容的别名 */
6
+ alias?: string;
7
+ /** 导入的内容的类型,只有明确在导入前加入了 type 标记的才属于 type 类型,没有明确的加入 type 标记的都属于 variable 类型 */
8
+ type: "type" | "variable";
9
+ }
10
+ /** 导入语句 */
11
+ export interface ImportStatement {
12
+ /** 导入的模块路径,可以是相对路径或绝对路径,比如 react, react-dom 或者 ./utils/index,@/utils/index 等 */
13
+ path: string;
14
+ /** 是否是导出语句,默认为 false */
15
+ isExport: boolean;
16
+ /** 是否是副作用导入,默认为 false */
17
+ isSideEffect: boolean;
18
+ /** 导入的内容 */
19
+ importContents: ImportContent[];
20
+ /** 导入语句上方的注释 */
21
+ leadingComments?: string[];
22
+ /** 在源代码中的起始位置(包括注释) */
23
+ start?: number;
24
+ /** 在源代码中的结束位置 */
25
+ end?: number;
26
+ }
27
+ /** 分组 */
28
+ export interface Group {
29
+ /** 分组名称,默认为 default */
30
+ name: string;
31
+ /** 是否是副作用分组,默认为 false */
32
+ isSideEffect: boolean;
33
+ /** 分组对应的导入语句列表 */
34
+ importStatements: ImportStatement[];
35
+ }
36
+ /** 获取分组名称的函数 */
37
+ export type GetGroupFunction = (importStatement: ImportStatement) => string;
38
+ /** 分组排序函数 */
39
+ export type SortGroupFunction = (a: Group, b: Group) => number;
40
+ /** 导入语句排序函数 */
41
+ export type SortImportStatementFunction = (a: ImportStatement, b: ImportStatement) => number;
42
+ /** 导入内容排序函数 */
43
+ export type SortImportContentFunction = (a: ImportContent, b: ImportContent) => number;
44
+ /** 分隔符函数 */
45
+ export type SeparatorFunction = (group: Group, index: number) => string | undefined;
46
+ /** 插件配置 */
47
+ export interface PluginConfig {
48
+ /** 可选的,获取分组名称 */
49
+ getGroup?: GetGroupFunction;
50
+ /** 可选的,默认按照分组名称的字母顺序排序 */
51
+ sortGroup?: SortGroupFunction;
52
+ /** 可选的,默认按照导入语句的 path 的字母顺序排序 */
53
+ sortImportStatement?: SortImportStatementFunction;
54
+ /** 可选的,默认按照导入内容的 name 的字母顺序排序,默认按照优先 type 类型在前,其次按照最终导入的内容名称的字母顺序排序 */
55
+ sortImportContent?: SortImportContentFunction;
56
+ /** 分隔符,分组之间的分隔符,默认为 undefined */
57
+ separator?: string | SeparatorFunction;
58
+ /** 是否对副作用导入进行排序,默认为 false */
59
+ sortSideEffect?: boolean;
60
+ /** 是否删除未使用的导入,默认为 false */
61
+ removeUnusedImports?: boolean;
62
+ }
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@1adybug/prettier-plugin-sort-imports",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "description": "一个 Prettier 插件,用于对 JavaScript/TypeScript 文件的导入语句进行分组和排序",
6
+ "keywords": [
7
+ "prettier",
8
+ "plugin",
9
+ "import",
10
+ "sort",
11
+ "organize",
12
+ "typescript",
13
+ "javascript"
14
+ ],
15
+ "author": "1adybug <lurongv@qq.com>",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/1adybug/prettier-plugin-sort-imports.git"
20
+ },
21
+ "homepage": "https://github.com/1adybug/prettier-plugin-sort-imports#readme",
22
+ "bugs": {
23
+ "url": "https://github.com/1adybug/prettier-plugin-sort-imports/issues"
24
+ },
25
+ "sideEffects": false,
26
+ "publishConfig": {
27
+ "access": "public",
28
+ "registry": "https://registry.npmjs.com/"
29
+ },
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js"
34
+ }
35
+ },
36
+ "types": "./dist/index.d.ts",
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "scripts": {
41
+ "build": "rslib build",
42
+ "dev": "rslib build --watch",
43
+ "prepublishOnly": "npm run build",
44
+ "format": "prettier --config prettier.config.mjs --write ."
45
+ },
46
+ "devDependencies": {
47
+ "@rslib/core": "^0.15.0",
48
+ "@types/babel__core": "^7.20.5",
49
+ "@types/node": "^22.18.6",
50
+ "prettier": "^3.6.2",
51
+ "supports-color": "^10.2.2",
52
+ "typescript": "^5.9.2"
53
+ },
54
+ "peerDependencies": {
55
+ "prettier": "^3.0.0"
56
+ },
57
+ "dependencies": {
58
+ "@babel/core": "^7.28.4",
59
+ "@babel/parser": "^7.28.4",
60
+ "@babel/types": "^7.28.4"
61
+ }
62
+ }