@gxp-dev/tools 2.0.63 → 2.0.65
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/README.md +32 -31
- package/bin/gx-devtools.js +74 -54
- package/bin/lib/cli.js +23 -21
- package/bin/lib/commands/add-dependency.js +366 -325
- package/bin/lib/commands/assets.js +137 -139
- package/bin/lib/commands/build.js +169 -174
- package/bin/lib/commands/datastore.js +181 -183
- package/bin/lib/commands/dev.js +127 -131
- package/bin/lib/commands/extensions.js +147 -149
- package/bin/lib/commands/extract-config.js +73 -67
- package/bin/lib/commands/index.js +12 -12
- package/bin/lib/commands/init.js +342 -240
- package/bin/lib/commands/publish.js +69 -75
- package/bin/lib/commands/socket.js +69 -69
- package/bin/lib/commands/ssl.js +14 -14
- package/bin/lib/constants.js +10 -24
- package/bin/lib/tui/App.tsx +761 -705
- package/bin/lib/tui/components/AIPanel.tsx +191 -171
- package/bin/lib/tui/components/CommandInput.tsx +394 -343
- package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
- package/bin/lib/tui/components/Header.tsx +23 -21
- package/bin/lib/tui/components/LogPanel.tsx +244 -220
- package/bin/lib/tui/components/TabBar.tsx +50 -48
- package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
- package/bin/lib/tui/index.tsx +37 -39
- package/bin/lib/tui/services/AIService.ts +518 -462
- package/bin/lib/tui/services/ExtensionService.ts +140 -129
- package/bin/lib/tui/services/GeminiService.ts +367 -337
- package/bin/lib/tui/services/ServiceManager.ts +344 -322
- package/bin/lib/tui/services/SocketService.ts +168 -168
- package/bin/lib/tui/services/ViteService.ts +88 -88
- package/bin/lib/tui/services/index.ts +47 -22
- package/bin/lib/utils/ai-scaffold.js +291 -280
- package/bin/lib/utils/extract-config.js +157 -140
- package/bin/lib/utils/files.js +82 -86
- package/bin/lib/utils/index.js +7 -7
- package/bin/lib/utils/paths.js +34 -34
- package/bin/lib/utils/prompts.js +194 -169
- package/bin/lib/utils/ssl.js +79 -81
- package/browser-extensions/README.md +0 -1
- package/browser-extensions/chrome/background.js +244 -237
- package/browser-extensions/chrome/content.js +32 -29
- package/browser-extensions/chrome/devtools.html +7 -7
- package/browser-extensions/chrome/devtools.js +19 -19
- package/browser-extensions/chrome/inspector.js +802 -767
- package/browser-extensions/chrome/manifest.json +71 -63
- package/browser-extensions/chrome/panel.html +674 -636
- package/browser-extensions/chrome/panel.js +722 -712
- package/browser-extensions/chrome/popup.html +586 -543
- package/browser-extensions/chrome/popup.js +282 -244
- package/browser-extensions/chrome/rules.json +1 -1
- package/browser-extensions/chrome/test-chrome.html +216 -136
- package/browser-extensions/chrome/test-mixed-content.html +284 -189
- package/browser-extensions/chrome/test-uri-pattern.html +221 -198
- package/browser-extensions/firefox/README.md +9 -6
- package/browser-extensions/firefox/background.js +221 -218
- package/browser-extensions/firefox/content.js +55 -52
- package/browser-extensions/firefox/debug-errors.html +386 -228
- package/browser-extensions/firefox/debug-https.html +153 -105
- package/browser-extensions/firefox/devtools.html +7 -7
- package/browser-extensions/firefox/devtools.js +23 -20
- package/browser-extensions/firefox/inspector.js +802 -767
- package/browser-extensions/firefox/manifest.json +68 -68
- package/browser-extensions/firefox/panel.html +674 -636
- package/browser-extensions/firefox/panel.js +722 -712
- package/browser-extensions/firefox/popup.html +572 -535
- package/browser-extensions/firefox/popup.js +281 -236
- package/browser-extensions/firefox/test-gramercy.html +170 -125
- package/browser-extensions/firefox/test-imports.html +59 -55
- package/browser-extensions/firefox/test-masking.html +231 -140
- package/browser-extensions/firefox/test-uri-pattern.html +221 -198
- package/dist/tui/App.d.ts +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +154 -150
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/AIPanel.d.ts.map +1 -1
- package/dist/tui/components/AIPanel.js +42 -35
- package/dist/tui/components/AIPanel.js.map +1 -1
- package/dist/tui/components/CommandInput.d.ts +1 -1
- package/dist/tui/components/CommandInput.d.ts.map +1 -1
- package/dist/tui/components/CommandInput.js +92 -62
- package/dist/tui/components/CommandInput.js.map +1 -1
- package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
- package/dist/tui/components/GeminiPanel.js +37 -30
- package/dist/tui/components/GeminiPanel.js.map +1 -1
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +1 -1
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/LogPanel.d.ts +1 -1
- package/dist/tui/components/LogPanel.d.ts.map +1 -1
- package/dist/tui/components/LogPanel.js +26 -24
- package/dist/tui/components/LogPanel.js.map +1 -1
- package/dist/tui/components/TabBar.d.ts +2 -2
- package/dist/tui/components/TabBar.d.ts.map +1 -1
- package/dist/tui/components/TabBar.js +11 -11
- package/dist/tui/components/TabBar.js.map +1 -1
- package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
- package/dist/tui/components/WelcomeScreen.js +6 -6
- package/dist/tui/components/WelcomeScreen.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +8 -8
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/services/AIService.d.ts +2 -2
- package/dist/tui/services/AIService.d.ts.map +1 -1
- package/dist/tui/services/AIService.js +165 -125
- package/dist/tui/services/AIService.js.map +1 -1
- package/dist/tui/services/ExtensionService.d.ts +1 -1
- package/dist/tui/services/ExtensionService.d.ts.map +1 -1
- package/dist/tui/services/ExtensionService.js +33 -26
- package/dist/tui/services/ExtensionService.js.map +1 -1
- package/dist/tui/services/GeminiService.d.ts +1 -1
- package/dist/tui/services/GeminiService.d.ts.map +1 -1
- package/dist/tui/services/GeminiService.js +87 -76
- package/dist/tui/services/GeminiService.js.map +1 -1
- package/dist/tui/services/ServiceManager.d.ts +3 -3
- package/dist/tui/services/ServiceManager.d.ts.map +1 -1
- package/dist/tui/services/ServiceManager.js +72 -58
- package/dist/tui/services/ServiceManager.js.map +1 -1
- package/dist/tui/services/SocketService.d.ts.map +1 -1
- package/dist/tui/services/SocketService.js +32 -32
- package/dist/tui/services/SocketService.js.map +1 -1
- package/dist/tui/services/ViteService.d.ts.map +1 -1
- package/dist/tui/services/ViteService.js +26 -28
- package/dist/tui/services/ViteService.js.map +1 -1
- package/dist/tui/services/index.d.ts +6 -6
- package/dist/tui/services/index.d.ts.map +1 -1
- package/dist/tui/services/index.js +6 -6
- package/dist/tui/services/index.js.map +1 -1
- package/mcp/gxp-api-server.js +83 -81
- package/package.json +109 -93
- package/runtime/PortalContainer.vue +258 -234
- package/runtime/dev-tools/DevToolsModal.vue +153 -155
- package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
- package/runtime/dev-tools/MockDataEditor.vue +456 -433
- package/runtime/dev-tools/SocketSimulator.vue +379 -371
- package/runtime/dev-tools/StoreInspector.vue +517 -455
- package/runtime/dev-tools/index.js +5 -5
- package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
- package/runtime/fallback-layouts/PublicLayout.vue +2 -2
- package/runtime/fallback-layouts/SystemLayout.vue +2 -2
- package/runtime/gxpStringsPlugin.js +159 -134
- package/runtime/index.html +17 -19
- package/runtime/main.js +24 -22
- package/runtime/mock-api/auth-middleware.js +15 -15
- package/runtime/mock-api/image-generator.js +46 -46
- package/runtime/mock-api/index.js +55 -55
- package/runtime/mock-api/response-generator.js +116 -105
- package/runtime/mock-api/route-generator.js +107 -84
- package/runtime/mock-api/socket-triggers.js +94 -93
- package/runtime/mock-api/spec-loader.js +79 -80
- package/runtime/package.json +3 -0
- package/runtime/server.js +68 -68
- package/runtime/stores/gxpPortalConfigStore.js +204 -186
- package/runtime/stores/index.js +2 -2
- package/runtime/vite-inspector-plugin.js +858 -707
- package/runtime/vite-source-tracker-plugin.js +132 -113
- package/runtime/vite.config.js +191 -139
- package/scripts/launch-chrome.js +41 -41
- package/scripts/pack-chrome.js +38 -39
- package/socket-events/AiSessionMessageCreated.json +17 -17
- package/socket-events/SocialStreamPostCreated.json +23 -23
- package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
- package/template/.claude/agents/gxp-developer.md +100 -99
- package/template/.claude/settings.json +7 -7
- package/template/AGENTS.md +30 -23
- package/template/GEMINI.md +20 -20
- package/template/README.md +70 -53
- package/template/app-manifest.json +2 -4
- package/template/configuration.json +10 -10
- package/template/default-styling.css +1 -1
- package/template/index.html +18 -20
- package/template/main.js +24 -22
- package/template/src/DemoPage.vue +415 -362
- package/template/src/Plugin.vue +76 -85
- package/template/src/stores/index.js +3 -3
- package/template/src/stores/test-data.json +164 -172
- package/template/theme-layouts/AdditionalStyling.css +50 -50
- package/template/theme-layouts/PrivateLayout.vue +8 -12
- package/template/theme-layouts/PublicLayout.vue +8 -12
- package/template/theme-layouts/SystemLayout.vue +8 -12
- package/template/vite.extend.js +45 -0
- package/template/vite.config.js +0 -409
package/runtime/vite.config.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { defineConfig, loadEnv } from "vite"
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import externalGlobals from "rollup-plugin-external-globals"
|
|
7
|
-
import { gxpInspectorPlugin } from "./vite-inspector-plugin.js"
|
|
8
|
-
import { gxpSourceTrackerPlugin } from "./vite-source-tracker-plugin.js"
|
|
1
|
+
import { defineConfig, loadEnv, mergeConfig } from "vite"
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from "url"
|
|
3
|
+
import vue from "@vitejs/plugin-vue"
|
|
4
|
+
import path from "path"
|
|
5
|
+
import fs from "fs"
|
|
6
|
+
import externalGlobals from "rollup-plugin-external-globals"
|
|
7
|
+
import { gxpInspectorPlugin } from "./vite-inspector-plugin.js"
|
|
8
|
+
import { gxpSourceTrackerPlugin } from "./vite-source-tracker-plugin.js"
|
|
9
9
|
|
|
10
10
|
// Environment URL configuration for API proxy
|
|
11
11
|
const ENVIRONMENT_URLS = {
|
|
@@ -14,26 +14,26 @@ const ENVIRONMENT_URLS = {
|
|
|
14
14
|
testing: "https://api.zenith-develop-testing.env.eventfinity.app",
|
|
15
15
|
develop: "https://api.zenith-develop.env.eventfinity.app",
|
|
16
16
|
local: "https://dashboard.eventfinity.test",
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Get the API proxy target URL based on environment
|
|
21
21
|
*/
|
|
22
22
|
function getApiProxyTarget(env) {
|
|
23
|
-
const apiEnv = env.API_ENV || "mock"
|
|
23
|
+
const apiEnv = env.API_ENV || "mock"
|
|
24
24
|
|
|
25
25
|
// Custom URL takes precedence
|
|
26
26
|
if (env.API_BASE_URL) {
|
|
27
|
-
return env.API_BASE_URL
|
|
27
|
+
return env.API_BASE_URL
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// Mock uses local mock-api server (no proxy needed, handled separately)
|
|
31
31
|
if (apiEnv === "mock") {
|
|
32
|
-
return null
|
|
32
|
+
return null
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// Look up environment URL
|
|
36
|
-
return ENVIRONMENT_URLS[apiEnv] || ENVIRONMENT_URLS.production
|
|
36
|
+
return ENVIRONMENT_URLS[apiEnv] || ENVIRONMENT_URLS.production
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -41,53 +41,53 @@ function getApiProxyTarget(env) {
|
|
|
41
41
|
*/
|
|
42
42
|
function getLibName() {
|
|
43
43
|
try {
|
|
44
|
-
const packageJsonPath = path.resolve(process.cwd(), "package.json")
|
|
44
|
+
const packageJsonPath = path.resolve(process.cwd(), "package.json")
|
|
45
45
|
if (fs.existsSync(packageJsonPath)) {
|
|
46
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"))
|
|
46
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"))
|
|
47
47
|
// Convert package name to a valid JS identifier
|
|
48
48
|
// e.g., "@company/my-plugin" -> "MyPlugin"
|
|
49
|
-
const name = packageJson.name || "Plugin"
|
|
49
|
+
const name = packageJson.name || "Plugin"
|
|
50
50
|
return name
|
|
51
51
|
.replace(/[@\/\-]/g, " ")
|
|
52
52
|
.replace(/\b\w/g, (l) => l.toUpperCase())
|
|
53
|
-
.replace(/\s/g, "")
|
|
53
|
+
.replace(/\s/g, "")
|
|
54
54
|
}
|
|
55
55
|
} catch (error) {
|
|
56
|
-
console.warn("Could not read package.json, using default lib name")
|
|
56
|
+
console.warn("Could not read package.json, using default lib name")
|
|
57
57
|
}
|
|
58
|
-
return "Plugin"
|
|
58
|
+
return "Plugin"
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Setup HTTPS configuration if certificates are available
|
|
63
63
|
*/
|
|
64
64
|
function getHttpsConfig(env) {
|
|
65
|
-
const useHttps = env.USE_HTTPS === "true"
|
|
66
|
-
const certPath = env.CERT_PATH
|
|
67
|
-
const keyPath = env.KEY_PATH
|
|
65
|
+
const useHttps = env.USE_HTTPS === "true"
|
|
66
|
+
const certPath = env.CERT_PATH
|
|
67
|
+
const keyPath = env.KEY_PATH
|
|
68
68
|
|
|
69
69
|
if (!useHttps || !certPath || !keyPath) {
|
|
70
|
-
return
|
|
70
|
+
return undefined
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// Resolve paths relative to project root
|
|
74
|
-
const resolvedCertPath = path.resolve(process.cwd(), certPath)
|
|
75
|
-
const resolvedKeyPath = path.resolve(process.cwd(), keyPath)
|
|
74
|
+
const resolvedCertPath = path.resolve(process.cwd(), certPath)
|
|
75
|
+
const resolvedKeyPath = path.resolve(process.cwd(), keyPath)
|
|
76
76
|
|
|
77
77
|
// Check if certificate files exist
|
|
78
78
|
if (!fs.existsSync(resolvedCertPath) || !fs.existsSync(resolvedKeyPath)) {
|
|
79
|
-
console.warn("⚠ SSL certificate files not found, falling back to HTTP")
|
|
80
|
-
return
|
|
79
|
+
console.warn("⚠ SSL certificate files not found, falling back to HTTP")
|
|
80
|
+
return undefined
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
try {
|
|
84
84
|
return {
|
|
85
85
|
key: fs.readFileSync(resolvedKeyPath),
|
|
86
86
|
cert: fs.readFileSync(resolvedCertPath),
|
|
87
|
-
}
|
|
87
|
+
}
|
|
88
88
|
} catch (error) {
|
|
89
|
-
console.warn("⚠ Failed to read SSL certificates, falling back to HTTP")
|
|
90
|
-
return
|
|
89
|
+
console.warn("⚠ Failed to read SSL certificates, falling back to HTTP")
|
|
90
|
+
return undefined
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -98,42 +98,79 @@ function findToolkitPath() {
|
|
|
98
98
|
// Derive from this config file's own location — always reliable regardless
|
|
99
99
|
// of how the package is installed (local, global, npm link, CI, etc.)
|
|
100
100
|
// This file lives at <toolkit>/runtime/vite.config.js, so toolkit root is one level up.
|
|
101
|
-
const configFileDir = path.dirname(fileURLToPath(import.meta.url))
|
|
102
|
-
return path.resolve(configFileDir, "..")
|
|
101
|
+
const configFileDir = path.dirname(fileURLToPath(import.meta.url))
|
|
102
|
+
return path.resolve(configFileDir, "..")
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
106
|
* Check if a file exists locally in the project
|
|
107
107
|
*/
|
|
108
108
|
function hasLocalFile(fileName) {
|
|
109
|
-
const localPath = path.resolve(process.cwd(), fileName)
|
|
110
|
-
return fs.existsSync(localPath)
|
|
109
|
+
const localPath = path.resolve(process.cwd(), fileName)
|
|
110
|
+
return fs.existsSync(localPath)
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Load the project-local `vite.extend.js` (or `.mjs`) if one exists.
|
|
115
|
+
*
|
|
116
|
+
* The file may export either a config object or a function
|
|
117
|
+
* `(ctx) => config | Promise<config>`, where `ctx` is
|
|
118
|
+
* `{ mode, command, env, runtimeConfig }`. The returned config is deep-merged
|
|
119
|
+
* into the runtime config via Vite's `mergeConfig` — arrays (plugins) are
|
|
120
|
+
* concatenated, objects (resolve.alias, define, etc.) are merged key-by-key,
|
|
121
|
+
* primitives are overwritten.
|
|
122
|
+
*/
|
|
123
|
+
async function loadExtensionConfig(ctx, runtimeConfig) {
|
|
124
|
+
const candidates = ["vite.extend.js", "vite.extend.mjs"]
|
|
125
|
+
for (const name of candidates) {
|
|
126
|
+
const abs = path.resolve(process.cwd(), name)
|
|
127
|
+
if (!fs.existsSync(abs)) {
|
|
128
|
+
continue
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const mod = await import(pathToFileURL(abs).href)
|
|
132
|
+
const exported = mod.default ?? mod
|
|
133
|
+
const extension =
|
|
134
|
+
typeof exported === "function"
|
|
135
|
+
? await exported({ ...ctx, runtimeConfig })
|
|
136
|
+
: exported
|
|
137
|
+
if (extension && typeof extension === "object") {
|
|
138
|
+
console.log(`🧩 Loaded ${name}`)
|
|
139
|
+
return extension
|
|
140
|
+
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
console.warn(`⚠ Failed to load ${name}:`, err.message)
|
|
143
|
+
}
|
|
144
|
+
return null
|
|
145
|
+
}
|
|
146
|
+
return null
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export default defineConfig(async (ctx) => {
|
|
150
|
+
const { mode } = ctx
|
|
114
151
|
// Load environment variables from project directory
|
|
115
|
-
const env = loadEnv(mode, process.cwd(), "")
|
|
152
|
+
const env = loadEnv(mode, process.cwd(), "")
|
|
116
153
|
|
|
117
154
|
// Get lib name from package.json
|
|
118
|
-
const libName = getLibName()
|
|
155
|
+
const libName = getLibName()
|
|
119
156
|
|
|
120
157
|
// Find the toolkit path for runtime imports
|
|
121
|
-
const toolkitPath = findToolkitPath()
|
|
122
|
-
const runtimeDir = path.resolve(toolkitPath, "runtime")
|
|
158
|
+
const toolkitPath = findToolkitPath()
|
|
159
|
+
const runtimeDir = path.resolve(toolkitPath, "runtime")
|
|
123
160
|
|
|
124
161
|
// Check for local dev files (requires both env var AND file to exist)
|
|
125
|
-
const hasLocalIndexHtml = hasLocalFile("index.html")
|
|
126
|
-
const hasLocalMainJs = hasLocalFile("main.js")
|
|
127
|
-
const useLocalIndex = env.USE_LOCAL_INDEX === "true" && hasLocalIndexHtml
|
|
128
|
-
const useLocalMain = env.USE_LOCAL_MAIN === "true" && hasLocalMainJs
|
|
162
|
+
const hasLocalIndexHtml = hasLocalFile("index.html")
|
|
163
|
+
const hasLocalMainJs = hasLocalFile("main.js")
|
|
164
|
+
const useLocalIndex = env.USE_LOCAL_INDEX === "true" && hasLocalIndexHtml
|
|
165
|
+
const useLocalMain = env.USE_LOCAL_MAIN === "true" && hasLocalMainJs
|
|
129
166
|
|
|
130
167
|
// Plugin enable/disable flags
|
|
131
|
-
const useSourceTracker = env.DISABLE_SOURCE_TRACKER !== "true"
|
|
132
|
-
const useInspector = env.DISABLE_INSPECTOR !== "true"
|
|
168
|
+
const useSourceTracker = env.DISABLE_SOURCE_TRACKER !== "true"
|
|
169
|
+
const useInspector = env.DISABLE_INSPECTOR !== "true"
|
|
133
170
|
|
|
134
171
|
// Log which files are being used
|
|
135
|
-
console.log(`📄 index.html: ${useLocalIndex ? "local" : "runtime"}`)
|
|
136
|
-
console.log(`📄 main.js: ${useLocalMain ? "local" : "runtime"}`)
|
|
172
|
+
console.log(`📄 index.html: ${useLocalIndex ? "local" : "runtime"}`)
|
|
173
|
+
console.log(`📄 main.js: ${useLocalMain ? "local" : "runtime"}`)
|
|
137
174
|
|
|
138
175
|
// Create plugin to serve runtime files (index.html and main.js) if no local ones exist
|
|
139
176
|
const runtimeFilesPlugin = {
|
|
@@ -144,47 +181,45 @@ export default defineConfig(({ mode }) => {
|
|
|
144
181
|
// (unless local index.html is opted in). SPA fallback is required so
|
|
145
182
|
// client-side routers (e.g. vue-router createWebHistory) can handle
|
|
146
183
|
// deep links when no physical index.html exists at the project root.
|
|
147
|
-
const rawUrl = req.url || ""
|
|
148
|
-
const urlPath = rawUrl.split("?")[0]
|
|
149
|
-
const accept = req.headers.accept || ""
|
|
150
|
-
const isGetOrHead = req.method === "GET" || req.method === "HEAD"
|
|
184
|
+
const rawUrl = req.url || ""
|
|
185
|
+
const urlPath = rawUrl.split("?")[0]
|
|
186
|
+
const accept = req.headers.accept || ""
|
|
187
|
+
const isGetOrHead = req.method === "GET" || req.method === "HEAD"
|
|
151
188
|
const isInternalPath =
|
|
152
189
|
urlPath.startsWith("/@") ||
|
|
153
190
|
urlPath.startsWith("/__") ||
|
|
154
191
|
urlPath.startsWith("/node_modules/") ||
|
|
155
192
|
urlPath.startsWith("/src/") ||
|
|
156
193
|
urlPath.startsWith("/dev-assets/") ||
|
|
157
|
-
urlPath.startsWith("/api-proxy/")
|
|
158
|
-
const hasExtension = path.extname(urlPath) !== ""
|
|
194
|
+
urlPath.startsWith("/api-proxy/")
|
|
195
|
+
const hasExtension = path.extname(urlPath) !== ""
|
|
159
196
|
const isSpaNavigation =
|
|
160
197
|
isGetOrHead &&
|
|
161
198
|
!isInternalPath &&
|
|
162
199
|
!hasExtension &&
|
|
163
|
-
accept.includes("text/html")
|
|
200
|
+
accept.includes("text/html")
|
|
164
201
|
|
|
165
202
|
if (
|
|
166
203
|
!useLocalIndex &&
|
|
167
|
-
(urlPath === "/" ||
|
|
168
|
-
urlPath === "/index.html" ||
|
|
169
|
-
isSpaNavigation)
|
|
204
|
+
(urlPath === "/" || urlPath === "/index.html" || isSpaNavigation)
|
|
170
205
|
) {
|
|
171
|
-
const runtimeIndexPath = path.join(runtimeDir, "index.html")
|
|
206
|
+
const runtimeIndexPath = path.join(runtimeDir, "index.html")
|
|
172
207
|
if (fs.existsSync(runtimeIndexPath)) {
|
|
173
208
|
// Read and transform the runtime index.html
|
|
174
209
|
server
|
|
175
210
|
.transformIndexHtml(
|
|
176
211
|
rawUrl,
|
|
177
|
-
fs.readFileSync(runtimeIndexPath, "utf-8")
|
|
212
|
+
fs.readFileSync(runtimeIndexPath, "utf-8"),
|
|
178
213
|
)
|
|
179
214
|
.then((html) => {
|
|
180
|
-
res.setHeader("Content-Type", "text/html")
|
|
181
|
-
res.end(html)
|
|
215
|
+
res.setHeader("Content-Type", "text/html")
|
|
216
|
+
res.end(html)
|
|
182
217
|
})
|
|
183
218
|
.catch((err) => {
|
|
184
|
-
console.error("Error transforming index.html:", err)
|
|
185
|
-
next(err)
|
|
186
|
-
})
|
|
187
|
-
return
|
|
219
|
+
console.error("Error transforming index.html:", err)
|
|
220
|
+
next(err)
|
|
221
|
+
})
|
|
222
|
+
return
|
|
188
223
|
}
|
|
189
224
|
}
|
|
190
225
|
|
|
@@ -194,77 +229,81 @@ export default defineConfig(({ mode }) => {
|
|
|
194
229
|
(req.url === "/@gx-runtime/main.js" ||
|
|
195
230
|
req.url?.startsWith("/@gx-runtime/main.js?"))
|
|
196
231
|
) {
|
|
197
|
-
const runtimeMainPath = path.join(runtimeDir, "main.js")
|
|
232
|
+
const runtimeMainPath = path.join(runtimeDir, "main.js")
|
|
198
233
|
if (fs.existsSync(runtimeMainPath)) {
|
|
199
234
|
// Use the real path to handle symlinks correctly
|
|
200
|
-
const realMainPath = fs.realpathSync(runtimeMainPath)
|
|
235
|
+
const realMainPath = fs.realpathSync(runtimeMainPath)
|
|
201
236
|
server
|
|
202
237
|
.transformRequest(realMainPath)
|
|
203
238
|
.then((result) => {
|
|
204
239
|
if (result) {
|
|
205
|
-
res.setHeader("Content-Type", "application/javascript")
|
|
206
|
-
res.end(result.code)
|
|
240
|
+
res.setHeader("Content-Type", "application/javascript")
|
|
241
|
+
res.end(result.code)
|
|
207
242
|
} else {
|
|
208
|
-
next()
|
|
243
|
+
next()
|
|
209
244
|
}
|
|
210
245
|
})
|
|
211
246
|
.catch((err) => {
|
|
212
|
-
console.error("Error transforming main.js:", err)
|
|
213
|
-
next(err)
|
|
214
|
-
})
|
|
215
|
-
return
|
|
247
|
+
console.error("Error transforming main.js:", err)
|
|
248
|
+
next(err)
|
|
249
|
+
})
|
|
250
|
+
return
|
|
216
251
|
}
|
|
217
252
|
}
|
|
218
253
|
|
|
219
|
-
next()
|
|
220
|
-
})
|
|
254
|
+
next()
|
|
255
|
+
})
|
|
221
256
|
},
|
|
222
|
-
}
|
|
257
|
+
}
|
|
223
258
|
|
|
224
259
|
// Resolve @layouts: use project's theme-layouts/ if it exists,
|
|
225
260
|
// otherwise fall back to toolkit's runtime/fallback-layouts/
|
|
226
|
-
const projectLayoutsDir = path.resolve(process.cwd(), "theme-layouts")
|
|
227
|
-
const fallbackLayoutsDir = path.resolve(runtimeDir, "fallback-layouts")
|
|
228
|
-
const layoutsDir = fs.existsSync(projectLayoutsDir)
|
|
261
|
+
const projectLayoutsDir = path.resolve(process.cwd(), "theme-layouts")
|
|
262
|
+
const fallbackLayoutsDir = path.resolve(runtimeDir, "fallback-layouts")
|
|
263
|
+
const layoutsDir = fs.existsSync(projectLayoutsDir)
|
|
264
|
+
? projectLayoutsDir
|
|
265
|
+
: fallbackLayoutsDir
|
|
229
266
|
|
|
230
267
|
if (layoutsDir === fallbackLayoutsDir) {
|
|
231
|
-
console.log(
|
|
268
|
+
console.log(
|
|
269
|
+
"📐 Layouts: using toolkit fallbacks (no theme-layouts/ directory)",
|
|
270
|
+
)
|
|
232
271
|
} else {
|
|
233
|
-
console.log("📐 Layouts: using project theme-layouts/")
|
|
272
|
+
console.log("📐 Layouts: using project theme-layouts/")
|
|
234
273
|
}
|
|
235
274
|
|
|
236
275
|
// Determine if HTTPS is enabled
|
|
237
|
-
const useHttps = getHttpsConfig(env) !==
|
|
276
|
+
const useHttps = getHttpsConfig(env) !== undefined
|
|
238
277
|
|
|
239
278
|
// Get API proxy target for non-mock environments
|
|
240
|
-
const apiProxyTarget = getApiProxyTarget(env)
|
|
279
|
+
const apiProxyTarget = getApiProxyTarget(env)
|
|
241
280
|
if (apiProxyTarget) {
|
|
242
|
-
console.log(`🔀 API Proxy: /api-proxy -> ${apiProxyTarget}`)
|
|
281
|
+
console.log(`🔀 API Proxy: /api-proxy -> ${apiProxyTarget}`)
|
|
243
282
|
}
|
|
244
283
|
|
|
245
|
-
|
|
284
|
+
const runtimeConfig = {
|
|
246
285
|
// Root is always the project directory
|
|
247
286
|
root: process.cwd(),
|
|
248
287
|
// Expose environment variables to the browser
|
|
249
288
|
define: {
|
|
250
289
|
"import.meta.env.VITE_API_ENV": JSON.stringify(env.API_ENV || "mock"),
|
|
251
290
|
"import.meta.env.VITE_API_BASE_URL": JSON.stringify(
|
|
252
|
-
env.API_BASE_URL || ""
|
|
291
|
+
env.API_BASE_URL || "",
|
|
253
292
|
),
|
|
254
293
|
"import.meta.env.VITE_API_KEY": JSON.stringify(env.API_KEY || ""),
|
|
255
294
|
"import.meta.env.VITE_API_PROJECT_ID": JSON.stringify(
|
|
256
|
-
env.API_PROJECT_ID || ""
|
|
295
|
+
env.API_PROJECT_ID || "",
|
|
257
296
|
),
|
|
258
297
|
"import.meta.env.VITE_USE_HTTPS": JSON.stringify(
|
|
259
|
-
useHttps ? "true" : "false"
|
|
298
|
+
useHttps ? "true" : "false",
|
|
260
299
|
),
|
|
261
300
|
"import.meta.env.VITE_NODE_PORT": JSON.stringify(env.NODE_PORT || "3060"),
|
|
262
301
|
"import.meta.env.VITE_SOCKET_IO_PORT": JSON.stringify(
|
|
263
|
-
env.SOCKET_IO_PORT || "3069"
|
|
302
|
+
env.SOCKET_IO_PORT || "3069",
|
|
264
303
|
),
|
|
265
304
|
"import.meta.env.SOCKET_URL": JSON.stringify(env.SOCKET_URL || ""),
|
|
266
305
|
"import.meta.env.SOCKET_DRIVER": JSON.stringify(
|
|
267
|
-
env.SOCKET_DRIVER || "io"
|
|
306
|
+
env.SOCKET_DRIVER || "io",
|
|
268
307
|
),
|
|
269
308
|
},
|
|
270
309
|
plugins: [
|
|
@@ -283,7 +322,7 @@ export default defineConfig(({ mode }) => {
|
|
|
283
322
|
},
|
|
284
323
|
{
|
|
285
324
|
include: ["src/**"],
|
|
286
|
-
}
|
|
325
|
+
},
|
|
287
326
|
),
|
|
288
327
|
// Custom request logging and CORS plugin
|
|
289
328
|
{
|
|
@@ -292,47 +331,47 @@ export default defineConfig(({ mode }) => {
|
|
|
292
331
|
server.middlewares.use((req, res, next) => {
|
|
293
332
|
// Health check route
|
|
294
333
|
if (req.url === "/__health") {
|
|
295
|
-
res.statusCode = 200
|
|
296
|
-
res.setHeader("Content-Type", "application/json")
|
|
297
|
-
res.end(JSON.stringify({ status: "ok" }))
|
|
298
|
-
return
|
|
334
|
+
res.statusCode = 200
|
|
335
|
+
res.setHeader("Content-Type", "application/json")
|
|
336
|
+
res.end(JSON.stringify({ status: "ok" }))
|
|
337
|
+
return
|
|
299
338
|
}
|
|
300
339
|
|
|
301
|
-
const start = Date.now()
|
|
302
|
-
const originalEnd = res.end
|
|
340
|
+
const start = Date.now()
|
|
341
|
+
const originalEnd = res.end
|
|
303
342
|
|
|
304
343
|
// Add CORS headers to all responses
|
|
305
|
-
res.setHeader("Access-Control-Allow-Origin", "*")
|
|
344
|
+
res.setHeader("Access-Control-Allow-Origin", "*")
|
|
306
345
|
res.setHeader(
|
|
307
346
|
"Access-Control-Allow-Methods",
|
|
308
|
-
"GET, POST, PUT, DELETE, OPTIONS"
|
|
309
|
-
)
|
|
310
|
-
res.setHeader("Access-Control-Allow-Headers", "*")
|
|
311
|
-
res.setHeader("Access-Control-Allow-Credentials", "false")
|
|
347
|
+
"GET, POST, PUT, DELETE, OPTIONS",
|
|
348
|
+
)
|
|
349
|
+
res.setHeader("Access-Control-Allow-Headers", "*")
|
|
350
|
+
res.setHeader("Access-Control-Allow-Credentials", "false")
|
|
312
351
|
|
|
313
352
|
// Handle preflight requests
|
|
314
353
|
if (req.method === "OPTIONS") {
|
|
315
|
-
res.statusCode = 200
|
|
316
|
-
res.end()
|
|
317
|
-
return
|
|
354
|
+
res.statusCode = 200
|
|
355
|
+
res.end()
|
|
356
|
+
return
|
|
318
357
|
}
|
|
319
358
|
|
|
320
359
|
res.end = function (...args) {
|
|
321
|
-
const duration = Date.now() - start
|
|
322
|
-
const status = res.statusCode
|
|
323
|
-
const method = req.method
|
|
324
|
-
const url = req.url
|
|
325
|
-
const referer = req.headers.referer || "direct"
|
|
326
|
-
const origin = req.headers.origin || "unknown"
|
|
360
|
+
const duration = Date.now() - start
|
|
361
|
+
const status = res.statusCode
|
|
362
|
+
const method = req.method
|
|
363
|
+
const url = req.url
|
|
364
|
+
const referer = req.headers.referer || "direct"
|
|
365
|
+
const origin = req.headers.origin || "unknown"
|
|
327
366
|
|
|
328
367
|
console.log(
|
|
329
|
-
`[${new Date().toISOString()}] ${method} ${url} ${status} (${duration}ms) - Origin: ${origin} - Referer: ${referer}
|
|
330
|
-
)
|
|
331
|
-
originalEnd.apply(this, args)
|
|
332
|
-
}
|
|
368
|
+
`[${new Date().toISOString()}] ${method} ${url} ${status} (${duration}ms) - Origin: ${origin} - Referer: ${referer}`,
|
|
369
|
+
)
|
|
370
|
+
originalEnd.apply(this, args)
|
|
371
|
+
}
|
|
333
372
|
|
|
334
|
-
next()
|
|
335
|
-
})
|
|
373
|
+
next()
|
|
374
|
+
})
|
|
336
375
|
},
|
|
337
376
|
},
|
|
338
377
|
],
|
|
@@ -343,11 +382,13 @@ export default defineConfig(({ mode }) => {
|
|
|
343
382
|
strictPort: true,
|
|
344
383
|
https: getHttpsConfig(env),
|
|
345
384
|
allowedHosts: env.ALLOWED_HOSTS
|
|
346
|
-
? env.ALLOWED_HOSTS.split(",")
|
|
347
|
-
|
|
385
|
+
? env.ALLOWED_HOSTS.split(",")
|
|
386
|
+
.map((h) => h.trim())
|
|
387
|
+
.filter(Boolean)
|
|
388
|
+
: true,
|
|
348
389
|
cors: {
|
|
349
390
|
origin: "*",
|
|
350
|
-
methods: ["GET", "POST", "PUT, DELETE", "OPTIONS"],
|
|
391
|
+
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
351
392
|
allowedHeaders: ["*"],
|
|
352
393
|
credentials: false,
|
|
353
394
|
},
|
|
@@ -355,13 +396,21 @@ export default defineConfig(({ mode }) => {
|
|
|
355
396
|
? {
|
|
356
397
|
protocol: env.HMR_PROTOCOL || "wss",
|
|
357
398
|
host: env.HMR_HOST,
|
|
358
|
-
port:
|
|
359
|
-
|
|
360
|
-
|
|
399
|
+
port:
|
|
400
|
+
parseInt(env.HMR_PORT) ||
|
|
401
|
+
parseInt(env.CLIENT_PORT) ||
|
|
402
|
+
parseInt(env.NODE_PORT) ||
|
|
403
|
+
3060,
|
|
404
|
+
clientPort:
|
|
405
|
+
parseInt(env.HMR_CLIENT_PORT) ||
|
|
406
|
+
parseInt(env.CLIENT_PORT) ||
|
|
407
|
+
parseInt(env.NODE_PORT) ||
|
|
408
|
+
3060,
|
|
409
|
+
}
|
|
361
410
|
: {
|
|
362
411
|
clientPort:
|
|
363
412
|
parseInt(env.CLIENT_PORT) || parseInt(env.NODE_PORT) || 3060,
|
|
364
|
-
|
|
413
|
+
},
|
|
365
414
|
host: true, // Allow access from network
|
|
366
415
|
// Allow serving files from the toolkit runtime directory
|
|
367
416
|
// Also resolve symlinks to allow files from the real path
|
|
@@ -379,30 +428,30 @@ export default defineConfig(({ mode }) => {
|
|
|
379
428
|
configure: (proxy, options) => {
|
|
380
429
|
proxy.on("proxyReq", (proxyReq, req) => {
|
|
381
430
|
// Forward the API key as Authorization header if set
|
|
382
|
-
const apiKey = env.API_KEY
|
|
431
|
+
const apiKey = env.API_KEY
|
|
383
432
|
if (apiKey) {
|
|
384
|
-
proxyReq.setHeader("Authorization", `Bearer ${apiKey}`)
|
|
433
|
+
proxyReq.setHeader("Authorization", `Bearer ${apiKey}`)
|
|
385
434
|
}
|
|
386
435
|
console.log(
|
|
387
436
|
`[API Proxy] ${req.method} ${
|
|
388
437
|
req.url
|
|
389
438
|
} -> ${apiProxyTarget}${req.url.replace(
|
|
390
439
|
/^\/api-proxy/,
|
|
391
|
-
""
|
|
392
|
-
)}
|
|
393
|
-
)
|
|
394
|
-
})
|
|
440
|
+
"",
|
|
441
|
+
)}`,
|
|
442
|
+
)
|
|
443
|
+
})
|
|
395
444
|
proxy.on("proxyRes", (proxyRes, req) => {
|
|
396
445
|
console.log(
|
|
397
|
-
`[API Proxy] ${req.method} ${req.url} <- ${proxyRes.statusCode}
|
|
398
|
-
)
|
|
399
|
-
})
|
|
446
|
+
`[API Proxy] ${req.method} ${req.url} <- ${proxyRes.statusCode}`,
|
|
447
|
+
)
|
|
448
|
+
})
|
|
400
449
|
proxy.on("error", (err, req) => {
|
|
401
|
-
console.error(`[API Proxy] Error: ${err.message}`)
|
|
402
|
-
})
|
|
450
|
+
console.error(`[API Proxy] Error: ${err.message}`)
|
|
451
|
+
})
|
|
403
452
|
},
|
|
404
453
|
},
|
|
405
|
-
|
|
454
|
+
}
|
|
406
455
|
: {},
|
|
407
456
|
},
|
|
408
457
|
build: {
|
|
@@ -450,5 +499,8 @@ export default defineConfig(({ mode }) => {
|
|
|
450
499
|
ssr: {
|
|
451
500
|
external: ["vue", "pinia"],
|
|
452
501
|
},
|
|
453
|
-
}
|
|
454
|
-
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const extension = await loadExtensionConfig(ctx, runtimeConfig)
|
|
505
|
+
return extension ? mergeConfig(runtimeConfig, extension) : runtimeConfig
|
|
506
|
+
})
|