@@ -6,16 +6,19 @@ import { basename, resolve } from 'path'
66import { Arguments } from 'yargs'
77
88import { CliCommand } from '..'
9- import { createJestPreset } from '../../config/create-jest-preset '
9+ import { TsJestPresets } from '../../types '
1010import { backportJestConfig } from '../../util/backports'
1111
12+ const DEFAULT_PRESET = 'ts-jest/presets/default'
13+
1214/**
1315 * @internal
1416 */
1517export const run : CliCommand = async ( args : Arguments /*, logger: Logger*/ ) => {
1618 const nullLogger = createLogger ( { targets : [ ] } )
1719 const file = args . _ [ 0 ]
1820 const filePath = resolve ( process . cwd ( ) , file )
21+ const footNotes : string [ ] = [ ]
1922 if ( ! existsSync ( filePath ) ) {
2023 throw new Error ( `Configuration file ${ file } does not exists.` )
2124 }
@@ -33,29 +36,71 @@ export const run: CliCommand = async (args: Arguments /*, logger: Logger*/) => {
3336 // migrate
3437 // first we backport our options
3538 const migratedConfig = backportJestConfig ( nullLogger , actualConfig )
39+ let presetName : string | undefined
3640 // then we check if we can use `preset`
3741 if ( ! migratedConfig . preset && args . jestPreset ) {
38- migratedConfig . preset = 'ts-jest'
39- } else if ( ! args . jestPreset && migratedConfig . preset === 'ts-jest' ) {
40- delete migratedConfig . preset
42+ // find the best preset
43+ if ( args . allowJs ) presetName = 'ts-jest/presets/js-with-ts'
44+ else {
45+ // try to detect what transformer the js extensions would target
46+ const jsTransformers = Object . keys ( migratedConfig . transform || { } ) . reduce (
47+ ( list , pattern ) => {
48+ if ( RegExp ( pattern . replace ( / ^ < r o o t D i r > \/ ? / , '/dummy-project/' ) ) . test ( '/dummy-project/src/foo.js' ) ) {
49+ let transformer : string = ( migratedConfig . transform as any ) [ pattern ]
50+ if ( / \b b a b e l - j e s t \b / . test ( transformer ) ) transformer = 'babel-jest'
51+ else if ( / \t s - j e s t \b / . test ( transformer ) ) transformer = 'ts-jest'
52+ return [ ...list , transformer ]
53+ }
54+ return list
55+ } ,
56+ [ ] as string [ ] ,
57+ )
58+ // depending on the transformer found, we use one or the other preset
59+ const jsWithTs = jsTransformers . includes ( 'ts-jest' )
60+ const jsWithBabel = jsTransformers . includes ( 'babel-jest' )
61+ if ( jsWithBabel && ! jsWithTs ) {
62+ presetName = 'ts-jest/presets/js-with-babel'
63+ } else if ( jsWithTs && ! jsWithBabel ) {
64+ presetName = 'ts-jest/presets/js-with-ts'
65+ } else {
66+ // sounds like js files are NOT handled, or handled with a unknown transformer, so we do not need to handle it
67+ presetName = DEFAULT_PRESET
68+ }
69+ }
70+ // ensure we are using a preset
71+ presetName = presetName || DEFAULT_PRESET
72+ migratedConfig . preset = presetName
73+ footNotes . push (
74+ `Detected preset '${ presetName . replace (
75+ / ^ t s - j e s t \/ p r e s e t s \/ / ,
76+ '' ,
77+ ) } ' as the best matching preset for your configuration.\nVisit https://kulshekhar.github.io/ts-jest/user/config/#jest-preset for more information about presets.\n`,
78+ )
79+ } else if ( migratedConfig . preset && migratedConfig . preset . startsWith ( 'ts-jest' ) ) {
80+ if ( args . jestPreset === false ) {
81+ delete migratedConfig . preset
82+ } else {
83+ presetName = migratedConfig . preset
84+ }
4185 }
42- const usesPreset = migratedConfig . preset === 'ts-jest'
43- const presets = createJestPreset ( { allowJs : args . allowJs } )
86+ const presets : TsJestPresets | undefined = presetName
87+ ? require ( `../../../${ presetName . replace ( / ^ t s - j e s t \/ / , '' ) } /jest-preset` )
88+ : undefined
4489
4590 // check the extensions
46- if ( migratedConfig . moduleFileExtensions && migratedConfig . moduleFileExtensions . length && usesPreset ) {
91+ if ( migratedConfig . moduleFileExtensions && migratedConfig . moduleFileExtensions . length && presets ) {
4792 const presetValue = dedupSort ( presets . moduleFileExtensions ) . join ( '::' )
4893 const migratedValue = dedupSort ( migratedConfig . moduleFileExtensions ) . join ( '::' )
4994 if ( presetValue === migratedValue ) {
5095 delete migratedConfig . moduleFileExtensions
5196 }
5297 }
5398 // there is a testRegex, remove our testMatch
54- if ( migratedConfig . testRegex && usesPreset ) {
99+ if ( migratedConfig . testRegex && presets ) {
55100 migratedConfig . testMatch = null as any
56101 }
57102 // check the testMatch
58- else if ( migratedConfig . testMatch && migratedConfig . testMatch . length && usesPreset ) {
103+ else if ( migratedConfig . testMatch && migratedConfig . testMatch . length && presets ) {
59104 const presetValue = dedupSort ( presets . testMatch ) . join ( '::' )
60105 const migratedValue = dedupSort ( migratedConfig . testMatch ) . join ( '::' )
61106 if ( presetValue === migratedValue ) {
@@ -75,7 +120,7 @@ export const run: CliCommand = async (args: Arguments /*, logger: Logger*/) => {
75120 }
76121 // check if it's the same as the preset's one
77122 if (
78- usesPreset &&
123+ presets &&
79124 migratedConfig . transform &&
80125 stringifyJson ( migratedConfig . transform ) === stringifyJson ( presets . transform )
81126 ) {
@@ -95,7 +140,7 @@ No migration needed for given Jest configuration
95140 }
96141
97142 const stringify = / \. j s o n $ / . test ( file ) ? JSON . stringify : stringifyJson5
98- const footNotes : string [ ] = [ ]
143+ const prefix = / \. j s o n $ / . test ( file ) ? '"jest": ' : 'module.exports = '
99144
100145 // if we are using preset, inform the user that he might be able to remove some section(s)
101146 // we couldn't check for equality
@@ -109,7 +154,7 @@ No migration needed for given Jest configuration
109154 // If it is the case, you can safely remove the "testMatch" from what I've migrated.
110155 // `)
111156 // }
112- if ( usesPreset && migratedConfig . transform ) {
157+ if ( presets && migratedConfig . transform ) {
113158 footNotes . push ( `
114159I couldn't check if your "transform" value is the same as mine which is: ${ stringify (
115160 presets . transform ,
@@ -124,7 +169,7 @@ If it is the case, you can safely remove the "transform" from what I've migrated
124169 process . stderr . write ( `
125170Migrated Jest configuration:
126171` )
127- process . stdout . write ( `${ stringify ( migratedConfig , undefined , ' ' ) } \n` )
172+ process . stdout . write ( `${ prefix } ${ stringify ( migratedConfig , undefined , ' ' ) } \n` )
128173 if ( footNotes . length ) {
129174 process . stderr . write ( `
130175${ footNotes . join ( '\n' ) }
@@ -152,6 +197,7 @@ function cleanupConfig(config: jest.InitialOptions): void {
152197 config . testMatch = dedupSort ( config . testMatch )
153198 if ( config . testMatch . length === 0 ) delete config . testMatch
154199 }
200+ if ( config . preset === DEFAULT_PRESET ) config . preset = 'ts-jest'
155201}
156202
157203function dedupSort ( arr : any [ ] ) {
0 commit comments