1- 'use strict' ;
2-
3- import { parse as parseJsonWithComments } from 'comment-json' ;
41import { Rule } from 'eslint' ;
52import fs from 'fs' ;
63import path from 'path' ;
74
5+ import { CompilerOptions } from '../types' ;
6+ import { getCompilerConfigFromFile } from '../utils/getCompilerConfigFromFile' ;
7+
88function findDirWithFile ( filename : string ) {
99 let dir = path . resolve ( filename ) ;
1010
@@ -20,68 +20,48 @@ function findDirWithFile(filename: string) {
2020}
2121
2222function findAlias (
23+ compilerOptions : CompilerOptions ,
2324 baseDir : string ,
2425 importPath : string ,
2526 filePath : string ,
2627 ignoredPaths : string [ ] = [ ] ,
2728) {
28- const isTsconfigExists = fs . existsSync ( path . join ( baseDir , 'tsconfig.json' ) ) ;
29- const isJsconfigExists = fs . existsSync ( path . join ( baseDir , 'jsconfig.json' ) ) ;
30-
31- const configFile = isTsconfigExists
32- ? 'tsconfig.json'
33- : isJsconfigExists
34- ? 'jsconfig.json'
35- : null ;
36-
37- if ( configFile ) {
38- const tsconfig = parseJsonWithComments (
39- fs . readFileSync ( path . join ( baseDir , configFile ) ) . toString ( 'utf8' ) ,
40- ) ;
41-
42- const paths : Record < string , string [ ] > =
43- ( tsconfig as any ) ?. compilerOptions ?. paths ?? { } ;
44- for ( const [ alias , aliasPaths ] of Object . entries ( paths ) ) {
45- // TODO: support full featured glob patterns instead of trivial cases like `@utils/*` and `src/utils/*`
46- const matchedPath = aliasPaths . find ( ( dirPath ) => {
47- // Remove last asterisk
48- const dirPathBase = path
49- . join ( baseDir , dirPath )
50- . split ( '/' )
51- . slice ( 0 , - 1 )
52- . join ( '/' ) ;
53-
54- if ( filePath . startsWith ( dirPathBase ) ) return false ;
55- if (
56- ignoredPaths . some ( ( ignoredPath ) =>
57- ignoredPath . startsWith ( dirPathBase ) ,
58- )
59- )
60- return false ;
61-
62- return importPath . startsWith ( dirPathBase ) ;
63- } ) ;
64-
65- if ( ! matchedPath ) continue ;
66-
67- // Split import path
68- // Remove basedir and slash in start
69- const slicedImportPath = importPath
70- . slice ( baseDir . length + 1 )
71- . slice ( path . dirname ( matchedPath ) . length + 1 ) ;
72-
73- // Remove asterisk from end of alias
74- const replacedPathSegments = path
75- . join ( path . dirname ( alias ) , slicedImportPath )
76- . split ( '/' ) ;
77-
78- // Add index in path
79- return (
80- replacedPathSegments . length === 1
81- ? [ ...replacedPathSegments , 'index' ]
82- : replacedPathSegments
83- ) . join ( '/' ) ;
84- }
29+ for ( const [ alias , aliasPaths ] of Object . entries ( compilerOptions . paths ) ) {
30+ // TODO: support full featured glob patterns instead of trivial cases like `@utils/*` and `src/utils/*`
31+ const matchedPath = aliasPaths . find ( ( dirPath ) => {
32+ // Remove last asterisk
33+ const dirPathBase = path
34+ . join ( baseDir , dirPath )
35+ . split ( '/' )
36+ . slice ( 0 , - 1 )
37+ . join ( '/' ) ;
38+
39+ if ( filePath . startsWith ( dirPathBase ) ) return false ;
40+ if ( ignoredPaths . some ( ( ignoredPath ) => ignoredPath . startsWith ( dirPathBase ) ) )
41+ return false ;
42+
43+ return importPath . startsWith ( dirPathBase ) ;
44+ } ) ;
45+
46+ if ( ! matchedPath ) continue ;
47+
48+ // Split import path
49+ // Remove basedir and slash in start
50+ const slicedImportPath = importPath
51+ . slice ( baseDir . length + 1 )
52+ . slice ( path . dirname ( matchedPath ) . length + 1 ) ;
53+
54+ // Remove asterisk from end of alias
55+ const replacedPathSegments = path
56+ . join ( path . dirname ( alias ) , slicedImportPath )
57+ . split ( '/' ) ;
58+
59+ // Add index in path
60+ return (
61+ replacedPathSegments . length === 1
62+ ? [ ...replacedPathSegments , 'index' ]
63+ : replacedPathSegments
64+ ) . join ( '/' ) ;
8565 }
8666
8767 return null ;
@@ -95,28 +75,34 @@ const rule: Rule.RuleModule = {
9575 } ,
9676 create ( context ) {
9777 const baseDir = findDirWithFile ( 'package.json' ) ;
98-
9978 if ( ! baseDir ) throw new Error ( "Can't find base dir" ) ;
10079
80+ const [ { ignoredPaths = [ ] , configFilePath = null } = { } ] = context . options as [
81+ { ignoredPaths : string [ ] ; configFilePath ?: string } ,
82+ ] ;
83+
84+ const compilerOptions = getCompilerConfigFromFile (
85+ baseDir ,
86+ configFilePath ?? undefined ,
87+ ) ;
88+ if ( ! compilerOptions ) throw new Error ( 'Compiler options did not found' ) ;
89+
10190 return {
10291 ImportDeclaration ( node ) {
103- const [ { ignoredPaths = [ ] } = { } ] = context . options as [
104- { ignoredPaths : string [ ] } ,
105- ] ;
106-
107- const source = node . source . value ;
108- if ( typeof source === 'string' && source . startsWith ( '.' ) ) {
92+ const importPath = node . source . value ;
93+ if ( typeof importPath === 'string' && importPath . startsWith ( '.' ) ) {
10994 const filename = context . getFilename ( ) ;
11095
11196 const resolvedIgnoredPaths = ignoredPaths . map ( ( ignoredPath ) =>
11297 path . normalize ( path . join ( path . dirname ( filename ) , ignoredPath ) ) ,
11398 ) ;
11499
115100 const absolutePath = path . normalize (
116- path . join ( path . dirname ( filename ) , source ) ,
101+ path . join ( path . dirname ( filename ) , importPath ) ,
117102 ) ;
118103
119104 const replacement = findAlias (
105+ compilerOptions ,
120106 baseDir ,
121107 absolutePath ,
122108 filename ,
0 commit comments