1
1
"use strict"
2
2
3
+ const { getTSConfig, getTSConfigForFile } = require ( "./get-tsconfig" )
4
+
3
5
const DEFAULT_MAPPING = normalise ( [
6
+ [ "" , ".js" ] ,
7
+ [ ".ts" , ".js" ] ,
8
+ [ ".cts" , ".cjs" ] ,
9
+ [ ".mts" , ".mjs" ] ,
10
+ [ ".tsx" , ".js" ] ,
11
+ ] )
12
+
13
+ const PRESERVE_MAPPING = normalise ( [
4
14
[ "" , ".js" ] ,
5
15
[ ".ts" , ".js" ] ,
6
16
[ ".cts" , ".cjs" ] ,
7
17
[ ".mts" , ".mjs" ] ,
8
18
[ ".tsx" , ".jsx" ] ,
9
19
] )
10
20
21
+ const tsConfigMapping = {
22
+ react : DEFAULT_MAPPING , // Emit .js files with JSX changed to the equivalent React.createElement calls
23
+ "react-jsx" : DEFAULT_MAPPING , // Emit .js files with the JSX changed to _jsx calls
24
+ "react-jsxdev" : DEFAULT_MAPPING , // Emit .js files with the JSX changed to _jsx calls
25
+ "react-native" : DEFAULT_MAPPING , // Emit .js files with the JSX unchanged
26
+ preserve : PRESERVE_MAPPING , // Emit .jsx files with the JSX unchanged
27
+ }
28
+
11
29
/**
12
30
* @typedef {Object } ExtensionMap
13
31
* @property {Record<string, string> } forward Convert from typescript to javascript
@@ -28,6 +46,22 @@ function normalise(typescriptExtensionMap) {
28
46
return { forward, backward }
29
47
}
30
48
49
+ /**
50
+ * Attempts to get the ExtensionMap from the resolved tsconfig.
51
+ *
52
+ * @param {import("get-tsconfig").TsConfigJsonResolved } [tsconfig] - The resolved tsconfig
53
+ * @returns {ExtensionMap } The `typescriptExtensionMap` value, or `null`.
54
+ */
55
+ function getMappingFromTSConfig ( tsconfig ) {
56
+ const jsx = tsconfig ?. compilerOptions ?. jsx
57
+
58
+ if ( { } . hasOwnProperty . call ( tsConfigMapping , jsx ) ) {
59
+ return tsConfigMapping [ jsx ]
60
+ }
61
+
62
+ return null
63
+ }
64
+
31
65
/**
32
66
* Gets `typescriptExtensionMap` property from a given option object.
33
67
*
@@ -36,46 +70,82 @@ function normalise(typescriptExtensionMap) {
36
70
*/
37
71
function get ( option ) {
38
72
if (
39
- option &&
40
- option . typescriptExtensionMap &&
41
- Array . isArray ( option . typescriptExtensionMap )
73
+ { } . hasOwnProperty . call ( tsConfigMapping , option ?. typescriptExtensionMap )
42
74
) {
75
+ return tsConfigMapping [ option . typescriptExtensionMap ]
76
+ }
77
+
78
+ if ( Array . isArray ( option ?. typescriptExtensionMap ) ) {
43
79
return normalise ( option . typescriptExtensionMap )
44
80
}
45
81
82
+ if ( option ?. tsconfigPath ) {
83
+ return getMappingFromTSConfig ( getTSConfig ( option ?. tsconfigPath ) )
84
+ }
85
+
46
86
return null
47
87
}
48
88
89
+ /**
90
+ * Attempts to get the ExtensionMap from the tsconfig of a given file.
91
+ *
92
+ * @param {string } filename - The filename we're getting from
93
+ * @returns {ExtensionMap } The `typescriptExtensionMap` value, or `null`.
94
+ */
95
+ function getFromTSConfigFromFile ( filename ) {
96
+ return getMappingFromTSConfig ( getTSConfigForFile ( filename ) ?. config )
97
+ }
98
+
49
99
/**
50
100
* Gets "typescriptExtensionMap" setting.
51
101
*
52
- * 1. This checks `options` property, then returns it if exists.
53
- * 2. This checks `settings.n` | `settings.node` property, then returns it if exists.
54
- * 3. This returns `DEFAULT_MAPPING`.
102
+ * 1. This checks `options.typescriptExtensionMap`, if its an array then it gets returned.
103
+ * 2. This checks `options.typescriptExtensionMap`, if its a string, convert to the correct mapping.
104
+ * 3. This checks `settings.n.typescriptExtensionMap`, if its an array then it gets returned.
105
+ * 4. This checks `settings.node.typescriptExtensionMap`, if its an array then it gets returned.
106
+ * 5. This checks `settings.n.typescriptExtensionMap`, if its a string, convert to the correct mapping.
107
+ * 6. This checks `settings.node.typescriptExtensionMap`, if its a string, convert to the correct mapping.
108
+ * 7. This checks for a `tsconfig.json` `config.compilerOptions.jsx` property, if its a string, convert to the correct mapping.
109
+ * 8. This returns `PRESERVE_MAPPING`.
55
110
*
56
- * @param {import(' eslint' ).Rule.RuleContext } context - The rule context.
111
+ * @param {import(" eslint" ).Rule.RuleContext } context - The rule context.
57
112
* @returns {string[] } A list of extensions.
58
113
*/
59
114
module . exports = function getTypescriptExtensionMap ( context ) {
60
115
return (
61
- get ( context . options && context . options [ 0 ] ) ||
62
- get (
63
- context . settings && ( context . settings . n || context . settings . node )
116
+ get ( context . options ?. [ 0 ] ) ||
117
+ get ( context . settings ?. n ?? context . settings ?. node ) ||
118
+ getFromTSConfigFromFile (
119
+ // eslint ^8
120
+ context . physicalFilename ??
121
+ // eslint ^7.28 (deprecated ^8)
122
+ context . getPhysicalFilename ?. ( ) ??
123
+ // eslint ^8 (if physicalFilename undefined)
124
+ context . filename ??
125
+ // eslint ^7 (deprecated ^8)
126
+ context . getFilename ?. ( )
64
127
) ||
65
- // TODO: Detect tsconfig.json here
66
- DEFAULT_MAPPING
128
+ PRESERVE_MAPPING
67
129
)
68
130
}
69
131
70
132
module . exports . schema = {
71
- type : "array" ,
72
- items : {
73
- type : "array" ,
74
- prefixItems : [
75
- { type : "string" , pattern : "^(?:|\\.\\w+)$" } ,
76
- { type : "string" , pattern : "^\\.\\w+$" } ,
77
- ] ,
78
- additionalItems : false ,
79
- } ,
80
- uniqueItems : true ,
133
+ oneOf : [
134
+ {
135
+ type : "array" ,
136
+ items : {
137
+ type : "array" ,
138
+ prefixItems : [
139
+ { type : "string" , pattern : "^(?:|\\.\\w+)$" } ,
140
+ { type : "string" , pattern : "^\\.\\w+$" } ,
141
+ ] ,
142
+ additionalItems : false ,
143
+ } ,
144
+ uniqueItems : true ,
145
+ } ,
146
+ {
147
+ type : "string" ,
148
+ enum : Object . keys ( tsConfigMapping ) ,
149
+ } ,
150
+ ] ,
81
151
}
0 commit comments