Skip to content

Commit 885bc44

Browse files
committed
feat(config): exposes custom transformers to config for presets
1 parent f95b880 commit 885bc44

8 files changed

Lines changed: 71 additions & 18 deletions

File tree

src/__helpers__/fakers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export function tsJestConfig(options?: Partial<TsJestConfig>): TsJestConfig {
5757
return {
5858
isolatedModules: false,
5959
compiler: 'typescript',
60+
transformers: [],
6061
babelConfig: undefined,
6162
tsConfig: undefined,
6263
stringifyContentPathRegex: undefined,

src/compiler.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,8 @@ import stableStringify = require('fast-json-stable-stringify')
3535
import { readFileSync, writeFileSync } from 'fs'
3636
import mkdirp = require('mkdirp')
3737
import { basename, extname, join, relative } from 'path'
38-
import { CustomTransformers } from 'typescript'
3938

4039
import { ConfigSet } from './config/config-set'
41-
import { factory as customTransformersFactory } from './transformers'
4240
import { MemoryCache, TsCompiler, TypeInfo } from './types'
4341
import { Errors, interpolate } from './util/messages'
4442
import { sha1 } from './util/sha1'
@@ -88,8 +86,7 @@ export function createCompiler(configs: ConfigSet): TsCompiler {
8886
? (path: string) => (/\.[tj]sx$/.test(path) ? '.jsx' : '.js')
8987
: (_: string) => '.js'
9088

91-
// TODO: grab internal transformers
92-
const transformers: CustomTransformers = customTransformersFactory(configs)
89+
const transformers = configs.tsCustomTransformers
9390

9491
/**
9592
* Create the basic required function using transpile mode.

src/config/__snapshots__/config-set.spec.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Object {
3232
},
3333
"isolatedModules": false,
3434
"stringifyContentPathRegex": undefined,
35+
"transformers": Array [],
3536
"tsConfig": Object {
3637
"kind": "file",
3738
"value": undefined,

src/config/config-set.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ import { existsSync, readFileSync } from 'fs'
1313
import json5 from 'json5'
1414
import { dirname, isAbsolute, join, resolve } from 'path'
1515
import semver from 'semver'
16-
import { Diagnostic, FormatDiagnosticsHost, ParsedCommandLine } from 'typescript'
16+
import { CustomTransformers, Diagnostic, FormatDiagnosticsHost, ParsedCommandLine } from 'typescript'
1717

1818
import { version as myVersion } from '..'
1919
import { createCompiler } from '../compiler'
20+
import { internals as internalAstTransformers } from '../transformers'
2021
import {
22+
AstTransformerDesc,
2123
BabelConfig,
2224
BabelJestTransformer,
2325
TTypeScript,
@@ -160,6 +162,9 @@ export class ConfigSet {
160162
}
161163
}
162164

165+
// transformers
166+
const transformers = (options.astTransformers || []).map(mod => this.resolvePath(mod, { nodeResolve: true }))
167+
163168
// babel jest
164169
const { babelConfig: babelConfigOpt } = options
165170
let babelConfig: TsJestConfig['babelConfig']
@@ -210,6 +215,7 @@ export class ConfigSet {
210215
diagnostics,
211216
isolatedModules: !!options.isolatedModules,
212217
compiler: options.compiler || 'typescript',
218+
transformers,
213219
stringifyContentPathRegex,
214220
}
215221
this.logger.debug({ tsJestConfig: res }, 'normalized ts-jest config')
@@ -316,6 +322,18 @@ export class ConfigSet {
316322
return createCompiler(this)
317323
}
318324

325+
@Memoize()
326+
get astTransformers(): AstTransformerDesc[] {
327+
return [...internalAstTransformers, ...this.tsJest.transformers.map(m => require(m))]
328+
}
329+
330+
@Memoize()
331+
get tsCustomTransformers(): CustomTransformers {
332+
return {
333+
before: this.astTransformers.map(t => t.factory(this)),
334+
}
335+
}
336+
319337
@Memoize()
320338
get hooks(): TsJestHooksMap {
321339
let hooksFile = process.env.TS_JEST_HOOKS
@@ -487,14 +505,32 @@ export class ConfigSet {
487505
return { input, resolved: result }
488506
}
489507

490-
resolvePath(inputPath: string, noFailIfMissing = false): string {
508+
resolvePath(
509+
inputPath: string,
510+
{ throwIfMissing = true, nodeResolve = false }: { throwIfMissing?: boolean; nodeResolve?: boolean } = {},
511+
): string {
491512
let path: string = inputPath
513+
let nodeResolved = false
492514
if (path.startsWith('<rootDir>')) {
493515
path = resolve(this.rootDir, path.substr(9))
494516
} else if (!isAbsolute(path)) {
495-
path = resolve(this.cwd, path)
517+
if (!path.startsWith('.') && nodeResolve) {
518+
try {
519+
path = require.resolve(path)
520+
nodeResolved = true
521+
} catch (_) {}
522+
}
523+
if (!nodeResolved) {
524+
path = resolve(this.cwd, path)
525+
}
526+
}
527+
if (!nodeResolved && nodeResolve) {
528+
try {
529+
path = require.resolve(path)
530+
nodeResolved = true
531+
} catch (_) {}
496532
}
497-
if (!noFailIfMissing && !existsSync(path)) {
533+
if (throwIfMissing && !existsSync(path)) {
498534
throw new Error(interpolate(Errors.FileNotFound, { inputPath, resolvedPath: path }))
499535
}
500536
this.logger.debug({ fromPath: inputPath, toPath: path }, 'resolved path from', inputPath, 'to', path)
@@ -514,6 +550,7 @@ export class ConfigSet {
514550

515551
return new JsonableValue({
516552
versions: this.versions,
553+
transformers: this.astTransformers.map(t => `${t.name}@${t.version}`),
517554
jest,
518555
tsJest: this.tsJest,
519556
babel: this.babel,

src/transformers/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ import {
1313
} from 'typescript';
1414
import { ConfigSet } from '../config-set'
1515

16+
// this is a unique identifier for your transformer
17+
export const name = 'my-transformer'
18+
// increment this each time you change the behavior of your transformer
19+
export const version = 1
20+
1621
export function factory(cs: ConfigSet) {
1722
const ts = cs.compilerModule
1823
function createVisitor(ctx: TransformationContext, sf: SourceFile) {

src/transformers/hoisting.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import { ConfigSet } from '../config/config-set'
1919
*/
2020
const HOIST_METHODS = ['mock', 'unmock']
2121

22+
export const name = 'hoisting-jest-mock'
23+
// increment this each time the code is modified
24+
export const version = 1
25+
2226
/**
2327
* The factory of hoisting transformer factory
2428
* @param cs Current jest configuration-set

src/transformers/index.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
import { CustomTransformers } from 'typescript'
1+
import { AstTransformerDesc } from '../types'
22

3-
import { ConfigSet } from '../config/config-set'
3+
import * as hoisting from './hoisting'
44

5-
import { factory as hoistingFactory } from './hoisting'
6-
7-
export function factory(cs: ConfigSet): CustomTransformers {
8-
return {
9-
before: [hoistingFactory(cs)],
10-
}
11-
}
5+
export const internals: AstTransformerDesc[] = [hoisting]

src/types.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as _babel from 'babel__core'
2-
import _ts, { CompilerOptions } from 'typescript'
2+
import _ts, { CompilerOptions, SourceFile, TransformerFactory } from 'typescript'
3+
4+
import { ConfigSet } from './config/config-set'
35

46
export type TBabelCore = typeof _babel
57
export type TTypeScript = typeof _ts
@@ -29,6 +31,11 @@ export interface TsJestGlobalOptions {
2931
*/
3032
compiler?: string
3133

34+
/**
35+
* Custom transformers (mostly used by jest presets)
36+
*/
37+
astTransformers?: string[]
38+
3239
/**
3340
* TS diagnostics - less to be reported if `isolatedModules` is `true`. It can be:
3441
* - `true` (or `undefined`, it's the default): show all diagnostics
@@ -92,6 +99,7 @@ export interface TsJestConfig {
9299
compiler: string
93100
diagnostics: TsJestConfig$diagnostics
94101
babelConfig: TsJestConfig$babelConfig
102+
transformers: string[]
95103

96104
// to deprecate / deprecated === === ===
97105
stringifyContentPathRegex: TsJestConfig$stringifyContentPathRegex
@@ -158,3 +166,9 @@ export interface TsCompiler {
158166
compile(code: string, fileName: string, lineOffset?: number): string
159167
getTypeInfo(code: string, fileName: string, position: number): TypeInfo
160168
}
169+
170+
export interface AstTransformerDesc {
171+
name: string
172+
version: number
173+
factory(cs: ConfigSet): TransformerFactory<SourceFile>
174+
}

0 commit comments

Comments
 (0)