/
init.ts
139 lines (123 loc) · 4.33 KB
/
init.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* This has been written quickly. While trying to improve I realised it'd be better to have it in Jest...
* ...and I saw a merged PR with `jest --init` tool!
* TODO: see what's the best path for this
*/
import { existsSync, readFileSync, writeFileSync } from 'fs'
import { stringify as stringifyJson5 } from 'json5'
import { basename, join } from 'path'
import { Arguments } from 'yargs'
import { CliCommand } from '..'
import { TsJestPresetDescriptor, defaults, jsWIthBabel, jsWithTs } from '../helpers/presets'
/**
* @internal
*/
export const run: CliCommand = async (args: Arguments /* , logger: Logger */) => {
const file = args._[0] || 'jest.config.js'
const filePath = join(process.cwd(), file)
const name = basename(file)
const isPackage = name === 'package.json'
const exists = existsSync(filePath)
const pkgFile = isPackage ? filePath : join(process.cwd(), 'package.json')
const hasPackage = isPackage || existsSync(pkgFile)
// read config
const { jestPreset = true, tsconfig: askedTsconfig, force, jsdom } = args
const tsconfig = askedTsconfig === 'tsconfig.json' ? undefined : askedTsconfig
// read package
const pkgJson = hasPackage ? JSON.parse(readFileSync(pkgFile, 'utf8')) : {}
// auto js/babel
let { js, babel } = args
if (js != null || babel != null) {
if (js == null) js = babel ? 'babel' : undefined
else if (babel == null) babel = js === 'babel'
}
// preset
let preset: TsJestPresetDescriptor | undefined
if (js === 'babel') {
preset = jsWIthBabel
} else if (js === 'ts') {
preset = jsWithTs
} else {
preset = defaults
}
if (isPackage && !exists) {
throw new Error(`File ${file} does not exists.`)
} else if (!isPackage && exists && !force) {
throw new Error(`Configuration file ${file} already exists.`)
}
if (!isPackage && !name.endsWith('.js')) {
throw new TypeError(`Configuration file ${file} must be a .js file or the package.json.`)
}
if (hasPackage && pkgJson.jest) {
if (force && !isPackage) {
delete pkgJson.jest
writeFileSync(pkgFile, JSON.stringify(pkgJson, undefined, ' '))
} else if (!force) {
throw new Error(`A Jest configuration is already set in ${pkgFile}.`)
}
}
// build configuration
let body: string
if (isPackage) {
// package.json config
const base: any = jestPreset ? { preset: preset.name } : { ...preset.value }
if (!jsdom) base.testEnvironment = 'node'
if (tsconfig || babel) {
const tsJestConf: any = {}
base.globals = { 'ts-jest': tsJestConf }
if (tsconfig) tsJestConf.tsconfig = tsconfig
if (babel) tsJestConf.babelConfig = true
}
body = JSON.stringify({ ...pkgJson, jest: base }, undefined, ' ')
} else {
// js config
const content = []
if (!jestPreset) {
content.push(`${preset.jsImport('tsjPreset')};`, '')
}
content.push('module.exports = {')
if (jestPreset) {
content.push(` preset: '${preset.name}',`)
} else {
content.push(` ...tsjPreset,`)
}
if (!jsdom) content.push(` testEnvironment: 'node',`)
if (tsconfig || babel) {
content.push(` globals: {`)
content.push(` 'ts-jest': {`)
if (tsconfig) content.push(` tsconfig: ${stringifyJson5(tsconfig)},`)
if (babel) content.push(` babelConfig: true,`)
content.push(` },`)
content.push(` },`)
}
content.push('};')
// join all together
body = content.join('\n')
}
writeFileSync(filePath, body)
process.stderr.write(`
Jest configuration written to "${filePath}".
`)
}
/**
* @internal
*/
export const help: CliCommand = async () => {
process.stdout.write(`
Usage:
ts-jest config:init [options] [<config-file>]
Arguments:
<config-file> Can be a js or json Jest config file. If it is a
package.json file, the configuration will be read from
the "jest" property.
Default: jest.config.js
Options:
--force Discard any existing Jest config
--js ts|babel Process .js files with ts-jest if 'ts' or with
babel-jest if 'babel'
--no-jest-preset Disable the use of Jest presets
--tsconfig <file> Path to the tsconfig.json file
--babel Pipe babel-jest after ts-jest
--jsdom Use jsdom as test environment instead of node
`)
}