@depup/ts-jest 29.4.6-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.lintstagedrc +4 -0
- package/.ts-jest-digest +1 -0
- package/CHANGELOG.md +2025 -0
- package/CONTRIBUTING.md +121 -0
- package/LICENSE.md +21 -0
- package/README.md +33 -0
- package/TROUBLESHOOTING.md +3 -0
- package/changes.json +18 -0
- package/cli.js +3 -0
- package/dist/cli/config/init.d.ts +6 -0
- package/dist/cli/config/init.js +139 -0
- package/dist/cli/config/migrate.d.ts +1 -0
- package/dist/cli/config/migrate.js +177 -0
- package/dist/cli/help.d.ts +1 -0
- package/dist/cli/help.js +25 -0
- package/dist/cli/helpers/presets.d.ts +1 -0
- package/dist/cli/helpers/presets.js +41 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +63 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +18 -0
- package/dist/config/paths-to-module-name-mapper.d.ts +9 -0
- package/dist/config/paths-to-module-name-mapper.js +52 -0
- package/dist/config/types.d.ts +2 -0
- package/dist/config/types.js +2 -0
- package/dist/constants.d.ts +13 -0
- package/dist/constants.js +22 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +31 -0
- package/dist/legacy/compiler/compiler-utils.d.ts +8 -0
- package/dist/legacy/compiler/compiler-utils.js +32 -0
- package/dist/legacy/compiler/index.d.ts +2 -0
- package/dist/legacy/compiler/index.js +18 -0
- package/dist/legacy/compiler/ts-compiler.d.ts +27 -0
- package/dist/legacy/compiler/ts-compiler.js +434 -0
- package/dist/legacy/compiler/ts-jest-compiler.d.ts +8 -0
- package/dist/legacy/compiler/ts-jest-compiler.js +18 -0
- package/dist/legacy/config/config-set.d.ts +36 -0
- package/dist/legacy/config/config-set.js +622 -0
- package/dist/legacy/index.d.ts +6 -0
- package/dist/legacy/index.js +6 -0
- package/dist/legacy/ts-jest-transformer.d.ts +28 -0
- package/dist/legacy/ts-jest-transformer.js +293 -0
- package/dist/presets/all-presets.d.ts +15 -0
- package/dist/presets/all-presets.js +42 -0
- package/dist/presets/create-jest-preset.d.ts +18 -0
- package/dist/presets/create-jest-preset.js +180 -0
- package/dist/raw-compiler-options.d.ts +556 -0
- package/dist/raw-compiler-options.js +2 -0
- package/dist/transformers/hoist-jest.d.ts +9 -0
- package/dist/transformers/hoist-jest.js +111 -0
- package/dist/transpilers/typescript/transpile-module.d.ts +8 -0
- package/dist/transpilers/typescript/transpile-module.js +174 -0
- package/dist/types.d.ts +282 -0
- package/dist/types.js +3 -0
- package/dist/utils/backports.d.ts +1 -0
- package/dist/utils/backports.js +118 -0
- package/dist/utils/diagnostics.d.ts +5 -0
- package/dist/utils/diagnostics.js +8 -0
- package/dist/utils/get-package-version.d.ts +1 -0
- package/dist/utils/get-package-version.js +14 -0
- package/dist/utils/importer.d.ts +1 -0
- package/dist/utils/importer.js +146 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/json.d.ts +2 -0
- package/dist/utils/json.js +16 -0
- package/dist/utils/jsonable-value.d.ts +10 -0
- package/dist/utils/jsonable-value.js +29 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.js +20 -0
- package/dist/utils/memoize.d.ts +1 -0
- package/dist/utils/memoize.js +60 -0
- package/dist/utils/messages.d.ts +1 -0
- package/dist/utils/messages.js +21 -0
- package/dist/utils/normalize-slashes.d.ts +1 -0
- package/dist/utils/normalize-slashes.js +9 -0
- package/dist/utils/sha1.d.ts +1 -0
- package/dist/utils/sha1.js +38 -0
- package/dist/utils/ts-error.d.ts +1 -0
- package/dist/utils/ts-error.js +37 -0
- package/jest-preset.js +1 -0
- package/legacy.js +1 -0
- package/package.json +167 -0
- package/preprocessor.js +7 -0
- package/presets/default/jest-preset.js +1 -0
- package/presets/default-esm/jest-preset.js +1 -0
- package/presets/default-esm-legacy/jest-preset.js +1 -0
- package/presets/default-legacy/jest-preset.js +1 -0
- package/presets/index.d.ts +3 -0
- package/presets/index.js +3 -0
- package/presets/js-with-babel/jest-preset.js +1 -0
- package/presets/js-with-babel-esm/jest-preset.js +1 -0
- package/presets/js-with-babel-esm-legacy/jest-preset.js +1 -0
- package/presets/js-with-babel-legacy/jest-preset.js +1 -0
- package/presets/js-with-ts/jest-preset.js +1 -0
- package/presets/js-with-ts-esm/jest-preset.js +1 -0
- package/presets/js-with-ts-esm-legacy/jest-preset.js +1 -0
- package/presets/js-with-ts-legacy/jest-preset.js +1 -0
- package/tsconfig.base.json +20 -0
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.ConfigSet = exports.TS_JEST_OUT_DIR = exports.IGNORE_DIAGNOSTIC_CODES = exports.MY_DIGEST = void 0;
|
|
40
|
+
/**
|
|
41
|
+
* This is the core of settings and so ts-jest.
|
|
42
|
+
* Since configuration are used to create a good cache key, everything
|
|
43
|
+
* depending on it is here. Fast jest relies on correct cache keys
|
|
44
|
+
* depending on all settings that could affect the generated output.
|
|
45
|
+
*
|
|
46
|
+
* The big issue is that jest calls first `getCacheKey()` with stringified
|
|
47
|
+
* version of the `jest.ProjectConfig`, and then later it calls `process()`
|
|
48
|
+
* with the complete, object version of it.
|
|
49
|
+
*/
|
|
50
|
+
const fs_1 = require("fs");
|
|
51
|
+
const module_1 = __importDefault(require("module"));
|
|
52
|
+
const path_1 = require("path");
|
|
53
|
+
const bs_logger_1 = require("bs-logger");
|
|
54
|
+
const jest_util_1 = require("jest-util");
|
|
55
|
+
const json5_1 = __importDefault(require("json5"));
|
|
56
|
+
const constants_1 = require("../../constants");
|
|
57
|
+
const hoistJestTransformer = __importStar(require("../../transformers/hoist-jest"));
|
|
58
|
+
const utils_1 = require("../../utils");
|
|
59
|
+
const backports_1 = require("../../utils/backports");
|
|
60
|
+
const importer_1 = require("../../utils/importer");
|
|
61
|
+
const messages_1 = require("../../utils/messages");
|
|
62
|
+
const normalize_slashes_1 = require("../../utils/normalize-slashes");
|
|
63
|
+
const sha1_1 = require("../../utils/sha1");
|
|
64
|
+
const ts_error_1 = require("../../utils/ts-error");
|
|
65
|
+
/**
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
exports.MY_DIGEST = (0, fs_1.readFileSync)((0, path_1.resolve)(__dirname, '../../../.ts-jest-digest'), 'utf8');
|
|
69
|
+
/**
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
exports.IGNORE_DIAGNOSTIC_CODES = [
|
|
73
|
+
6059, // "'rootDir' is expected to contain all source files."
|
|
74
|
+
18002, // "The 'files' list in config file is empty."
|
|
75
|
+
18003, // "No inputs were found in config file."
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
exports.TS_JEST_OUT_DIR = '$$ts-jest$$';
|
|
81
|
+
const normalizeRegex = (pattern) => pattern ? (typeof pattern === 'string' ? pattern : pattern.source) : undefined;
|
|
82
|
+
const toDiagnosticCode = (code) => code ? parseInt(`${code}`.trim().replace(/^TS/, ''), 10) ?? undefined : undefined;
|
|
83
|
+
const toDiagnosticCodeList = (items, into = []) => {
|
|
84
|
+
for (let item of items) {
|
|
85
|
+
if (typeof item === 'string') {
|
|
86
|
+
const children = item.trim().split(/\s*,\s*/g);
|
|
87
|
+
if (children.length > 1) {
|
|
88
|
+
toDiagnosticCodeList(children, into);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
item = children[0];
|
|
92
|
+
}
|
|
93
|
+
if (!item)
|
|
94
|
+
continue;
|
|
95
|
+
const code = toDiagnosticCode(item);
|
|
96
|
+
if (code && !into.includes(code))
|
|
97
|
+
into.push(code);
|
|
98
|
+
}
|
|
99
|
+
return into;
|
|
100
|
+
};
|
|
101
|
+
const requireFromString = (code, fileName) => {
|
|
102
|
+
// @ts-expect-error `_nodeModulePaths` is not exposed in typing
|
|
103
|
+
const paths = module_1.default._nodeModulePaths((0, path_1.dirname)(fileName));
|
|
104
|
+
const parent = module.parent;
|
|
105
|
+
const m = new module_1.default(fileName, parent);
|
|
106
|
+
m.filename = fileName;
|
|
107
|
+
m.paths = [].concat(paths);
|
|
108
|
+
// @ts-expect-error `_compile` is not exposed in typing
|
|
109
|
+
m._compile(code, fileName);
|
|
110
|
+
const exports = m.exports;
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
112
|
+
parent && parent.children && parent.children.splice(parent.children.indexOf(m), 1);
|
|
113
|
+
return exports;
|
|
114
|
+
};
|
|
115
|
+
class ConfigSet {
|
|
116
|
+
parentLogger;
|
|
117
|
+
/**
|
|
118
|
+
* Use by e2e, don't mark as internal
|
|
119
|
+
*/
|
|
120
|
+
tsJestDigest = exports.MY_DIGEST;
|
|
121
|
+
logger;
|
|
122
|
+
compilerModule;
|
|
123
|
+
isolatedModules;
|
|
124
|
+
cwd;
|
|
125
|
+
rootDir;
|
|
126
|
+
cacheSuffix;
|
|
127
|
+
tsCacheDir;
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
129
|
+
parsedTsConfig;
|
|
130
|
+
resolvedTransformers = {
|
|
131
|
+
before: [],
|
|
132
|
+
after: [],
|
|
133
|
+
afterDeclarations: [],
|
|
134
|
+
};
|
|
135
|
+
useESM = false;
|
|
136
|
+
/**
|
|
137
|
+
* @internal
|
|
138
|
+
*/
|
|
139
|
+
babelConfig;
|
|
140
|
+
/**
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
babelJestTransformer;
|
|
144
|
+
/**
|
|
145
|
+
* @internal
|
|
146
|
+
*/
|
|
147
|
+
_jestCfg;
|
|
148
|
+
/**
|
|
149
|
+
* @internal
|
|
150
|
+
*/
|
|
151
|
+
_diagnostics;
|
|
152
|
+
/**
|
|
153
|
+
* @internal
|
|
154
|
+
*/
|
|
155
|
+
_stringifyContentRegExp;
|
|
156
|
+
/**
|
|
157
|
+
* @internal
|
|
158
|
+
*/
|
|
159
|
+
_matchablePatterns;
|
|
160
|
+
/**
|
|
161
|
+
* @internal
|
|
162
|
+
*/
|
|
163
|
+
_matchTestFilePath;
|
|
164
|
+
/**
|
|
165
|
+
* @internal
|
|
166
|
+
*/
|
|
167
|
+
_shouldIgnoreDiagnosticsForFile;
|
|
168
|
+
/**
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
171
|
+
_overriddenCompilerOptions = {
|
|
172
|
+
inlineSourceMap: false,
|
|
173
|
+
declaration: false, // we don't want to create declaration files
|
|
174
|
+
isolatedDeclarations: false, // we don't want to create declaration files
|
|
175
|
+
noEmit: false, // set to true will make compiler API not emit any compiled results.
|
|
176
|
+
// else istanbul related will be dropped
|
|
177
|
+
removeComments: false,
|
|
178
|
+
// to clear out else it's buggy
|
|
179
|
+
out: undefined,
|
|
180
|
+
outFile: undefined,
|
|
181
|
+
composite: undefined, // see https://github.com/TypeStrong/ts-node/pull/657/files
|
|
182
|
+
declarationDir: undefined,
|
|
183
|
+
declarationMap: undefined,
|
|
184
|
+
emitDeclarationOnly: undefined,
|
|
185
|
+
sourceRoot: undefined,
|
|
186
|
+
tsBuildInfoFile: undefined,
|
|
187
|
+
rewriteRelativeImportExtensions: false,
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* @internal
|
|
191
|
+
*/
|
|
192
|
+
tsconfigFilePath;
|
|
193
|
+
constructor(jestConfig, parentLogger) {
|
|
194
|
+
this.parentLogger = parentLogger;
|
|
195
|
+
this.logger = this.parentLogger
|
|
196
|
+
? this.parentLogger.child({ [bs_logger_1.LogContexts.namespace]: 'config' })
|
|
197
|
+
: utils_1.rootLogger.child({ namespace: 'config' });
|
|
198
|
+
this._backportJestCfg(jestConfig ?? Object.create(null));
|
|
199
|
+
this.cwd = (0, path_1.normalize)(this._jestCfg.cwd ?? process.cwd());
|
|
200
|
+
this.rootDir = (0, path_1.normalize)(this._jestCfg.rootDir ?? this.cwd);
|
|
201
|
+
const tsJestCfg = this._jestCfg.globals && this._jestCfg.globals['ts-jest'];
|
|
202
|
+
const options = tsJestCfg ?? Object.create(null);
|
|
203
|
+
// compiler module
|
|
204
|
+
this.compilerModule = importer_1.importer.typescript("Using \"ts-jest\" requires this package to be installed." /* ImportReasons.TsJest */, options.compiler ?? 'typescript');
|
|
205
|
+
this.logger.debug({ compilerModule: this.compilerModule }, 'normalized compiler module config via ts-jest option');
|
|
206
|
+
this._setupConfigSet(options);
|
|
207
|
+
this._matchablePatterns = [...this._jestCfg.testMatch, ...this._jestCfg.testRegex].filter((pattern) =>
|
|
208
|
+
/**
|
|
209
|
+
* jest config testRegex doesn't always deliver the correct RegExp object
|
|
210
|
+
* See https://github.com/facebook/jest/issues/9778
|
|
211
|
+
*/
|
|
212
|
+
pattern instanceof RegExp || typeof pattern === 'string');
|
|
213
|
+
if (!this._matchablePatterns.length) {
|
|
214
|
+
this._matchablePatterns.push(...constants_1.DEFAULT_JEST_TEST_MATCH);
|
|
215
|
+
}
|
|
216
|
+
this._matchTestFilePath = (0, jest_util_1.globsToMatcher)(this._matchablePatterns.filter((pattern) => typeof pattern === 'string'));
|
|
217
|
+
// isolatedModules
|
|
218
|
+
if (options.isolatedModules) {
|
|
219
|
+
this.parsedTsConfig.options.isolatedModules = true;
|
|
220
|
+
if (this.tsconfigFilePath) {
|
|
221
|
+
this.logger.warn((0, messages_1.interpolate)("\n The \"ts-jest\" config option \"isolatedModules\" is deprecated and will be removed in v30.0.0. Please use \"isolatedModules: true\" in {{tsconfigFilePath}} instead, see https://www.typescriptlang.org/tsconfig/#isolatedModules\n " /* Deprecations.IsolatedModulesWithTsconfigPath */, {
|
|
222
|
+
tsconfigFilePath: this.tsconfigFilePath,
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
this.logger.warn("\n The \"ts-jest\" config option \"isolatedModules\" is deprecated and will be removed in v30.0.0. Please use \"isolatedModules: true\", see https://www.typescriptlang.org/tsconfig/#isolatedModules\n " /* Deprecations.IsolatedModulesWithoutTsconfigPath */);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
this.isolatedModules = this.parsedTsConfig.options.isolatedModules ?? false;
|
|
230
|
+
this._resolveTsCacheDir();
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* @internal
|
|
234
|
+
*/
|
|
235
|
+
_backportJestCfg(jestCfg) {
|
|
236
|
+
const config = (0, backports_1.backportJestConfig)(this.logger, jestCfg);
|
|
237
|
+
this.logger.debug({ jestConfig: config }, 'normalized jest config');
|
|
238
|
+
this._jestCfg = {
|
|
239
|
+
...config,
|
|
240
|
+
testMatch: config.testMatch ?? constants_1.DEFAULT_JEST_TEST_MATCH,
|
|
241
|
+
testRegex: config.testRegex ?? [],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
_setupConfigSet(options) {
|
|
248
|
+
// useESM
|
|
249
|
+
this.useESM = options.useESM ?? false;
|
|
250
|
+
// babel config (for babel-jest) default is undefined so we don't need to have fallback like tsConfig
|
|
251
|
+
if (!options.babelConfig) {
|
|
252
|
+
this.logger.debug('babel is disabled');
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
const baseBabelCfg = { cwd: this.cwd };
|
|
256
|
+
if (typeof options.babelConfig === 'string') {
|
|
257
|
+
const babelCfgPath = this.resolvePath(options.babelConfig);
|
|
258
|
+
const babelFileExtName = (0, path_1.extname)(options.babelConfig);
|
|
259
|
+
if (babelFileExtName === '.js' || babelFileExtName === '.cjs') {
|
|
260
|
+
this.babelConfig = {
|
|
261
|
+
...baseBabelCfg,
|
|
262
|
+
...require(babelCfgPath),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
this.babelConfig = {
|
|
267
|
+
...baseBabelCfg,
|
|
268
|
+
...json5_1.default.parse((0, fs_1.readFileSync)(babelCfgPath, 'utf-8')),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (typeof options.babelConfig === 'object') {
|
|
273
|
+
this.babelConfig = {
|
|
274
|
+
...baseBabelCfg,
|
|
275
|
+
...options.babelConfig,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
this.babelConfig = baseBabelCfg;
|
|
280
|
+
}
|
|
281
|
+
this.logger.debug({ babelConfig: this.babelConfig }, 'normalized babel config via ts-jest option');
|
|
282
|
+
this.babelJestTransformer = importer_1.importer
|
|
283
|
+
.babelJest("Using \"babel-jest\" requires this package to be installed." /* ImportReasons.BabelJest */)
|
|
284
|
+
.createTransformer(this.babelConfig);
|
|
285
|
+
this.logger.debug('created babel-jest transformer');
|
|
286
|
+
}
|
|
287
|
+
// diagnostics
|
|
288
|
+
const diagnosticsOpt = options.diagnostics ?? true;
|
|
289
|
+
const ignoreList = [...exports.IGNORE_DIAGNOSTIC_CODES];
|
|
290
|
+
if (typeof diagnosticsOpt === 'object') {
|
|
291
|
+
const { ignoreCodes } = diagnosticsOpt;
|
|
292
|
+
if (ignoreCodes) {
|
|
293
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
294
|
+
Array.isArray(ignoreCodes) ? ignoreList.push(...ignoreCodes) : ignoreList.push(ignoreCodes);
|
|
295
|
+
}
|
|
296
|
+
this._diagnostics = {
|
|
297
|
+
pretty: diagnosticsOpt.pretty ?? true,
|
|
298
|
+
exclude: diagnosticsOpt.exclude ?? [],
|
|
299
|
+
ignoreCodes: toDiagnosticCodeList(ignoreList),
|
|
300
|
+
throws: !diagnosticsOpt.warnOnly,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
this._diagnostics = {
|
|
305
|
+
ignoreCodes: diagnosticsOpt ? toDiagnosticCodeList(ignoreList) : [],
|
|
306
|
+
exclude: [],
|
|
307
|
+
pretty: true,
|
|
308
|
+
throws: diagnosticsOpt,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
if (diagnosticsOpt) {
|
|
312
|
+
this._shouldIgnoreDiagnosticsForFile = this._diagnostics.exclude.length
|
|
313
|
+
? (0, jest_util_1.globsToMatcher)(this._diagnostics.exclude)
|
|
314
|
+
: () => false;
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
this._shouldIgnoreDiagnosticsForFile = () => true;
|
|
318
|
+
}
|
|
319
|
+
this.logger.debug({ diagnostics: this._diagnostics }, 'normalized diagnostics config via ts-jest option');
|
|
320
|
+
// tsconfig
|
|
321
|
+
const tsconfigOpt = options.tsconfig;
|
|
322
|
+
const configFilePath = typeof tsconfigOpt === 'string' ? this.resolvePath(tsconfigOpt) : undefined;
|
|
323
|
+
this.parsedTsConfig = this._getAndResolveTsConfig(typeof tsconfigOpt === 'object' ? tsconfigOpt : undefined, configFilePath);
|
|
324
|
+
// throw errors if any matching wanted diagnostics
|
|
325
|
+
this.raiseDiagnostics(this.parsedTsConfig.errors, configFilePath);
|
|
326
|
+
this.logger.debug({ tsconfig: this.parsedTsConfig }, 'normalized typescript config via ts-jest option');
|
|
327
|
+
// transformers
|
|
328
|
+
this.resolvedTransformers.before = [
|
|
329
|
+
{
|
|
330
|
+
factory: hoistJestTransformer.factory,
|
|
331
|
+
name: hoistJestTransformer.name,
|
|
332
|
+
version: hoistJestTransformer.version,
|
|
333
|
+
},
|
|
334
|
+
];
|
|
335
|
+
const { astTransformers } = options;
|
|
336
|
+
if (astTransformers) {
|
|
337
|
+
const resolveTransformerFunc = (transformerPath) => {
|
|
338
|
+
let transformerFunc;
|
|
339
|
+
if ((0, path_1.extname)(transformerPath) === '.ts') {
|
|
340
|
+
const compiledTransformer = importer_1.importer
|
|
341
|
+
.esBuild("Using \"esbuild\" requires this package to be installed." /* ImportReasons.EsBuild */)
|
|
342
|
+
.transformSync((0, fs_1.readFileSync)(transformerPath, 'utf-8'), {
|
|
343
|
+
loader: 'ts',
|
|
344
|
+
format: 'cjs',
|
|
345
|
+
target: 'es2015',
|
|
346
|
+
}).code;
|
|
347
|
+
transformerFunc = requireFromString(compiledTransformer, transformerPath.replace('.ts', '.js'));
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
transformerFunc = require(transformerPath);
|
|
351
|
+
}
|
|
352
|
+
if (!transformerFunc.version) {
|
|
353
|
+
this.logger.warn("The AST transformer {{file}} must have an `export const version = <your_transformer_version>`" /* Errors.MissingTransformerVersion */, { file: transformerPath });
|
|
354
|
+
}
|
|
355
|
+
if (!transformerFunc.name) {
|
|
356
|
+
this.logger.warn("The AST transformer {{file}} must have an `export const name = <your_transformer_name>`" /* Errors.MissingTransformerName */, { file: transformerPath });
|
|
357
|
+
}
|
|
358
|
+
return transformerFunc;
|
|
359
|
+
};
|
|
360
|
+
const resolveTransformers = (transformers) => transformers.map((transformer) => {
|
|
361
|
+
if (typeof transformer === 'string') {
|
|
362
|
+
return resolveTransformerFunc(this.resolvePath(transformer, { nodeResolve: true }));
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
return {
|
|
366
|
+
...resolveTransformerFunc(this.resolvePath(transformer.path, { nodeResolve: true })),
|
|
367
|
+
options: transformer.options,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
if (astTransformers.before) {
|
|
372
|
+
/* istanbul ignore next (already covered in unit test) */
|
|
373
|
+
this.resolvedTransformers.before?.push(...resolveTransformers(astTransformers.before));
|
|
374
|
+
}
|
|
375
|
+
if (astTransformers.after) {
|
|
376
|
+
this.resolvedTransformers = {
|
|
377
|
+
...this.resolvedTransformers,
|
|
378
|
+
after: resolveTransformers(astTransformers.after),
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
if (astTransformers.afterDeclarations) {
|
|
382
|
+
this.resolvedTransformers = {
|
|
383
|
+
...this.resolvedTransformers,
|
|
384
|
+
afterDeclarations: resolveTransformers(astTransformers.afterDeclarations),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
this.logger.debug({ customTransformers: this.resolvedTransformers }, 'normalized custom AST transformers via ts-jest option');
|
|
389
|
+
// stringifyContentPathRegex
|
|
390
|
+
if (options.stringifyContentPathRegex) {
|
|
391
|
+
this._stringifyContentRegExp =
|
|
392
|
+
typeof options.stringifyContentPathRegex === 'string'
|
|
393
|
+
? new RegExp(normalizeRegex(options.stringifyContentPathRegex)) // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
394
|
+
: options.stringifyContentPathRegex;
|
|
395
|
+
this.logger.debug({ stringifyContentPathRegex: this._stringifyContentRegExp }, 'normalized stringifyContentPathRegex config via ts-jest option');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* @internal
|
|
400
|
+
*/
|
|
401
|
+
_resolveTsCacheDir() {
|
|
402
|
+
this.cacheSuffix = (0, sha1_1.sha1)((0, utils_1.stringify)({
|
|
403
|
+
version: this.compilerModule.version,
|
|
404
|
+
digest: this.tsJestDigest,
|
|
405
|
+
babelConfig: this.babelConfig,
|
|
406
|
+
tsconfig: {
|
|
407
|
+
options: this.parsedTsConfig.options,
|
|
408
|
+
raw: this.parsedTsConfig.raw,
|
|
409
|
+
},
|
|
410
|
+
isolatedModules: this.isolatedModules,
|
|
411
|
+
diagnostics: this._diagnostics,
|
|
412
|
+
transformers: Object.values(this.resolvedTransformers)
|
|
413
|
+
.reduce((prevVal, currentVal) => [...prevVal, currentVal])
|
|
414
|
+
.map((transformer) => `${transformer.name}-${transformer.version}`),
|
|
415
|
+
}));
|
|
416
|
+
if (!this._jestCfg.cache) {
|
|
417
|
+
this.logger.debug('file caching disabled');
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
const res = (0, path_1.join)(this._jestCfg.cacheDirectory, 'ts-jest', this.cacheSuffix.substr(0, 2), this.cacheSuffix.substr(2));
|
|
421
|
+
this.logger.debug({ cacheDirectory: res }, 'will use file caching');
|
|
422
|
+
this.tsCacheDir = res;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* @internal
|
|
427
|
+
*/
|
|
428
|
+
_getAndResolveTsConfig(compilerOptions, resolvedConfigFile) {
|
|
429
|
+
const result = this._resolveTsConfig(compilerOptions, resolvedConfigFile);
|
|
430
|
+
const { _overriddenCompilerOptions: forcedOptions } = this;
|
|
431
|
+
const finalOptions = result.options;
|
|
432
|
+
// Target ES2015 output by default (instead of ES3).
|
|
433
|
+
if (finalOptions.target === undefined) {
|
|
434
|
+
finalOptions.target = this.compilerModule.ScriptTarget.ES2015;
|
|
435
|
+
}
|
|
436
|
+
// check the module interoperability
|
|
437
|
+
const target = finalOptions.target;
|
|
438
|
+
// compute the default if not set
|
|
439
|
+
const defaultModule = [this.compilerModule.ScriptTarget.ES3, this.compilerModule.ScriptTarget.ES5].includes(target)
|
|
440
|
+
? this.compilerModule.ModuleKind.CommonJS
|
|
441
|
+
: this.compilerModule.ModuleKind.ESNext;
|
|
442
|
+
const moduleValue = finalOptions.module ?? defaultModule;
|
|
443
|
+
const warningModulesForEsmInterop = [
|
|
444
|
+
this.compilerModule.ModuleKind.CommonJS,
|
|
445
|
+
this.compilerModule.ModuleKind.Node16,
|
|
446
|
+
this.compilerModule.ModuleKind.NodeNext,
|
|
447
|
+
];
|
|
448
|
+
if (!this.babelConfig &&
|
|
449
|
+
!warningModulesForEsmInterop.includes(moduleValue) &&
|
|
450
|
+
!(finalOptions.esModuleInterop || finalOptions.allowSyntheticDefaultImports)) {
|
|
451
|
+
result.errors.push({
|
|
452
|
+
code: utils_1.TsJestDiagnosticCodes.ConfigModuleOption,
|
|
453
|
+
messageText: "If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information." /* Errors.ConfigNoModuleInterop */,
|
|
454
|
+
category: this.compilerModule.DiagnosticCategory.Message,
|
|
455
|
+
file: undefined,
|
|
456
|
+
start: undefined,
|
|
457
|
+
length: undefined,
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
// Make sure when allowJs is enabled, outDir is required to have when using allowJs: true
|
|
461
|
+
if (finalOptions.allowJs && !finalOptions.outDir) {
|
|
462
|
+
finalOptions.outDir = exports.TS_JEST_OUT_DIR;
|
|
463
|
+
}
|
|
464
|
+
// ensure undefined are removed and other values are overridden
|
|
465
|
+
for (const key of Object.keys(forcedOptions)) {
|
|
466
|
+
const val = forcedOptions[key];
|
|
467
|
+
if (val === undefined) {
|
|
468
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
469
|
+
delete finalOptions[key];
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
finalOptions[key] = val;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* See https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping
|
|
477
|
+
* Every time this page is updated, we also need to update here. Here we only show warning message for Node LTS versions
|
|
478
|
+
*/
|
|
479
|
+
const nodeJsVer = process.version;
|
|
480
|
+
const compilationTarget = result.options.target;
|
|
481
|
+
const TARGET_TO_VERSION_MAPPING = {
|
|
482
|
+
[this.compilerModule.ScriptTarget.ES2018]: 'es2018',
|
|
483
|
+
[this.compilerModule.ScriptTarget.ES2019]: 'es2019',
|
|
484
|
+
[this.compilerModule.ScriptTarget.ES2020]: 'es2020',
|
|
485
|
+
[this.compilerModule.ScriptTarget.ESNext]: 'ESNext',
|
|
486
|
+
};
|
|
487
|
+
/* istanbul ignore next (cover by e2e) */
|
|
488
|
+
if (compilationTarget &&
|
|
489
|
+
!this.babelConfig &&
|
|
490
|
+
nodeJsVer.startsWith('v12') &&
|
|
491
|
+
compilationTarget > this.compilerModule.ScriptTarget.ES2019) {
|
|
492
|
+
const message = (0, messages_1.interpolate)("There is a mismatch between your NodeJs version {{nodeJsVer}} and your TypeScript target {{compilationTarget}}. This might lead to some unexpected errors when running tests with `ts-jest`. To fix this, you can check https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping" /* Errors.MismatchNodeTargetMapping */, {
|
|
493
|
+
nodeJsVer: process.version,
|
|
494
|
+
compilationTarget: TARGET_TO_VERSION_MAPPING[compilationTarget],
|
|
495
|
+
});
|
|
496
|
+
this.logger.warn(message);
|
|
497
|
+
}
|
|
498
|
+
const resultOptions = result.options;
|
|
499
|
+
const sourceMap = resultOptions.sourceMap ?? true;
|
|
500
|
+
return {
|
|
501
|
+
...result,
|
|
502
|
+
options: {
|
|
503
|
+
...resultOptions,
|
|
504
|
+
sourceMap,
|
|
505
|
+
inlineSources: sourceMap,
|
|
506
|
+
module: resultOptions.module ?? this.compilerModule.ModuleKind.CommonJS,
|
|
507
|
+
},
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
_resolveTsConfig(compilerOptions, resolvedConfigFile) {
|
|
511
|
+
let config = { compilerOptions: Object.create(null) };
|
|
512
|
+
let basePath = (0, normalize_slashes_1.normalizeSlashes)(this.rootDir);
|
|
513
|
+
const ts = this.compilerModule;
|
|
514
|
+
// Read project configuration when available.
|
|
515
|
+
this.tsconfigFilePath = resolvedConfigFile
|
|
516
|
+
? (0, normalize_slashes_1.normalizeSlashes)(resolvedConfigFile)
|
|
517
|
+
: ts.findConfigFile((0, normalize_slashes_1.normalizeSlashes)(this.rootDir), ts.sys.fileExists);
|
|
518
|
+
if (this.tsconfigFilePath) {
|
|
519
|
+
this.logger.debug({ tsConfigFileName: this.tsconfigFilePath }, 'readTsConfig(): reading', this.tsconfigFilePath);
|
|
520
|
+
const result = ts.readConfigFile(this.tsconfigFilePath, ts.sys.readFile);
|
|
521
|
+
// Return diagnostics.
|
|
522
|
+
if (result.error) {
|
|
523
|
+
return { errors: [result.error], fileNames: [], options: {} };
|
|
524
|
+
}
|
|
525
|
+
config = result.config;
|
|
526
|
+
basePath = (0, normalize_slashes_1.normalizeSlashes)((0, path_1.dirname)(this.tsconfigFilePath));
|
|
527
|
+
}
|
|
528
|
+
// Override default configuration options `ts-jest` requires.
|
|
529
|
+
config.compilerOptions = {
|
|
530
|
+
...config.compilerOptions,
|
|
531
|
+
...compilerOptions,
|
|
532
|
+
};
|
|
533
|
+
// parse json, merge config extending others, ...
|
|
534
|
+
return ts.parseJsonConfigFileContent(config, ts.sys, basePath, undefined, this.tsconfigFilePath);
|
|
535
|
+
}
|
|
536
|
+
isTestFile(fileName) {
|
|
537
|
+
return this._matchablePatterns.some((pattern) => typeof pattern === 'string' ? this._matchTestFilePath(fileName) : pattern.test(fileName));
|
|
538
|
+
}
|
|
539
|
+
shouldStringifyContent(filePath) {
|
|
540
|
+
return this._stringifyContentRegExp ? this._stringifyContentRegExp.test(filePath) : false;
|
|
541
|
+
}
|
|
542
|
+
raiseDiagnostics(diagnostics, filePath, logger = this.logger) {
|
|
543
|
+
const { ignoreCodes } = this._diagnostics;
|
|
544
|
+
const { DiagnosticCategory } = this.compilerModule;
|
|
545
|
+
const filteredDiagnostics = filePath && !this.shouldReportDiagnostics(filePath)
|
|
546
|
+
? []
|
|
547
|
+
: diagnostics.filter((diagnostic) => {
|
|
548
|
+
if (diagnostic.file?.fileName && !this.shouldReportDiagnostics(diagnostic.file.fileName)) {
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
return !ignoreCodes.includes(diagnostic.code);
|
|
552
|
+
});
|
|
553
|
+
if (!filteredDiagnostics.length)
|
|
554
|
+
return;
|
|
555
|
+
const error = this.createTsError(filteredDiagnostics);
|
|
556
|
+
// only throw if `warnOnly` and it is a warning or error
|
|
557
|
+
const importantCategories = [DiagnosticCategory.Warning, DiagnosticCategory.Error];
|
|
558
|
+
if (this._diagnostics.throws && filteredDiagnostics.some((d) => importantCategories.includes(d.category))) {
|
|
559
|
+
throw error;
|
|
560
|
+
}
|
|
561
|
+
logger.warn({ error }, error.message);
|
|
562
|
+
}
|
|
563
|
+
shouldReportDiagnostics(filePath) {
|
|
564
|
+
const fileExtension = (0, path_1.extname)(filePath);
|
|
565
|
+
return constants_1.JS_JSX_EXTENSIONS.includes(fileExtension)
|
|
566
|
+
? this.parsedTsConfig.options.checkJs && !this._shouldIgnoreDiagnosticsForFile(filePath)
|
|
567
|
+
: !this._shouldIgnoreDiagnosticsForFile(filePath);
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* @internal
|
|
571
|
+
*/
|
|
572
|
+
createTsError(diagnostics) {
|
|
573
|
+
const formatDiagnostics = this._diagnostics.pretty
|
|
574
|
+
? this.compilerModule.formatDiagnosticsWithColorAndContext
|
|
575
|
+
: this.compilerModule.formatDiagnostics;
|
|
576
|
+
/* istanbul ignore next (not possible to cover) */
|
|
577
|
+
const diagnosticHost = {
|
|
578
|
+
getNewLine: () => '\n',
|
|
579
|
+
getCurrentDirectory: () => this.cwd,
|
|
580
|
+
getCanonicalFileName: (path) => path,
|
|
581
|
+
};
|
|
582
|
+
const diagnosticText = formatDiagnostics(diagnostics, diagnosticHost);
|
|
583
|
+
const diagnosticCodes = diagnostics.map((x) => x.code);
|
|
584
|
+
return new ts_error_1.TSError(diagnosticText, diagnosticCodes);
|
|
585
|
+
}
|
|
586
|
+
resolvePath(inputPath, { throwIfMissing = true, nodeResolve = false } = {}) {
|
|
587
|
+
let path = inputPath;
|
|
588
|
+
let nodeResolved = false;
|
|
589
|
+
if (path.startsWith('<rootDir>')) {
|
|
590
|
+
path = (0, path_1.resolve)((0, path_1.join)(this.rootDir, path.substr(9)));
|
|
591
|
+
}
|
|
592
|
+
else if (!(0, path_1.isAbsolute)(path)) {
|
|
593
|
+
if (!path.startsWith('.') && nodeResolve) {
|
|
594
|
+
try {
|
|
595
|
+
path = require.resolve(path);
|
|
596
|
+
nodeResolved = true;
|
|
597
|
+
}
|
|
598
|
+
catch {
|
|
599
|
+
this.logger.debug({ path }, 'failed to resolve path', path);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (!nodeResolved) {
|
|
603
|
+
path = (0, path_1.resolve)(this.cwd, path);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (!nodeResolved && nodeResolve) {
|
|
607
|
+
try {
|
|
608
|
+
path = require.resolve(path);
|
|
609
|
+
nodeResolved = true;
|
|
610
|
+
}
|
|
611
|
+
catch {
|
|
612
|
+
this.logger.debug({ path }, 'failed to resolve path', path);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
if (throwIfMissing && !(0, fs_1.existsSync)(path)) {
|
|
616
|
+
throw new Error((0, messages_1.interpolate)("File not found: {{inputPath}} (resolved as: {{resolvedPath}})" /* Errors.FileNotFound */, { inputPath, resolvedPath: path }));
|
|
617
|
+
}
|
|
618
|
+
this.logger.debug({ fromPath: inputPath, toPath: path }, 'resolved path from', inputPath, 'to', path);
|
|
619
|
+
return path;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
exports.ConfigSet = ConfigSet;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SyncTransformer, TransformedSource } from '@jest/transform';
|
|
2
|
+
import type { CompilerInstance, TsJestTransformerOptions, TsJestTransformOptions } from '../types';
|
|
3
|
+
import { ConfigSet } from './config/config-set';
|
|
4
|
+
export declare class TsJestTransformer implements SyncTransformer<TsJestTransformerOptions> {
|
|
5
|
+
private readonly transformerOptions?;
|
|
6
|
+
private readonly _logger;
|
|
7
|
+
protected _compiler: CompilerInstance;
|
|
8
|
+
private _transformCfgStr;
|
|
9
|
+
private _depGraphs;
|
|
10
|
+
private _watchMode;
|
|
11
|
+
constructor(transformerOptions?: TsJestTransformerOptions | undefined);
|
|
12
|
+
private _configsFor;
|
|
13
|
+
protected _createConfigSet(config: TsJestTransformOptions['config'] | undefined): ConfigSet;
|
|
14
|
+
protected _createCompiler(configSet: ConfigSet, cacheFS: Map<string, string>): void;
|
|
15
|
+
process(sourceText: string, sourcePath: string, transformOptions: TsJestTransformOptions): TransformedSource;
|
|
16
|
+
processAsync(sourceText: string, sourcePath: string, transformOptions: TsJestTransformOptions): Promise<TransformedSource>;
|
|
17
|
+
private processWithTs;
|
|
18
|
+
private runTsJestHook;
|
|
19
|
+
/**
|
|
20
|
+
* Jest uses this to cache the compiled version of a file
|
|
21
|
+
*
|
|
22
|
+
* @see https://github.com/facebook/jest/blob/v23.5.0/packages/jest-runtime/src/script_transformer.js#L61-L90
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
getCacheKey(fileContent: string, filePath: string, transformOptions: TsJestTransformOptions): string;
|
|
27
|
+
getCacheKeyAsync(sourceText: string, sourcePath: string, transformOptions: TsJestTransformOptions): Promise<string>;
|
|
28
|
+
}
|