@gxp-dev/tools 2.0.62 → 2.0.64
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 +207 -132
- 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
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* - gxp-src/v-gxp-src -> assets
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
const fs = require("fs")
|
|
22
|
-
const path = require("path")
|
|
21
|
+
const fs = require("fs")
|
|
22
|
+
const path = require("path")
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Extract configuration from all Vue/JS files in the src directory
|
|
@@ -33,34 +33,40 @@ function extractConfigFromSource(srcDir) {
|
|
|
33
33
|
assets: {},
|
|
34
34
|
triggerState: {},
|
|
35
35
|
dependencies: [],
|
|
36
|
-
}
|
|
36
|
+
}
|
|
37
37
|
|
|
38
38
|
if (!fs.existsSync(srcDir)) {
|
|
39
|
-
console.error(`❌ Source directory not found: ${srcDir}`)
|
|
40
|
-
return config
|
|
39
|
+
console.error(`❌ Source directory not found: ${srcDir}`)
|
|
40
|
+
return config
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// Find all .vue and .js files recursively
|
|
44
|
-
const files = findFilesRecursive(srcDir, [
|
|
44
|
+
const files = findFilesRecursive(srcDir, [
|
|
45
|
+
".vue",
|
|
46
|
+
".js",
|
|
47
|
+
".ts",
|
|
48
|
+
".jsx",
|
|
49
|
+
".tsx",
|
|
50
|
+
])
|
|
45
51
|
|
|
46
52
|
for (const file of files) {
|
|
47
53
|
try {
|
|
48
|
-
const content = fs.readFileSync(file, "utf-8")
|
|
49
|
-
const relativePath = path.relative(srcDir, file)
|
|
54
|
+
const content = fs.readFileSync(file, "utf-8")
|
|
55
|
+
const relativePath = path.relative(srcDir, file)
|
|
50
56
|
|
|
51
57
|
// Extract from JavaScript/TypeScript code
|
|
52
|
-
extractFromScript(content, config, relativePath)
|
|
58
|
+
extractFromScript(content, config, relativePath)
|
|
53
59
|
|
|
54
60
|
// Extract from Vue templates
|
|
55
61
|
if (file.endsWith(".vue")) {
|
|
56
|
-
extractFromTemplate(content, config, relativePath)
|
|
62
|
+
extractFromTemplate(content, config, relativePath)
|
|
57
63
|
}
|
|
58
64
|
} catch (error) {
|
|
59
|
-
console.warn(`⚠ Could not parse ${file}: ${error.message}`)
|
|
65
|
+
console.warn(`⚠ Could not parse ${file}: ${error.message}`)
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
|
|
63
|
-
return config
|
|
69
|
+
return config
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
/**
|
|
@@ -70,30 +76,30 @@ function extractConfigFromSource(srcDir) {
|
|
|
70
76
|
* @returns {string[]} Array of file paths
|
|
71
77
|
*/
|
|
72
78
|
function findFilesRecursive(dir, extensions) {
|
|
73
|
-
const files = []
|
|
79
|
+
const files = []
|
|
74
80
|
|
|
75
81
|
function walk(currentDir) {
|
|
76
|
-
const entries = fs.readdirSync(currentDir, { withFileTypes: true })
|
|
82
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true })
|
|
77
83
|
|
|
78
84
|
for (const entry of entries) {
|
|
79
|
-
const fullPath = path.join(currentDir, entry.name)
|
|
85
|
+
const fullPath = path.join(currentDir, entry.name)
|
|
80
86
|
|
|
81
87
|
if (entry.isDirectory()) {
|
|
82
88
|
// Skip node_modules and hidden directories
|
|
83
89
|
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
84
|
-
walk(fullPath)
|
|
90
|
+
walk(fullPath)
|
|
85
91
|
}
|
|
86
92
|
} else if (entry.isFile()) {
|
|
87
|
-
const ext = path.extname(entry.name).toLowerCase()
|
|
93
|
+
const ext = path.extname(entry.name).toLowerCase()
|
|
88
94
|
if (extensions.includes(ext)) {
|
|
89
|
-
files.push(fullPath)
|
|
95
|
+
files.push(fullPath)
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
}
|
|
94
100
|
|
|
95
|
-
walk(dir)
|
|
96
|
-
return files
|
|
101
|
+
walk(dir)
|
|
102
|
+
return files
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
/**
|
|
@@ -104,103 +110,109 @@ function findFilesRecursive(dir, extensions) {
|
|
|
104
110
|
*/
|
|
105
111
|
function extractFromScript(content, config, sourcePath) {
|
|
106
112
|
// Extract getString calls: getString('key', 'default') or getString("key", "default")
|
|
107
|
-
const getStringRegex =
|
|
108
|
-
|
|
113
|
+
const getStringRegex =
|
|
114
|
+
/\.getString\s*\(\s*['"`]([^'"`]+)['"`]\s*(?:,\s*['"`]([^'"`]*)['"`])?\s*\)/g
|
|
115
|
+
let match
|
|
109
116
|
while ((match = getStringRegex.exec(content)) !== null) {
|
|
110
|
-
const key = match[1]
|
|
111
|
-
const defaultValue = match[2] || ""
|
|
117
|
+
const key = match[1]
|
|
118
|
+
const defaultValue = match[2] || ""
|
|
112
119
|
if (!config.strings[key]) {
|
|
113
|
-
config.strings[key] = defaultValue
|
|
120
|
+
config.strings[key] = defaultValue
|
|
114
121
|
}
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
// Extract getSetting calls: getSetting('key', 'default') or getSetting('key', value)
|
|
118
|
-
const getSettingRegex =
|
|
125
|
+
const getSettingRegex =
|
|
126
|
+
/\.getSetting\s*\(\s*['"`]([^'"`]+)['"`]\s*(?:,\s*['"`]?([^'"`),]*)['"`]?)?\s*\)/g
|
|
119
127
|
while ((match = getSettingRegex.exec(content)) !== null) {
|
|
120
|
-
const key = match[1]
|
|
121
|
-
let defaultValue = match[2] || ""
|
|
128
|
+
const key = match[1]
|
|
129
|
+
let defaultValue = match[2] || ""
|
|
122
130
|
// Clean up the default value
|
|
123
|
-
defaultValue = defaultValue.trim()
|
|
131
|
+
defaultValue = defaultValue.trim()
|
|
124
132
|
// Try to parse as JSON for non-string values
|
|
125
133
|
if (defaultValue && !config.settings[key]) {
|
|
126
134
|
try {
|
|
127
|
-
config.settings[key] = JSON.parse(defaultValue)
|
|
135
|
+
config.settings[key] = JSON.parse(defaultValue)
|
|
128
136
|
} catch {
|
|
129
|
-
config.settings[key] = defaultValue
|
|
137
|
+
config.settings[key] = defaultValue
|
|
130
138
|
}
|
|
131
139
|
} else if (!config.settings[key]) {
|
|
132
|
-
config.settings[key] = ""
|
|
140
|
+
config.settings[key] = ""
|
|
133
141
|
}
|
|
134
142
|
}
|
|
135
143
|
|
|
136
144
|
// Extract getAsset calls: getAsset('key', 'default')
|
|
137
|
-
const getAssetRegex =
|
|
145
|
+
const getAssetRegex =
|
|
146
|
+
/\.getAsset\s*\(\s*['"`]([^'"`]+)['"`]\s*(?:,\s*['"`]([^'"`]*)['"`])?\s*\)/g
|
|
138
147
|
while ((match = getAssetRegex.exec(content)) !== null) {
|
|
139
|
-
const key = match[1]
|
|
140
|
-
const defaultValue = match[2] || ""
|
|
148
|
+
const key = match[1]
|
|
149
|
+
const defaultValue = match[2] || ""
|
|
141
150
|
if (!config.assets[key]) {
|
|
142
|
-
config.assets[key] = defaultValue
|
|
151
|
+
config.assets[key] = defaultValue
|
|
143
152
|
}
|
|
144
153
|
}
|
|
145
154
|
|
|
146
155
|
// Extract getState calls: getState('key', default)
|
|
147
|
-
const getStateRegex =
|
|
156
|
+
const getStateRegex =
|
|
157
|
+
/\.getState\s*\(\s*['"`]([^'"`]+)['"`]\s*(?:,\s*['"`]?([^'"`),]*)['"`]?)?\s*\)/g
|
|
148
158
|
while ((match = getStateRegex.exec(content)) !== null) {
|
|
149
|
-
const key = match[1]
|
|
150
|
-
let defaultValue = match[2] || ""
|
|
151
|
-
defaultValue = defaultValue.trim()
|
|
159
|
+
const key = match[1]
|
|
160
|
+
let defaultValue = match[2] || ""
|
|
161
|
+
defaultValue = defaultValue.trim()
|
|
152
162
|
if (!config.triggerState[key]) {
|
|
153
163
|
try {
|
|
154
|
-
config.triggerState[key] = JSON.parse(defaultValue)
|
|
164
|
+
config.triggerState[key] = JSON.parse(defaultValue)
|
|
155
165
|
} catch {
|
|
156
|
-
config.triggerState[key] = defaultValue || null
|
|
166
|
+
config.triggerState[key] = defaultValue || null
|
|
157
167
|
}
|
|
158
168
|
}
|
|
159
169
|
}
|
|
160
170
|
|
|
161
171
|
// Extract callApi calls: callApi('path', 'identifier') or apiGet/apiPost with identifier patterns
|
|
162
172
|
// Pattern: callApi('/path', 'identifier') or any api method with path
|
|
163
|
-
const callApiRegex =
|
|
173
|
+
const callApiRegex =
|
|
174
|
+
/\.(?:callApi|apiGet|apiPost|apiPut|apiPatch|apiDelete)\s*\(\s*['"`]([^'"`]+)['"`]\s*(?:,\s*['"`]([^'"`]+)['"`])?\s*\)/g
|
|
164
175
|
while ((match = callApiRegex.exec(content)) !== null) {
|
|
165
|
-
const apiPath = match[1]
|
|
166
|
-
const identifier = match[2]
|
|
176
|
+
const apiPath = match[1]
|
|
177
|
+
const identifier = match[2]
|
|
167
178
|
if (identifier) {
|
|
168
179
|
// Check if this dependency already exists
|
|
169
180
|
const exists = config.dependencies.some(
|
|
170
|
-
(dep) => dep.identifier === identifier && dep.path === apiPath
|
|
171
|
-
)
|
|
181
|
+
(dep) => dep.identifier === identifier && dep.path === apiPath,
|
|
182
|
+
)
|
|
172
183
|
if (!exists) {
|
|
173
184
|
config.dependencies.push({
|
|
174
185
|
identifier: identifier,
|
|
175
186
|
path: apiPath,
|
|
176
|
-
})
|
|
187
|
+
})
|
|
177
188
|
}
|
|
178
189
|
}
|
|
179
190
|
}
|
|
180
191
|
|
|
181
192
|
// Extract listenSocket calls for reference: listenSocket('socketName', 'event', callback)
|
|
182
193
|
// These help identify what socket events the app expects
|
|
183
|
-
const listenSocketRegex =
|
|
194
|
+
const listenSocketRegex =
|
|
195
|
+
/\.(?:listenSocket|useSocketListener)\s*\(\s*['"`]([^'"`]+)['"`]\s*,\s*['"`]([^'"`]+)['"`]/g
|
|
184
196
|
while ((match = listenSocketRegex.exec(content)) !== null) {
|
|
185
|
-
const socketName = match[1]
|
|
186
|
-
const eventName = match[2]
|
|
197
|
+
const socketName = match[1]
|
|
198
|
+
const eventName = match[2]
|
|
187
199
|
// Add as a dependency reference if not 'primary'
|
|
188
200
|
if (socketName !== "primary") {
|
|
189
201
|
const exists = config.dependencies.some(
|
|
190
|
-
(dep) => dep.identifier === socketName
|
|
191
|
-
)
|
|
202
|
+
(dep) => dep.identifier === socketName,
|
|
203
|
+
)
|
|
192
204
|
if (!exists) {
|
|
193
205
|
config.dependencies.push({
|
|
194
206
|
identifier: socketName,
|
|
195
207
|
path: "",
|
|
196
208
|
events: { [eventName]: eventName },
|
|
197
|
-
})
|
|
209
|
+
})
|
|
198
210
|
} else {
|
|
199
211
|
// Add the event to existing dependency
|
|
200
|
-
const dep = config.dependencies.find((d) => d.identifier === socketName)
|
|
212
|
+
const dep = config.dependencies.find((d) => d.identifier === socketName)
|
|
201
213
|
if (dep) {
|
|
202
|
-
dep.events = dep.events || {}
|
|
203
|
-
dep.events[eventName] = eventName
|
|
214
|
+
dep.events = dep.events || {}
|
|
215
|
+
dep.events[eventName] = eventName
|
|
204
216
|
}
|
|
205
217
|
}
|
|
206
218
|
}
|
|
@@ -215,111 +227,116 @@ function extractFromScript(content, config, sourcePath) {
|
|
|
215
227
|
*/
|
|
216
228
|
function extractFromTemplate(content, config, sourcePath) {
|
|
217
229
|
// Extract template section
|
|
218
|
-
const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/i)
|
|
230
|
+
const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/i)
|
|
219
231
|
if (!templateMatch) {
|
|
220
|
-
return
|
|
232
|
+
return
|
|
221
233
|
}
|
|
222
234
|
|
|
223
|
-
const template = templateMatch[1]
|
|
235
|
+
const template = templateMatch[1]
|
|
224
236
|
|
|
225
237
|
// Extract gxp-string/v-gxp-string without other gxp attributes (pure strings)
|
|
226
238
|
// Pattern: <tag gxp-string="key">default</tag> or <tag v-gxp-string="'key'">default</tag>
|
|
227
239
|
// But NOT when gxp-setting, gxp-asset, or gxp-state is present
|
|
228
|
-
const pureStringRegex =
|
|
229
|
-
|
|
240
|
+
const pureStringRegex =
|
|
241
|
+
/<([a-z][a-z0-9-]*)\s+[^>]*(?:v-gxp-string|gxp-string)=["']([^"']+)["'][^>]*>([^<]*)</gi
|
|
242
|
+
let match
|
|
230
243
|
while ((match = pureStringRegex.exec(template)) !== null) {
|
|
231
|
-
const fullMatch = match[0]
|
|
232
|
-
const key = match[2].replace(/['"]/g, "")
|
|
233
|
-
const defaultValue = match[3].trim()
|
|
244
|
+
const fullMatch = match[0]
|
|
245
|
+
const key = match[2].replace(/['"]/g, "") // Remove quotes for v-gxp-string="'key'"
|
|
246
|
+
const defaultValue = match[3].trim()
|
|
234
247
|
|
|
235
248
|
// Check if this element has gxp-setting, gxp-asset, or gxp-state
|
|
236
|
-
const hasGxpSetting = /gxp-setting|v-gxp-setting/i.test(fullMatch)
|
|
237
|
-
const hasGxpAsset = /gxp-asset|v-gxp-asset/i.test(fullMatch)
|
|
238
|
-
const hasGxpState = /gxp-state|v-gxp-state/i.test(fullMatch)
|
|
249
|
+
const hasGxpSetting = /gxp-setting|v-gxp-setting/i.test(fullMatch)
|
|
250
|
+
const hasGxpAsset = /gxp-asset|v-gxp-asset/i.test(fullMatch)
|
|
251
|
+
const hasGxpState = /gxp-state|v-gxp-state/i.test(fullMatch)
|
|
239
252
|
|
|
240
253
|
if (hasGxpSetting) {
|
|
241
254
|
// gxp-string key with gxp-setting -> settings
|
|
242
255
|
if (!config.settings[key]) {
|
|
243
|
-
config.settings[key] = defaultValue
|
|
256
|
+
config.settings[key] = defaultValue
|
|
244
257
|
}
|
|
245
258
|
} else if (hasGxpAsset) {
|
|
246
259
|
// gxp-string key with gxp-asset -> assets
|
|
247
260
|
if (!config.assets[key]) {
|
|
248
|
-
config.assets[key] = defaultValue
|
|
261
|
+
config.assets[key] = defaultValue
|
|
249
262
|
}
|
|
250
263
|
} else if (hasGxpState) {
|
|
251
264
|
// gxp-string key with gxp-state -> triggerState
|
|
252
265
|
if (!config.triggerState[key]) {
|
|
253
|
-
config.triggerState[key] = defaultValue || null
|
|
266
|
+
config.triggerState[key] = defaultValue || null
|
|
254
267
|
}
|
|
255
268
|
} else {
|
|
256
269
|
// Pure gxp-string -> strings
|
|
257
270
|
if (!config.strings[key]) {
|
|
258
|
-
config.strings[key] = defaultValue
|
|
271
|
+
config.strings[key] = defaultValue
|
|
259
272
|
}
|
|
260
273
|
}
|
|
261
274
|
}
|
|
262
275
|
|
|
263
276
|
// Extract standalone gxp-setting/v-gxp-setting with value (not using gxp-string for key)
|
|
264
277
|
// Pattern: <tag gxp-setting="key">default</tag>
|
|
265
|
-
const settingRegex =
|
|
278
|
+
const settingRegex =
|
|
279
|
+
/<([a-z][a-z0-9-]*)\s+[^>]*(?:v-gxp-setting|gxp-setting)=["']([^"']+)["'][^>]*>([^<]*)</gi
|
|
266
280
|
while ((match = settingRegex.exec(template)) !== null) {
|
|
267
|
-
const key = match[2].replace(/['"]/g, "")
|
|
268
|
-
const defaultValue = match[3].trim()
|
|
281
|
+
const key = match[2].replace(/['"]/g, "")
|
|
282
|
+
const defaultValue = match[3].trim()
|
|
269
283
|
// Only add if key looks like an actual key (not empty)
|
|
270
284
|
if (key && !config.settings[key]) {
|
|
271
|
-
config.settings[key] = defaultValue
|
|
285
|
+
config.settings[key] = defaultValue
|
|
272
286
|
}
|
|
273
287
|
}
|
|
274
288
|
|
|
275
289
|
// Extract standalone gxp-asset/v-gxp-asset with value
|
|
276
|
-
const assetRegex =
|
|
290
|
+
const assetRegex =
|
|
291
|
+
/<([a-z][a-z0-9-]*)\s+[^>]*(?:v-gxp-asset|gxp-asset)=["']([^"']+)["'][^>]*>([^<]*)</gi
|
|
277
292
|
while ((match = assetRegex.exec(template)) !== null) {
|
|
278
|
-
const key = match[2].replace(/['"]/g, "")
|
|
279
|
-
const defaultValue = match[3].trim()
|
|
293
|
+
const key = match[2].replace(/['"]/g, "")
|
|
294
|
+
const defaultValue = match[3].trim()
|
|
280
295
|
if (key && !config.assets[key]) {
|
|
281
|
-
config.assets[key] = defaultValue
|
|
296
|
+
config.assets[key] = defaultValue
|
|
282
297
|
}
|
|
283
298
|
}
|
|
284
299
|
|
|
285
300
|
// Extract gxp-src/v-gxp-src: <img gxp-src="key" src="default" />
|
|
286
301
|
// Pattern matches self-closing and regular tags with gxp-src and src attributes
|
|
287
|
-
const gxpSrcRegex =
|
|
302
|
+
const gxpSrcRegex =
|
|
303
|
+
/<([a-z][a-z0-9-]*)\s+[^>]*(?:v-gxp-src|gxp-src)=["']([^"']+)["'][^>]*src=["']([^"']+)["'][^>]*\/?>/gi
|
|
288
304
|
while ((match = gxpSrcRegex.exec(template)) !== null) {
|
|
289
|
-
const key = match[2].replace(/['"]/g, "")
|
|
290
|
-
const defaultSrc = match[3]
|
|
305
|
+
const key = match[2].replace(/['"]/g, "")
|
|
306
|
+
const defaultSrc = match[3]
|
|
291
307
|
|
|
292
308
|
// Check if gxp-state is present
|
|
293
|
-
const fullMatch = match[0]
|
|
294
|
-
const hasGxpState = /gxp-state|v-gxp-state/i.test(fullMatch)
|
|
309
|
+
const fullMatch = match[0]
|
|
310
|
+
const hasGxpState = /gxp-state|v-gxp-state/i.test(fullMatch)
|
|
295
311
|
|
|
296
312
|
if (hasGxpState) {
|
|
297
313
|
if (!config.triggerState[key]) {
|
|
298
|
-
config.triggerState[key] = defaultSrc
|
|
314
|
+
config.triggerState[key] = defaultSrc
|
|
299
315
|
}
|
|
300
316
|
} else {
|
|
301
317
|
if (!config.assets[key]) {
|
|
302
|
-
config.assets[key] = defaultSrc
|
|
318
|
+
config.assets[key] = defaultSrc
|
|
303
319
|
}
|
|
304
320
|
}
|
|
305
321
|
}
|
|
306
322
|
|
|
307
323
|
// Also try reverse order: src before gxp-src
|
|
308
|
-
const gxpSrcReverseRegex =
|
|
324
|
+
const gxpSrcReverseRegex =
|
|
325
|
+
/<([a-z][a-z0-9-]*)\s+[^>]*src=["']([^"']+)["'][^>]*(?:v-gxp-src|gxp-src)=["']([^"']+)["'][^>]*\/?>/gi
|
|
309
326
|
while ((match = gxpSrcReverseRegex.exec(template)) !== null) {
|
|
310
|
-
const defaultSrc = match[2]
|
|
311
|
-
const key = match[3].replace(/['"]/g, "")
|
|
327
|
+
const defaultSrc = match[2]
|
|
328
|
+
const key = match[3].replace(/['"]/g, "")
|
|
312
329
|
|
|
313
|
-
const fullMatch = match[0]
|
|
314
|
-
const hasGxpState = /gxp-state|v-gxp-state/i.test(fullMatch)
|
|
330
|
+
const fullMatch = match[0]
|
|
331
|
+
const hasGxpState = /gxp-state|v-gxp-state/i.test(fullMatch)
|
|
315
332
|
|
|
316
333
|
if (hasGxpState) {
|
|
317
334
|
if (!config.triggerState[key]) {
|
|
318
|
-
config.triggerState[key] = defaultSrc
|
|
335
|
+
config.triggerState[key] = defaultSrc
|
|
319
336
|
}
|
|
320
337
|
} else {
|
|
321
338
|
if (!config.assets[key]) {
|
|
322
|
-
config.assets[key] = defaultSrc
|
|
339
|
+
config.assets[key] = defaultSrc
|
|
323
340
|
}
|
|
324
341
|
}
|
|
325
342
|
}
|
|
@@ -333,62 +350,62 @@ function extractFromTemplate(content, config, sourcePath) {
|
|
|
333
350
|
* @returns {Object} Merged manifest
|
|
334
351
|
*/
|
|
335
352
|
function mergeConfig(existingManifest, extractedConfig, options = {}) {
|
|
336
|
-
const { overwrite = false } = options
|
|
353
|
+
const { overwrite = false } = options
|
|
337
354
|
|
|
338
|
-
const merged = { ...existingManifest }
|
|
355
|
+
const merged = { ...existingManifest }
|
|
339
356
|
|
|
340
357
|
// Ensure nested structures exist
|
|
341
|
-
if (!merged.strings) merged.strings = {}
|
|
342
|
-
if (!merged.strings.default) merged.strings.default = {}
|
|
343
|
-
if (!merged.settings) merged.settings = {}
|
|
344
|
-
if (!merged.assets) merged.assets = {}
|
|
345
|
-
if (!merged.triggerState) merged.triggerState = {}
|
|
346
|
-
if (!merged.dependencies) merged.dependencies = []
|
|
358
|
+
if (!merged.strings) merged.strings = {}
|
|
359
|
+
if (!merged.strings.default) merged.strings.default = {}
|
|
360
|
+
if (!merged.settings) merged.settings = {}
|
|
361
|
+
if (!merged.assets) merged.assets = {}
|
|
362
|
+
if (!merged.triggerState) merged.triggerState = {}
|
|
363
|
+
if (!merged.dependencies) merged.dependencies = []
|
|
347
364
|
|
|
348
365
|
// Merge strings
|
|
349
366
|
for (const [key, value] of Object.entries(extractedConfig.strings)) {
|
|
350
367
|
if (overwrite || !merged.strings.default[key]) {
|
|
351
|
-
merged.strings.default[key] = value
|
|
368
|
+
merged.strings.default[key] = value
|
|
352
369
|
}
|
|
353
370
|
}
|
|
354
371
|
|
|
355
372
|
// Merge settings
|
|
356
373
|
for (const [key, value] of Object.entries(extractedConfig.settings)) {
|
|
357
374
|
if (overwrite || merged.settings[key] === undefined) {
|
|
358
|
-
merged.settings[key] = value
|
|
375
|
+
merged.settings[key] = value
|
|
359
376
|
}
|
|
360
377
|
}
|
|
361
378
|
|
|
362
379
|
// Merge assets
|
|
363
380
|
for (const [key, value] of Object.entries(extractedConfig.assets)) {
|
|
364
381
|
if (overwrite || !merged.assets[key]) {
|
|
365
|
-
merged.assets[key] = value
|
|
382
|
+
merged.assets[key] = value
|
|
366
383
|
}
|
|
367
384
|
}
|
|
368
385
|
|
|
369
386
|
// Merge triggerState
|
|
370
387
|
for (const [key, value] of Object.entries(extractedConfig.triggerState)) {
|
|
371
388
|
if (overwrite || merged.triggerState[key] === undefined) {
|
|
372
|
-
merged.triggerState[key] = value
|
|
389
|
+
merged.triggerState[key] = value
|
|
373
390
|
}
|
|
374
391
|
}
|
|
375
392
|
|
|
376
393
|
// Merge dependencies (by identifier)
|
|
377
394
|
for (const dep of extractedConfig.dependencies) {
|
|
378
395
|
const existingIndex = merged.dependencies.findIndex(
|
|
379
|
-
(d) => d.identifier === dep.identifier
|
|
380
|
-
)
|
|
396
|
+
(d) => d.identifier === dep.identifier,
|
|
397
|
+
)
|
|
381
398
|
if (existingIndex === -1) {
|
|
382
|
-
merged.dependencies.push(dep)
|
|
399
|
+
merged.dependencies.push(dep)
|
|
383
400
|
} else if (overwrite) {
|
|
384
401
|
merged.dependencies[existingIndex] = {
|
|
385
402
|
...merged.dependencies[existingIndex],
|
|
386
403
|
...dep,
|
|
387
|
-
}
|
|
404
|
+
}
|
|
388
405
|
}
|
|
389
406
|
}
|
|
390
407
|
|
|
391
|
-
return merged
|
|
408
|
+
return merged
|
|
392
409
|
}
|
|
393
410
|
|
|
394
411
|
/**
|
|
@@ -397,67 +414,67 @@ function mergeConfig(existingManifest, extractedConfig, options = {}) {
|
|
|
397
414
|
* @returns {string} Summary text
|
|
398
415
|
*/
|
|
399
416
|
function generateSummary(config) {
|
|
400
|
-
const lines = []
|
|
417
|
+
const lines = []
|
|
401
418
|
|
|
402
|
-
const stringCount = Object.keys(config.strings).length
|
|
403
|
-
const settingCount = Object.keys(config.settings).length
|
|
404
|
-
const assetCount = Object.keys(config.assets).length
|
|
405
|
-
const stateCount = Object.keys(config.triggerState).length
|
|
406
|
-
const depCount = config.dependencies.length
|
|
419
|
+
const stringCount = Object.keys(config.strings).length
|
|
420
|
+
const settingCount = Object.keys(config.settings).length
|
|
421
|
+
const assetCount = Object.keys(config.assets).length
|
|
422
|
+
const stateCount = Object.keys(config.triggerState).length
|
|
423
|
+
const depCount = config.dependencies.length
|
|
407
424
|
|
|
408
|
-
lines.push("📊 Extraction Summary:")
|
|
409
|
-
lines.push("")
|
|
425
|
+
lines.push("📊 Extraction Summary:")
|
|
426
|
+
lines.push("")
|
|
410
427
|
|
|
411
428
|
if (stringCount > 0) {
|
|
412
|
-
lines.push(`📝 Strings (${stringCount}):`)
|
|
429
|
+
lines.push(`📝 Strings (${stringCount}):`)
|
|
413
430
|
for (const [key, value] of Object.entries(config.strings)) {
|
|
414
|
-
const displayValue = value ? `"${value}"` : "(empty)"
|
|
415
|
-
lines.push(` ${key}: ${displayValue}`)
|
|
431
|
+
const displayValue = value ? `"${value}"` : "(empty)"
|
|
432
|
+
lines.push(` ${key}: ${displayValue}`)
|
|
416
433
|
}
|
|
417
|
-
lines.push("")
|
|
434
|
+
lines.push("")
|
|
418
435
|
}
|
|
419
436
|
|
|
420
437
|
if (settingCount > 0) {
|
|
421
|
-
lines.push(`⚙️ Settings (${settingCount}):`)
|
|
438
|
+
lines.push(`⚙️ Settings (${settingCount}):`)
|
|
422
439
|
for (const [key, value] of Object.entries(config.settings)) {
|
|
423
|
-
lines.push(` ${key}: ${JSON.stringify(value)}`)
|
|
440
|
+
lines.push(` ${key}: ${JSON.stringify(value)}`)
|
|
424
441
|
}
|
|
425
|
-
lines.push("")
|
|
442
|
+
lines.push("")
|
|
426
443
|
}
|
|
427
444
|
|
|
428
445
|
if (assetCount > 0) {
|
|
429
|
-
lines.push(`🖼️ Assets (${assetCount}):`)
|
|
446
|
+
lines.push(`🖼️ Assets (${assetCount}):`)
|
|
430
447
|
for (const [key, value] of Object.entries(config.assets)) {
|
|
431
|
-
lines.push(` ${key}: ${value || "(empty)"}`)
|
|
448
|
+
lines.push(` ${key}: ${value || "(empty)"}`)
|
|
432
449
|
}
|
|
433
|
-
lines.push("")
|
|
450
|
+
lines.push("")
|
|
434
451
|
}
|
|
435
452
|
|
|
436
453
|
if (stateCount > 0) {
|
|
437
|
-
lines.push(`🔄 Trigger State (${stateCount}):`)
|
|
454
|
+
lines.push(`🔄 Trigger State (${stateCount}):`)
|
|
438
455
|
for (const [key, value] of Object.entries(config.triggerState)) {
|
|
439
|
-
lines.push(` ${key}: ${JSON.stringify(value)}`)
|
|
456
|
+
lines.push(` ${key}: ${JSON.stringify(value)}`)
|
|
440
457
|
}
|
|
441
|
-
lines.push("")
|
|
458
|
+
lines.push("")
|
|
442
459
|
}
|
|
443
460
|
|
|
444
461
|
if (depCount > 0) {
|
|
445
|
-
lines.push(`🔗 Dependencies (${depCount}):`)
|
|
462
|
+
lines.push(`🔗 Dependencies (${depCount}):`)
|
|
446
463
|
for (const dep of config.dependencies) {
|
|
447
|
-
lines.push(` ${dep.identifier}: ${dep.path || "(no path)"}`)
|
|
464
|
+
lines.push(` ${dep.identifier}: ${dep.path || "(no path)"}`)
|
|
448
465
|
if (dep.events) {
|
|
449
|
-
lines.push(` Events: ${Object.keys(dep.events).join(", ")}`)
|
|
466
|
+
lines.push(` Events: ${Object.keys(dep.events).join(", ")}`)
|
|
450
467
|
}
|
|
451
468
|
}
|
|
452
|
-
lines.push("")
|
|
469
|
+
lines.push("")
|
|
453
470
|
}
|
|
454
471
|
|
|
455
472
|
if (stringCount + settingCount + assetCount + stateCount + depCount === 0) {
|
|
456
|
-
lines.push(" No configuration found in source files.")
|
|
457
|
-
lines.push("")
|
|
473
|
+
lines.push(" No configuration found in source files.")
|
|
474
|
+
lines.push("")
|
|
458
475
|
}
|
|
459
476
|
|
|
460
|
-
return lines.join("\n")
|
|
477
|
+
return lines.join("\n")
|
|
461
478
|
}
|
|
462
479
|
|
|
463
480
|
module.exports = {
|
|
@@ -465,4 +482,4 @@ module.exports = {
|
|
|
465
482
|
mergeConfig,
|
|
466
483
|
generateSummary,
|
|
467
484
|
findFilesRecursive,
|
|
468
|
-
}
|
|
485
|
+
}
|