catalyst-core 0.2.0-beta.3 → 0.3.0-beta.2
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/babel.native.config.cjs +8 -0
- package/bin/catalyst.js +49 -105
- package/changelog.md +8 -0
- package/dist/caching.js +1 -1
- package/dist/globals.d.ts +7 -0
- package/dist/index.jsx +8 -0
- package/dist/logger.js +74 -3
- package/dist/native/androidProject/app/build.gradle.kts +45 -4
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +86 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/BridgeUtils.kt +8 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +173 -13
- package/dist/native/androidProject/settings.gradle.kts +10 -0
- package/dist/native/androidSetup.js +300 -8
- package/dist/native/bridge/WebBridge.js +481 -59
- package/dist/native/bridge/constants/NativeInterfaces.js +304 -45
- package/dist/native/bridge/errors.js +250 -26
- package/dist/native/bridge/hooks/index.js +132 -1
- package/dist/native/bridge/hooks/useAI.js +94 -0
- package/dist/native/bridge/hooks/useCamera.js +347 -9
- package/dist/native/bridge/hooks/useDataProtection.js +200 -2
- package/dist/native/bridge/hooks/useDeviceInfo.js +71 -2
- package/dist/native/bridge/hooks/useFilePicker.js +429 -2
- package/dist/native/bridge/hooks/useGoogleSignIn.js +81 -1
- package/dist/native/bridge/hooks/useHapticFeedback.js +196 -1
- package/dist/native/bridge/hooks/useIntent.js +95 -1
- package/dist/native/bridge/hooks/useNativeTransition.js +202 -27
- package/dist/native/bridge/hooks/useNetworkStatus.js +84 -3
- package/dist/native/bridge/hooks/useNotification.js +318 -2
- package/dist/native/bridge/hooks/useSafeArea.js +84 -2
- package/dist/native/bridge/hooks/useVideoStream.js +434 -6
- package/dist/native/bridge/hooks/utils.js +27 -1
- package/dist/native/bridge/hooks.js +16 -1
- package/dist/native/bridge/perf/collectors/ApiCollector.js +66 -3
- package/dist/native/bridge/perf/collectors/CacheCollector.js +186 -11
- package/dist/native/bridge/perf/collectors/HookCollector.js +141 -19
- package/dist/native/bridge/perf/collectors/InsightsCollector.js +481 -23
- package/dist/native/bridge/perf/collectors/InteractionCollector.js +245 -10
- package/dist/native/bridge/perf/collectors/KeyboardCollector.js +107 -8
- package/dist/native/bridge/perf/collectors/NavigationCollector.js +273 -32
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +178 -2
- package/dist/native/bridge/perf/collectors/RenderCollector.js +258 -14
- package/dist/native/bridge/perf/collectors/ScrollCollector.js +95 -9
- package/dist/native/bridge/perf/collectors/ThreadCollector.js +90 -6
- package/dist/native/bridge/perf/core/constants.js +103 -20
- package/dist/native/bridge/perf/core/measure.js +179 -30
- package/dist/native/bridge/perf/core/session.js +89 -23
- package/dist/native/bridge/perf/core/store.js +554 -1
- package/dist/native/bridge/perf/core/summary.js +174 -1
- package/dist/native/bridge/perf/core/traceExport.js +240 -1
- package/dist/native/bridge/perf/core/waterfalls.js +146 -1
- package/dist/native/bridge/perf/index.js +359 -38
- package/dist/native/bridge/safeArea.js +53 -5
- package/dist/native/bridge/standardizedHooks.js +595 -82
- package/dist/native/bridge/useBaseHook.js +274 -38
- package/dist/native/bridge/utils/CameraUtils.js +201 -56
- package/dist/native/bridge/utils/FileObjectConverter.js +129 -18
- package/dist/native/bridge/utils/NativeBridge.js +425 -141
- package/dist/native/buildAndroid/assets.js +510 -13
- package/dist/native/buildAndroid/build.js +296 -19
- package/dist/native/buildAndroid/config.js +87 -1
- package/dist/native/buildAndroid/index.js +406 -1
- package/dist/native/buildAppAndroid.js +34 -2
- package/dist/native/buildAppIos.js +62 -2
- package/dist/native/buildIos/assets.js +609 -8
- package/dist/native/buildIos/build.js +639 -20
- package/dist/native/buildIos/config.js +294 -12
- package/dist/native/buildIos/index.js +343 -6
- package/dist/native/buildIos/plugins.js +343 -16
- package/dist/native/internal-plugins/device-info-plugin/android/DeviceInfoPlugin.kt +43 -0
- package/dist/native/internal-plugins/device-info-plugin/ios/DeviceInfoPlugin.swift +28 -0
- package/dist/native/internal-plugins/device-info-plugin/manifest.json +19 -0
- package/dist/native/internalPluginUtils.js +232 -7
- package/dist/native/package.json +3 -0
- package/dist/native/plugin-bridge/PluginBridge.js +227 -1
- package/dist/native/pluginComposerAndroid.js +407 -23
- package/dist/native/pluginComposerIos.js +435 -11
- package/dist/native/renameAndroidProject.js +1094 -88
- package/dist/native/setupEmulatorIos.js +289 -22
- package/dist/native/setupServer.js +160 -19
- package/dist/native/terminalProgress.js +199 -11
- package/dist/native/utils.js +193 -15
- package/dist/offline/catalyst-sw.js +145 -1
- package/dist/offline/registerServiceWorker.js +33 -1
- package/dist/otel.js +375 -46
- package/dist/router/ClientRouter.js +14 -2
- package/dist/router/ServerRouter.js +9 -1
- package/dist/router.js +1 -1
- package/dist/scripts/build.js +112 -3
- package/dist/scripts/checkVersion.js +3 -1
- package/dist/scripts/cleanCache.js +30 -1
- package/dist/scripts/generateOfflineManifest.js +116 -1
- package/dist/scripts/loadEnvironmentVariables.js +32 -6
- package/dist/scripts/plugins.js +309 -1
- package/dist/scripts/preServerInit.js +13 -0
- package/dist/scripts/scriptUtils.js +54 -3
- package/dist/scripts/serve.js +51 -4
- package/dist/scripts/start.js +47 -10
- package/dist/scripts/validator.js +149 -1
- package/dist/sentry.cjs +127 -0
- package/dist/sentry.js +125 -5
- package/dist/server/expressServer.js +296 -5
- package/dist/server/manifestCache.js +36 -0
- package/dist/server/renderer/ChunkExtractor.js +144 -0
- package/dist/server/renderer/document/Body.jsx +59 -0
- package/dist/server/renderer/document/FastRefresh.jsx +20 -0
- package/dist/server/renderer/document/Head.jsx +60 -0
- package/dist/server/renderer/document/index.jsx +2 -0
- package/dist/server/renderer/extract.js +149 -31
- package/dist/server/renderer/handler.jsx +450 -0
- package/dist/server/renderer/index.js +8 -1
- package/dist/server/renderer/render.js +47 -0
- package/dist/server/utils/botDetectionMiddleware.js +29 -0
- package/dist/server/utils/cjsRequire.js +10 -0
- package/dist/server/utils/userAgentUtil.js +87 -9
- package/dist/server/utils/validator.js +164 -1
- package/dist/vite/FastRefresh.jsx +20 -0
- package/dist/vite/inject-cache-key-plugin.js +276 -0
- package/dist/vite/loadCustomViteConfig.js +22 -0
- package/dist/vite/manifest-categorization-plugin.js +455 -0
- package/dist/vite/node-loader.mjs +458 -0
- package/dist/vite/scssParams.js +21 -0
- package/dist/vite/vite.config.client.js +130 -0
- package/dist/vite/vite.config.js +498 -0
- package/dist/vite/vite.config.server.js +84 -0
- package/dist/web-router/components/MetaTag.jsx +34 -0
- package/dist/web-router/components/RouterDataProvider.jsx +332 -0
- package/dist/web-router/components/Split.jsx +200 -0
- package/dist/web-router/components/SplitInview.jsx +106 -0
- package/dist/web-router/components/SsrRequestContext.jsx +14 -0
- package/dist/web-router/context.jsx +12 -0
- package/dist/web-router/hooks.jsx +72 -0
- package/dist/web-router/types/components/MetaTag.d.ts +2 -0
- package/dist/web-router/types/components/RouterDataProvider.d.ts +95 -0
- package/dist/web-router/types/context.d.ts +14 -0
- package/dist/web-router/types/hooks.d.ts +1 -0
- package/dist/web-router/types/index.d.ts +3 -0
- package/dist/web-router/types/utils/metaDataUtils.d.ts +24 -0
- package/dist/web-router/utils/metaDataUtils.jsx +119 -0
- package/mcp_v2/conversion-tasks.json +35 -17
- package/mcp_v2/knowledge-base.json +176 -17
- package/mcp_v2/lib/helpers.js +10 -0
- package/mcp_v2/mcp.js +40 -8
- package/mcp_v2/package.json +1 -0
- package/mcp_v2/tools/build.js +161 -37
- package/mcp_v2/tools/conversion.js +106 -5
- package/mcp_v2/tools/tasks.js +18 -14
- package/package.json +35 -68
- package/babel.config.js +0 -32
- package/dist/index.js +0 -1
- package/dist/scripts/devBuild.js +0 -3
- package/dist/scripts/devServe.js +0 -3
- package/dist/scripts/loadScriptsBeforeServerStarts.js +0 -4
- package/dist/scripts/registerAliases.js +0 -6
- package/dist/server/renderer/document/Body.js +0 -11
- package/dist/server/renderer/document/Head.js +0 -9
- package/dist/server/renderer/document/index.js +0 -1
- package/dist/server/renderer/handler.js +0 -47
- package/dist/server/startServer.js +0 -57
- package/dist/webpack/babel-plugins/remove-client.plugin.js +0 -5
- package/dist/webpack/babel-plugins/remove-ssr.plugin.js +0 -5
- package/dist/webpack/babel.config.client.js +0 -1
- package/dist/webpack/babel.config.ssr.js +0 -1
- package/dist/webpack/base.babel.js +0 -7
- package/dist/webpack/development.client.babel.js +0 -10
- package/dist/webpack/production.client.babel.js +0 -4
- package/dist/webpack/production.ssr.babel.js +0 -8
- package/dist/webpack/scssParams.js +0 -9
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import { fileURLToPath, pathToFileURL } from "url"
|
|
2
|
+
import { dirname, resolve as resolvePath, join, extname } from "path"
|
|
3
|
+
import { readFileSync, existsSync, statSync } from "fs"
|
|
4
|
+
import { createRequire } from "module"
|
|
5
|
+
import { transformSync } from "esbuild"
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
8
|
+
const __dirname = dirname(__filename)
|
|
9
|
+
|
|
10
|
+
// Cache for loaded aliases
|
|
11
|
+
let aliasCache = null
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Load and resolve module aliases from both the consuming app and catalyst-core
|
|
15
|
+
*/
|
|
16
|
+
function loadAliases() {
|
|
17
|
+
if (aliasCache) {
|
|
18
|
+
return aliasCache
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const appRoot = process.env.src_path || process.cwd()
|
|
22
|
+
|
|
23
|
+
const appPackageJsonConfig = resolvePath(appRoot, "package.json")
|
|
24
|
+
const catalystPackageJsonConfig = resolvePath(__dirname, "../../package.json")
|
|
25
|
+
|
|
26
|
+
let appModuleAliases = {}
|
|
27
|
+
let catalystModuleAliases = {}
|
|
28
|
+
|
|
29
|
+
// Read aliases from consuming application's package.json
|
|
30
|
+
try {
|
|
31
|
+
const appPackageJsonContent = readFileSync(appPackageJsonConfig, "utf8")
|
|
32
|
+
const appPackageJson = JSON.parse(appPackageJsonContent)
|
|
33
|
+
appModuleAliases = appPackageJson._moduleAliases || {}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
// Silently fail if app package.json doesn't exist or is invalid
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Read aliases from catalyst-core's package.json
|
|
39
|
+
try {
|
|
40
|
+
const catalystPackageJsonContent = readFileSync(catalystPackageJsonConfig, "utf8")
|
|
41
|
+
const catalystPackageJson = JSON.parse(catalystPackageJsonContent)
|
|
42
|
+
catalystModuleAliases = catalystPackageJson._moduleAliases || {}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
// Silently fail if catalyst package.json doesn't exist or is invalid
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Application aliases take precedence over catalyst-core aliases
|
|
48
|
+
const allAliases = { ...catalystModuleAliases, ...appModuleAliases }
|
|
49
|
+
|
|
50
|
+
// Convert aliases to resolved paths
|
|
51
|
+
aliasCache = {}
|
|
52
|
+
for (const [alias, aliasPath] of Object.entries(allAliases)) {
|
|
53
|
+
if (aliasPath && typeof aliasPath === "string") {
|
|
54
|
+
try {
|
|
55
|
+
// All aliases resolve relative to consuming project root (src_path)
|
|
56
|
+
const resolvedPath = resolvePath(appRoot, ...aliasPath.split("/"))
|
|
57
|
+
aliasCache[alias] = resolvedPath
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.warn(`Failed to resolve alias ${alias}:`, error.message)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return aliasCache
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Try to resolve a path by applying common JS/TS/ESM extensions and index fallbacks.
|
|
69
|
+
* This brings resolution closer to webpack-style behavior for extensionless imports.
|
|
70
|
+
*/
|
|
71
|
+
function resolveWithExtensions(basePath) {
|
|
72
|
+
// Exact match — but only if it's a file, not a directory
|
|
73
|
+
if (existsSync(basePath) && statSync(basePath).isFile()) {
|
|
74
|
+
return basePath
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const extensions = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".scss"]
|
|
78
|
+
|
|
79
|
+
// Try with common extensions (for extensionless imports)
|
|
80
|
+
for (const ext of extensions) {
|
|
81
|
+
const candidate = `${basePath}${ext}`
|
|
82
|
+
if (existsSync(candidate)) {
|
|
83
|
+
return candidate
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Try replacing the existing extension (e.g. .js → .jsx, .ts → .tsx)
|
|
88
|
+
// This handles webpack-style resolution where .js imports can resolve to .jsx files
|
|
89
|
+
const currentExt = extname(basePath)
|
|
90
|
+
if (currentExt) {
|
|
91
|
+
const withoutExt = basePath.slice(0, -currentExt.length)
|
|
92
|
+
for (const ext of extensions) {
|
|
93
|
+
if (ext === currentExt) continue
|
|
94
|
+
const candidate = `${withoutExt}${ext}`
|
|
95
|
+
if (existsSync(candidate)) {
|
|
96
|
+
return candidate
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Try index files inside a directory
|
|
102
|
+
for (const ext of extensions) {
|
|
103
|
+
const candidate = join(basePath, `index${ext}`)
|
|
104
|
+
if (existsSync(candidate)) {
|
|
105
|
+
return candidate
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return null
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Resolve an import specifier using aliases
|
|
114
|
+
*/
|
|
115
|
+
function resolveAlias(specifier, parentURL) {
|
|
116
|
+
const aliases = loadAliases()
|
|
117
|
+
|
|
118
|
+
// Check if specifier starts with any alias
|
|
119
|
+
for (const [alias, aliasPath] of Object.entries(aliases)) {
|
|
120
|
+
if (specifier.startsWith(alias + "/") || specifier === alias) {
|
|
121
|
+
const remainingPath = specifier === alias ? "" : specifier.slice(alias.length + 1)
|
|
122
|
+
const rawResolvedPath = join(aliasPath, remainingPath)
|
|
123
|
+
const finalResolvedPath = resolveWithExtensions(rawResolvedPath)
|
|
124
|
+
|
|
125
|
+
if (finalResolvedPath) {
|
|
126
|
+
return resolvePath(finalResolvedPath)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return null
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Try to resolve a relative specifier by computing the absolute path from the
|
|
136
|
+
* parent module and running it through extension / index resolution.
|
|
137
|
+
*/
|
|
138
|
+
function resolveRelative(specifier, parentURL) {
|
|
139
|
+
if (!parentURL) return null
|
|
140
|
+
try {
|
|
141
|
+
const parentPath = fileURLToPath(parentURL)
|
|
142
|
+
const parentDir = dirname(parentPath)
|
|
143
|
+
const absolutePath = resolvePath(parentDir, specifier)
|
|
144
|
+
return resolveWithExtensions(absolutePath)
|
|
145
|
+
} catch {
|
|
146
|
+
return null
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Resolve a bare specifier (e.g. "@tata1mg/synapse/utils") using CJS resolution
|
|
152
|
+
* rules via createRequire. CJS require.resolve handles extensionless imports,
|
|
153
|
+
* directory/index resolution, and package.json "main" fields automatically.
|
|
154
|
+
*/
|
|
155
|
+
function resolveBareSpecifier(specifier, parentURL) {
|
|
156
|
+
if (!parentURL) return null
|
|
157
|
+
try {
|
|
158
|
+
const req = createRequire(parentURL)
|
|
159
|
+
const resolved = req.resolve(specifier)
|
|
160
|
+
return resolved
|
|
161
|
+
} catch {
|
|
162
|
+
return null
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Node.js loader hook for resolving modules
|
|
168
|
+
*/
|
|
169
|
+
export async function resolve(specifier, context, defaultResolve) {
|
|
170
|
+
try {
|
|
171
|
+
// 1. Try alias resolution first
|
|
172
|
+
const aliasResolved = resolveAlias(specifier, context.parentURL)
|
|
173
|
+
if (aliasResolved) {
|
|
174
|
+
const fileURL = pathToFileURL(aliasResolved).href
|
|
175
|
+
const ext = extname(aliasResolved)
|
|
176
|
+
// Node's default resolver can't handle .jsx/.tsx — shortCircuit directly
|
|
177
|
+
if (ext === ".jsx" || ext === ".tsx") {
|
|
178
|
+
return { url: fileURL, shortCircuit: true }
|
|
179
|
+
}
|
|
180
|
+
return await defaultResolve(fileURL, context)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// 2. For relative imports, try extension / directory index resolution
|
|
184
|
+
// before handing off to Node's strict ESM resolver.
|
|
185
|
+
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
186
|
+
const resolved = resolveRelative(specifier, context.parentURL)
|
|
187
|
+
if (resolved) {
|
|
188
|
+
return {
|
|
189
|
+
url: pathToFileURL(resolved).href,
|
|
190
|
+
shortCircuit: true,
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 3. Default resolver
|
|
196
|
+
return await defaultResolve(specifier, context)
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (error.code === "ERR_UNSUPPORTED_DIR_IMPORT" || error.code === "ERR_MODULE_NOT_FOUND") {
|
|
199
|
+
// 4a. For relative imports, retry with extension / directory resolution
|
|
200
|
+
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
201
|
+
const resolved = resolveRelative(specifier, context.parentURL)
|
|
202
|
+
if (resolved) {
|
|
203
|
+
return {
|
|
204
|
+
url: pathToFileURL(resolved).href,
|
|
205
|
+
shortCircuit: true,
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 4b. For bare specifiers (node_modules), fall back to CJS require.resolve
|
|
211
|
+
const cjsResolved = resolveBareSpecifier(specifier, context.parentURL)
|
|
212
|
+
if (cjsResolved) {
|
|
213
|
+
return {
|
|
214
|
+
url: pathToFileURL(cjsResolved).href,
|
|
215
|
+
shortCircuit: true,
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
throw error
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Walk up from a directory to find the nearest package.json and return its parsed content.
|
|
225
|
+
*/
|
|
226
|
+
function findNearestPackageType(dir) {
|
|
227
|
+
while (dir !== dirname(dir)) {
|
|
228
|
+
const pkgPath = join(dir, "package.json")
|
|
229
|
+
if (existsSync(pkgPath)) {
|
|
230
|
+
try {
|
|
231
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"))
|
|
232
|
+
return pkg.type || "commonjs"
|
|
233
|
+
} catch {
|
|
234
|
+
return "commonjs"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
dir = dirname(dir)
|
|
238
|
+
}
|
|
239
|
+
return "commonjs"
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if a file is a CJS module based on extension and nearest package.json.
|
|
244
|
+
*/
|
|
245
|
+
function isCjsModule(filePath) {
|
|
246
|
+
const ext = extname(filePath)
|
|
247
|
+
if (ext === ".mjs") return false
|
|
248
|
+
if (ext === ".cjs") return true
|
|
249
|
+
return findNearestPackageType(dirname(filePath)) !== "module"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const VALID_IDENTIFIER_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/
|
|
253
|
+
const JS_RESERVED = new Set([
|
|
254
|
+
"break",
|
|
255
|
+
"case",
|
|
256
|
+
"catch",
|
|
257
|
+
"continue",
|
|
258
|
+
"debugger",
|
|
259
|
+
"default",
|
|
260
|
+
"delete",
|
|
261
|
+
"do",
|
|
262
|
+
"else",
|
|
263
|
+
"finally",
|
|
264
|
+
"for",
|
|
265
|
+
"function",
|
|
266
|
+
"if",
|
|
267
|
+
"in",
|
|
268
|
+
"instanceof",
|
|
269
|
+
"new",
|
|
270
|
+
"return",
|
|
271
|
+
"switch",
|
|
272
|
+
"this",
|
|
273
|
+
"throw",
|
|
274
|
+
"try",
|
|
275
|
+
"typeof",
|
|
276
|
+
"var",
|
|
277
|
+
"void",
|
|
278
|
+
"while",
|
|
279
|
+
"with",
|
|
280
|
+
"class",
|
|
281
|
+
"const",
|
|
282
|
+
"enum",
|
|
283
|
+
"export",
|
|
284
|
+
"extends",
|
|
285
|
+
"import",
|
|
286
|
+
"super",
|
|
287
|
+
"implements",
|
|
288
|
+
"interface",
|
|
289
|
+
"let",
|
|
290
|
+
"package",
|
|
291
|
+
"private",
|
|
292
|
+
"protected",
|
|
293
|
+
"public",
|
|
294
|
+
"static",
|
|
295
|
+
"yield",
|
|
296
|
+
])
|
|
297
|
+
|
|
298
|
+
function isValidExportName(name) {
|
|
299
|
+
return VALID_IDENTIFIER_RE.test(name) && !JS_RESERVED.has(name) && name !== "default"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Loader-scoped require for discovering CJS exports
|
|
303
|
+
const loaderRequire = createRequire(import.meta.url)
|
|
304
|
+
|
|
305
|
+
const CJS_PATTERN = /\b(module\.exports\b|exports\.\w+\s*=)/
|
|
306
|
+
const REQUIRE_CALL_PATTERN = /\brequire\s*\(/
|
|
307
|
+
|
|
308
|
+
// Shim __dirname and __filename for ESM app files (these globals only exist in CJS)
|
|
309
|
+
const createDirnameShim = (source) => {
|
|
310
|
+
const hasFilename = /\b(?:const|let|var)\s+__filename\b/.test(source)
|
|
311
|
+
const hasDirname = /\b(?:const|let|var)\s+__dirname\b/.test(source)
|
|
312
|
+
if (hasFilename && hasDirname) return ""
|
|
313
|
+
|
|
314
|
+
return [
|
|
315
|
+
!hasFilename && `import { fileURLToPath as __node_loader_fileURLToPath } from "url";`,
|
|
316
|
+
!hasDirname && `import { dirname as __node_loader_dirname } from "path";`,
|
|
317
|
+
!hasFilename && `const __filename = __node_loader_fileURLToPath(import.meta.url);`,
|
|
318
|
+
!hasDirname && `const __dirname = __node_loader_dirname(__filename);`,
|
|
319
|
+
]
|
|
320
|
+
.filter(Boolean)
|
|
321
|
+
.join("\n")
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Shim require for ESM app files that still import legacy CJS dependencies.
|
|
325
|
+
const createRequireShim = (source) => {
|
|
326
|
+
if (!REQUIRE_CALL_PATTERN.test(source)) return ""
|
|
327
|
+
if (/\b(?:const|let|var)\s+require\b/.test(source) || /\bfunction\s+require\b/.test(source)) return ""
|
|
328
|
+
|
|
329
|
+
return [
|
|
330
|
+
`import { createRequire as __node_loader_createRequire } from "module";`,
|
|
331
|
+
`const require = __node_loader_createRequire(import.meta.url);`,
|
|
332
|
+
].join("\n")
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Generate an ESM wrapper for a CJS file using createRequire.
|
|
337
|
+
* Discovers named exports by executing the module via require().
|
|
338
|
+
*/
|
|
339
|
+
function generateCjsWrapper(filePath, url) {
|
|
340
|
+
const mod = loaderRequire(filePath)
|
|
341
|
+
const exportNames = Object.keys(mod).filter(isValidExportName)
|
|
342
|
+
|
|
343
|
+
return [
|
|
344
|
+
`import { createRequire as __createRequire } from "module";`,
|
|
345
|
+
`const __require = __createRequire(${JSON.stringify(url)});`,
|
|
346
|
+
`const __mod = __require(${JSON.stringify(filePath)});`,
|
|
347
|
+
`export default __mod;`,
|
|
348
|
+
...exportNames.map((name) => `export const ${name} = __mod[${JSON.stringify(name)}];`),
|
|
349
|
+
].join("\n")
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Node.js loader hook for transforming source code.
|
|
354
|
+
* - Wraps CJS modules (node_modules and app files) as ESM so named imports work.
|
|
355
|
+
* - Transpiles JSX in .js/.js app files so Node can execute them.
|
|
356
|
+
*/
|
|
357
|
+
export async function load(url, context, defaultLoad) {
|
|
358
|
+
// Only transform file:// URLs (skip node: builtins, data: urls, etc.)
|
|
359
|
+
if (!url.startsWith("file://")) {
|
|
360
|
+
return defaultLoad(url, context)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const filePath = fileURLToPath(url)
|
|
364
|
+
const ext = extname(filePath)
|
|
365
|
+
|
|
366
|
+
if (ext !== ".js" && ext !== ".jsx" && ext !== ".cjs") {
|
|
367
|
+
return defaultLoad(url, context)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const isNodeModule = filePath.includes("/node_modules/")
|
|
371
|
+
|
|
372
|
+
// --- CJS detection and wrapping ---
|
|
373
|
+
// For node_modules: check via package.json "type" field
|
|
374
|
+
// For app files: check source content (because package.json may say "module"
|
|
375
|
+
// but the file may still use CJS syntax during migration)
|
|
376
|
+
if (ext === ".cjs" || (isNodeModule && isCjsModule(filePath))) {
|
|
377
|
+
try {
|
|
378
|
+
const source = generateCjsWrapper(filePath, url)
|
|
379
|
+
return { format: "module", source, shortCircuit: true }
|
|
380
|
+
} catch {
|
|
381
|
+
return defaultLoad(url, context)
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// For non-node_modules .js/.js files, read source to detect CJS or JSX
|
|
386
|
+
if (!isNodeModule) {
|
|
387
|
+
const source = readFileSync(filePath, "utf8")
|
|
388
|
+
|
|
389
|
+
// If source uses CJS module.exports/exports, wrap it in an ESM shim.
|
|
390
|
+
// We can't use createRequire here because the file lives in a "type":"module"
|
|
391
|
+
// package — Node's CJS require refuses to load it. Instead, we wrap the
|
|
392
|
+
// source inline so that `module.exports` becomes the default export.
|
|
393
|
+
if (CJS_PATTERN.test(source)) {
|
|
394
|
+
const shimmed = [
|
|
395
|
+
createRequireShim(source),
|
|
396
|
+
createDirnameShim(source),
|
|
397
|
+
`var module = { exports: {} };`,
|
|
398
|
+
`var exports = module.exports;`,
|
|
399
|
+
source,
|
|
400
|
+
`export default module.exports;`,
|
|
401
|
+
].join("\n")
|
|
402
|
+
|
|
403
|
+
// Run through esbuild in case the CJS file also has JSX
|
|
404
|
+
try {
|
|
405
|
+
const result = transformSync(shimmed, {
|
|
406
|
+
loader: "jsx",
|
|
407
|
+
format: "esm",
|
|
408
|
+
sourcefile: filePath,
|
|
409
|
+
target: "node20",
|
|
410
|
+
})
|
|
411
|
+
return { format: "module", source: result.code, shortCircuit: true }
|
|
412
|
+
} catch {
|
|
413
|
+
// If esbuild fails, return the shimmed source as-is
|
|
414
|
+
return { format: "module", source: shimmed, shortCircuit: true }
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// ESM app files: prepend __dirname/__filename shim + JSX transform
|
|
419
|
+
{
|
|
420
|
+
const transformed = `${createRequireShim(source)}\n${createDirnameShim(source)}\n${source}`
|
|
421
|
+
try {
|
|
422
|
+
const result = transformSync(transformed, {
|
|
423
|
+
loader: "jsx",
|
|
424
|
+
format: "esm",
|
|
425
|
+
sourcefile: filePath,
|
|
426
|
+
target: "node20",
|
|
427
|
+
})
|
|
428
|
+
return {
|
|
429
|
+
format: "module",
|
|
430
|
+
source: result.code,
|
|
431
|
+
shortCircuit: true,
|
|
432
|
+
}
|
|
433
|
+
} catch {
|
|
434
|
+
// If esbuild fails, return with just the shim
|
|
435
|
+
return { format: "module", source: transformed, shortCircuit: true }
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// .jsx files in node_modules still need esbuild transformation
|
|
441
|
+
// since Node.js cannot natively handle the .jsx extension
|
|
442
|
+
if (ext === ".jsx") {
|
|
443
|
+
const source = readFileSync(filePath, "utf8")
|
|
444
|
+
try {
|
|
445
|
+
const result = transformSync(source, {
|
|
446
|
+
loader: "jsx",
|
|
447
|
+
format: "esm",
|
|
448
|
+
sourcefile: filePath,
|
|
449
|
+
target: "node20",
|
|
450
|
+
})
|
|
451
|
+
return { format: "module", source: result.code, shortCircuit: true }
|
|
452
|
+
} catch {
|
|
453
|
+
return { format: "module", source, shortCircuit: true }
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return defaultLoad(url, context)
|
|
458
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description generate assets url according to enviorment
|
|
3
|
+
* @returns returns path required for loading assets according to enviorment
|
|
4
|
+
*/
|
|
5
|
+
export const imageUrl = () => {
|
|
6
|
+
const { PUBLIC_STATIC_ASSET_URL, PUBLIC_STATIC_ASSET_PATH } = process.env
|
|
7
|
+
let publicPath = `${PUBLIC_STATIC_ASSET_URL}${PUBLIC_STATIC_ASSET_PATH}`
|
|
8
|
+
const imagePath = `${publicPath}images/`
|
|
9
|
+
return imagePath
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @description generate assets font url according to enviorment
|
|
14
|
+
* @returns returns path required for loading fonts according to enviorment
|
|
15
|
+
*/
|
|
16
|
+
export const fontUrl = () => {
|
|
17
|
+
const { PUBLIC_STATIC_ASSET_URL, PUBLIC_STATIC_ASSET_PATH } = process.env
|
|
18
|
+
let publicPath = `${PUBLIC_STATIC_ASSET_URL}${PUBLIC_STATIC_ASSET_PATH}`
|
|
19
|
+
const fontPath = `${publicPath}fonts/`
|
|
20
|
+
return fontPath
|
|
21
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import loadEnvironmentVariables from "../scripts/loadEnvironmentVariables.js"
|
|
2
|
+
loadEnvironmentVariables()
|
|
3
|
+
import { defineConfig } from "vite"
|
|
4
|
+
import baseConfig, { getClientEnvVariables } from "./vite.config.js"
|
|
5
|
+
import path from "path"
|
|
6
|
+
import { manifestCategorizationPlugin } from "./manifest-categorization-plugin.js"
|
|
7
|
+
import { injectCacheKeyPlugin } from "./inject-cache-key-plugin.js"
|
|
8
|
+
import { loadCustomViteConfig } from "./loadCustomViteConfig.js"
|
|
9
|
+
|
|
10
|
+
const createClientConfig = async () => {
|
|
11
|
+
const customViteConfig = await loadCustomViteConfig()
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
...baseConfig,
|
|
15
|
+
mode: "production",
|
|
16
|
+
base: `${process.env.PUBLIC_STATIC_ASSET_URL || ""}${process.env.PUBLIC_STATIC_ASSET_PATH || "/"}`,
|
|
17
|
+
|
|
18
|
+
plugins: [
|
|
19
|
+
...(baseConfig.plugins || []),
|
|
20
|
+
manifestCategorizationPlugin({
|
|
21
|
+
outputFile: "asset-categories.json",
|
|
22
|
+
publicPath: `${process.env.PUBLIC_STATIC_ASSET_URL}${process.env.PUBLIC_STATIC_ASSET_PATH}/client/assets/`,
|
|
23
|
+
}),
|
|
24
|
+
injectCacheKeyPlugin(),
|
|
25
|
+
...(customViteConfig?.clientPlugins || []),
|
|
26
|
+
],
|
|
27
|
+
|
|
28
|
+
build: {
|
|
29
|
+
target: "esnext",
|
|
30
|
+
minify: "esbuild",
|
|
31
|
+
sourcemap: false,
|
|
32
|
+
manifest: true,
|
|
33
|
+
ssrManifest: true,
|
|
34
|
+
outDir: path.join(process.env.src_path, process.env.BUILD_OUTPUT_PATH || "build"),
|
|
35
|
+
|
|
36
|
+
// cssCodeSplit: true (default) — each chunk gets its own CSS file.
|
|
37
|
+
// Since ALL CSS is served via external <link> tags (never inlined),
|
|
38
|
+
// per-chunk CSS is fine — more files but each is small and cacheable.
|
|
39
|
+
|
|
40
|
+
rollupOptions: {
|
|
41
|
+
input: {
|
|
42
|
+
main: path.join(process.env.src_path, "client/index.js"),
|
|
43
|
+
},
|
|
44
|
+
output: {
|
|
45
|
+
format: "es",
|
|
46
|
+
entryFileNames: (chunkInfo) => {
|
|
47
|
+
return chunkInfo.name === "server"
|
|
48
|
+
? "server/[name].js"
|
|
49
|
+
: "client/assets/[name]-[hash].js"
|
|
50
|
+
},
|
|
51
|
+
chunkFileNames: "client/assets/[name]-[hash].js",
|
|
52
|
+
assetFileNames: (assetInfo) => {
|
|
53
|
+
const extType = assetInfo.name.split(".").pop()
|
|
54
|
+
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
|
|
55
|
+
return "client/assets/images/[name]-[hash][extname]"
|
|
56
|
+
}
|
|
57
|
+
if (/woff2?|eot|ttf|otf/i.test(extType)) {
|
|
58
|
+
return "client/assets/fonts/[name]-[hash][extname]"
|
|
59
|
+
}
|
|
60
|
+
if (/css/i.test(extType)) {
|
|
61
|
+
return "client/assets/css/[name]-[hash][extname]"
|
|
62
|
+
}
|
|
63
|
+
return "client/assets/[name]-[hash][extname]"
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// Each manual chunk gets its own [hash] from chunkFileNames,
|
|
67
|
+
// so a change in one group does not bust caches for the others.
|
|
68
|
+
// Keep CSS out of manual chunks so cssCodeSplit works correctly.
|
|
69
|
+
manualChunks(id) {
|
|
70
|
+
if (/\.(css|scss|sass|less|styl)(\?.*)?$/.test(id)) {
|
|
71
|
+
return undefined
|
|
72
|
+
}
|
|
73
|
+
if (!/[\\/]node_modules[\\/]/.test(id)) {
|
|
74
|
+
return undefined
|
|
75
|
+
}
|
|
76
|
+
if (
|
|
77
|
+
/[\\/]node_modules[\\/](react|react-dom|scheduler|react-fast-compare|react-side-effect|react-helmet-async)[\\/]/.test(
|
|
78
|
+
id
|
|
79
|
+
)
|
|
80
|
+
) {
|
|
81
|
+
return "vendor-react"
|
|
82
|
+
}
|
|
83
|
+
if (/[\\/]node_modules[\\/](react-router(?:-dom|-config)?|history)[\\/]/.test(id)) {
|
|
84
|
+
return "vendor-router"
|
|
85
|
+
}
|
|
86
|
+
if (/[\\/]node_modules[\\/]axios[\\/]/.test(id)) {
|
|
87
|
+
return "vendor-network"
|
|
88
|
+
}
|
|
89
|
+
if (/[\\/]node_modules[\\/]lottie[^\\/]*[\\/]/.test(id)) {
|
|
90
|
+
return "vendor-lottie"
|
|
91
|
+
}
|
|
92
|
+
if (
|
|
93
|
+
/[\\/]node_modules[\\/](react-google-recaptcha|react-async-script|react-dfp)[\\/]/.test(
|
|
94
|
+
id
|
|
95
|
+
)
|
|
96
|
+
) {
|
|
97
|
+
return "vendor-ads"
|
|
98
|
+
}
|
|
99
|
+
if (
|
|
100
|
+
/[\\/]node_modules[\\/](react-loadable-visibility|react-detect-offline|normalize\.css)[\\/]/.test(
|
|
101
|
+
id
|
|
102
|
+
)
|
|
103
|
+
) {
|
|
104
|
+
return "vendor-ui"
|
|
105
|
+
}
|
|
106
|
+
if (/[\\/]node_modules[\\/]catalyst-core[\\/]/.test(id)) {
|
|
107
|
+
return "app"
|
|
108
|
+
}
|
|
109
|
+
// Other node_modules → let Vite pack them with the chunks that use them.
|
|
110
|
+
return undefined
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
modulePreload: false,
|
|
116
|
+
chunkSizeWarningLimit: 2000,
|
|
117
|
+
},
|
|
118
|
+
esbuild: {
|
|
119
|
+
legalComments: "none",
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
define: {
|
|
123
|
+
...getClientEnvVariables(),
|
|
124
|
+
__DEV__: false,
|
|
125
|
+
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export default defineConfig(createClientConfig)
|