/
patchTypes.ts
68 lines (63 loc) · 2.07 KB
/
patchTypes.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
import { readFileSync, readdirSync, statSync, writeFileSync } from 'fs'
import { dirname, relative, resolve } from 'path'
import { fileURLToPath } from 'url'
import type { ParseResult } from '@babel/parser'
import { parse } from '@babel/parser'
import type { File } from '@babel/types'
import colors from 'picocolors'
import MagicString from 'magic-string'
const dir = dirname(fileURLToPath(import.meta.url))
const tempDir = resolve(dir, '../temp/node')
const typesDir = resolve(dir, '../types')
// walk through the temp dts dir, find all import/export of types/*
// and rewrite them into relative imports - so that api-extractor actually
// includes them in the rolled-up final d.ts file.
walkDir(tempDir)
console.log(colors.green(colors.bold(`patched types/* imports`)))
function slash(p: string): string {
return p.replace(/\\/g, '/')
}
function walkDir(dir: string): void {
const files = readdirSync(dir)
for (const file of files) {
const resolved = resolve(dir, file)
const isDir = statSync(resolved).isDirectory()
if (isDir) {
walkDir(resolved)
} else {
rewriteFile(resolved)
}
}
}
function rewriteFile(file: string): void {
const content = readFileSync(file, 'utf-8')
const str = new MagicString(content)
let ast: ParseResult<File>
try {
ast = parse(content, {
sourceType: 'module',
plugins: ['typescript', 'classProperties']
})
} catch (e) {
console.log(colors.red(`failed to parse ${file}`))
throw e
}
for (const statement of ast.program.body) {
if (
(statement.type === 'ImportDeclaration' ||
statement.type === 'ExportNamedDeclaration' ||
statement.type === 'ExportAllDeclaration') &&
statement.source?.value.startsWith('types/')
) {
const source = statement.source
const absoluteTypePath = resolve(typesDir, source.value.slice(6))
const relativeTypePath = slash(relative(dirname(file), absoluteTypePath))
str.overwrite(
source.start!,
source.end!,
JSON.stringify(relativeTypePath)
)
}
}
writeFileSync(file, str.toString())
}