Skip to content

Commit e29f044

Browse files
committed
refactor: use eslint-import-context package instead
1 parent ab2d06f commit e29f044

20 files changed

+539
-1522
lines changed

.changeset/four-pumas-leave.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export default config(
9999
'import-x/no-extraneous-dependencies': [
100100
'error',
101101
{
102-
devDependencies: ['test/**'],
102+
devDependencies: ['test/**', 'tsdown.config.ts'],
103103
optionalDependencies: false,
104104
peerDependencies: true,
105105
bundledDependencies: false,

index.d.cts

Lines changed: 0 additions & 3 deletions
This file was deleted.

package.json

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"type": "module",
55
"description": "Import with sanity.",
66
"repository": "https://github.com/un-ts/eslint-plugin-import-x",
7+
"homepage": "https://github.com/un-ts/eslint-plugin-import-x#readme",
78
"author": "JounQin <admin@1stg.me> (https://www.1stG.me)",
89
"funding": "https://opencollective.com/eslint-plugin-import-x",
910
"license": "MIT",
@@ -12,7 +13,7 @@
1213
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1314
},
1415
"main": "lib/index.cjs",
15-
"types": "index.d.cts",
16+
"types": "lib/index.d.cts",
1617
"module": "lib/index.js",
1718
"exports": {
1819
".": {
@@ -21,7 +22,7 @@
2122
"default": "./lib/index.js"
2223
},
2324
"require": {
24-
"types": "./index.d.cts",
25+
"types": "./lib/index.d.cts",
2526
"default": "./lib/index.cjs"
2627
}
2728
},
@@ -32,9 +33,7 @@
3233
"./*": "./lib/*.js"
3334
},
3435
"files": [
35-
"index.d.cts",
36-
"lib",
37-
"!lib/*.tsbuildinfo"
36+
"lib"
3837
],
3938
"keywords": [
4039
"eslint",
@@ -48,9 +47,9 @@
4847
],
4948
"scripts": {
5049
"build": "run-p 'build:*'",
51-
"build:r": "r -f cjs -e named",
5250
"build:tsc": "tsc -p src",
53-
"clean": "rimraf lib",
51+
"build:tsdown": "tsdown --no-clean -d lib -f cjs src/index.ts",
52+
"clean": "premove coverage lib context/lib .eslintcache",
5453
"format": "prettier --write .",
5554
"lint": "run-p 'lint:*'",
5655
"lint:docs": "yarn update:eslint-docs --check",
@@ -70,8 +69,8 @@
7069
"@typescript-eslint/utils": "^8.31.0",
7170
"comment-parser": "^1.4.1",
7271
"debug": "^4.4.0",
72+
"eslint-import-context": "^0.1.3",
7373
"eslint-import-resolver-node": "^0.3.9",
74-
"get-tsconfig": "^4.10.0",
7574
"is-glob": "^4.0.3",
7675
"minimatch": "^9.0.3 || ^10.0.1",
7776
"semver": "^7.7.1",
@@ -101,7 +100,6 @@
101100
"@commitlint/cli": "^19.8.0",
102101
"@eslint/import-test-order-redirect-scoped": "link:./test/fixtures/order-redirect-scoped",
103102
"@eslint/js": "^9.25.1",
104-
"@pkgr/rollup": "^6.0.3",
105103
"@swc-node/jest": "^1.8.13",
106104
"@swc/core": "^1.11.22",
107105
"@swc/helpers": "^0.5.17",
@@ -145,12 +143,13 @@
145143
"nano-staged": "^0.8.0",
146144
"npm-run-all2": "^7.0.2",
147145
"path-serializer": "^0.4.0",
146+
"premove": "^4.0.0",
148147
"prettier": "^3.5.3",
149148
"redux": "^5.0.1",
150-
"rimraf": "^6.0.1",
151149
"simple-git-hooks": "^2.13.0",
152150
"tinyexec": "^1.0.1",
153151
"ts-node": "^10.9.2",
152+
"tsdown": "^0.12.2",
154153
"type-fest": "^4.40.0",
155154
"typescript": "^5.8.3",
156155
"typescript-eslint": "^8.31.0",

src/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"compilerOptions": {
44
"rootDir": ".",
55
"outDir": "../lib"
6-
}
6+
},
7+
"include": ["."]
78
}

src/types.ts

Lines changed: 19 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
2-
import type { TsConfigJsonResolved } from 'get-tsconfig'
2+
import type { PluginName, PluginSettings } from 'eslint-import-context'
33
import type { MinimatchOptions } from 'minimatch'
4-
import type { KebabCase } from 'type-fest'
5-
import type { NapiResolveOptions } from 'unrs-resolver'
64

7-
import type {
8-
ImportType as ImportType_,
9-
LegacyImportResolver,
10-
LegacyResolver,
11-
PluginName,
12-
} from './utils/index.js'
5+
import type { ImportType as ImportType_ } from './utils/index.js'
136

147
export type {
158
LegacyResolver,
@@ -31,97 +24,28 @@ export type {
3124
// ResolverObject
3225
LegacyResolverObject,
3326
LegacyResolverObject as ResolverObject,
34-
} from './utils/index.js'
27+
NodeResolverOptions,
28+
WebpackResolverOptions,
29+
TsResolverOptions,
30+
NewResolverResolve,
31+
NewResolver,
32+
FileExtension,
33+
DocStyle,
34+
ResultNotFound,
35+
ResultFound,
36+
Resolver,
37+
ResolvedResult,
38+
ImportSettings,
39+
WithPluginName,
40+
PluginSettings,
41+
RuleContext,
42+
ChildContext,
43+
} from 'eslint-import-context'
3544

3645
export type ImportType = ImportType_ | 'object' | 'type'
3746

38-
export interface NodeResolverOptions {
39-
extensions?: readonly string[]
40-
moduleDirectory?: string[]
41-
paths?: string[]
42-
}
43-
44-
export interface WebpackResolverOptions {
45-
config?: string | { resolve: NapiResolveOptions }
46-
'config-index'?: number
47-
env?: Record<string, unknown>
48-
argv?: Record<string, unknown>
49-
}
50-
51-
export interface TsResolverOptions extends NapiResolveOptions {
52-
alwaysTryTypes?: boolean
53-
project?: string[] | string
54-
extensions?: string[]
55-
}
56-
57-
export interface ResolveOptionsExtra {
58-
tsconfig?: TsConfigJsonResolved
59-
}
60-
61-
export interface ResolveOptions extends ResolveOptionsExtra {
62-
context: ChildContext | RuleContext
63-
}
64-
65-
// TODO: remove prefix New in the next major version
66-
export type NewResolverResolve = (
67-
modulePath: string,
68-
sourceFile: string,
69-
options: ResolveOptions,
70-
) => ResolvedResult
71-
72-
// TODO: remove prefix New in the next major version
73-
export interface NewResolver {
74-
interfaceVersion: 3
75-
/** Optional name for the resolver, this is used in logs/debug output */
76-
name?: string
77-
resolve: NewResolverResolve
78-
}
79-
80-
export type FileExtension = `.${string}`
81-
82-
export type DocStyle = 'jsdoc' | 'tomdoc'
83-
8447
export type Arrayable<T> = T | readonly T[]
8548

86-
export interface ResultNotFound {
87-
found: false
88-
path?: undefined
89-
}
90-
91-
export interface ResultFound {
92-
found: true
93-
path: string | null
94-
}
95-
96-
export type Resolver = LegacyResolver | NewResolver
97-
98-
export type ResolvedResult = ResultNotFound | ResultFound
99-
100-
export interface ImportSettings {
101-
cache?: {
102-
lifetime?: number | '∞' | 'Infinity'
103-
}
104-
coreModules?: string[]
105-
docstyle?: DocStyle[]
106-
extensions?: readonly FileExtension[]
107-
externalModuleFolders?: string[]
108-
ignore?: string[]
109-
internalRegex?: string
110-
parsers?: Record<string, readonly FileExtension[]>
111-
resolve?: NodeResolverOptions
112-
resolver?: LegacyImportResolver
113-
'resolver-legacy'?: LegacyImportResolver
114-
'resolver-next'?: NewResolver[] | NewResolver
115-
}
116-
117-
export type WithPluginName<T extends string | object> = T extends string
118-
? `${PluginName}/${KebabCase<T>}`
119-
: {
120-
[K in keyof T as WithPluginName<`${KebabCase<K & string>}`>]: T[K]
121-
}
122-
123-
export type PluginSettings = WithPluginName<ImportSettings>
124-
12549
export interface PluginConfig extends TSESLint.ClassicConfig.Config {
12650
plugins?: [PluginName]
12751
settings?: PluginSettings
@@ -137,25 +61,6 @@ export interface PluginFlatConfig extends PluginFlatBaseConfig {
13761
name?: `${PluginName}/${string}`
13862
}
13963

140-
export interface RuleContext<
141-
TMessageIds extends string = string,
142-
TOptions extends readonly unknown[] = readonly unknown[],
143-
> extends Omit<TSESLint.RuleContext<TMessageIds, TOptions>, 'settings'> {
144-
settings: PluginSettings
145-
}
146-
147-
export interface ChildContext {
148-
cacheKey: string
149-
settings: PluginSettings
150-
parserPath?: string | null
151-
parserOptions?: TSESLint.ParserOptions
152-
languageOptions?: TSESLint.FlatConfig.LanguageOptions
153-
path: string
154-
cwd: string
155-
filename: string
156-
physicalFilename: string
157-
}
158-
15964
export interface ParseError extends Error {
16065
lineNumber: number
16166
column: number

src/utils/constants.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/utils/export-map.ts

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import fs from 'node:fs'
2-
import path from 'node:path'
32

43
import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
54
import type * as commentParser from 'comment-parser'
65
import debug from 'debug'
76
import type { AST } from 'eslint'
87
import { SourceCode } from 'eslint'
9-
import type { TsConfigJsonResolved, TsConfigResult } from 'get-tsconfig'
10-
import { getTsconfig } from 'get-tsconfig'
8+
import { getTsconfigWithContext } from 'eslint-import-context'
119
import { stableHash } from 'stable-hash'
1210

1311
import { cjsRequire } from '../require.js'
@@ -32,8 +30,6 @@ const log = debug('eslint-plugin-import-x:ExportMap')
3230

3331
const exportCache = new Map<string, ExportMap | null>()
3432

35-
const tsconfigCache = new Map<string, TsConfigJsonResolved | null | undefined>()
36-
3733
export type DocStyleParsers = Record<
3834
DocStyle,
3935
(comments: TSESTree.Comment[]) => commentParser.Block | undefined
@@ -90,43 +86,6 @@ const parseComment = (comment: string): commentParser.Block => {
9086
}
9187
}
9288

93-
export function getTsconfigWithContext(context: ChildContext | RuleContext) {
94-
const parserOptions =
95-
context.languageOptions?.parserOptions || context.parserOptions
96-
let tsconfigRootDir = parserOptions?.tsconfigRootDir
97-
const project = parserOptions?.project
98-
const cacheKey = stableHash([tsconfigRootDir, project])
99-
let tsConfig: TsConfigJsonResolved | null | undefined
100-
if (tsconfigCache.has(cacheKey)) {
101-
tsConfig = tsconfigCache.get(cacheKey)!
102-
} else {
103-
tsconfigRootDir =
104-
tsconfigRootDir ||
105-
// TODO: uncomment in next major
106-
// || context.cwd
107-
process.cwd()
108-
let tsconfigResult: TsConfigResult | null | undefined
109-
if (project) {
110-
const projects = Array.isArray(project) ? project : [project]
111-
for (const project of projects) {
112-
tsconfigResult = getTsconfig(
113-
project === true
114-
? context.physicalFilename
115-
: path.resolve(tsconfigRootDir, project),
116-
)
117-
if (tsconfigResult) {
118-
break
119-
}
120-
}
121-
} else {
122-
tsconfigResult = getTsconfig(tsconfigRootDir)
123-
}
124-
tsConfig = tsconfigResult?.config
125-
tsconfigCache.set(cacheKey, tsConfig)
126-
}
127-
return tsConfig
128-
}
129-
13089
export class ExportMap {
13190
static for(context: ChildContext) {
13291
const filepath = context.path
@@ -198,13 +157,8 @@ export class ExportMap {
198157
}
199158

200159
static get(source: string, context: RuleContext) {
201-
const tsconfig = lazy(() => getTsconfigWithContext(context))
160+
const path = resolve(source, context)
202161

203-
const path = resolve(
204-
source,
205-
context,
206-
defineLazyProperty({}, 'tsconfig', tsconfig),
207-
)
208162
if (path == null) {
209163
return null
210164
}
@@ -291,13 +245,7 @@ export class ExportMap {
291245
const namespaces = new Map</* identifier */ string, /* source */ string>()
292246

293247
function remotePath(value: string) {
294-
return relative(
295-
value,
296-
filepath,
297-
context.settings,
298-
context,
299-
defineLazyProperty({}, 'tsconfig', tsconfig),
300-
)
248+
return relative(value, filepath, context.settings, context)
301249
}
302250

303251
function resolveImport(value: string) {

src/utils/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
export * from './constants.js'
1+
export type * from 'eslint-import-context'
2+
23
export * from './create-rule.js'
34
export * from './declared-scope.js'
45
export * from './docs-url.js'

0 commit comments

Comments
 (0)