@@ -7,8 +7,56 @@ import stableStringify from 'fast-json-stable-stringify'
7
7
import { stringify as stringifyJson5 } from 'json5'
8
8
9
9
import type { CliCommand , CliCommandArgs } from '..'
10
+ import { createDefaultPreset , createJsWithBabelPreset , createJsWithTsPreset } from '../../presets/create-jest-preset'
11
+ import type { TsJestTransformerOptions } from '../../types'
10
12
import { backportJestConfig } from '../../utils/backports'
11
- import { JestPresetNames , TsJestPresetDescriptor , allPresets , defaults } from '../helpers/presets'
13
+ import { JestPresetNames , type TsJestPresetDescriptor , allPresets } from '../helpers/presets'
14
+
15
+ const migrateGlobalConfigToTransformConfig = (
16
+ transformConfig : Config . InitialOptions [ 'transform' ] ,
17
+ globalsTsJestConfig : TsJestTransformerOptions | undefined ,
18
+ ) => {
19
+ if ( transformConfig ) {
20
+ return Object . entries ( transformConfig ) . reduce ( ( previousValue , currentValue ) => {
21
+ const [ key , transformOptions ] = currentValue
22
+ if ( typeof transformOptions === 'string' && transformOptions . includes ( 'ts-jest' ) ) {
23
+ return {
24
+ ...previousValue ,
25
+ [ key ] : globalsTsJestConfig ? [ 'ts-jest' , globalsTsJestConfig ] : 'ts-jest' ,
26
+ }
27
+ }
28
+
29
+ return {
30
+ ...previousValue ,
31
+ [ key ] : transformOptions ,
32
+ }
33
+ } , { } )
34
+ }
35
+
36
+ return { }
37
+ }
38
+
39
+ const migratePresetToTransformConfig = (
40
+ transformConfig : Config . InitialOptions [ 'transform' ] ,
41
+ preset : TsJestPresetDescriptor | undefined ,
42
+ globalsTsJestConfig : TsJestTransformerOptions | undefined ,
43
+ ) => {
44
+ if ( preset ) {
45
+ const transformConfigFromPreset =
46
+ preset . name === JestPresetNames . jsWithTs
47
+ ? createJsWithTsPreset ( globalsTsJestConfig )
48
+ : preset . name === JestPresetNames . jsWIthBabel
49
+ ? createJsWithBabelPreset ( globalsTsJestConfig )
50
+ : createDefaultPreset ( globalsTsJestConfig )
51
+
52
+ return {
53
+ ...transformConfig ,
54
+ ...transformConfigFromPreset . transform ,
55
+ }
56
+ }
57
+
58
+ return transformConfig
59
+ }
12
60
13
61
/**
14
62
* @internal
@@ -17,7 +65,6 @@ export const run: CliCommand = async (args: CliCommandArgs /* , logger: Logger*/
17
65
const nullLogger = createLogger ( { targets : [ ] } )
18
66
const file = args . _ [ 0 ] ?. toString ( )
19
67
const filePath = resolve ( process . cwd ( ) , file )
20
- const footNotes : string [ ] = [ ]
21
68
if ( ! existsSync ( filePath ) ) {
22
69
throw new Error ( `Configuration file ${ file } does not exists.` )
23
70
}
@@ -36,59 +83,18 @@ export const run: CliCommand = async (args: CliCommandArgs /* , logger: Logger*/
36
83
// migrate
37
84
// first we backport our options
38
85
const migratedConfig = backportJestConfig ( nullLogger , actualConfig )
39
- let presetName : JestPresetNames | undefined
40
86
let preset : TsJestPresetDescriptor | undefined
41
- // then we check if we can use `preset`
42
- if ( ! migratedConfig . preset && args . jestPreset ) {
43
- // find the best preset
87
+ if ( migratedConfig . preset ) {
88
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+ preset = ( allPresets as any ) [ migratedConfig . preset ] ?? allPresets [ JestPresetNames . default ]
90
+ } else {
44
91
if ( args . js ) {
45
- presetName = args . js === 'babel' ? JestPresetNames . jsWIthBabel : JestPresetNames . jsWithTs
46
- } else {
47
- // try to detect what transformer the js extensions would target
48
- const jsTransformers = Object . keys ( migratedConfig . transform || { } ) . reduce ( ( list , pattern ) => {
49
- if ( RegExp ( pattern . replace ( / ^ < r o o t D i r > \/ ? / , '/dummy-project/' ) ) . test ( '/dummy-project/src/foo.js' ) ) {
50
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
- let transformer : string = ( migratedConfig . transform as any ) [ pattern ]
52
- if ( / \b b a b e l - j e s t \b / . test ( transformer ) ) transformer = 'babel-jest'
53
- else if ( / \t s - j e s t \b / . test ( transformer ) ) transformer = 'ts-jest'
54
-
55
- return [ ...list , transformer ]
56
- }
57
-
58
- return list
59
- } , [ ] as string [ ] )
60
- // depending on the transformer found, we use one or the other preset
61
- const jsWithTs = jsTransformers . includes ( 'ts-jest' )
62
- const jsWithBabel = jsTransformers . includes ( 'babel-jest' )
63
- if ( jsWithBabel && ! jsWithTs ) {
64
- presetName = JestPresetNames . jsWIthBabel
65
- } else if ( jsWithTs && ! jsWithBabel ) {
66
- presetName = JestPresetNames . jsWithTs
67
- } else {
68
- // sounds like js files are NOT handled, or handled with a unknown transformer, so we do not need to handle it
69
- presetName = JestPresetNames . default
70
- }
71
- }
72
- // ensure we are using a preset
73
- presetName = presetName ?? JestPresetNames . default
74
- preset = allPresets [ presetName ]
75
- footNotes . push (
76
- `Detected preset '${ preset . label } ' as the best matching preset for your configuration.
77
- Visit https://kulshekhar.github.io/ts-jest/user/config/#jest-preset for more information about presets.
78
- ` ,
79
- )
80
- } else if ( migratedConfig . preset ?. startsWith ( 'ts-jest' ) ) {
81
- if ( args . jestPreset === false ) {
82
- delete migratedConfig . preset
92
+ preset = args . js === 'babel' ? allPresets [ JestPresetNames . jsWIthBabel ] : allPresets [ JestPresetNames . jsWithTs ]
83
93
} else {
84
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
- preset = ( allPresets as any ) [ migratedConfig . preset ] ?? defaults
94
+ preset = allPresets [ JestPresetNames . default ]
86
95
}
87
96
}
88
97
89
- // enforce the correct name
90
- if ( preset ) migratedConfig . preset = preset . name
91
-
92
98
// check the extensions
93
99
if ( migratedConfig . moduleFileExtensions ?. length && preset ) {
94
100
const presetValue = dedupSort ( preset . value . moduleFileExtensions ?? [ ] ) . join ( '::' )
@@ -98,7 +104,7 @@ Visit https://kulshekhar.github.io/ts-jest/user/config/#jest-preset for more inf
98
104
}
99
105
}
100
106
// there is a testRegex, remove our testMatch
101
- if ( ( typeof migratedConfig . testRegex === 'string' || migratedConfig . testRegex ?. length ) && preset ) {
107
+ if ( typeof migratedConfig . testRegex === 'string' || migratedConfig . testRegex ?. length ) {
102
108
delete migratedConfig . testMatch
103
109
}
104
110
// check the testMatch
@@ -110,64 +116,10 @@ Visit https://kulshekhar.github.io/ts-jest/user/config/#jest-preset for more inf
110
116
}
111
117
}
112
118
113
- // migrate the transform
114
- if ( migratedConfig . transform ) {
115
- Object . keys ( migratedConfig . transform ) . forEach ( ( key ) => {
116
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
- const val = ( migratedConfig . transform as any ) [ key ]
118
- if ( typeof val === 'string' && / \/ ? t s - j e s t ? (?: \/ p r e p r o c e s s o r \. j s ) ? $ / . test ( val ) ) {
119
- // eslint-disable-next-line
120
- ; ( migratedConfig . transform as any ) [ key ] = 'ts-jest'
121
- }
122
- } )
123
- }
124
-
125
- // migrate globals config to transformer config
126
119
const globalsTsJestConfig = migratedConfig . globals ?. [ 'ts-jest' ]
127
- if ( globalsTsJestConfig && migratedConfig . transform ) {
128
- Object . keys ( migratedConfig . transform ) . forEach ( ( key ) => {
129
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
- const val = ( migratedConfig . transform as any ) [ key ]
131
- if ( typeof val === 'string' && val . includes ( 'ts-jest' ) ) {
132
- // eslint-disable-next-line
133
- ; ( migratedConfig . transform as any ) [ key ] = Object . keys ( globalsTsJestConfig ) . length ? [ val , globalsTsJestConfig ] : val
134
- }
135
- } )
136
- delete ( migratedConfig . globals ?? Object . create ( null ) ) [ 'ts-jest' ]
137
- }
120
+ migratedConfig . transform = migrateGlobalConfigToTransformConfig ( migratedConfig . transform , globalsTsJestConfig )
121
+ migratedConfig . transform = migratePresetToTransformConfig ( migratedConfig . transform , preset , globalsTsJestConfig )
138
122
139
- // check if it's the same as the preset's one
140
- if ( preset && migratedConfig . transform ) {
141
- if ( stableStringify ( migratedConfig . transform ) === stableStringify ( preset . value . transform ) ) {
142
- delete migratedConfig . transform
143
- } else {
144
- const migratedConfigTransform = migratedConfig . transform
145
- const presetValueTransform = preset . value . transform
146
- if ( migratedConfigTransform && presetValueTransform ) {
147
- migratedConfig . transform = Object . entries ( migratedConfigTransform ) . reduce (
148
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
- ( acc : undefined | Record < string , any > , [ fileRegex , transformerConfig ] ) => {
150
- const presetValueTransformerConfig = presetValueTransform [ fileRegex ]
151
- const shouldRemoveDuplicatedConfig =
152
- ( presetValueTransformerConfig &&
153
- Array . isArray ( presetValueTransformerConfig ) &&
154
- transformerConfig === presetValueTransformerConfig [ 0 ] &&
155
- ! Object . keys ( presetValueTransformerConfig [ 1 ] ) . length ) ||
156
- transformerConfig === presetValueTransformerConfig
157
-
158
- return shouldRemoveDuplicatedConfig
159
- ? acc
160
- : acc
161
- ? { ...acc , [ fileRegex ] : transformerConfig }
162
- : { [ fileRegex ] : transformerConfig }
163
- } ,
164
- undefined ,
165
- )
166
- }
167
- }
168
- }
169
-
170
- // cleanup
171
123
cleanupConfig ( actualConfig )
172
124
cleanupConfig ( migratedConfig )
173
125
const before = stableStringify ( actualConfig )
@@ -183,48 +135,16 @@ No migration needed for given Jest configuration
183
135
const stringify = file . endsWith ( '.json' ) ? JSON . stringify : stringifyJson5
184
136
const prefix = file . endsWith ( '.json' ) ? '"jest": ' : 'module.exports = '
185
137
186
- // if we are using preset, inform the user that he might be able to remove some section(s)
187
- // we couldn't check for equality
188
- // if (usesPreset && migratedConfig.testMatch) {
189
- // footNotes.push(`
190
- // I couldn't check if your "testMatch" value is the same as mine which is: ${stringify(
191
- // presets.testMatch,
192
- // undefined,
193
- // ' ',
194
- // )}
195
- // If it is the case, you can safely remove the "testMatch" from what I've migrated.
196
- // `)
197
- // }
198
- if ( preset && migratedConfig . transform ) {
199
- footNotes . push ( `
200
- I couldn't check if your "transform" value is the same as mine which is: ${ stringify (
201
- preset . value . transform ,
202
- undefined ,
203
- ' ' ,
204
- ) }
205
- If it is the case, you can safely remove the "transform" from what I've migrated.
206
- ` )
207
- }
208
-
209
138
// output new config
210
139
process . stderr . write ( `
211
140
Migrated Jest configuration:
212
141
` )
213
142
process . stdout . write ( `${ prefix } ${ stringify ( migratedConfig , undefined , ' ' ) } \n` )
214
- if ( footNotes . length ) {
215
- process . stderr . write ( `
216
- ${ footNotes . join ( '\n' ) }
217
- ` )
218
- }
219
143
}
220
144
221
145
function cleanupConfig ( config : Config . InitialOptions ) : void {
222
146
if ( config . globals ) {
223
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
224
- if ( ( config as any ) . globals [ 'ts-jest' ] && Object . keys ( ( config as any ) . globals [ 'ts-jest' ] ) . length === 0 ) {
225
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
226
- delete ( config as any ) . globals [ 'ts-jest' ]
227
- }
147
+ delete config . globals [ 'ts-jest' ]
228
148
if ( ! Object . keys ( config . globals ) . length ) {
229
149
delete config . globals
230
150
}
@@ -240,7 +160,7 @@ function cleanupConfig(config: Config.InitialOptions): void {
240
160
config . testMatch = dedupSort ( config . testMatch )
241
161
if ( ! config . testMatch . length ) delete config . testMatch
242
162
}
243
- if ( config . preset === JestPresetNames . default ) config . preset = defaults . name
163
+ delete config . preset
244
164
}
245
165
246
166
// eslint-disable-next-line @typescript-eslint/no-explicit-any
0 commit comments