Skip to content

Commit

Permalink
fix: organize imports
Browse files Browse the repository at this point in the history
  • Loading branch information
rintoj committed Jun 14, 2024
1 parent d1477f5 commit a761115
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 12 deletions.
21 changes: 21 additions & 0 deletions src/ts/create-import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,24 @@ export function createImport(from: string, ...imports: string[]) {
undefined,
)
}

export function createDefaultImport(from: string, name: string) {
return ts.factory.createImportDeclaration(
undefined,
ts.factory.createImportClause(false, ts.factory.createIdentifier(name), undefined),
ts.factory.createStringLiteral(from),
undefined,
)
}
export function createNamespaceImport(from: string, name: string) {
return ts.factory.createImportDeclaration(
undefined,
ts.factory.createImportClause(
false,
undefined,
ts.factory.createNamespaceImport(ts.factory.createIdentifier(name)),
),
ts.factory.createStringLiteral(from),
undefined,
)
}
4 changes: 4 additions & 0 deletions src/ts/organize-import.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ describe('organizeImport', () => {
import { Shipment } from './shipment.model'
import { ShipmentType, TransactionStatus } from './shipment.type'
import { Context, Parent, ResolveField, Resolver } from '@nestjs/graphql'
import gql from 'graphql'
import * as ts from 'typescript'
`)
const code = await prettify(printTS(organizeImports(sourceFile)))
expect(toParsedOutput(code)).toEqual(
toParsedOutput(`
import { Context, Parent, ResolveField, Resolver } from '@nestjs/graphql'
import gql from 'graphql'
import * as ts from 'typescript'
import { FieldResolver } from '../../common/field-resolver-type'
import { GQLContext } from '../../context'
import { ReturnService } from '../return/return.service'
Expand Down
40 changes: 28 additions & 12 deletions src/ts/organize-imports.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
import ts from 'typescript'
import { createImport } from './create-import'
import { createDefaultImport, createImport, createNamespaceImport } from './create-import'

export function organizeImports(sourceFile: ts.SourceFile): ts.SourceFile {
const importStatements: { [id: string]: Set<string> } = {}
const importStatements: {
[id: string]: { names: Set<string>; isDefault?: boolean; isNamespaceImport?: boolean }
} = {}
sourceFile.statements.map((statement: any) => {
if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
const importFrom = statement.moduleSpecifier.text
if (!importStatements[importFrom]) {
importStatements[importFrom] = new Set()
importStatements[importFrom] = { names: new Set() }
}
if (statement.importClause) {
if (statement.importClause.name && ts.isIdentifier(statement.importClause.name)) {
importStatements[importFrom].add(statement.importClause.name.text)
importStatements[importFrom].names.add(statement.importClause.name.text)
importStatements[importFrom].isDefault = true
} else if (
statement.importClause.namedBindings &&
ts.isNamespaceImport(statement.importClause.namedBindings) &&
ts.isIdentifier(statement.importClause.namedBindings.name)
) {
importStatements[importFrom].names.add(statement.importClause.namedBindings.name.text)
importStatements[importFrom].isNamespaceImport = true
} else if (
statement.importClause.namedBindings &&
ts.isNamedImports(statement.importClause.namedBindings)
) {
statement.importClause.namedBindings.elements.map(el =>
importStatements[importFrom].add(el.name.text),
importStatements[importFrom].names.add(el.name.text),
)
}
}
Expand All @@ -26,8 +36,8 @@ export function organizeImports(sourceFile: ts.SourceFile): ts.SourceFile {
})

const sortedFileNameMap = Object.keys(importStatements)
.filter(fromFile => !!importStatements[fromFile].size)
.map(from => ({ from, firstImport: Array.from(importStatements[from]).sort()[0] }))
.filter(fromFile => !!importStatements[fromFile].names.size)
.map(from => ({ from, firstImport: Array.from(importStatements[from].names).sort()[0] }))

const sortImport = (a: any, b: any) => {
const value = a.from.localeCompare(b.from)
Expand All @@ -49,12 +59,18 @@ export function organizeImports(sourceFile: ts.SourceFile): ts.SourceFile {
...sourceFile,
statements: [
...Object.keys(importStatements)
.filter(fromFile => !importStatements[fromFile].size)
.filter(fromFile => !importStatements[fromFile].names.size)
.sort()
.map(fromFile => createImport(fromFile, ...Array.from(importStatements[fromFile]).sort())),
...sortedFileNames.map(fromFile =>
createImport(fromFile, ...Array.from(importStatements[fromFile]).sort()),
),
.map(fromFile => createImport(fromFile)),
...sortedFileNames.map(fromFile => {
const importStatement = importStatements[fromFile]
if (importStatement.isDefault) {
return createDefaultImport(fromFile, Array.from(importStatement.names)[0])
} else if (importStatement.isNamespaceImport) {
return createNamespaceImport(fromFile, Array.from(importStatement.names)[0])
}
return createImport(fromFile, ...Array.from(importStatement.names).sort())
}),
...sourceFile.statements.filter(statement => !ts.isImportDeclaration(statement)),
] as any,
}
Expand Down
5 changes: 5 additions & 0 deletions src/ts/update-statements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ts from 'typescript'

export function updateStatements(node: ts.SourceFile, statements: ts.Statement[]): ts.SourceFile {
return { ...node, statements: statements as any }
}

0 comments on commit a761115

Please sign in to comment.