-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathload-tsconfig.mts
129 lines (116 loc) · 3.16 KB
/
load-tsconfig.mts
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
/**
* @file loadTsconfig
* @module tsconfig-utils/lib/loadTsconfig
*/
import normalizeRelativePaths from '#internal/normalize-relative-paths'
import mergeTsconfig from '#lib/merge-tsconfig'
import readTsconfig from '#lib/read-tsconfig'
import type { ModuleId } from '@flex-development/mlly'
import * as mlly from '@flex-development/mlly'
import type {
LoadTsconfigOptions,
ResolvedTsconfig,
Tsconfig
} from '@flex-development/tsconfig-utils'
import { ksort, omit, shake, trim } from '@flex-development/tutils'
/**
* Load a tsconfig file.
*
* @see {@linkcode ModuleId}
* @see {@linkcode LoadTsconfigOptions}
* @see {@linkcode ResolvedTsconfig}
*
* @async
*
* @this {void}
*
* @param {ModuleId} id
* Module id of tsconfig file, or path to tsconfig file
* @param {LoadTsconfigOptions | null | undefined} [options]
* Load options
* @return {Promise<ResolvedTsconfig | null>}
* Resolved tsconfig or `null` if tsconfig file is not found
*/
async function loadTsconfig(
this: void,
id: ModuleId,
options?: LoadTsconfigOptions | null | undefined
): Promise<ResolvedTsconfig | null> {
/**
* Resolved tsconfig object.
*
* @var {ResolvedTsconfig | null} tsconfig
*/
let resolved: ResolvedTsconfig | null = await readTsconfig(id, options)
if (resolved !== null) {
/**
* List of property paths where the value may be a relative path.
*
* @const {Set<string>} relativePaths
*/
const relativePaths: Set<string> = new Set(options?.relativePaths ?? [
'compilerOptions.baseUrl',
'compilerOptions.outDir',
'compilerOptions.paths.*',
'compilerOptions.paths.*.*',
'compilerOptions.rootDir',
'files.*'
])
if (
resolved.tsconfig.extends !== false &&
resolved.tsconfig.extends !== null &&
resolved.tsconfig.extends !== undefined
) {
/**
* Configuration files to inherit from.
*
* @const {string[]} bases
*/
const bases: string[] = [resolved.tsconfig.extends]
.flat()
.map(trim)
.filter(extend => extend.length > 0)
for (const specifier of bases) {
/**
* Resolved base tsconfig.
*
* @const {ResolvedTsconfig | null} extend
*/
const extend: ResolvedTsconfig | null = await loadTsconfig(
await mlly.resolveModule(specifier, resolved.url, options),
options
)
if (extend) {
normalizeRelativePaths(
resolved.url,
extend.url,
extend.tsconfig,
null,
relativePaths
)
/**
* Tsconfig to inherit from.
*
* @const {Tsconfig} base
*/
const base: Tsconfig = omit(extend.tsconfig, ['references'])
resolved.tsconfig = mergeTsconfig(base, resolved.tsconfig)
}
}
delete resolved.tsconfig.extends
}
normalizeRelativePaths(
resolved.url,
resolved.url,
resolved.tsconfig,
null,
relativePaths
)
return {
tsconfig: ksort(shake(resolved.tsconfig), { deep: true }),
url: resolved.url
}
}
return null
}
export default loadTsconfig