@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.
Files changed (182) hide show
  1. package/README.md +32 -31
  2. package/bin/gx-devtools.js +74 -54
  3. package/bin/lib/cli.js +23 -21
  4. package/bin/lib/commands/add-dependency.js +366 -325
  5. package/bin/lib/commands/assets.js +137 -139
  6. package/bin/lib/commands/build.js +169 -174
  7. package/bin/lib/commands/datastore.js +181 -183
  8. package/bin/lib/commands/dev.js +127 -131
  9. package/bin/lib/commands/extensions.js +147 -149
  10. package/bin/lib/commands/extract-config.js +73 -67
  11. package/bin/lib/commands/index.js +12 -12
  12. package/bin/lib/commands/init.js +342 -240
  13. package/bin/lib/commands/publish.js +69 -75
  14. package/bin/lib/commands/socket.js +69 -69
  15. package/bin/lib/commands/ssl.js +14 -14
  16. package/bin/lib/constants.js +10 -24
  17. package/bin/lib/tui/App.tsx +761 -705
  18. package/bin/lib/tui/components/AIPanel.tsx +191 -171
  19. package/bin/lib/tui/components/CommandInput.tsx +394 -343
  20. package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
  21. package/bin/lib/tui/components/Header.tsx +23 -21
  22. package/bin/lib/tui/components/LogPanel.tsx +244 -220
  23. package/bin/lib/tui/components/TabBar.tsx +50 -48
  24. package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
  25. package/bin/lib/tui/index.tsx +37 -39
  26. package/bin/lib/tui/services/AIService.ts +518 -462
  27. package/bin/lib/tui/services/ExtensionService.ts +140 -129
  28. package/bin/lib/tui/services/GeminiService.ts +367 -337
  29. package/bin/lib/tui/services/ServiceManager.ts +344 -322
  30. package/bin/lib/tui/services/SocketService.ts +168 -168
  31. package/bin/lib/tui/services/ViteService.ts +88 -88
  32. package/bin/lib/tui/services/index.ts +47 -22
  33. package/bin/lib/utils/ai-scaffold.js +291 -280
  34. package/bin/lib/utils/extract-config.js +157 -140
  35. package/bin/lib/utils/files.js +82 -86
  36. package/bin/lib/utils/index.js +7 -7
  37. package/bin/lib/utils/paths.js +34 -34
  38. package/bin/lib/utils/prompts.js +194 -169
  39. package/bin/lib/utils/ssl.js +79 -81
  40. package/browser-extensions/README.md +0 -1
  41. package/browser-extensions/chrome/background.js +244 -237
  42. package/browser-extensions/chrome/content.js +32 -29
  43. package/browser-extensions/chrome/devtools.html +7 -7
  44. package/browser-extensions/chrome/devtools.js +19 -19
  45. package/browser-extensions/chrome/inspector.js +802 -767
  46. package/browser-extensions/chrome/manifest.json +71 -63
  47. package/browser-extensions/chrome/panel.html +674 -636
  48. package/browser-extensions/chrome/panel.js +722 -712
  49. package/browser-extensions/chrome/popup.html +586 -543
  50. package/browser-extensions/chrome/popup.js +282 -244
  51. package/browser-extensions/chrome/rules.json +1 -1
  52. package/browser-extensions/chrome/test-chrome.html +216 -136
  53. package/browser-extensions/chrome/test-mixed-content.html +284 -189
  54. package/browser-extensions/chrome/test-uri-pattern.html +221 -198
  55. package/browser-extensions/firefox/README.md +9 -6
  56. package/browser-extensions/firefox/background.js +221 -218
  57. package/browser-extensions/firefox/content.js +55 -52
  58. package/browser-extensions/firefox/debug-errors.html +386 -228
  59. package/browser-extensions/firefox/debug-https.html +153 -105
  60. package/browser-extensions/firefox/devtools.html +7 -7
  61. package/browser-extensions/firefox/devtools.js +23 -20
  62. package/browser-extensions/firefox/inspector.js +802 -767
  63. package/browser-extensions/firefox/manifest.json +68 -68
  64. package/browser-extensions/firefox/panel.html +674 -636
  65. package/browser-extensions/firefox/panel.js +722 -712
  66. package/browser-extensions/firefox/popup.html +572 -535
  67. package/browser-extensions/firefox/popup.js +281 -236
  68. package/browser-extensions/firefox/test-gramercy.html +170 -125
  69. package/browser-extensions/firefox/test-imports.html +59 -55
  70. package/browser-extensions/firefox/test-masking.html +231 -140
  71. package/browser-extensions/firefox/test-uri-pattern.html +221 -198
  72. package/dist/tui/App.d.ts +1 -1
  73. package/dist/tui/App.d.ts.map +1 -1
  74. package/dist/tui/App.js +154 -150
  75. package/dist/tui/App.js.map +1 -1
  76. package/dist/tui/components/AIPanel.d.ts.map +1 -1
  77. package/dist/tui/components/AIPanel.js +42 -35
  78. package/dist/tui/components/AIPanel.js.map +1 -1
  79. package/dist/tui/components/CommandInput.d.ts +1 -1
  80. package/dist/tui/components/CommandInput.d.ts.map +1 -1
  81. package/dist/tui/components/CommandInput.js +92 -62
  82. package/dist/tui/components/CommandInput.js.map +1 -1
  83. package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
  84. package/dist/tui/components/GeminiPanel.js +37 -30
  85. package/dist/tui/components/GeminiPanel.js.map +1 -1
  86. package/dist/tui/components/Header.d.ts.map +1 -1
  87. package/dist/tui/components/Header.js +1 -1
  88. package/dist/tui/components/Header.js.map +1 -1
  89. package/dist/tui/components/LogPanel.d.ts +1 -1
  90. package/dist/tui/components/LogPanel.d.ts.map +1 -1
  91. package/dist/tui/components/LogPanel.js +26 -24
  92. package/dist/tui/components/LogPanel.js.map +1 -1
  93. package/dist/tui/components/TabBar.d.ts +2 -2
  94. package/dist/tui/components/TabBar.d.ts.map +1 -1
  95. package/dist/tui/components/TabBar.js +11 -11
  96. package/dist/tui/components/TabBar.js.map +1 -1
  97. package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
  98. package/dist/tui/components/WelcomeScreen.js +6 -6
  99. package/dist/tui/components/WelcomeScreen.js.map +1 -1
  100. package/dist/tui/index.d.ts.map +1 -1
  101. package/dist/tui/index.js +8 -8
  102. package/dist/tui/index.js.map +1 -1
  103. package/dist/tui/services/AIService.d.ts +2 -2
  104. package/dist/tui/services/AIService.d.ts.map +1 -1
  105. package/dist/tui/services/AIService.js +165 -125
  106. package/dist/tui/services/AIService.js.map +1 -1
  107. package/dist/tui/services/ExtensionService.d.ts +1 -1
  108. package/dist/tui/services/ExtensionService.d.ts.map +1 -1
  109. package/dist/tui/services/ExtensionService.js +33 -26
  110. package/dist/tui/services/ExtensionService.js.map +1 -1
  111. package/dist/tui/services/GeminiService.d.ts +1 -1
  112. package/dist/tui/services/GeminiService.d.ts.map +1 -1
  113. package/dist/tui/services/GeminiService.js +87 -76
  114. package/dist/tui/services/GeminiService.js.map +1 -1
  115. package/dist/tui/services/ServiceManager.d.ts +3 -3
  116. package/dist/tui/services/ServiceManager.d.ts.map +1 -1
  117. package/dist/tui/services/ServiceManager.js +72 -58
  118. package/dist/tui/services/ServiceManager.js.map +1 -1
  119. package/dist/tui/services/SocketService.d.ts.map +1 -1
  120. package/dist/tui/services/SocketService.js +32 -32
  121. package/dist/tui/services/SocketService.js.map +1 -1
  122. package/dist/tui/services/ViteService.d.ts.map +1 -1
  123. package/dist/tui/services/ViteService.js +26 -28
  124. package/dist/tui/services/ViteService.js.map +1 -1
  125. package/dist/tui/services/index.d.ts +6 -6
  126. package/dist/tui/services/index.d.ts.map +1 -1
  127. package/dist/tui/services/index.js +6 -6
  128. package/dist/tui/services/index.js.map +1 -1
  129. package/mcp/gxp-api-server.js +83 -81
  130. package/package.json +109 -93
  131. package/runtime/PortalContainer.vue +258 -234
  132. package/runtime/dev-tools/DevToolsModal.vue +153 -155
  133. package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
  134. package/runtime/dev-tools/MockDataEditor.vue +456 -433
  135. package/runtime/dev-tools/SocketSimulator.vue +379 -371
  136. package/runtime/dev-tools/StoreInspector.vue +517 -455
  137. package/runtime/dev-tools/index.js +5 -5
  138. package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
  139. package/runtime/fallback-layouts/PublicLayout.vue +2 -2
  140. package/runtime/fallback-layouts/SystemLayout.vue +2 -2
  141. package/runtime/gxpStringsPlugin.js +159 -134
  142. package/runtime/index.html +17 -19
  143. package/runtime/main.js +24 -22
  144. package/runtime/mock-api/auth-middleware.js +15 -15
  145. package/runtime/mock-api/image-generator.js +46 -46
  146. package/runtime/mock-api/index.js +55 -55
  147. package/runtime/mock-api/response-generator.js +116 -105
  148. package/runtime/mock-api/route-generator.js +107 -84
  149. package/runtime/mock-api/socket-triggers.js +94 -93
  150. package/runtime/mock-api/spec-loader.js +79 -80
  151. package/runtime/package.json +3 -0
  152. package/runtime/server.js +68 -68
  153. package/runtime/stores/gxpPortalConfigStore.js +204 -186
  154. package/runtime/stores/index.js +2 -2
  155. package/runtime/vite-inspector-plugin.js +858 -707
  156. package/runtime/vite-source-tracker-plugin.js +132 -113
  157. package/runtime/vite.config.js +191 -139
  158. package/scripts/launch-chrome.js +41 -41
  159. package/scripts/pack-chrome.js +38 -39
  160. package/socket-events/AiSessionMessageCreated.json +17 -17
  161. package/socket-events/SocialStreamPostCreated.json +23 -23
  162. package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
  163. package/template/.claude/agents/gxp-developer.md +100 -99
  164. package/template/.claude/settings.json +7 -7
  165. package/template/AGENTS.md +30 -23
  166. package/template/GEMINI.md +20 -20
  167. package/template/README.md +70 -53
  168. package/template/app-manifest.json +2 -4
  169. package/template/configuration.json +10 -10
  170. package/template/default-styling.css +1 -1
  171. package/template/index.html +18 -20
  172. package/template/main.js +24 -22
  173. package/template/src/DemoPage.vue +415 -362
  174. package/template/src/Plugin.vue +76 -85
  175. package/template/src/stores/index.js +3 -3
  176. package/template/src/stores/test-data.json +164 -172
  177. package/template/theme-layouts/AdditionalStyling.css +50 -50
  178. package/template/theme-layouts/PrivateLayout.vue +8 -12
  179. package/template/theme-layouts/PublicLayout.vue +8 -12
  180. package/template/theme-layouts/SystemLayout.vue +8 -12
  181. package/template/vite.extend.js +45 -0
  182. package/template/vite.config.js +0 -409
@@ -1,7 +1,7 @@
1
- import { defineStore } from "pinia";
2
- import { ref, computed, reactive } from "vue";
3
- import axios from "axios";
4
- import { io } from "socket.io-client";
1
+ import { defineStore } from "pinia"
2
+ import { ref, computed, reactive } from "vue"
3
+ import axios from "axios"
4
+ import { io } from "socket.io-client"
5
5
 
6
6
  // Environment URL configuration (matches constants.js ENVIRONMENT_URLS)
7
7
  const ENVIRONMENT_URLS = {
@@ -20,19 +20,18 @@ const ENVIRONMENT_URLS = {
20
20
  local: {
21
21
  apiBaseUrl: "https://dashboard.eventfinity.test",
22
22
  },
23
- };
23
+ }
24
24
 
25
25
  /**
26
26
  * Generate a random bearer token for mock API
27
27
  */
28
28
  function generateMockToken() {
29
- const chars =
30
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
31
- let token = "";
29
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
30
+ let token = ""
32
31
  for (let i = 0; i < 32; i++) {
33
- token += chars.charAt(Math.floor(Math.random() * chars.length));
32
+ token += chars.charAt(Math.floor(Math.random() * chars.length))
34
33
  }
35
- return token;
34
+ return token
36
35
  }
37
36
 
38
37
  /**
@@ -43,55 +42,55 @@ function generateMockToken() {
43
42
  * @returns {{ apiBaseUrl: string, authToken: string, projectId: string }}
44
43
  */
45
44
  function getApiConfig() {
46
- const apiEnv = import.meta.env.VITE_API_ENV || "mock";
47
- const apiKey = import.meta.env.VITE_API_KEY || "";
48
- const projectId = import.meta.env.VITE_API_PROJECT_ID || "";
49
- const useHttps = import.meta.env.VITE_USE_HTTPS !== "false";
50
- const nodePort = import.meta.env.VITE_NODE_PORT || "3060";
51
- const mockPort = import.meta.env.VITE_SOCKET_IO_PORT || "3061";
45
+ const apiEnv = import.meta.env.VITE_API_ENV || "mock"
46
+ const apiKey = import.meta.env.VITE_API_KEY || ""
47
+ const projectId = import.meta.env.VITE_API_PROJECT_ID || ""
48
+ const useHttps = import.meta.env.VITE_USE_HTTPS !== "false"
49
+ const nodePort = import.meta.env.VITE_NODE_PORT || "3060"
50
+ const mockPort = import.meta.env.VITE_SOCKET_IO_PORT || "3061"
52
51
 
53
52
  // Check if we're in development mode (Vite dev server)
54
- const isDev = import.meta.env.DEV;
53
+ const isDev = import.meta.env.DEV
55
54
 
56
55
  if (apiEnv === "mock") {
57
56
  // Mock API: use local dev server with random token
58
- const protocol = useHttps ? "https" : "http";
57
+ const protocol = useHttps ? "https" : "http"
59
58
  return {
60
59
  apiBaseUrl: `${protocol}://localhost:${mockPort}/mock-api`,
61
60
  authToken: generateMockToken(),
62
61
  projectId: "team/project",
63
- };
62
+ }
64
63
  }
65
64
 
66
65
  // For non-mock environments in development, use the local Vite proxy
67
66
  // The proxy handles CORS and injects the Authorization header
68
67
  if (isDev) {
69
- const protocol = useHttps ? "https" : "http";
68
+ const protocol = useHttps ? "https" : "http"
70
69
  return {
71
70
  apiBaseUrl: `${protocol}://localhost:${nodePort}/api-proxy`,
72
71
  authToken: "", // Proxy injects the token server-side
73
72
  projectId: projectId,
74
- };
73
+ }
75
74
  }
76
75
 
77
76
  // Production build: use the actual API URL directly
78
- const envConfig = ENVIRONMENT_URLS[apiEnv];
77
+ const envConfig = ENVIRONMENT_URLS[apiEnv]
79
78
  if (!envConfig) {
80
79
  console.warn(
81
- `[GxP Store] Unknown API_ENV "${apiEnv}", falling back to production`
82
- );
80
+ `[GxP Store] Unknown API_ENV "${apiEnv}", falling back to production`,
81
+ )
83
82
  return {
84
83
  apiBaseUrl: ENVIRONMENT_URLS.production.apiBaseUrl,
85
84
  authToken: apiKey,
86
85
  projectId: projectId,
87
- };
86
+ }
88
87
  }
89
88
 
90
89
  return {
91
90
  apiBaseUrl: envConfig.apiBaseUrl,
92
91
  authToken: apiKey,
93
92
  projectId: projectId,
94
- };
93
+ }
95
94
  }
96
95
 
97
96
  // Default values used when app-manifest.json doesn't exist or is missing keys
@@ -111,48 +110,48 @@ const defaultData = {
111
110
  pluginData: {},
112
111
  portalAssets: {},
113
112
  portal: null,
114
- };
113
+ }
115
114
 
116
115
  export const useGxpStore = defineStore("gxp-portal-app", () => {
117
116
  // Core configuration - these will be injected by the platform in production
118
- const pluginVars = ref({ ...defaultData.pluginVars });
119
- const stringsList = ref({ ...defaultData.stringsList });
120
- const assetList = ref({ ...defaultData.assetList });
121
- const dependencyList = ref({ ...defaultData.dependencyList });
122
- const dependencies = ref([]); // Store full dependency objects for socket initialization
123
- const permissionFlags = ref([...defaultData.permissionFlags]);
124
- const triggerState = ref({ ...defaultData.triggerState });
117
+ const pluginVars = ref({ ...defaultData.pluginVars })
118
+ const stringsList = ref({ ...defaultData.stringsList })
119
+ const assetList = ref({ ...defaultData.assetList })
120
+ const dependencyList = ref({ ...defaultData.dependencyList })
121
+ const dependencies = ref([]) // Store full dependency objects for socket initialization
122
+ const permissionFlags = ref([...defaultData.permissionFlags])
123
+ const triggerState = ref({ ...defaultData.triggerState })
125
124
 
126
125
  // User session data (injected by platform in production)
127
- const auth = ref(defaultData.auth);
128
- const userSession = ref(defaultData.userSession);
129
- const pluginData = ref({ ...defaultData.pluginData });
130
- const portalAssets = ref({ ...defaultData.portalAssets });
131
- const portal = ref(defaultData.portal);
126
+ const auth = ref(defaultData.auth)
127
+ const userSession = ref(defaultData.userSession)
128
+ const pluginData = ref({ ...defaultData.pluginData })
129
+ const portalAssets = ref({ ...defaultData.portalAssets })
130
+ const portal = ref(defaultData.portal)
132
131
 
133
- const apiOperations = ref({});
132
+ const apiOperations = ref({})
134
133
 
135
134
  // Loading state for manifest
136
- const manifestLoaded = ref(false);
137
- const manifestError = ref(null);
135
+ const manifestLoaded = ref(false)
136
+ const manifestError = ref(null)
138
137
 
139
138
  // API configuration - initialized from environment
140
- const apiConfig = getApiConfig();
141
- const apiBaseUrl = ref(apiConfig.apiBaseUrl);
142
- const authToken = ref(apiConfig.authToken);
143
- pluginVars.value.projectId = apiConfig.projectId;
144
- pluginVars.value.apiPageAuthId = apiConfig.authToken;
145
- pluginVars.value.apiBaseUrl = apiConfig.apiBaseUrl;
139
+ const apiConfig = getApiConfig()
140
+ const apiBaseUrl = ref(apiConfig.apiBaseUrl)
141
+ const authToken = ref(apiConfig.authToken)
142
+ pluginVars.value.projectId = apiConfig.projectId
143
+ pluginVars.value.apiPageAuthId = apiConfig.authToken
144
+ pluginVars.value.apiBaseUrl = apiConfig.apiBaseUrl
146
145
 
147
146
  // Log API configuration for debugging
148
147
  console.log(
149
- `[GxP Store] API Environment: ${import.meta.env.VITE_API_ENV || "mock"}`
150
- );
151
- console.log(`[GxP Store] API Base URL: ${apiConfig.apiBaseUrl}`);
148
+ `[GxP Store] API Environment: ${import.meta.env.VITE_API_ENV || "mock"}`,
149
+ )
150
+ console.log(`[GxP Store] API Base URL: ${apiConfig.apiBaseUrl}`)
152
151
 
153
152
  // WebSocket configuration - initialized as reactive objects immediately
154
- const sockets = reactive({});
155
- const socketConnections = reactive({});
153
+ const sockets = reactive({})
154
+ const socketConnections = reactive({})
156
155
 
157
156
  // API client setup
158
157
  const apiClient = axios.create({
@@ -160,25 +159,25 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
160
159
  headers: {
161
160
  "Content-Type": "application/json",
162
161
  },
163
- });
162
+ })
164
163
 
165
164
  // Add auth token to requests
166
165
  apiClient.interceptors.request.use((config) => {
167
166
  if (authToken.value) {
168
- config.headers.Authorization = `Bearer ${authToken.value}`;
167
+ config.headers.Authorization = `Bearer ${authToken.value}`
169
168
  }
170
- config.baseURL = apiBaseUrl.value;
171
- return config;
172
- });
169
+ config.baseURL = apiBaseUrl.value
170
+ return config
171
+ })
173
172
 
174
173
  // Response interceptor for error handling
175
174
  apiClient.interceptors.response.use(
176
175
  (response) => response,
177
176
  (error) => {
178
- console.error("API Error:", error.response?.data || error.message);
179
- throw error;
180
- }
181
- );
177
+ console.error("API Error:", error.response?.data || error.message)
178
+ throw error
179
+ },
180
+ )
182
181
 
183
182
  /**
184
183
  * Load configuration from app-manifest.json
@@ -189,31 +188,31 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
189
188
  */
190
189
  async function loadManifest() {
191
190
  try {
192
- const response = await fetch("/app-manifest.json");
191
+ const response = await fetch("/app-manifest.json")
193
192
  if (!response.ok) {
194
193
  if (response.status === 404) {
195
- console.log("[GxP Store] No app-manifest.json found, using defaults");
196
- manifestLoaded.value = true;
197
- return;
194
+ console.log("[GxP Store] No app-manifest.json found, using defaults")
195
+ manifestLoaded.value = true
196
+ return
198
197
  }
199
- throw new Error(`HTTP ${response.status}`);
198
+ throw new Error(`HTTP ${response.status}`)
200
199
  }
201
200
 
202
- const manifest = await response.json();
203
- applyManifest(manifest);
204
- manifestLoaded.value = true;
205
- manifestError.value = null;
206
- console.log("[GxP Store] Loaded configuration from app-manifest.json");
201
+ const manifest = await response.json()
202
+ applyManifest(manifest)
203
+ manifestLoaded.value = true
204
+ manifestError.value = null
205
+ console.log("[GxP Store] Loaded configuration from app-manifest.json")
207
206
 
208
207
  // Re-initialize dependency sockets after manifest loads
209
- initializeDependencySockets();
208
+ initializeDependencySockets()
210
209
  } catch (error) {
211
210
  console.warn(
212
211
  "[GxP Store] Could not load app-manifest.json:",
213
- error.message
214
- );
215
- manifestError.value = error.message;
216
- manifestLoaded.value = true;
212
+ error.message,
213
+ )
214
+ manifestError.value = error.message
215
+ manifestLoaded.value = true
217
216
  }
218
217
  }
219
218
 
@@ -222,7 +221,7 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
222
221
  */
223
222
  function applyManifest(manifest) {
224
223
  if (manifest.settings && typeof manifest.settings === "object") {
225
- pluginVars.value = { ...defaultData.pluginVars, ...manifest.settings };
224
+ pluginVars.value = { ...defaultData.pluginVars, ...manifest.settings }
226
225
  }
227
226
 
228
227
  // Handle strings - can be { default: {...} } or flat object
@@ -231,31 +230,31 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
231
230
  manifest.strings.default &&
232
231
  typeof manifest.strings.default === "object"
233
232
  ) {
234
- stringsList.value = { ...manifest.strings.default };
233
+ stringsList.value = { ...manifest.strings.default }
235
234
  } else if (typeof manifest.strings === "object") {
236
- stringsList.value = { ...manifest.strings };
235
+ stringsList.value = { ...manifest.strings }
237
236
  }
238
237
  }
239
238
 
240
239
  if (manifest.assets && typeof manifest.assets === "object") {
241
- assetList.value = { ...manifest.assets };
240
+ assetList.value = { ...manifest.assets }
242
241
  }
243
242
 
244
243
  if (manifest.dependencies && Array.isArray(manifest.dependencies)) {
245
- dependencies.value = manifest.dependencies; // Store full dependency objects
244
+ dependencies.value = manifest.dependencies // Store full dependency objects
246
245
  dependencyList.value = manifest.dependencies.reduce((acc, dependency) => {
247
- acc[dependency.identifier] = "1";
248
- return acc;
249
- }, {});
250
- console.log("[GxP Store] Dependency List:", dependencyList.value);
246
+ acc[dependency.identifier] = "1"
247
+ return acc
248
+ }, {})
249
+ console.log("[GxP Store] Dependency List:", dependencyList.value)
251
250
  }
252
251
 
253
252
  if (manifest.permissions && Array.isArray(manifest.permissions)) {
254
- permissionFlags.value = [...manifest.permissions];
253
+ permissionFlags.value = [...manifest.permissions]
255
254
  }
256
255
 
257
256
  if (manifest.triggerState && typeof manifest.triggerState === "object") {
258
- triggerState.value = { ...manifest.triggerState };
257
+ triggerState.value = { ...manifest.triggerState }
259
258
  }
260
259
  }
261
260
 
@@ -268,49 +267,55 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
268
267
  * SOCKET_URL = explicit socket server URL (overrides auto-detected default)
269
268
  */
270
269
  function initializeSockets() {
271
- const socketDriver = import.meta.env.SOCKET_DRIVER || "io";
270
+ const socketDriver = import.meta.env.SOCKET_DRIVER || "io"
272
271
 
273
272
  if (socketDriver !== "io") {
274
- console.log(`[GxP Store] Sockets disabled (SOCKET_DRIVER=${socketDriver})`);
275
- return;
273
+ console.log(
274
+ `[GxP Store] Sockets disabled (SOCKET_DRIVER=${socketDriver})`,
275
+ )
276
+ return
276
277
  }
277
278
 
278
279
  // Resolve socket URL — explicit env var takes priority over auto-detected default
279
280
  const socketUrl = (() => {
280
281
  if (import.meta.env.SOCKET_URL) {
281
- return import.meta.env.SOCKET_URL;
282
+ return import.meta.env.SOCKET_URL
282
283
  }
283
284
  const protocol =
284
285
  typeof window !== "undefined" && window.location.protocol === "https:"
285
286
  ? "https"
286
- : "http";
287
- const port = import.meta.env.VITE_SOCKET_IO_PORT || 3069;
288
- return `${protocol}://localhost:${port}`;
289
- })();
287
+ : "http"
288
+ const port = import.meta.env.VITE_SOCKET_IO_PORT || 3069
289
+ return `${protocol}://localhost:${port}`
290
+ })()
290
291
 
291
292
  if (socketDriver === "io") {
292
- console.log(`[GxP Store] Connecting via Socket.IO to ${socketUrl}`);
293
- const primarySocket = io(socketUrl);
293
+ console.log(`[GxP Store] Connecting via Socket.IO to ${socketUrl}`)
294
+ const primarySocket = io(socketUrl)
294
295
 
295
296
  sockets.primary = {
296
297
  broadcast: function (event, data) {
297
- primarySocket.emit(event, data);
298
+ primarySocket.emit(event, data)
298
299
  },
299
300
  listen: function (event, callback) {
300
- return primarySocket.on(event, callback);
301
+ return primarySocket.on(event, callback)
301
302
  },
302
303
  listenForStateChange: function (callback) {
303
- return primarySocket.on("state-change", callback);
304
+ return primarySocket.on("state-change", callback)
304
305
  },
305
- };
306
+ }
306
307
 
307
- socketConnections.primary = primarySocket;
308
+ socketConnections.primary = primarySocket
308
309
  } else if (socketDriver === "echo") {
309
- console.log(`[GxP Store] Connecting via Laravel Echo to ${socketUrl}`);
310
+ console.log(`[GxP Store] Connecting via Laravel Echo to ${socketUrl}`)
310
311
  // Echo driver — consumers can extend this via socketConnections.primary
311
- console.warn("[GxP Store] Echo driver selected — configure Echo externally via socketConnections.primary");
312
+ console.warn(
313
+ "[GxP Store] Echo driver selected — configure Echo externally via socketConnections.primary",
314
+ )
312
315
  } else {
313
- console.warn(`[GxP Store] Unknown SOCKET_DRIVER "${socketDriver}", sockets not initialized`);
316
+ console.warn(
317
+ `[GxP Store] Unknown SOCKET_DRIVER "${socketDriver}", sockets not initialized`,
318
+ )
314
319
  }
315
320
  }
316
321
  /**
@@ -320,7 +325,9 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
320
325
  // Operations are built from OpenAPI spec paths
321
326
  // Structure: { [operationId]: { method, path, parameters } }
322
327
  try {
323
- const specUrl = `${apiBaseUrl.value}/api-specs/openapi.json`
328
+ const apiDocsBaseUrl =
329
+ apiEnv === "mock" ? "https://api.gramercy.cloud" : apiBaseUrl.value
330
+ const specUrl = `${apiDocsBaseUrl}/api-specs/openapi.json`
324
331
  const response = await axios.get(specUrl)
325
332
  const spec = response.data
326
333
 
@@ -367,8 +374,8 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
367
374
  * Called after manifest loads to set up dependency-specific listeners
368
375
  */
369
376
  function initializeDependencySockets() {
370
- const primarySocket = socketConnections.primary;
371
- if (!primarySocket) return;
377
+ const primarySocket = socketConnections.primary
378
+ if (!primarySocket) return
372
379
 
373
380
  // Initialize dependency-based sockets based on the new structure
374
381
  if (Array.isArray(dependencies.value)) {
@@ -417,11 +424,11 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
417
424
  }
418
425
  if (dependency.events && Object.keys(dependency.events).length > 0) {
419
426
  // Create socket listeners for each event type
420
- sockets[dependency.identifier] = {};
427
+ sockets[dependency.identifier] = {}
421
428
 
422
429
  Object.keys(dependency.events).forEach((eventType) => {
423
- const eventName = dependency.events[eventType];
424
- const channel = `private.${dependency.model}.${dependency.identifier}`;
430
+ const eventName = dependency.events[eventType]
431
+ const channel = `private.${dependency.model}.${dependency.identifier}`
425
432
 
426
433
  sockets[dependency.identifier][eventType] = {
427
434
  listen: function (callback) {
@@ -429,68 +436,68 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
429
436
  return primarySocket.on(eventName, (data) => {
430
437
  console.log(
431
438
  `Socket event received: ${eventName} on ${channel}`,
432
- data
433
- );
434
- callback(data);
435
- });
439
+ data,
440
+ )
441
+ callback(data)
442
+ })
436
443
  },
437
- };
438
- });
444
+ }
445
+ })
439
446
  } else {
440
447
  // For dependencies without events, create empty listeners
441
448
  sockets[dependency.identifier] = {
442
449
  created: { listen: () => () => {} },
443
450
  updated: { listen: () => () => {} },
444
451
  deleted: { listen: () => () => {} },
445
- };
452
+ }
446
453
  }
447
- });
454
+ })
448
455
  }
449
456
  }
450
457
 
451
458
  // API methods for common operations
452
459
  async function apiGet(endpoint, params = {}) {
453
460
  try {
454
- const response = await apiClient.get(endpoint, { params });
455
- return response.data;
461
+ const response = await apiClient.get(endpoint, { params })
462
+ return response.data
456
463
  } catch (error) {
457
- throw new Error(`GET ${endpoint}: ${error.message}`);
464
+ throw new Error(`GET ${endpoint}: ${error.message}`)
458
465
  }
459
466
  }
460
467
 
461
468
  async function apiPost(endpoint, data = {}) {
462
469
  try {
463
- const response = await apiClient.post(endpoint, data);
464
- return response.data;
470
+ const response = await apiClient.post(endpoint, data)
471
+ return response.data
465
472
  } catch (error) {
466
- throw new Error(`POST ${endpoint}: ${error.message}`);
473
+ throw new Error(`POST ${endpoint}: ${error.message}`)
467
474
  }
468
475
  }
469
476
 
470
477
  async function apiPut(endpoint, data = {}) {
471
478
  try {
472
- const response = await apiClient.put(endpoint, data);
473
- return response.data;
479
+ const response = await apiClient.put(endpoint, data)
480
+ return response.data
474
481
  } catch (error) {
475
- throw new Error(`PUT ${endpoint}: ${error.message}`);
482
+ throw new Error(`PUT ${endpoint}: ${error.message}`)
476
483
  }
477
484
  }
478
485
 
479
486
  async function apiPatch(endpoint, data = {}) {
480
487
  try {
481
- const response = await apiClient.patch(endpoint, data);
482
- return response.data;
488
+ const response = await apiClient.patch(endpoint, data)
489
+ return response.data
483
490
  } catch (error) {
484
- throw new Error(`PATCH ${endpoint}: ${error.message}`);
491
+ throw new Error(`PATCH ${endpoint}: ${error.message}`)
485
492
  }
486
493
  }
487
494
 
488
495
  async function apiDelete(endpoint) {
489
496
  try {
490
- const response = await apiClient.delete(endpoint);
491
- return response.data;
497
+ const response = await apiClient.delete(endpoint)
498
+ return response.data
492
499
  } catch (error) {
493
- throw new Error(`DELETE ${endpoint}: ${error.message}`);
500
+ throw new Error(`DELETE ${endpoint}: ${error.message}`)
494
501
  }
495
502
  }
496
503
  async function callApi(operationId, identifier, data = {}) {
@@ -500,8 +507,7 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
500
507
  }
501
508
  let operationConfig = apiOperations.value[operationId]
502
509
  if (!operationConfig) {
503
- operationConfig =
504
- apiOperations.value["portal.v1.project." + operationId]
510
+ operationConfig = apiOperations.value["portal.v1.project." + operationId]
505
511
  if (!operationConfig) {
506
512
  throw new Error(`Operation not found: portal.v1.${operationId}`)
507
513
  }
@@ -580,7 +586,7 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
580
586
  if (identifier && bodyData[identifier] !== undefined) {
581
587
  delete bodyData[identifier]
582
588
  }
583
-
589
+
584
590
  try {
585
591
  let response
586
592
  if (method === "get" || method === "delete") {
@@ -606,7 +612,6 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
606
612
  throw new Error(`${method.toUpperCase()} ${resolvedPath}: ${message}`)
607
613
  }
608
614
 
609
-
610
615
  // try {
611
616
  // const operationConfig = apiOperations.value[identifier][operation];
612
617
  // if (!operationConfig) {
@@ -624,79 +629,90 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
624
629
 
625
630
  // Utility methods
626
631
  function getString(key, fallback = "") {
627
- return stringsList.value[key] || fallback;
632
+ return stringsList.value[key] || fallback
628
633
  }
629
634
 
630
635
  function getSetting(key, fallback = null) {
631
- return pluginVars.value[key] || fallback;
636
+ return pluginVars.value[key] || fallback
632
637
  }
633
638
 
634
639
  function getAsset(key, fallback = "") {
635
- return assetList.value[key] || fallback;
640
+ return assetList.value[key] || fallback
636
641
  }
637
642
 
638
643
  function getState(key, fallback = null) {
639
- return triggerState.value[key] || fallback;
644
+ return triggerState.value[key] || fallback
640
645
  }
641
646
  function findDependency(identifier) {
642
- if (Array.isArray(dependencyList.value)) {
643
- return dependencyList.value.find((dep) => dep.identifier === identifier);
644
- }
645
- return null;
647
+ return dependencyList.value[identifier]
646
648
  }
647
649
  function hasPermission(flag) {
648
- return permissionFlags.value.includes(flag);
650
+ return permissionFlags.value.includes(flag)
649
651
  }
650
652
 
651
653
  // Update methods - these replace the entire object to ensure Vue reactivity triggers
652
654
  // Used by DevTools and for programmatic updates
653
655
  function updateString(key, value) {
654
- stringsList.value = { ...stringsList.value, [key]: value };
656
+ stringsList.value = { ...stringsList.value, [key]: value }
655
657
  }
656
658
 
657
659
  function updateSetting(key, value) {
658
- pluginVars.value = { ...pluginVars.value, [key]: value };
660
+ pluginVars.value = { ...pluginVars.value, [key]: value }
659
661
  }
660
662
 
661
663
  function updateAsset(key, value) {
662
- assetList.value = { ...assetList.value, [key]: value };
664
+ assetList.value = { ...assetList.value, [key]: value }
663
665
  }
664
666
 
665
667
  function updateState(key, value) {
666
- triggerState.value = { ...triggerState.value, [key]: value };
668
+ triggerState.value = { ...triggerState.value, [key]: value }
667
669
  }
668
670
 
669
671
  // Convenience method to add dev assets with proper URL
670
672
  function addDevAsset(key, filename) {
671
673
  const appPort =
672
- typeof window !== "undefined" ? window.location.port || 3000 : 3000;
674
+ typeof window !== "undefined" ? window.location.port || 3000 : 3000
673
675
  const appProtocol =
674
- typeof window !== "undefined" ? window.location.protocol : "http:";
675
- const assetUrl = `${appProtocol}//localhost:${appPort}/dev-assets/images/${filename}`;
676
- updateAsset(key, assetUrl);
676
+ typeof window !== "undefined" ? window.location.protocol : "http:"
677
+ const assetUrl = `${appProtocol}//localhost:${appPort}/dev-assets/images/${filename}`
678
+ updateAsset(key, assetUrl)
677
679
  }
678
680
 
679
- // Socket helper methods
680
- function emitSocket(socketName, event, data) {
681
- if (sockets[socketName] && sockets[socketName].broadcast) {
682
- sockets[socketName].broadcast(event, data);
681
+ // Standard Socket helper methods
682
+ function listen(socketName, event, callback) {
683
+ if (sockets[socketName] && sockets[socketName].listen) {
684
+ return sockets[socketName].listen(event, callback)
683
685
  } else {
684
- console.warn(`Socket not found: ${socketName}`);
686
+ console.warn(`Socket not found: ${socketName}`)
687
+ return () => {}
685
688
  }
686
689
  }
687
690
 
688
- function listenSocket(socketName, event, callback) {
689
- if (sockets[socketName] && sockets[socketName].listen) {
690
- return sockets[socketName].listen(event, callback);
691
- } else {
692
- console.warn(`Socket not found: ${socketName}`);
693
- return () => {};
691
+ function broadcast(socketName, event, data) {
692
+ try {
693
+ if (sockets[socketName] && sockets[socketName].broadcast) {
694
+ sockets[socketName].broadcast(event, data)
695
+ } else {
696
+ console.warn(`Socket not found: ${socketName}`)
697
+ }
698
+ return true
699
+ } catch (error) {
700
+ console.error(`Error broadcasting on socket ${socketName}:`, error)
701
+ return false
694
702
  }
695
703
  }
696
704
 
697
- // Component helper - allows components to register socket listeners easily
705
+ // deprecated helpers: maintain legacy support
706
+ function emitSocket(socketName, event, data) {
707
+ return broadcast(socketName, event, data)
708
+ }
709
+
710
+ function listenSocket(socketName, event, callback) {
711
+ return listen(socketName, event, callback)
712
+ }
713
+
698
714
  function useSocketListener(socketName, event, callback) {
699
- return listenSocket(socketName, event, callback);
715
+ return listenSocket(socketName, event, callback)
700
716
  }
701
717
 
702
718
  // Theme configuration
@@ -706,43 +722,43 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
706
722
  primary_color: getSetting("primary_color", "#FFD600"),
707
723
  start_background_color: getSetting(
708
724
  "start_background_color",
709
- "linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
725
+ "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
710
726
  ),
711
727
  start_text_color: getSetting("start_text_color", "#ffffff"),
712
728
  final_background_color: getSetting("final_background_color", "#4CAF50"),
713
729
  final_text_color: getSetting("final_text_color", "#ffffff"),
714
- }));
730
+ }))
715
731
 
716
732
  function listAssets() {
717
- console.log("📁 Current Assets:");
733
+ console.log("📁 Current Assets:")
718
734
  Object.entries(assetList.value).forEach(([key, url]) => {
719
- console.log(` ${key}: ${url}`);
720
- });
721
- return assetList.value;
735
+ console.log(` ${key}: ${url}`)
736
+ })
737
+ return assetList.value
722
738
  }
723
739
 
724
740
  // Initialize sockets SYNCHRONOUSLY when store is created
725
741
  // This ensures sockets is available immediately
726
- initializeSockets();
742
+ initializeSockets()
727
743
  initializeApiOperations()
728
744
  // Load manifest ASYNCHRONOUSLY in the background
729
745
  // This allows the store to be used immediately while manifest loads
730
- loadManifest();
746
+ loadManifest()
731
747
 
732
748
  // Setup Vite HMR for app-manifest.json hot-reload
733
749
  if (import.meta.hot) {
734
750
  // Listen for custom HMR event from Vite plugin
735
751
  import.meta.hot.on("gxp:manifest-update", (data) => {
736
- console.log("[GxP Store] Hot-reloading app-manifest.json");
737
- applyManifest(data);
738
- initializeDependencySockets();
739
- });
752
+ console.log("[GxP Store] Hot-reloading app-manifest.json")
753
+ applyManifest(data)
754
+ initializeDependencySockets()
755
+ })
740
756
 
741
757
  // Also support full-reload trigger if needed
742
758
  import.meta.hot.on("gxp:manifest-reload", () => {
743
- console.log("[GxP Store] Reloading app-manifest.json");
744
- loadManifest();
745
- });
759
+ console.log("[GxP Store] Reloading app-manifest.json")
760
+ loadManifest()
761
+ })
746
762
  }
747
763
 
748
764
  return {
@@ -789,6 +805,8 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
789
805
  // Socket methods
790
806
  emitSocket,
791
807
  listenSocket,
808
+ listen,
809
+ broadcast,
792
810
  useSocketListener,
793
811
 
794
812
  // Manifest methods
@@ -797,5 +815,5 @@ export const useGxpStore = defineStore("gxp-portal-app", () => {
797
815
 
798
816
  // Development methods
799
817
  listAssets,
800
- };
801
- });
818
+ }
819
+ })