-
Notifications
You must be signed in to change notification settings - Fork 73
/
read-tsconfig.ts
86 lines (68 loc) · 2.22 KB
/
read-tsconfig.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
import {readFile, readdir} from 'node:fs/promises'
import {dirname, join} from 'node:path'
import {memoizedWarn} from '../errors/warn'
import {TSConfig} from '../interfaces'
import {makeDebug} from '../logger'
import {mergeNestedObjects} from './util'
const debug = makeDebug('read-tsconfig')
function resolve(root: string, name: string): string | undefined {
try {
return require.resolve(name, {paths: [root]})
} catch {
// return undefined
}
}
async function upUntil(path: string, test: (path: string) => Promise<boolean>): Promise<string | undefined> {
let result: boolean | undefined
try {
result = await test(path)
} catch {
result = false
}
if (result) return path
const parent = dirname(path)
if (parent === path) return
return upUntil(parent, test)
}
export async function readTSConfig(root: string, tsconfigName = 'tsconfig.json'): Promise<TSConfig | undefined> {
const found: Record<string, any>[] = []
let typescript: typeof import('typescript') | undefined
try {
typescript = require('typescript')
} catch {
try {
typescript = require(root + '/node_modules/typescript')
} catch {}
}
if (!typescript) {
memoizedWarn(
'Could not find typescript. Please ensure that typescript is a devDependency. Falling back to compiled source.',
)
return
}
const read = async (path: string): Promise<unknown> => {
const localRoot = await upUntil(path, async (p) => (await readdir(p)).includes('package.json'))
if (!localRoot) return
try {
const contents = await readFile(path, 'utf8')
const parsed = typescript?.parseConfigFileTextToJson(path, contents).config
found.push(parsed)
if (parsed.extends) {
if (parsed.extends.startsWith('.')) {
const nextPath = resolve(localRoot, parsed.extends)
return nextPath ? read(nextPath) : undefined
}
const resolved = resolve(localRoot, parsed.extends)
if (resolved) return read(resolved)
}
return parsed
} catch (error) {
debug(error)
}
}
await read(join(root, tsconfigName))
return {
compilerOptions: mergeNestedObjects(found, 'compilerOptions'),
'ts-node': mergeNestedObjects(found, 'ts-node'),
}
}