@gxp-dev/tools 2.0.6 → 2.0.7
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/browser-extensions/README.md +1 -0
- package/browser-extensions/chrome/background.js +857 -0
- package/browser-extensions/chrome/content.js +51 -0
- package/browser-extensions/chrome/devtools.html +9 -0
- package/browser-extensions/chrome/devtools.js +23 -0
- package/browser-extensions/chrome/icons/gx_off_128.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_16.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_32.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_64.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_128.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_16.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_32.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_64.png +0 -0
- package/browser-extensions/chrome/inspector.js +1087 -0
- package/browser-extensions/chrome/manifest.json +70 -0
- package/browser-extensions/chrome/panel.html +638 -0
- package/browser-extensions/chrome/panel.js +862 -0
- package/browser-extensions/chrome/popup.html +399 -0
- package/browser-extensions/chrome/popup.js +515 -0
- package/browser-extensions/chrome/rules.json +1 -0
- package/browser-extensions/chrome/test-chrome.html +145 -0
- package/browser-extensions/chrome/test-mixed-content.html +190 -0
- package/browser-extensions/chrome/test-uri-pattern.html +199 -0
- package/browser-extensions/firefox/README.md +134 -0
- package/browser-extensions/firefox/background.js +804 -0
- package/browser-extensions/firefox/content.js +120 -0
- package/browser-extensions/firefox/debug-errors.html +229 -0
- package/browser-extensions/firefox/debug-https.html +113 -0
- package/browser-extensions/firefox/devtools.html +9 -0
- package/browser-extensions/firefox/devtools.js +24 -0
- package/browser-extensions/firefox/icons/gx_off_128.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_16.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_32.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_64.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_128.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_16.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_32.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_64.png +0 -0
- package/browser-extensions/firefox/inspector.js +1087 -0
- package/browser-extensions/firefox/manifest.json +67 -0
- package/browser-extensions/firefox/panel.html +638 -0
- package/browser-extensions/firefox/panel.js +862 -0
- package/browser-extensions/firefox/popup.html +525 -0
- package/browser-extensions/firefox/popup.js +536 -0
- package/browser-extensions/firefox/test-gramercy.html +126 -0
- package/browser-extensions/firefox/test-imports.html +58 -0
- package/browser-extensions/firefox/test-masking.html +147 -0
- package/browser-extensions/firefox/test-uri-pattern.html +199 -0
- package/package.json +7 -2
- package/runtime/PortalContainer.vue +326 -0
- package/runtime/dev-tools/DevToolsModal.vue +217 -0
- package/runtime/dev-tools/LayoutSwitcher.vue +221 -0
- package/runtime/dev-tools/MockDataEditor.vue +621 -0
- package/runtime/dev-tools/SocketSimulator.vue +562 -0
- package/runtime/dev-tools/StoreInspector.vue +644 -0
- package/runtime/dev-tools/index.js +6 -0
- package/runtime/gxpStringsPlugin.js +428 -0
- package/runtime/index.html +22 -0
- package/runtime/main.js +32 -0
- package/runtime/mock-api/auth-middleware.js +97 -0
- package/runtime/mock-api/image-generator.js +221 -0
- package/runtime/mock-api/index.js +197 -0
- package/runtime/mock-api/response-generator.js +394 -0
- package/runtime/mock-api/route-generator.js +323 -0
- package/runtime/mock-api/socket-triggers.js +371 -0
- package/runtime/mock-api/spec-loader.js +300 -0
- package/runtime/server.js +180 -0
- package/runtime/stores/gxpPortalConfigStore.js +554 -0
- package/runtime/stores/index.js +6 -0
- package/runtime/vite-inspector-plugin.js +749 -0
- package/runtime/vite-source-tracker-plugin.js +232 -0
- package/runtime/vite.config.js +402 -0
- package/scripts/launch-chrome.js +90 -0
- package/scripts/pack-chrome.js +91 -0
- package/socket-events/AiSessionMessageCreated.json +18 -0
- package/socket-events/SocialStreamPostCreated.json +24 -0
- package/socket-events/SocialStreamPostVariantCompleted.json +23 -0
- package/template/README.md +332 -0
- package/template/app-manifest.json +32 -0
- package/template/dev-assets/images/avatar-placeholder.png +0 -0
- package/template/dev-assets/images/background-placeholder.jpg +0 -0
- package/template/dev-assets/images/banner-placeholder.jpg +0 -0
- package/template/dev-assets/images/icon-placeholder.png +0 -0
- package/template/dev-assets/images/logo-placeholder.png +0 -0
- package/template/dev-assets/images/product-placeholder.jpg +0 -0
- package/template/dev-assets/images/thumbnail-placeholder.jpg +0 -0
- package/template/env.example +51 -0
- package/template/gitignore +53 -0
- package/template/index.html +22 -0
- package/template/main.js +28 -0
- package/template/src/DemoPage.vue +459 -0
- package/template/src/Plugin.vue +38 -0
- package/template/src/stores/index.js +9 -0
- package/template/src/stores/test-data.json +173 -0
- package/template/theme-layouts/AdditionalStyling.css +0 -0
- package/template/theme-layouts/PrivateLayout.vue +39 -0
- package/template/theme-layouts/PublicLayout.vue +39 -0
- package/template/theme-layouts/SystemLayout.vue +39 -0
- package/template/vite.config.js +333 -0
|
@@ -0,0 +1,554 @@
|
|
|
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
|
+
|
|
6
|
+
// Environment URL configuration (matches constants.js ENVIRONMENT_URLS)
|
|
7
|
+
const ENVIRONMENT_URLS = {
|
|
8
|
+
production: {
|
|
9
|
+
apiBaseUrl: "https://api.gramercy.cloud",
|
|
10
|
+
},
|
|
11
|
+
staging: {
|
|
12
|
+
apiBaseUrl: "https://api.efz-staging.env.eventfinity.app",
|
|
13
|
+
},
|
|
14
|
+
testing: {
|
|
15
|
+
apiBaseUrl: "https://api.zenith-develop-testing.env.eventfinity.app",
|
|
16
|
+
},
|
|
17
|
+
develop: {
|
|
18
|
+
apiBaseUrl: "https://api.zenith-develop.env.eventfinity.app",
|
|
19
|
+
},
|
|
20
|
+
local: {
|
|
21
|
+
apiBaseUrl: "https://dashboard.eventfinity.test",
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generate a random bearer token for mock API
|
|
27
|
+
*/
|
|
28
|
+
function generateMockToken() {
|
|
29
|
+
const chars =
|
|
30
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
31
|
+
let token = "";
|
|
32
|
+
for (let i = 0; i < 32; i++) {
|
|
33
|
+
token += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
34
|
+
}
|
|
35
|
+
return token;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get API configuration based on API_ENV environment variable
|
|
40
|
+
* During development, non-mock environments use Vite's proxy at /api-proxy
|
|
41
|
+
* which handles CORS and forwards requests to the actual API server.
|
|
42
|
+
* The proxy also injects the Authorization header, so authToken is not needed client-side.
|
|
43
|
+
* @returns {{ apiBaseUrl: string, authToken: string, projectId: string }}
|
|
44
|
+
*/
|
|
45
|
+
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
|
+
|
|
52
|
+
// Check if we're in development mode (Vite dev server)
|
|
53
|
+
const isDev = import.meta.env.DEV;
|
|
54
|
+
|
|
55
|
+
if (apiEnv === "mock") {
|
|
56
|
+
// Mock API: use local dev server with random token
|
|
57
|
+
const protocol = useHttps ? "https" : "http";
|
|
58
|
+
return {
|
|
59
|
+
apiBaseUrl: `${protocol}://localhost:${nodePort}/mock-api`,
|
|
60
|
+
authToken: generateMockToken(),
|
|
61
|
+
projectId: "team/project",
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// For non-mock environments in development, use the local Vite proxy
|
|
66
|
+
// The proxy handles CORS and injects the Authorization header
|
|
67
|
+
if (isDev) {
|
|
68
|
+
const protocol = useHttps ? "https" : "http";
|
|
69
|
+
return {
|
|
70
|
+
apiBaseUrl: `${protocol}://localhost:${nodePort}/api-proxy`,
|
|
71
|
+
authToken: "", // Proxy injects the token server-side
|
|
72
|
+
projectId: projectId,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Production build: use the actual API URL directly
|
|
77
|
+
const envConfig = ENVIRONMENT_URLS[apiEnv];
|
|
78
|
+
if (!envConfig) {
|
|
79
|
+
console.warn(
|
|
80
|
+
`[GxP Store] Unknown API_ENV "${apiEnv}", falling back to production`
|
|
81
|
+
);
|
|
82
|
+
return {
|
|
83
|
+
apiBaseUrl: ENVIRONMENT_URLS.production.apiBaseUrl,
|
|
84
|
+
authToken: apiKey,
|
|
85
|
+
projectId: projectId,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
apiBaseUrl: envConfig.apiBaseUrl,
|
|
91
|
+
authToken: apiKey,
|
|
92
|
+
projectId: projectId,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Default values used when app-manifest.json doesn't exist or is missing keys
|
|
97
|
+
const defaultData = {
|
|
98
|
+
pluginVars: {
|
|
99
|
+
primary_color: "#FFD600",
|
|
100
|
+
background_color: "#ffffff",
|
|
101
|
+
text_color: "#333333",
|
|
102
|
+
},
|
|
103
|
+
stringsList: {},
|
|
104
|
+
assetList: {},
|
|
105
|
+
dependencyList: {},
|
|
106
|
+
permissionFlags: [],
|
|
107
|
+
triggerState: {},
|
|
108
|
+
auth: null,
|
|
109
|
+
userSession: null,
|
|
110
|
+
pluginData: {},
|
|
111
|
+
portalAssets: {},
|
|
112
|
+
portal: null,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const useGxpStore = defineStore("gxp-portal-app", () => {
|
|
116
|
+
// Core configuration - these will be injected by the platform in production
|
|
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 });
|
|
124
|
+
|
|
125
|
+
// User session data (injected by platform in production)
|
|
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);
|
|
131
|
+
|
|
132
|
+
// Loading state for manifest
|
|
133
|
+
const manifestLoaded = ref(false);
|
|
134
|
+
const manifestError = ref(null);
|
|
135
|
+
|
|
136
|
+
// API configuration - initialized from environment
|
|
137
|
+
const apiConfig = getApiConfig();
|
|
138
|
+
const apiBaseUrl = ref(apiConfig.apiBaseUrl);
|
|
139
|
+
const authToken = ref(apiConfig.authToken);
|
|
140
|
+
pluginVars.value.projectId = apiConfig.projectId;
|
|
141
|
+
pluginVars.value.apiPageAuthId = apiConfig.authToken;
|
|
142
|
+
pluginVars.value.apiBaseUrl = apiConfig.apiBaseUrl;
|
|
143
|
+
|
|
144
|
+
// Log API configuration for debugging
|
|
145
|
+
console.log(
|
|
146
|
+
`[GxP Store] API Environment: ${import.meta.env.VITE_API_ENV || "mock"}`
|
|
147
|
+
);
|
|
148
|
+
console.log(`[GxP Store] API Base URL: ${apiConfig.apiBaseUrl}`);
|
|
149
|
+
|
|
150
|
+
// WebSocket configuration - initialized as reactive objects immediately
|
|
151
|
+
const sockets = reactive({});
|
|
152
|
+
const socketConnections = reactive({});
|
|
153
|
+
|
|
154
|
+
// API client setup
|
|
155
|
+
const apiClient = axios.create({
|
|
156
|
+
timeout: 30000,
|
|
157
|
+
headers: {
|
|
158
|
+
"Content-Type": "application/json",
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Add auth token to requests
|
|
163
|
+
apiClient.interceptors.request.use((config) => {
|
|
164
|
+
if (authToken.value) {
|
|
165
|
+
config.headers.Authorization = `Bearer ${authToken.value}`;
|
|
166
|
+
}
|
|
167
|
+
config.baseURL = apiBaseUrl.value;
|
|
168
|
+
return config;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Response interceptor for error handling
|
|
172
|
+
apiClient.interceptors.response.use(
|
|
173
|
+
(response) => response,
|
|
174
|
+
(error) => {
|
|
175
|
+
console.error("API Error:", error.response?.data || error.message);
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Load configuration from app-manifest.json
|
|
182
|
+
* Maps manifest keys to store properties:
|
|
183
|
+
* - settings -> pluginVars
|
|
184
|
+
* - strings.default -> stringsList
|
|
185
|
+
* - assets -> assetList
|
|
186
|
+
*/
|
|
187
|
+
async function loadManifest() {
|
|
188
|
+
try {
|
|
189
|
+
const response = await fetch("/app-manifest.json");
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
if (response.status === 404) {
|
|
192
|
+
console.log("[GxP Store] No app-manifest.json found, using defaults");
|
|
193
|
+
manifestLoaded.value = true;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
throw new Error(`HTTP ${response.status}`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const manifest = await response.json();
|
|
200
|
+
applyManifest(manifest);
|
|
201
|
+
manifestLoaded.value = true;
|
|
202
|
+
manifestError.value = null;
|
|
203
|
+
console.log("[GxP Store] Loaded configuration from app-manifest.json");
|
|
204
|
+
|
|
205
|
+
// Re-initialize dependency sockets after manifest loads
|
|
206
|
+
initializeDependencySockets();
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.warn(
|
|
209
|
+
"[GxP Store] Could not load app-manifest.json:",
|
|
210
|
+
error.message
|
|
211
|
+
);
|
|
212
|
+
manifestError.value = error.message;
|
|
213
|
+
manifestLoaded.value = true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Apply manifest data to store
|
|
219
|
+
*/
|
|
220
|
+
function applyManifest(manifest) {
|
|
221
|
+
if (manifest.settings && typeof manifest.settings === "object") {
|
|
222
|
+
pluginVars.value = { ...defaultData.pluginVars, ...manifest.settings };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Handle strings - can be { default: {...} } or flat object
|
|
226
|
+
if (manifest.strings) {
|
|
227
|
+
if (
|
|
228
|
+
manifest.strings.default &&
|
|
229
|
+
typeof manifest.strings.default === "object"
|
|
230
|
+
) {
|
|
231
|
+
stringsList.value = { ...manifest.strings.default };
|
|
232
|
+
} else if (typeof manifest.strings === "object") {
|
|
233
|
+
stringsList.value = { ...manifest.strings };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (manifest.assets && typeof manifest.assets === "object") {
|
|
238
|
+
assetList.value = { ...manifest.assets };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (manifest.dependencies && Array.isArray(manifest.dependencies)) {
|
|
242
|
+
dependencies.value = manifest.dependencies; // Store full dependency objects
|
|
243
|
+
dependencyList.value = manifest.dependencies.reduce((acc, dependency) => {
|
|
244
|
+
acc[dependency.identifier] = "1";
|
|
245
|
+
return acc;
|
|
246
|
+
}, {});
|
|
247
|
+
console.log("[GxP Store] Dependency List:", dependencyList.value);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (manifest.permissions && Array.isArray(manifest.permissions)) {
|
|
251
|
+
permissionFlags.value = [...manifest.permissions];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (manifest.triggerState && typeof manifest.triggerState === "object") {
|
|
255
|
+
triggerState.value = { ...manifest.triggerState };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Initialize primary WebSocket connection
|
|
261
|
+
* Called synchronously when store is created
|
|
262
|
+
*/
|
|
263
|
+
function initializeSockets() {
|
|
264
|
+
// Primary socket connection
|
|
265
|
+
// Use the same protocol as the current page for Socket.IO connection
|
|
266
|
+
const socketProtocol =
|
|
267
|
+
typeof window !== "undefined" && window.location.protocol === "https:"
|
|
268
|
+
? "https"
|
|
269
|
+
: "http";
|
|
270
|
+
const socketPort = import.meta.env.VITE_SOCKET_IO_PORT || 3069;
|
|
271
|
+
console.log(`[GxP Store] Connecting to Socket.IO on port ${socketPort}`);
|
|
272
|
+
const primarySocket = io(`${socketProtocol}://localhost:${socketPort}`);
|
|
273
|
+
|
|
274
|
+
sockets.primary = {
|
|
275
|
+
broadcast: function (event, data) {
|
|
276
|
+
primarySocket.emit(event, data);
|
|
277
|
+
},
|
|
278
|
+
listen: function (event, callback) {
|
|
279
|
+
return primarySocket.on(event, callback);
|
|
280
|
+
},
|
|
281
|
+
listenForStateChange: function (callback) {
|
|
282
|
+
return primarySocket.on("state-change", callback);
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
socketConnections.primary = primarySocket;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Initialize dependency-based sockets
|
|
291
|
+
* Called after manifest loads to set up dependency-specific listeners
|
|
292
|
+
*/
|
|
293
|
+
function initializeDependencySockets() {
|
|
294
|
+
const primarySocket = socketConnections.primary;
|
|
295
|
+
if (!primarySocket) return;
|
|
296
|
+
|
|
297
|
+
// Initialize dependency-based sockets based on the new structure
|
|
298
|
+
if (Array.isArray(dependencies.value)) {
|
|
299
|
+
dependencies.value.forEach((dependency) => {
|
|
300
|
+
if (dependency.events && Object.keys(dependency.events).length > 0) {
|
|
301
|
+
// Create socket listeners for each event type
|
|
302
|
+
sockets[dependency.identifier] = {};
|
|
303
|
+
|
|
304
|
+
Object.keys(dependency.events).forEach((eventType) => {
|
|
305
|
+
const eventName = dependency.events[eventType];
|
|
306
|
+
const channel = `private.${dependency.model}.${dependency.identifier}`;
|
|
307
|
+
|
|
308
|
+
sockets[dependency.identifier][eventType] = {
|
|
309
|
+
listen: function (callback) {
|
|
310
|
+
// Listen for the specific event on the primary socket
|
|
311
|
+
return primarySocket.on(eventName, (data) => {
|
|
312
|
+
console.log(
|
|
313
|
+
`Socket event received: ${eventName} on ${channel}`,
|
|
314
|
+
data
|
|
315
|
+
);
|
|
316
|
+
callback(data);
|
|
317
|
+
});
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
});
|
|
321
|
+
} else {
|
|
322
|
+
// For dependencies without events, create empty listeners
|
|
323
|
+
sockets[dependency.identifier] = {
|
|
324
|
+
created: { listen: () => () => {} },
|
|
325
|
+
updated: { listen: () => () => {} },
|
|
326
|
+
deleted: { listen: () => () => {} },
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// API methods for common operations
|
|
334
|
+
async function apiGet(endpoint, params = {}) {
|
|
335
|
+
try {
|
|
336
|
+
const response = await apiClient.get(endpoint, { params });
|
|
337
|
+
return response.data;
|
|
338
|
+
} catch (error) {
|
|
339
|
+
throw new Error(`GET ${endpoint}: ${error.message}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async function apiPost(endpoint, data = {}) {
|
|
344
|
+
try {
|
|
345
|
+
const response = await apiClient.post(endpoint, data);
|
|
346
|
+
return response.data;
|
|
347
|
+
} catch (error) {
|
|
348
|
+
throw new Error(`POST ${endpoint}: ${error.message}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
async function apiPut(endpoint, data = {}) {
|
|
353
|
+
try {
|
|
354
|
+
const response = await apiClient.put(endpoint, data);
|
|
355
|
+
return response.data;
|
|
356
|
+
} catch (error) {
|
|
357
|
+
throw new Error(`PUT ${endpoint}: ${error.message}`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
async function apiPatch(endpoint, data = {}) {
|
|
362
|
+
try {
|
|
363
|
+
const response = await apiClient.patch(endpoint, data);
|
|
364
|
+
return response.data;
|
|
365
|
+
} catch (error) {
|
|
366
|
+
throw new Error(`PATCH ${endpoint}: ${error.message}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
async function apiDelete(endpoint) {
|
|
371
|
+
try {
|
|
372
|
+
const response = await apiClient.delete(endpoint);
|
|
373
|
+
return response.data;
|
|
374
|
+
} catch (error) {
|
|
375
|
+
throw new Error(`DELETE ${endpoint}: ${error.message}`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Utility methods
|
|
380
|
+
function getString(key, fallback = "") {
|
|
381
|
+
return stringsList.value[key] || fallback;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function getSetting(key, fallback = null) {
|
|
385
|
+
return pluginVars.value[key] || fallback;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function getAsset(key, fallback = "") {
|
|
389
|
+
return assetList.value[key] || fallback;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function getState(key, fallback = null) {
|
|
393
|
+
return triggerState.value[key] || fallback;
|
|
394
|
+
}
|
|
395
|
+
function findDependency(identifier) {
|
|
396
|
+
if (Array.isArray(dependencyList.value)) {
|
|
397
|
+
return dependencyList.value.find((dep) => dep.identifier === identifier);
|
|
398
|
+
}
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
function hasPermission(flag) {
|
|
402
|
+
return permissionFlags.value.includes(flag);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Update methods - these replace the entire object to ensure Vue reactivity triggers
|
|
406
|
+
// Used by DevTools and for programmatic updates
|
|
407
|
+
function updateString(key, value) {
|
|
408
|
+
stringsList.value = { ...stringsList.value, [key]: value };
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function updateSetting(key, value) {
|
|
412
|
+
pluginVars.value = { ...pluginVars.value, [key]: value };
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function updateAsset(key, value) {
|
|
416
|
+
assetList.value = { ...assetList.value, [key]: value };
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function updateState(key, value) {
|
|
420
|
+
triggerState.value = { ...triggerState.value, [key]: value };
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Convenience method to add dev assets with proper URL
|
|
424
|
+
function addDevAsset(key, filename) {
|
|
425
|
+
const appPort =
|
|
426
|
+
typeof window !== "undefined" ? window.location.port || 3000 : 3000;
|
|
427
|
+
const appProtocol =
|
|
428
|
+
typeof window !== "undefined" ? window.location.protocol : "http:";
|
|
429
|
+
const assetUrl = `${appProtocol}//localhost:${appPort}/dev-assets/images/${filename}`;
|
|
430
|
+
updateAsset(key, assetUrl);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Socket helper methods
|
|
434
|
+
function emitSocket(socketName, event, data) {
|
|
435
|
+
if (sockets[socketName] && sockets[socketName].broadcast) {
|
|
436
|
+
sockets[socketName].broadcast(event, data);
|
|
437
|
+
} else {
|
|
438
|
+
console.warn(`Socket not found: ${socketName}`);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function listenSocket(socketName, event, callback) {
|
|
443
|
+
if (sockets[socketName] && sockets[socketName].listen) {
|
|
444
|
+
return sockets[socketName].listen(event, callback);
|
|
445
|
+
} else {
|
|
446
|
+
console.warn(`Socket not found: ${socketName}`);
|
|
447
|
+
return () => {};
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Component helper - allows components to register socket listeners easily
|
|
452
|
+
function useSocketListener(socketName, event, callback) {
|
|
453
|
+
return listenSocket(socketName, event, callback);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Theme configuration
|
|
457
|
+
const theme = computed(() => ({
|
|
458
|
+
background_color: getSetting("background_color", "#ffffff"),
|
|
459
|
+
text_color: getSetting("text_color", "#333333"),
|
|
460
|
+
primary_color: getSetting("primary_color", "#FFD600"),
|
|
461
|
+
start_background_color: getSetting(
|
|
462
|
+
"start_background_color",
|
|
463
|
+
"linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
|
|
464
|
+
),
|
|
465
|
+
start_text_color: getSetting("start_text_color", "#ffffff"),
|
|
466
|
+
final_background_color: getSetting("final_background_color", "#4CAF50"),
|
|
467
|
+
final_text_color: getSetting("final_text_color", "#ffffff"),
|
|
468
|
+
}));
|
|
469
|
+
|
|
470
|
+
function listAssets() {
|
|
471
|
+
console.log("📁 Current Assets:");
|
|
472
|
+
Object.entries(assetList.value).forEach(([key, url]) => {
|
|
473
|
+
console.log(` ${key}: ${url}`);
|
|
474
|
+
});
|
|
475
|
+
return assetList.value;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Initialize sockets SYNCHRONOUSLY when store is created
|
|
479
|
+
// This ensures sockets is available immediately
|
|
480
|
+
initializeSockets();
|
|
481
|
+
|
|
482
|
+
// Load manifest ASYNCHRONOUSLY in the background
|
|
483
|
+
// This allows the store to be used immediately while manifest loads
|
|
484
|
+
loadManifest();
|
|
485
|
+
|
|
486
|
+
// Setup Vite HMR for app-manifest.json hot-reload
|
|
487
|
+
if (import.meta.hot) {
|
|
488
|
+
// Listen for custom HMR event from Vite plugin
|
|
489
|
+
import.meta.hot.on("gxp:manifest-update", (data) => {
|
|
490
|
+
console.log("[GxP Store] Hot-reloading app-manifest.json");
|
|
491
|
+
applyManifest(data);
|
|
492
|
+
initializeDependencySockets();
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
// Also support full-reload trigger if needed
|
|
496
|
+
import.meta.hot.on("gxp:manifest-reload", () => {
|
|
497
|
+
console.log("[GxP Store] Reloading app-manifest.json");
|
|
498
|
+
loadManifest();
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return {
|
|
503
|
+
// State
|
|
504
|
+
pluginVars,
|
|
505
|
+
stringsList,
|
|
506
|
+
assetList,
|
|
507
|
+
dependencyList,
|
|
508
|
+
permissionFlags,
|
|
509
|
+
auth,
|
|
510
|
+
userSession,
|
|
511
|
+
pluginData,
|
|
512
|
+
portalAssets,
|
|
513
|
+
portal,
|
|
514
|
+
sockets,
|
|
515
|
+
theme,
|
|
516
|
+
triggerState,
|
|
517
|
+
manifestLoaded,
|
|
518
|
+
manifestError,
|
|
519
|
+
|
|
520
|
+
// API methods
|
|
521
|
+
apiGet,
|
|
522
|
+
apiPost,
|
|
523
|
+
apiPatch,
|
|
524
|
+
apiPut,
|
|
525
|
+
apiDelete,
|
|
526
|
+
|
|
527
|
+
// Utility methods
|
|
528
|
+
getString,
|
|
529
|
+
getSetting,
|
|
530
|
+
getAsset,
|
|
531
|
+
getState,
|
|
532
|
+
hasPermission,
|
|
533
|
+
findDependency,
|
|
534
|
+
|
|
535
|
+
// Update methods (for DevTools and programmatic updates)
|
|
536
|
+
updateString,
|
|
537
|
+
updateSetting,
|
|
538
|
+
updateAsset,
|
|
539
|
+
updateState,
|
|
540
|
+
addDevAsset,
|
|
541
|
+
|
|
542
|
+
// Socket methods
|
|
543
|
+
emitSocket,
|
|
544
|
+
listenSocket,
|
|
545
|
+
useSocketListener,
|
|
546
|
+
|
|
547
|
+
// Manifest methods
|
|
548
|
+
loadManifest,
|
|
549
|
+
applyManifest,
|
|
550
|
+
|
|
551
|
+
// Development methods
|
|
552
|
+
listAssets,
|
|
553
|
+
};
|
|
554
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Import from package runtime directory by default
|
|
2
|
+
// To customize, run: gxdev publish gxpPortalConfigStore.js
|
|
3
|
+
// Then update this import to: import { useGxpStore } from './gxpPortalConfigStore.js';
|
|
4
|
+
import { useGxpStore } from "@gx-runtime/stores/gxpPortalConfigStore";
|
|
5
|
+
|
|
6
|
+
export { useGxpStore };
|