/
utils.ts
141 lines (127 loc) · 3.93 KB
/
utils.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
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
130
131
132
133
134
135
136
137
138
139
140
141
import fsp from 'fs/promises'
import { promisify } from 'util'
import { readdirSync, statSync } from 'fs'
import { dirname, resolve } from 'pathe'
import mkdirp from 'mkdirp'
import _rimraf from 'rimraf'
import jiti from 'jiti'
import consola from 'consola'
import type { PackageJson } from 'pkg-types'
import { autoPreset } from './auto'
import type { BuildPreset, BuildConfig, BuildContext } from './types'
export async function ensuredir (path: string) {
await mkdirp(dirname(path))
}
export function warn (ctx: BuildContext, message: string) {
if (ctx.warnings.has(message)) { return }
consola.debug('[unbuild] [warn]', message)
ctx.warnings.add(message)
}
export async function symlink (from: string, to: string, force: boolean = true) {
await ensuredir(to)
if (force) {
await fsp.unlink(to).catch(() => { })
}
await fsp.symlink(from, to, 'junction')
}
export function dumpObject (obj: Record<string, any>) {
return '{ ' + Object.keys(obj).map(key => `${key}: ${JSON.stringify(obj[key])}`).join(', ') + ' }'
}
export function getpkg (id: string = '') {
const s = id.split('/')
return s[0][0] === '@' ? `${s[0]}/${s[1]}` : s[0]
}
const rimraf = promisify(_rimraf)
export async function rmdir (dir: string) {
await fsp.unlink(dir).catch(() => { })
await rimraf(dir)
}
export function listRecursively (path: string) {
const filenames = new Set<string>()
const walk = (path: string) => {
const files = readdirSync(path)
for (const file of files) {
const fullPath = resolve(path, file)
if (statSync(fullPath).isDirectory()) {
filenames.add(fullPath + '/')
walk(fullPath)
} else {
filenames.add(fullPath)
}
}
}
walk(path)
return Array.from(filenames)
}
export function tryRequire (id: string, rootDir: string = process.cwd()) {
const _require = jiti(rootDir, { interopDefault: true })
try {
return _require(id)
} catch (err: any) {
if (err.code !== 'MODULE_NOT_FOUND') {
console.error(`Error trying import ${id} from ${rootDir}`, err)
}
return {}
}
}
export function tryResolve (id: string, rootDir: string = process.cwd()) {
const _require = jiti(rootDir, { interopDefault: true })
try {
return _require.resolve(id)
} catch (err: any) {
if (err.code !== 'MODULE_NOT_FOUND') {
console.error(`Error trying import ${id} from ${rootDir}`, err)
}
return id
}
}
export function resolvePreset (preset: string | BuildPreset, rootDir: string): BuildConfig {
if (preset === 'auto') {
preset = autoPreset
} else if (typeof preset === 'string') {
preset = tryRequire(preset, rootDir) || {}
}
if (typeof preset === 'function') {
preset = preset()
}
return preset as BuildConfig
}
export function inferExportType (condition: string, previousConditions: string[] = [], filename = ''): 'esm' | 'cjs' {
if (filename) {
if (filename.endsWith('.d.ts')) {
return 'esm'
}
if (filename.endsWith('.mjs')) {
return 'esm'
}
if (filename.endsWith('.cjs')) {
return 'cjs'
}
}
switch (condition) {
case 'import':
return 'esm'
case 'require':
return 'cjs'
default: {
if (!previousConditions.length) {
// TODO: Check against type:module for default
return 'esm'
}
const [newCondition, ...rest] = previousConditions
return inferExportType(newCondition, rest, filename)
}
}
}
export type OutputDescriptor = { file: string, type?: 'esm' | 'cjs' }
export function extractExportFilenames (exports: PackageJson['exports'], conditions: string[] = []): OutputDescriptor[] {
if (!exports) { return [] }
if (typeof exports === 'string') {
return [{ file: exports, type: 'esm' }]
}
return Object.entries(exports).flatMap(
([condition, exports]) => typeof exports === 'string'
? { file: exports, type: inferExportType(condition, conditions, exports) }
: extractExportFilenames(exports, [...conditions, condition])
)
}