-
-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathplugin.ts
More file actions
117 lines (102 loc) · 2.87 KB
/
plugin.ts
File metadata and controls
117 lines (102 loc) · 2.87 KB
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
import { existsSync } from 'node:fs'
import { mkdir, writeFile } from 'node:fs/promises'
import { basename, dirname, join, relative, resolve } from 'node:path'
import { loadDevupConfig, mergeImportAliases } from '@devup-ui/plugin-utils'
import {
codeExtract,
getThemeInterface,
hasDevupUI,
registerTheme,
setDebug,
} from '@devup-ui/wasm'
import { plugin } from 'bun'
const libPackage = '@devup-ui/react'
const devupFile = 'devup.json'
const distDir = 'df'
const cssDir = resolve(distDir, 'devup-ui')
const singleCss = true
const importAliases = mergeImportAliases()
async function writeDataFiles() {
let theme = {}
try {
const config = await loadDevupConfig(devupFile)
theme = config.theme ?? {}
} catch {
// Error reading devup.json, use empty theme
}
registerTheme(theme)
// Generate theme interface after registration (always write, even if empty)
await writeFile(
join(distDir, 'theme.d.ts'),
getThemeInterface(
libPackage,
'CustomColors',
'DevupThemeTypography',
'DevupTheme',
),
'utf-8',
)
if (!existsSync(cssDir)) {
await mkdir(cssDir, { recursive: true })
}
}
async function initialize() {
if (!existsSync(distDir)) await mkdir(distDir, { recursive: true })
await writeFile(join(distDir, '.gitignore'), '*', 'utf-8')
await writeDataFiles()
}
function resolveCssPath(path: string, importer?: string) {
const fileName = basename(path).split('?')[0]
const resolvedPath = importer
? resolve(dirname(importer), path)
: resolve(path)
const expectedPath = resolve(join(cssDir, fileName))
if (!relative(resolvedPath, expectedPath) || path.startsWith(cssDir)) {
return { path: join(cssDir, fileName) }
}
return undefined
}
async function loadSourceFile(filePath: string) {
const loader: 'tsx' | 'ts' | 'jsx' | 'js' = filePath.endsWith('.tsx')
? 'tsx'
: filePath.endsWith('.ts')
? 'ts'
: filePath.endsWith('.jsx')
? 'jsx'
: 'js'
const contents = await Bun.file(filePath).text()
if (hasDevupUI(filePath, contents, libPackage)) {
const code = codeExtract(
filePath,
contents,
libPackage,
relative(dirname(filePath), cssDir).replaceAll('\\', '/'),
singleCss,
true,
false,
importAliases,
)
return { contents: code.code, loader }
}
return { contents, loader }
}
// Register plugin immediately before any other imports
plugin({
name: 'devup-ui',
async setup(build) {
await initialize()
setDebug(true)
// Resolve devup-ui CSS files
build.onResolve({ filter: /devup-ui(-\d+)?\.css$/ }, ({ path, importer }) =>
resolveCssPath(path, importer),
)
// Load source files from packages directory (file namespace)
build.onLoad(
{
filter: /\.(?:tsx?|jsx|mjs)$|[\\/]@devup-ui[\\/].*\.js$/,
},
({ path }) => loadSourceFile(path),
)
},
})
export { plugin }