forked from kulshekhar/ts-jest
/
paths-to-module-name-mapper.ts
65 lines (54 loc) · 2.45 KB
/
paths-to-module-name-mapper.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
import type { Config } from '@jest/types'
import { LogContexts } from 'bs-logger'
import type { CompilerOptions } from 'typescript'
import { rootLogger } from '../utils'
import { Errors, interpolate } from '../utils/messages'
type TsPathMapping = Exclude<CompilerOptions['paths'], undefined>
type JestPathMapping = Config.InitialOptions['moduleNameMapper']
// we don't need to escape all chars, so commented out is the real one
// const escapeRegex = (str: string) => str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
const escapeRegex = (str: string) => str.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
const logger = rootLogger.child({ [LogContexts.namespace]: 'path-mapper' })
export const pathsToModuleNameMapper = (
mapping: TsPathMapping,
{ prefix = '', useESM = false }: { prefix?: string; useESM?: boolean } = {},
): JestPathMapping => {
const jestMap: JestPathMapping = {}
for (const fromPath of Object.keys(mapping)) {
const toPaths = mapping[fromPath]
// check that we have only one target path
if (toPaths.length === 0) {
logger.warn(interpolate(Errors.NotMappingPathWithEmptyMap, { path: fromPath }))
continue
}
// split with '*'
const segments = fromPath.split(/\*/g)
if (segments.length === 1) {
const paths = toPaths.map((target) => {
const enrichedPrefix = prefix !== '' && !prefix.endsWith('/') ? `${prefix}/` : prefix
return `${enrichedPrefix}${target}`
})
const cjsPattern = `^${escapeRegex(fromPath)}$`
jestMap[cjsPattern] = paths.length === 1 ? paths[0] : paths
} else if (segments.length === 2) {
const paths = toPaths.map((target) => {
const enrichedTarget =
target.startsWith('./') && prefix !== '' ? target.substring(target.indexOf('/') + 1) : target
const enrichedPrefix = prefix !== '' && !prefix.endsWith('/') ? `${prefix}/` : prefix
return `${enrichedPrefix}${enrichedTarget.replace(/\*/g, '$1')}`
})
if (useESM) {
const esmPattern = `^${escapeRegex(segments[0])}(.*)${escapeRegex(segments[1])}\\.js$`
jestMap[esmPattern] = paths.length === 1 ? paths[0] : paths
}
const cjsPattern = `^${escapeRegex(segments[0])}(.*)${escapeRegex(segments[1])}$`
jestMap[cjsPattern] = paths.length === 1 ? paths[0] : paths
} else {
logger.warn(interpolate(Errors.NotMappingMultiStarPath, { path: fromPath }))
}
}
if (useESM) {
jestMap['^(\\.{1,2}/.*)\\.js$'] = '$1'
}
return jestMap
}