@hanzogui/static 2.0.0-rc.41-hanzoai.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/check-dep-versions.cjs +372 -0
- package/dist/checkDeps.cjs +271 -0
- package/dist/constants.cjs +51 -0
- package/dist/exports.cjs +46 -0
- package/dist/extractor/accessSafe.cjs +48 -0
- package/dist/extractor/babelParse.cjs +56 -0
- package/dist/extractor/buildClassName.cjs +86 -0
- package/dist/extractor/bundle.cjs +224 -0
- package/dist/extractor/bundleConfig.cjs +716 -0
- package/dist/extractor/concatClassName.cjs +92 -0
- package/dist/extractor/createEvaluator.cjs +88 -0
- package/dist/extractor/createExtractor.cjs +1827 -0
- package/dist/extractor/createLogger.cjs +50 -0
- package/dist/extractor/detectModuleFormat.cjs +55 -0
- package/dist/extractor/ensureImportingConcat.cjs +54 -0
- package/dist/extractor/errors.cjs +28 -0
- package/dist/extractor/esbuildAliasPlugin.cjs +56 -0
- package/dist/extractor/esbuildTsconfigPaths.cjs +108 -0
- package/dist/extractor/evaluateAstNode.cjs +128 -0
- package/dist/extractor/extractHelpers.cjs +182 -0
- package/dist/extractor/extractMediaStyle.cjs +169 -0
- package/dist/extractor/extractToClassNames.cjs +427 -0
- package/dist/extractor/extractToNative.cjs +361 -0
- package/dist/extractor/findTopmostFunction.cjs +43 -0
- package/dist/extractor/generatedUid.cjs +58 -0
- package/dist/extractor/getHanzoguiConfigPathFromOptionsConfig.cjs +41 -0
- package/dist/extractor/getPrefixLogs.cjs +31 -0
- package/dist/extractor/getPropValueFromAttributes.cjs +85 -0
- package/dist/extractor/getSourceModule.cjs +100 -0
- package/dist/extractor/getStaticBindingsForScope.cjs +213 -0
- package/dist/extractor/hasTopLevelAwait.cjs +62 -0
- package/dist/extractor/hoistClassNames.cjs +76 -0
- package/dist/extractor/literalToAst.cjs +109 -0
- package/dist/extractor/loadFile.cjs +17 -0
- package/dist/extractor/loadHanzogui.cjs +367 -0
- package/dist/extractor/logLines.cjs +43 -0
- package/dist/extractor/normalizeTernaries.cjs +95 -0
- package/dist/extractor/propsToFontFamilyCache.cjs +42 -0
- package/dist/extractor/regenerateConfig.cjs +178 -0
- package/dist/extractor/removeUnusedHooks.cjs +108 -0
- package/dist/extractor/timer.cjs +52 -0
- package/dist/extractor/validHTMLAttributes.cjs +79 -0
- package/dist/extractor/watchHanzoguiConfig.cjs +70 -0
- package/dist/getPragmaOptions.cjs +73 -0
- package/dist/helpers/memoize.cjs +45 -0
- package/dist/helpers/requireHanzoguiCore.cjs +40 -0
- package/dist/index.cjs +42 -0
- package/dist/registerRequire.cjs +208 -0
- package/dist/server.cjs +82 -0
- package/dist/setup.cjs +0 -0
- package/dist/types.cjs +18 -0
- package/dist/worker.cjs +111 -0
- package/package.json +101 -0
- package/src/check-dep-versions.ts +738 -0
- package/src/checkDeps.ts +371 -0
- package/src/constants.ts +14 -0
- package/src/exports.ts +15 -0
- package/src/extractor/accessSafe.ts +22 -0
- package/src/extractor/babelParse.ts +38 -0
- package/src/extractor/buildClassName.ts +76 -0
- package/src/extractor/bundle.ts +277 -0
- package/src/extractor/bundleConfig.ts +958 -0
- package/src/extractor/concatClassName.ts +105 -0
- package/src/extractor/createEvaluator.ts +82 -0
- package/src/extractor/createExtractor.ts +2680 -0
- package/src/extractor/createLogger.ts +41 -0
- package/src/extractor/detectModuleFormat.ts +42 -0
- package/src/extractor/ensureImportingConcat.ts +36 -0
- package/src/extractor/errors.ts +1 -0
- package/src/extractor/esbuildAliasPlugin.ts +40 -0
- package/src/extractor/esbuildTsconfigPaths.ts +103 -0
- package/src/extractor/evaluateAstNode.ts +136 -0
- package/src/extractor/extractHelpers.ts +211 -0
- package/src/extractor/extractMediaStyle.ts +194 -0
- package/src/extractor/extractToClassNames.ts +631 -0
- package/src/extractor/extractToNative.ts +489 -0
- package/src/extractor/findTopmostFunction.ts +24 -0
- package/src/extractor/generatedUid.ts +41 -0
- package/src/extractor/getHanzoguiConfigPathFromOptionsConfig.ts +24 -0
- package/src/extractor/getPrefixLogs.ts +9 -0
- package/src/extractor/getPropValueFromAttributes.ts +95 -0
- package/src/extractor/getSourceModule.ts +96 -0
- package/src/extractor/getStaticBindingsForScope.ts +237 -0
- package/src/extractor/hasTopLevelAwait.ts +28 -0
- package/src/extractor/hoistClassNames.ts +52 -0
- package/src/extractor/literalToAst.ts +85 -0
- package/src/extractor/loadFile.ts +17 -0
- package/src/extractor/loadHanzogui.ts +487 -0
- package/src/extractor/logLines.ts +16 -0
- package/src/extractor/normalizeTernaries.ts +75 -0
- package/src/extractor/propsToFontFamilyCache.ts +18 -0
- package/src/extractor/regenerateConfig.ts +186 -0
- package/src/extractor/removeUnusedHooks.ts +83 -0
- package/src/extractor/timer.ts +25 -0
- package/src/extractor/validHTMLAttributes.ts +52 -0
- package/src/extractor/watchHanzoguiConfig.ts +57 -0
- package/src/getPragmaOptions.ts +57 -0
- package/src/helpers/memoize.ts +24 -0
- package/src/helpers/requireHanzoguiCore.ts +28 -0
- package/src/index.ts +4 -0
- package/src/registerRequire.ts +283 -0
- package/src/server.ts +43 -0
- package/src/setup.ts +0 -0
- package/src/types.ts +109 -0
- package/src/worker.ts +142 -0
- package/types/check-dep-versions.d.ts +37 -0
- package/types/check-dep-versions.d.ts.map +1 -0
- package/types/checkDeps.d.ts +19 -0
- package/types/checkDeps.d.ts.map +1 -0
- package/types/constants.d.ts +6 -0
- package/types/constants.d.ts.map +1 -0
- package/types/exports.d.ts +16 -0
- package/types/exports.d.ts.map +1 -0
- package/types/extractor/accessSafe.d.ts +3 -0
- package/types/extractor/accessSafe.d.ts.map +1 -0
- package/types/extractor/babelParse.d.ts +5 -0
- package/types/extractor/babelParse.d.ts.map +1 -0
- package/types/extractor/buildClassName.d.ts +7 -0
- package/types/extractor/buildClassName.d.ts.map +1 -0
- package/types/extractor/bundle.d.ts +121 -0
- package/types/extractor/bundle.d.ts.map +1 -0
- package/types/extractor/bundleConfig.d.ts +49 -0
- package/types/extractor/bundleConfig.d.ts.map +1 -0
- package/types/extractor/concatClassName.d.ts +8 -0
- package/types/extractor/concatClassName.d.ts.map +1 -0
- package/types/extractor/createEvaluator.d.ts +12 -0
- package/types/extractor/createEvaluator.d.ts.map +1 -0
- package/types/extractor/createExtractor.d.ts +32 -0
- package/types/extractor/createExtractor.d.ts.map +1 -0
- package/types/extractor/createLogger.d.ts +3 -0
- package/types/extractor/createLogger.d.ts.map +1 -0
- package/types/extractor/detectModuleFormat.d.ts +5 -0
- package/types/extractor/detectModuleFormat.d.ts.map +1 -0
- package/types/extractor/ensureImportingConcat.d.ts +4 -0
- package/types/extractor/ensureImportingConcat.d.ts.map +1 -0
- package/types/extractor/errors.d.ts +3 -0
- package/types/extractor/errors.d.ts.map +1 -0
- package/types/extractor/esbuildAliasPlugin.d.ts +18 -0
- package/types/extractor/esbuildAliasPlugin.d.ts.map +1 -0
- package/types/extractor/esbuildTsconfigPaths.d.ts +11 -0
- package/types/extractor/esbuildTsconfigPaths.d.ts.map +1 -0
- package/types/extractor/evaluateAstNode.d.ts +3 -0
- package/types/extractor/evaluateAstNode.d.ts.map +1 -0
- package/types/extractor/extractHelpers.d.ts +28 -0
- package/types/extractor/extractHelpers.d.ts.map +1 -0
- package/types/extractor/extractMediaStyle.d.ts +11 -0
- package/types/extractor/extractMediaStyle.d.ts.map +1 -0
- package/types/extractor/extractToClassNames.d.ts +25 -0
- package/types/extractor/extractToClassNames.d.ts.map +1 -0
- package/types/extractor/extractToNative.d.ts +13 -0
- package/types/extractor/extractToNative.d.ts.map +1 -0
- package/types/extractor/findTopmostFunction.d.ts +4 -0
- package/types/extractor/findTopmostFunction.d.ts.map +1 -0
- package/types/extractor/generatedUid.d.ts +5 -0
- package/types/extractor/generatedUid.d.ts.map +1 -0
- package/types/extractor/getHanzoguiConfigPathFromOptionsConfig.d.ts +3 -0
- package/types/extractor/getHanzoguiConfigPathFromOptionsConfig.d.ts.map +1 -0
- package/types/extractor/getPrefixLogs.d.ts +3 -0
- package/types/extractor/getPrefixLogs.d.ts.map +1 -0
- package/types/extractor/getPropValueFromAttributes.d.ts +19 -0
- package/types/extractor/getPropValueFromAttributes.d.ts.map +1 -0
- package/types/extractor/getSourceModule.d.ts +16 -0
- package/types/extractor/getSourceModule.d.ts.map +1 -0
- package/types/extractor/getStaticBindingsForScope.d.ts +5 -0
- package/types/extractor/getStaticBindingsForScope.d.ts.map +1 -0
- package/types/extractor/hasTopLevelAwait.d.ts +2 -0
- package/types/extractor/hasTopLevelAwait.d.ts.map +1 -0
- package/types/extractor/hoistClassNames.d.ts +6 -0
- package/types/extractor/hoistClassNames.d.ts.map +1 -0
- package/types/extractor/literalToAst.d.ts +4 -0
- package/types/extractor/literalToAst.d.ts.map +1 -0
- package/types/extractor/loadFile.d.ts +1 -0
- package/types/extractor/loadFile.d.ts.map +1 -0
- package/types/extractor/loadHanzogui.d.ts +22 -0
- package/types/extractor/loadHanzogui.d.ts.map +1 -0
- package/types/extractor/logLines.d.ts +2 -0
- package/types/extractor/logLines.d.ts.map +1 -0
- package/types/extractor/normalizeTernaries.d.ts +3 -0
- package/types/extractor/normalizeTernaries.d.ts.map +1 -0
- package/types/extractor/propsToFontFamilyCache.d.ts +4 -0
- package/types/extractor/propsToFontFamilyCache.d.ts.map +1 -0
- package/types/extractor/regenerateConfig.d.ts +9 -0
- package/types/extractor/regenerateConfig.d.ts.map +1 -0
- package/types/extractor/removeUnusedHooks.d.ts +3 -0
- package/types/extractor/removeUnusedHooks.d.ts.map +1 -0
- package/types/extractor/timer.d.ts +5 -0
- package/types/extractor/timer.d.ts.map +1 -0
- package/types/extractor/validHTMLAttributes.d.ts +52 -0
- package/types/extractor/validHTMLAttributes.d.ts.map +1 -0
- package/types/extractor/watchHanzoguiConfig.d.ts +5 -0
- package/types/extractor/watchHanzoguiConfig.d.ts.map +1 -0
- package/types/getPragmaOptions.d.ts +8 -0
- package/types/getPragmaOptions.d.ts.map +1 -0
- package/types/helpers/memoize.d.ts +8 -0
- package/types/helpers/memoize.d.ts.map +1 -0
- package/types/helpers/requireHanzoguiCore.d.ts +3 -0
- package/types/helpers/requireHanzoguiCore.d.ts.map +1 -0
- package/types/index.d.ts +4 -0
- package/types/index.d.ts.map +1 -0
- package/types/registerRequire.d.ts +10 -0
- package/types/registerRequire.d.ts.map +1 -0
- package/types/server.d.ts +3 -0
- package/types/server.d.ts.map +1 -0
- package/types/setup.d.ts +1 -0
- package/types/setup.d.ts.map +1 -0
- package/types/types.d.ts +92 -0
- package/types/types.d.ts.map +1 -0
- package/types/worker.d.ts +46 -0
- package/types/worker.d.ts.map +1 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import { basename, dirname, extname, join, relative, resolve } from 'node:path'
|
|
2
|
+
// @ts-ignore why
|
|
3
|
+
import { Color, colorLog } from '@hanzogui/cli-color'
|
|
4
|
+
import type { CLIResolvedOptions, CLIUserOptions, HanzoguiOptions } from '@hanzogui/types'
|
|
5
|
+
import type { HanzoguiInternalConfig } from '@hanzogui/web'
|
|
6
|
+
import esbuild from 'esbuild'
|
|
7
|
+
import * as esbuildWasm from 'esbuild-wasm'
|
|
8
|
+
import * as fsExtra from 'fs-extra'
|
|
9
|
+
|
|
10
|
+
import { SHOULD_DEBUG } from '../constants'
|
|
11
|
+
import { requireHanzoguiCore } from '../helpers/requireHanzoguiCore'
|
|
12
|
+
import { getNameToPaths, registerRequire } from '../registerRequire'
|
|
13
|
+
import {
|
|
14
|
+
type HanzoguiProjectInfo,
|
|
15
|
+
getBundledConfig,
|
|
16
|
+
getLoadedConfig,
|
|
17
|
+
hasBundledConfigChanged,
|
|
18
|
+
loadComponentsSync,
|
|
19
|
+
writeHanzoguiCSS,
|
|
20
|
+
} from './bundleConfig'
|
|
21
|
+
import { getHanzoguiConfigPathFromOptionsConfig } from './getHanzoguiConfigPathFromOptionsConfig'
|
|
22
|
+
import {
|
|
23
|
+
generateHanzoguiThemes,
|
|
24
|
+
regenerateConfig,
|
|
25
|
+
regenerateConfigSync,
|
|
26
|
+
} from './regenerateConfig'
|
|
27
|
+
|
|
28
|
+
const getFilledOptions = (propsIn: Partial<HanzoguiOptions>): HanzoguiOptions => ({
|
|
29
|
+
// defaults
|
|
30
|
+
platform: (process.env.TAMAGUI_TARGET as any) || 'web',
|
|
31
|
+
config: 'hanzogui.config.ts',
|
|
32
|
+
components: ['hanzogui'],
|
|
33
|
+
...(propsIn as Partial<HanzoguiOptions>),
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
let isLoadingPromise: null | Promise<any>
|
|
37
|
+
|
|
38
|
+
export async function loadHanzogui(
|
|
39
|
+
propsIn: Partial<HanzoguiOptions>
|
|
40
|
+
): Promise<HanzoguiProjectInfo | null> {
|
|
41
|
+
if (isLoadingPromise) return await isLoadingPromise
|
|
42
|
+
|
|
43
|
+
let resolvePromise
|
|
44
|
+
let rejectPromise
|
|
45
|
+
isLoadingPromise = new Promise((res, rej) => {
|
|
46
|
+
resolvePromise = res
|
|
47
|
+
rejectPromise = rej
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const props = getFilledOptions(propsIn)
|
|
52
|
+
|
|
53
|
+
const bundleInfo = await getBundledConfig(props)
|
|
54
|
+
if (!bundleInfo) {
|
|
55
|
+
console.warn(
|
|
56
|
+
`No bundled config generated, maybe an error in bundling. Set DEBUG=hanzogui and re-run to get logs.`
|
|
57
|
+
)
|
|
58
|
+
resolvePromise(null)
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// this affects the bundled config so run it first
|
|
63
|
+
await generateThemesAndLog(props)
|
|
64
|
+
|
|
65
|
+
// if they accidently pass in a config without createHanzogui called,call it
|
|
66
|
+
const maybeHanzoguiConfig = bundleInfo.hanzoguiConfig as HanzoguiInternalConfig
|
|
67
|
+
if (maybeHanzoguiConfig && !maybeHanzoguiConfig.parsed) {
|
|
68
|
+
const { createHanzogui } = requireHanzoguiCore(props.platform || 'web')
|
|
69
|
+
bundleInfo.hanzoguiConfig = createHanzogui(bundleInfo.hanzoguiConfig as any)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!hasBundledConfigChanged()) {
|
|
73
|
+
resolvePromise(bundleInfo)
|
|
74
|
+
return bundleInfo
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await regenerateConfig(props, bundleInfo)
|
|
78
|
+
|
|
79
|
+
resolvePromise(bundleInfo)
|
|
80
|
+
return bundleInfo
|
|
81
|
+
} catch (err) {
|
|
82
|
+
rejectPromise()
|
|
83
|
+
throw err
|
|
84
|
+
} finally {
|
|
85
|
+
isLoadingPromise = null
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// debounce a bit
|
|
90
|
+
let waiting = false
|
|
91
|
+
|
|
92
|
+
export const generateThemesAndLog = async (options: HanzoguiOptions, force = false) => {
|
|
93
|
+
if (waiting) return
|
|
94
|
+
if (!options.themeBuilder) return
|
|
95
|
+
try {
|
|
96
|
+
waiting = true
|
|
97
|
+
await new Promise((res) => setTimeout(res, 30))
|
|
98
|
+
const didGenerate = await generateHanzoguiThemes(options, force)
|
|
99
|
+
|
|
100
|
+
// only logs when changed
|
|
101
|
+
if (didGenerate) {
|
|
102
|
+
const whitespaceBefore = ` `
|
|
103
|
+
colorLog(
|
|
104
|
+
Color.FgYellow,
|
|
105
|
+
`${whitespaceBefore}➡ [hanzogui] generated themes: ${relative(
|
|
106
|
+
process.cwd(),
|
|
107
|
+
options.themeBuilder.output
|
|
108
|
+
)}`
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if (options.outputCSS) {
|
|
112
|
+
const loadedConfig = getLoadedConfig()
|
|
113
|
+
if (loadedConfig) {
|
|
114
|
+
await writeHanzoguiCSS(options.outputCSS, loadedConfig)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} finally {
|
|
119
|
+
waiting = false
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const last: Record<string, HanzoguiProjectInfo | null> = {}
|
|
124
|
+
const lastVersion: Record<string, string> = {}
|
|
125
|
+
|
|
126
|
+
// esbuild-wasm state - initialized once per process
|
|
127
|
+
let esbuildWasmInitialized = false
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Load hanzogui.build.ts config using esbuild-wasm transform
|
|
131
|
+
* Uses WASM to avoid native esbuild service lifecycle issues (EPIPE errors)
|
|
132
|
+
*/
|
|
133
|
+
export async function loadHanzoguiBuildConfigAsync(
|
|
134
|
+
hanzoguiOptions: Partial<HanzoguiOptions> | undefined
|
|
135
|
+
): Promise<HanzoguiOptions> {
|
|
136
|
+
const buildFilePath = hanzoguiOptions?.buildFile ?? './hanzogui.build.ts'
|
|
137
|
+
const absolutePath =
|
|
138
|
+
buildFilePath[0] === '.' ? join(process.cwd(), buildFilePath) : buildFilePath
|
|
139
|
+
|
|
140
|
+
if (fsExtra.existsSync(absolutePath)) {
|
|
141
|
+
try {
|
|
142
|
+
const source = await fsExtra.readFile(absolutePath, 'utf-8')
|
|
143
|
+
|
|
144
|
+
// initialize esbuild-wasm once
|
|
145
|
+
if (!esbuildWasmInitialized) {
|
|
146
|
+
await esbuildWasm.initialize({})
|
|
147
|
+
esbuildWasmInitialized = true
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// use esbuild-wasm.transform to compile - no native service needed
|
|
151
|
+
const result = await esbuildWasm.transform(source, {
|
|
152
|
+
loader: 'ts',
|
|
153
|
+
format: 'cjs',
|
|
154
|
+
target: 'node18',
|
|
155
|
+
sourcefile: absolutePath,
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// evaluate the compiled code to get the exports
|
|
159
|
+
// pass process so process.env works in the config
|
|
160
|
+
const module = { exports: {} as any }
|
|
161
|
+
const fn = new Function('module', 'exports', 'require', 'process', result.code)
|
|
162
|
+
fn(module, module.exports, require, process)
|
|
163
|
+
|
|
164
|
+
const out = module.exports.default || module.exports
|
|
165
|
+
if (!out || typeof out !== 'object') {
|
|
166
|
+
throw new Error(`No default export found in ${buildFilePath}: ${out}`)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
hanzoguiOptions = {
|
|
170
|
+
...hanzoguiOptions,
|
|
171
|
+
...out,
|
|
172
|
+
}
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.error(`[hanzogui] Error loading ${buildFilePath}:`, err)
|
|
175
|
+
throw err
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!hanzoguiOptions) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`No hanzogui build options found either via input props or at hanzogui.build.ts`
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
config: 'hanzogui.config.ts',
|
|
187
|
+
components: ['hanzogui', '@hanzogui/core'],
|
|
188
|
+
...hanzoguiOptions,
|
|
189
|
+
} as HanzoguiOptions
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @deprecated Use loadHanzoguiBuildConfigAsync instead to avoid EPIPE errors
|
|
194
|
+
*/
|
|
195
|
+
export function loadHanzoguiBuildConfigSync(
|
|
196
|
+
hanzoguiOptions: Partial<HanzoguiOptions> | undefined
|
|
197
|
+
) {
|
|
198
|
+
const buildFilePath = hanzoguiOptions?.buildFile ?? './hanzogui.build.ts'
|
|
199
|
+
if (fsExtra.existsSync(buildFilePath)) {
|
|
200
|
+
const registered = registerRequire('web')
|
|
201
|
+
try {
|
|
202
|
+
const out = require(
|
|
203
|
+
buildFilePath[0] === '.' ? join(process.cwd(), buildFilePath) : buildFilePath
|
|
204
|
+
).default
|
|
205
|
+
if (!out) {
|
|
206
|
+
throw new Error(`No default export found in ${buildFilePath}: ${out}`)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
hanzoguiOptions = {
|
|
210
|
+
...hanzoguiOptions,
|
|
211
|
+
...out,
|
|
212
|
+
}
|
|
213
|
+
} finally {
|
|
214
|
+
registered.unregister()
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (!hanzoguiOptions) {
|
|
218
|
+
throw new Error(
|
|
219
|
+
`No hanzogui build options found either via input props or at hanzogui.build.ts`
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
config: 'hanzogui.config.ts',
|
|
224
|
+
components: ['hanzogui', '@hanzogui/core'],
|
|
225
|
+
...hanzoguiOptions,
|
|
226
|
+
} as HanzoguiOptions
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// loads in-process using esbuild-register
|
|
230
|
+
export function loadHanzoguiSync({
|
|
231
|
+
forceExports,
|
|
232
|
+
cacheKey,
|
|
233
|
+
...propsIn
|
|
234
|
+
}: Partial<HanzoguiOptions> & {
|
|
235
|
+
forceExports?: boolean
|
|
236
|
+
cacheKey?: string
|
|
237
|
+
}): HanzoguiProjectInfo {
|
|
238
|
+
const key = JSON.stringify(propsIn)
|
|
239
|
+
|
|
240
|
+
if (last[key] && !hasBundledConfigChanged()) {
|
|
241
|
+
if (!lastVersion[key] || lastVersion[key] === cacheKey) {
|
|
242
|
+
return last[key]!
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
lastVersion[key] = cacheKey || ''
|
|
247
|
+
|
|
248
|
+
const props = getFilledOptions(propsIn)
|
|
249
|
+
|
|
250
|
+
// lets shim require and avoid importing react-native + react-native-web
|
|
251
|
+
// we just need to read the config around them
|
|
252
|
+
process.env.IS_STATIC = 'is_static'
|
|
253
|
+
process.env.TAMAGUI_IS_SERVER = 'true'
|
|
254
|
+
|
|
255
|
+
const { unregister } = registerRequire(props.platform || 'web', {
|
|
256
|
+
proxyWormImports: !!forceExports,
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
try {
|
|
260
|
+
const devValueOG = globalThis['__DEV__' as any]
|
|
261
|
+
globalThis['__DEV__' as any] = process.env.NODE_ENV === 'development'
|
|
262
|
+
|
|
263
|
+
try {
|
|
264
|
+
// config
|
|
265
|
+
let hanzoguiConfig: HanzoguiInternalConfig | null = null
|
|
266
|
+
if (propsIn.config) {
|
|
267
|
+
const configPath = getHanzoguiConfigPathFromOptionsConfig(propsIn.config)
|
|
268
|
+
const exp = require(configPath)
|
|
269
|
+
|
|
270
|
+
if (!exp || exp._isProxyWorm) {
|
|
271
|
+
throw new Error(`Got a empty / proxied config!`)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
hanzoguiConfig = (exp['default'] || exp['config'] || exp) as HanzoguiInternalConfig
|
|
275
|
+
|
|
276
|
+
if (!hanzoguiConfig || !hanzoguiConfig.parsed) {
|
|
277
|
+
const confPath = require.resolve(configPath)
|
|
278
|
+
throw new Error(`Can't find valid config in ${confPath}:
|
|
279
|
+
|
|
280
|
+
Be sure you "export default" or "export const config" the config.`)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// set up core
|
|
284
|
+
if (hanzoguiConfig) {
|
|
285
|
+
const { createHanzogui } = requireHanzoguiCore(props.platform || 'web')
|
|
286
|
+
createHanzogui(hanzoguiConfig as any)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// components
|
|
291
|
+
const components = loadComponentsSync(props, forceExports)
|
|
292
|
+
if (!components) {
|
|
293
|
+
throw new Error(`No components loaded`)
|
|
294
|
+
}
|
|
295
|
+
if (process.env.DEBUG === 'hanzogui') {
|
|
296
|
+
console.info(`components`, components)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// undo shims
|
|
300
|
+
process.env.IS_STATIC = undefined
|
|
301
|
+
globalThis['__DEV__' as any] = devValueOG
|
|
302
|
+
|
|
303
|
+
const info = {
|
|
304
|
+
components,
|
|
305
|
+
hanzoguiConfig,
|
|
306
|
+
nameToPaths: getNameToPaths(),
|
|
307
|
+
} satisfies HanzoguiProjectInfo
|
|
308
|
+
|
|
309
|
+
if (hanzoguiConfig) {
|
|
310
|
+
const { outputCSS } = props
|
|
311
|
+
if (outputCSS) {
|
|
312
|
+
writeHanzoguiCSS(outputCSS, hanzoguiConfig)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
regenerateConfigSync(props, info)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
last[key] = {
|
|
319
|
+
...info,
|
|
320
|
+
cached: true,
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return info as any
|
|
324
|
+
} catch (err) {
|
|
325
|
+
if (err instanceof Error) {
|
|
326
|
+
if (!SHOULD_DEBUG && !forceExports) {
|
|
327
|
+
console.warn(
|
|
328
|
+
`Error loading hanzogui.config.ts (set DEBUG=hanzogui to see full stack), running hanzogui without custom config`
|
|
329
|
+
)
|
|
330
|
+
console.info(`\n\n ${err.message}\n\n`)
|
|
331
|
+
} else {
|
|
332
|
+
if (SHOULD_DEBUG) {
|
|
333
|
+
console.error(err)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
} else {
|
|
337
|
+
console.error(`Error loading hanzogui.config.ts`, err)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
components: [],
|
|
342
|
+
hanzoguiConfig: null,
|
|
343
|
+
nameToPaths: {},
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
} finally {
|
|
347
|
+
unregister()
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export async function getOptions({
|
|
352
|
+
root = process.cwd(),
|
|
353
|
+
tsconfigPath = 'tsconfig.json',
|
|
354
|
+
hanzoguiOptions,
|
|
355
|
+
host,
|
|
356
|
+
debug,
|
|
357
|
+
}: Partial<CLIUserOptions> = {}): Promise<CLIResolvedOptions> {
|
|
358
|
+
const dotDir = join(root, '.hanzogui')
|
|
359
|
+
let pkgJson = {}
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
pkgJson = await fsExtra.readJSON(join(root, 'package.json'))
|
|
363
|
+
} catch (err) {
|
|
364
|
+
// ok
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
|
|
369
|
+
root,
|
|
370
|
+
host: host || '127.0.0.1',
|
|
371
|
+
pkgJson,
|
|
372
|
+
debug,
|
|
373
|
+
tsconfigPath,
|
|
374
|
+
hanzoguiOptions: {
|
|
375
|
+
platform: (process.env.TAMAGUI_TARGET as any) || 'web',
|
|
376
|
+
components: ['hanzogui'],
|
|
377
|
+
...hanzoguiOptions,
|
|
378
|
+
config:
|
|
379
|
+
hanzoguiOptions?.config ??
|
|
380
|
+
(await getDefaultHanzoguiConfigPath(root, hanzoguiOptions?.config)),
|
|
381
|
+
},
|
|
382
|
+
paths: {
|
|
383
|
+
root,
|
|
384
|
+
dotDir,
|
|
385
|
+
conf: join(dotDir, 'hanzogui.config.json'),
|
|
386
|
+
types: join(dotDir, 'types.json'),
|
|
387
|
+
},
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export function resolveWebOrNativeSpecificEntry(entry: string) {
|
|
392
|
+
const workspaceRoot = resolve()
|
|
393
|
+
const resolved = require.resolve(entry, { paths: [workspaceRoot] })
|
|
394
|
+
const ext = extname(resolved)
|
|
395
|
+
const fileName = basename(resolved).replace(ext, '')
|
|
396
|
+
const specificExt = process.env.TAMAGUI_TARGET === 'web' ? 'web' : 'native'
|
|
397
|
+
const specificFile = join(dirname(resolved), fileName + '.' + specificExt + ext)
|
|
398
|
+
if (fsExtra.existsSync(specificFile)) {
|
|
399
|
+
return specificFile
|
|
400
|
+
}
|
|
401
|
+
return entry
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const defaultPaths = ['hanzogui.config.ts', join('src', 'hanzogui.config.ts')]
|
|
405
|
+
let hasWarnedOnce = false
|
|
406
|
+
|
|
407
|
+
async function getDefaultHanzoguiConfigPath(root: string, configPath?: string) {
|
|
408
|
+
const searchPaths = [
|
|
409
|
+
...new Set(
|
|
410
|
+
[configPath, ...defaultPaths].filter(Boolean).map((p) => join(root, p as string))
|
|
411
|
+
),
|
|
412
|
+
]
|
|
413
|
+
|
|
414
|
+
for (const path of searchPaths) {
|
|
415
|
+
if (await fsExtra.pathExists(path)) {
|
|
416
|
+
return path
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (!hasWarnedOnce) {
|
|
421
|
+
hasWarnedOnce = true
|
|
422
|
+
console.warn(`Warning: couldn't find hanzogui.config.ts in the following paths given configuration "${configPath}":
|
|
423
|
+
${searchPaths.join(`\n `)}
|
|
424
|
+
`)
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export type { HanzoguiProjectInfo }
|
|
429
|
+
|
|
430
|
+
export async function esbuildWatchFiles(entry: string, onChanged: () => void) {
|
|
431
|
+
let hasRunOnce = false
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* We're just (ab)using this as a file watcher, so bundle = true to follow paths
|
|
435
|
+
* and then write: false and logLevel silent to avoid all errors
|
|
436
|
+
*/
|
|
437
|
+
|
|
438
|
+
const context = await esbuild.context({
|
|
439
|
+
bundle: true,
|
|
440
|
+
entryPoints: [entry],
|
|
441
|
+
resolveExtensions: ['.ts', '.tsx', '.js', '.mjs'],
|
|
442
|
+
logLevel: 'silent',
|
|
443
|
+
write: false,
|
|
444
|
+
|
|
445
|
+
alias: {
|
|
446
|
+
'@react-native/normalize-color': '@hanzogui/proxy-worm',
|
|
447
|
+
'react-native-web': '@hanzogui/react-native-web-lite',
|
|
448
|
+
'react-native': '@hanzogui/proxy-worm',
|
|
449
|
+
},
|
|
450
|
+
|
|
451
|
+
plugins: [
|
|
452
|
+
// to log what its watching:
|
|
453
|
+
// {
|
|
454
|
+
// name: 'test',
|
|
455
|
+
// setup({ onResolve }) {
|
|
456
|
+
// onResolve({ filter: /.*/ }, (args) => {
|
|
457
|
+
// console.log('wtf', args.path)
|
|
458
|
+
// })
|
|
459
|
+
// },
|
|
460
|
+
// },
|
|
461
|
+
|
|
462
|
+
{
|
|
463
|
+
name: `on-rebuild`,
|
|
464
|
+
setup({ onEnd, onResolve }) {
|
|
465
|
+
// external node modules
|
|
466
|
+
let filter = /^[^./]|^\.[^./]|^\.\.[^/]/ // Must not start with "/" or "./" or "../"
|
|
467
|
+
onResolve({ filter }, (args) => ({ path: args.path, external: true }))
|
|
468
|
+
|
|
469
|
+
onEnd(() => {
|
|
470
|
+
if (!hasRunOnce) {
|
|
471
|
+
hasRunOnce = true
|
|
472
|
+
} else {
|
|
473
|
+
onChanged()
|
|
474
|
+
}
|
|
475
|
+
})
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
// just returns after dispose is called i think
|
|
482
|
+
void context.watch()
|
|
483
|
+
|
|
484
|
+
return () => {
|
|
485
|
+
context.dispose()
|
|
486
|
+
}
|
|
487
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const prefix = ' '
|
|
2
|
+
|
|
3
|
+
export const logLines = (str: string, singleLine = false) => {
|
|
4
|
+
if (singleLine) {
|
|
5
|
+
return prefix + str.split(' ').join(`\n${prefix}`)
|
|
6
|
+
}
|
|
7
|
+
const lines: string[] = ['']
|
|
8
|
+
const items = str.split(' ')
|
|
9
|
+
for (const item of items) {
|
|
10
|
+
if (item.length + lines[lines.length - 1].length > 85) {
|
|
11
|
+
lines.push('')
|
|
12
|
+
}
|
|
13
|
+
lines[lines.length - 1] += item + ' '
|
|
14
|
+
}
|
|
15
|
+
return lines.map((line, i) => prefix + (i == 0 ? '' : ' ') + line.trim()).join('\n')
|
|
16
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import generate from '@babel/generator'
|
|
2
|
+
import * as t from '@babel/types'
|
|
3
|
+
import { mergeProps } from '@hanzogui/web'
|
|
4
|
+
import invariant from 'invariant'
|
|
5
|
+
import type { Ternary } from '../types'
|
|
6
|
+
import { forwardFontFamilyName } from './propsToFontFamilyCache'
|
|
7
|
+
|
|
8
|
+
export function normalizeTernaries(ternaries: Ternary[]) {
|
|
9
|
+
invariant(
|
|
10
|
+
Array.isArray(ternaries),
|
|
11
|
+
'extractStaticTernaries expects param 1 to be an array of ternaries'
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
if (ternaries.length === 0) {
|
|
15
|
+
return []
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const ternariesByKey: { [key: string]: Ternary } = {}
|
|
19
|
+
|
|
20
|
+
for (let idx = -1, len = ternaries.length; ++idx < len; ) {
|
|
21
|
+
const { test, consequent, alternate, remove, ...rest } = ternaries[idx]
|
|
22
|
+
|
|
23
|
+
let ternaryTest = test
|
|
24
|
+
|
|
25
|
+
// strip parens
|
|
26
|
+
if (t.isExpressionStatement(test)) {
|
|
27
|
+
ternaryTest = (test as any).expression
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// convert `!thing` to `thing` with swapped consequent and alternate
|
|
31
|
+
let shouldSwap = false
|
|
32
|
+
if (t.isUnaryExpression(test) && test.operator === '!') {
|
|
33
|
+
ternaryTest = test.argument
|
|
34
|
+
shouldSwap = true
|
|
35
|
+
} else if (t.isBinaryExpression(test)) {
|
|
36
|
+
if (test.operator === '!==' || test.operator === '!=') {
|
|
37
|
+
ternaryTest = t.binaryExpression(
|
|
38
|
+
test.operator.replace('!', '=') as any,
|
|
39
|
+
test.left,
|
|
40
|
+
test.right
|
|
41
|
+
)
|
|
42
|
+
shouldSwap = true
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
const key = generate(ternaryTest as any).code
|
|
48
|
+
|
|
49
|
+
if (!ternariesByKey[key]) {
|
|
50
|
+
ternariesByKey[key] = {
|
|
51
|
+
...rest,
|
|
52
|
+
alternate: {},
|
|
53
|
+
consequent: {},
|
|
54
|
+
test: ternaryTest,
|
|
55
|
+
remove,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const altStyle = (shouldSwap ? consequent : alternate) ?? {}
|
|
59
|
+
const consStyle = (shouldSwap ? alternate : consequent) ?? {}
|
|
60
|
+
|
|
61
|
+
const nextAlt = ternariesByKey[key].alternate!
|
|
62
|
+
ternariesByKey[key].alternate = mergeProps(altStyle, nextAlt)
|
|
63
|
+
forwardFontFamilyName(altStyle, ternariesByKey[key].alternate)
|
|
64
|
+
|
|
65
|
+
const nextCons = ternariesByKey[key].consequent!
|
|
66
|
+
ternariesByKey[key].consequent = mergeProps(consStyle, nextCons)
|
|
67
|
+
forwardFontFamilyName(consStyle, ternariesByKey[key].consequent)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const ternaryExpression = Object.keys(ternariesByKey).map((key) => {
|
|
71
|
+
return ternariesByKey[key]
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
return ternaryExpression
|
|
75
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// weird stuff
|
|
2
|
+
|
|
3
|
+
const cache = new WeakMap<any, string>()
|
|
4
|
+
|
|
5
|
+
export function setPropsToFontFamily(props: any, ff: string) {
|
|
6
|
+
cache.set(props, ff.replace('$', '').trim())
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getFontFamilyNameFromProps(props: any) {
|
|
10
|
+
return cache.get(props)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function forwardFontFamilyName(prev: any, next: any, fallback?: string) {
|
|
14
|
+
const ff = getFontFamilyNameFromProps(prev) || fallback
|
|
15
|
+
if (ff) {
|
|
16
|
+
setPropsToFontFamily(next, ff)
|
|
17
|
+
}
|
|
18
|
+
}
|