1
1
import type { RuleContext } from '../types.js' ;
2
2
import fs from 'fs' ;
3
3
import path from 'path' ;
4
- import { getPackageJson } from './get-package-json.js' ;
4
+ import { getPackageJsons } from './get-package-json.js' ;
5
5
import { getFilename , getSourceCode } from './compat.js' ;
6
6
7
7
const isRunInBrowser = ! fs . readFileSync ;
8
8
9
- export type SvelteContext = {
10
- svelteVersion : '3/4' | '5' | 'undetermined' ;
11
- svelteFileType : '.svelte' | '.svelte.[js|ts]' | null ;
12
- runes : boolean | 'undetermined' ;
13
- svelteKitVersion : '1-next' | '1' | '2' | null ;
9
+ export type SvelteContext = (
10
+ | ( {
11
+ svelteVersion : '3/4' ;
12
+ } & {
13
+ svelteFileType : '.svelte' | 'other' ;
14
+ runes : null ;
15
+ } )
16
+ | ( {
17
+ svelteVersion : '5' ;
18
+ } & (
19
+ | {
20
+ svelteFileType : '.svelte' | '.svelte.[js|ts]' ;
21
+ /** If a user uses a parser other than `svelte-eslint-parser`, `undetermined` will be set. */
22
+ runes : boolean | 'undetermined' ;
23
+ }
24
+ | {
25
+ /** e.g. `foo.js` / `package.json` */
26
+ svelteFileType : 'other' ;
27
+ runes : null ;
28
+ }
29
+ ) )
30
+ | {
31
+ /** For projects that do not use Svelte. */
32
+ svelteVersion : null ;
33
+ svelteFileType : null ;
34
+ runes : null ;
35
+ }
36
+ ) & {
37
+ svelteKitVersion : '1.0.0-next' | '1' | '2' | null ;
14
38
svelteKitFileType :
15
39
| '+page.svelte'
16
40
| '+page.js'
@@ -23,7 +47,7 @@ export type SvelteContext = {
23
47
| null ;
24
48
} ;
25
49
26
- function getSvelteFileType ( filePath : string ) : SvelteContext [ 'svelteFileType' ] | null {
50
+ function getSvelteFileType ( filePath : string ) : NonNullable < SvelteContext [ 'svelteFileType' ] > {
27
51
if ( filePath . endsWith ( '.svelte' ) ) {
28
52
return '.svelte' ;
29
53
}
@@ -32,7 +56,7 @@ function getSvelteFileType(filePath: string): SvelteContext['svelteFileType'] |
32
56
return '.svelte.[js|ts]' ;
33
57
}
34
58
35
- return null ;
59
+ return 'other' ;
36
60
}
37
61
38
62
function getSvelteKitFileTypeFromFilePath ( filePath : string ) : SvelteContext [ 'svelteKitFileType' ] {
@@ -112,6 +136,29 @@ function getSvelteKitContext(
112
136
} ;
113
137
}
114
138
139
+ function getSvelteVersion ( filePath : string ) : SvelteContext [ 'svelteVersion' ] {
140
+ // Hack: if it runs in browser, it regards as Svelte project.
141
+ if ( isRunInBrowser ) return '5' ;
142
+ try {
143
+ const packageJsons = getPackageJsons ( filePath ) ;
144
+ for ( const packageJson of packageJsons ) {
145
+ const version = packageJson . dependencies ?. svelte ?? packageJson . devDependencies ?. svelte ;
146
+ if ( typeof version !== 'string' ) {
147
+ continue ;
148
+ }
149
+ const major = version . split ( '.' ) [ 0 ] ;
150
+ if ( major === '3' || major === '4' ) {
151
+ return '3/4' ;
152
+ }
153
+ return major as SvelteContext [ 'svelteVersion' ] ;
154
+ }
155
+ } catch {
156
+ /** do nothing */
157
+ }
158
+
159
+ return null ;
160
+ }
161
+
115
162
/**
116
163
* Check givin file is under SvelteKit project.
117
164
*
@@ -124,41 +171,28 @@ function getSvelteKitVersion(filePath: string): SvelteContext['svelteKitVersion'
124
171
// Hack: if it runs in browser, it regards as SvelteKit project.
125
172
if ( isRunInBrowser ) return '2' ;
126
173
try {
127
- const packageJson = getPackageJson ( filePath ) ;
128
- if ( ! packageJson ) return null ;
129
- if ( packageJson . name === 'eslint-plugin-svelte' )
174
+ const packageJsons = getPackageJsons ( filePath ) ;
175
+ if ( packageJsons . length === 0 ) return null ;
176
+ if ( packageJsons [ 0 ] . name === 'eslint-plugin-svelte' ) {
130
177
// Hack: CI removes `@sveltejs/kit` and it returns false and test failed.
131
- // So always it returns true if it runs on the package.
178
+ // So always it returns 2 if it runs on the package.
132
179
return '2' ;
133
-
134
- const version =
135
- packageJson . dependencies ?. [ '@sveltejs/kit' ] ?? packageJson . devDependencies ?. [ '@sveltejs/kit' ] ;
136
- if ( typeof version !== 'string' ) {
137
- return null ;
138
180
}
139
- if ( version . startsWith ( '1.0.0-next.' ) ) {
140
- return '1-next' ;
141
- } else if ( version . startsWith ( '1.' ) ) {
142
- return '1' ;
143
- } else if ( version . startsWith ( '2.' ) ) {
144
- return '2' ;
181
+
182
+ for ( const packageJson of packageJsons ) {
183
+ const version =
184
+ packageJson . dependencies ?. [ '@sveltejs/kit' ] ??
185
+ packageJson . devDependencies ?. [ '@sveltejs/kit' ] ;
186
+ if ( typeof version !== 'string' ) {
187
+ return null ;
188
+ }
189
+ return version . split ( '.' ) [ 0 ] as SvelteContext [ 'svelteKitVersion' ] ;
145
190
}
146
- // If unknown version, it recognize as v2.
147
- return '2' ;
148
191
} catch {
149
- return null ;
192
+ /** do nothing */
150
193
}
151
- }
152
194
153
- function getSvelteVersion ( compilerVersion : string | undefined ) : SvelteContext [ 'svelteVersion' ] {
154
- if ( compilerVersion == null ) {
155
- return 'undetermined' ;
156
- }
157
- const version = parseInt ( compilerVersion . split ( '.' ) [ 0 ] , 10 ) ;
158
- if ( version === 3 || version === 4 ) {
159
- return '3/4' ;
160
- }
161
- return String ( version ) as '5' ;
195
+ return null ;
162
196
}
163
197
164
198
/**
@@ -168,22 +202,57 @@ function getSvelteVersion(compilerVersion: string | undefined): SvelteContext['s
168
202
*/
169
203
function getProjectRootDir ( filePath : string ) : string | null {
170
204
if ( isRunInBrowser ) return null ;
171
- const packageJsonFilePath = getPackageJson ( filePath ) ?. filePath ;
205
+ const packageJsons = getPackageJsons ( filePath ) ;
206
+ if ( packageJsons . length === 0 ) {
207
+ return null ;
208
+ }
209
+ const packageJsonFilePath = packageJsons [ 0 ] . filePath ;
172
210
if ( ! packageJsonFilePath ) return null ;
173
211
return path . dirname ( path . resolve ( packageJsonFilePath ) ) ;
174
212
}
175
213
176
214
export function getSvelteContext ( context : RuleContext ) : SvelteContext | null {
177
215
const { parserServices } = getSourceCode ( context ) ;
178
216
const { svelteParseContext } = parserServices ;
179
- const compilerVersion = svelteParseContext ?. compilerVersion ;
180
217
const filePath = getFilename ( context ) ;
181
218
const svelteKitContext = getSvelteKitContext ( context ) ;
219
+ const svelteVersion = getSvelteVersion ( filePath ) ;
220
+ const svelteFileType = getSvelteFileType ( filePath ) ;
221
+
222
+ if ( svelteVersion == null ) {
223
+ return {
224
+ svelteVersion : null ,
225
+ svelteFileType : null ,
226
+ runes : null ,
227
+ svelteKitVersion : svelteKitContext . svelteKitVersion ,
228
+ svelteKitFileType : svelteKitContext . svelteKitFileType
229
+ } ;
230
+ }
231
+
232
+ if ( svelteFileType === 'other' ) {
233
+ return {
234
+ svelteVersion,
235
+ svelteFileType,
236
+ runes : null ,
237
+ svelteKitVersion : svelteKitContext . svelteKitVersion ,
238
+ svelteKitFileType : svelteKitContext . svelteKitFileType
239
+ } ;
240
+ }
241
+
242
+ if ( svelteVersion === '3/4' ) {
243
+ return {
244
+ svelteVersion,
245
+ svelteFileType : svelteFileType === '.svelte' ? '.svelte' : 'other' ,
246
+ runes : null ,
247
+ svelteKitVersion : svelteKitContext . svelteKitVersion ,
248
+ svelteKitFileType : svelteKitContext . svelteKitFileType
249
+ } ;
250
+ }
182
251
183
252
return {
184
- svelteVersion : getSvelteVersion ( compilerVersion ) ,
253
+ svelteVersion,
185
254
runes : svelteParseContext ?. runes ?? 'undetermined' ,
186
- svelteFileType : getSvelteFileType ( filePath ) ,
255
+ svelteFileType,
187
256
svelteKitVersion : svelteKitContext . svelteKitVersion ,
188
257
svelteKitFileType : svelteKitContext . svelteKitFileType
189
258
} ;
0 commit comments