@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.
Files changed (99) hide show
  1. package/browser-extensions/README.md +1 -0
  2. package/browser-extensions/chrome/background.js +857 -0
  3. package/browser-extensions/chrome/content.js +51 -0
  4. package/browser-extensions/chrome/devtools.html +9 -0
  5. package/browser-extensions/chrome/devtools.js +23 -0
  6. package/browser-extensions/chrome/icons/gx_off_128.png +0 -0
  7. package/browser-extensions/chrome/icons/gx_off_16.png +0 -0
  8. package/browser-extensions/chrome/icons/gx_off_32.png +0 -0
  9. package/browser-extensions/chrome/icons/gx_off_64.png +0 -0
  10. package/browser-extensions/chrome/icons/gx_on_128.png +0 -0
  11. package/browser-extensions/chrome/icons/gx_on_16.png +0 -0
  12. package/browser-extensions/chrome/icons/gx_on_32.png +0 -0
  13. package/browser-extensions/chrome/icons/gx_on_64.png +0 -0
  14. package/browser-extensions/chrome/inspector.js +1087 -0
  15. package/browser-extensions/chrome/manifest.json +70 -0
  16. package/browser-extensions/chrome/panel.html +638 -0
  17. package/browser-extensions/chrome/panel.js +862 -0
  18. package/browser-extensions/chrome/popup.html +399 -0
  19. package/browser-extensions/chrome/popup.js +515 -0
  20. package/browser-extensions/chrome/rules.json +1 -0
  21. package/browser-extensions/chrome/test-chrome.html +145 -0
  22. package/browser-extensions/chrome/test-mixed-content.html +190 -0
  23. package/browser-extensions/chrome/test-uri-pattern.html +199 -0
  24. package/browser-extensions/firefox/README.md +134 -0
  25. package/browser-extensions/firefox/background.js +804 -0
  26. package/browser-extensions/firefox/content.js +120 -0
  27. package/browser-extensions/firefox/debug-errors.html +229 -0
  28. package/browser-extensions/firefox/debug-https.html +113 -0
  29. package/browser-extensions/firefox/devtools.html +9 -0
  30. package/browser-extensions/firefox/devtools.js +24 -0
  31. package/browser-extensions/firefox/icons/gx_off_128.png +0 -0
  32. package/browser-extensions/firefox/icons/gx_off_16.png +0 -0
  33. package/browser-extensions/firefox/icons/gx_off_32.png +0 -0
  34. package/browser-extensions/firefox/icons/gx_off_64.png +0 -0
  35. package/browser-extensions/firefox/icons/gx_on_128.png +0 -0
  36. package/browser-extensions/firefox/icons/gx_on_16.png +0 -0
  37. package/browser-extensions/firefox/icons/gx_on_32.png +0 -0
  38. package/browser-extensions/firefox/icons/gx_on_64.png +0 -0
  39. package/browser-extensions/firefox/inspector.js +1087 -0
  40. package/browser-extensions/firefox/manifest.json +67 -0
  41. package/browser-extensions/firefox/panel.html +638 -0
  42. package/browser-extensions/firefox/panel.js +862 -0
  43. package/browser-extensions/firefox/popup.html +525 -0
  44. package/browser-extensions/firefox/popup.js +536 -0
  45. package/browser-extensions/firefox/test-gramercy.html +126 -0
  46. package/browser-extensions/firefox/test-imports.html +58 -0
  47. package/browser-extensions/firefox/test-masking.html +147 -0
  48. package/browser-extensions/firefox/test-uri-pattern.html +199 -0
  49. package/package.json +7 -2
  50. package/runtime/PortalContainer.vue +326 -0
  51. package/runtime/dev-tools/DevToolsModal.vue +217 -0
  52. package/runtime/dev-tools/LayoutSwitcher.vue +221 -0
  53. package/runtime/dev-tools/MockDataEditor.vue +621 -0
  54. package/runtime/dev-tools/SocketSimulator.vue +562 -0
  55. package/runtime/dev-tools/StoreInspector.vue +644 -0
  56. package/runtime/dev-tools/index.js +6 -0
  57. package/runtime/gxpStringsPlugin.js +428 -0
  58. package/runtime/index.html +22 -0
  59. package/runtime/main.js +32 -0
  60. package/runtime/mock-api/auth-middleware.js +97 -0
  61. package/runtime/mock-api/image-generator.js +221 -0
  62. package/runtime/mock-api/index.js +197 -0
  63. package/runtime/mock-api/response-generator.js +394 -0
  64. package/runtime/mock-api/route-generator.js +323 -0
  65. package/runtime/mock-api/socket-triggers.js +371 -0
  66. package/runtime/mock-api/spec-loader.js +300 -0
  67. package/runtime/server.js +180 -0
  68. package/runtime/stores/gxpPortalConfigStore.js +554 -0
  69. package/runtime/stores/index.js +6 -0
  70. package/runtime/vite-inspector-plugin.js +749 -0
  71. package/runtime/vite-source-tracker-plugin.js +232 -0
  72. package/runtime/vite.config.js +402 -0
  73. package/scripts/launch-chrome.js +90 -0
  74. package/scripts/pack-chrome.js +91 -0
  75. package/socket-events/AiSessionMessageCreated.json +18 -0
  76. package/socket-events/SocialStreamPostCreated.json +24 -0
  77. package/socket-events/SocialStreamPostVariantCompleted.json +23 -0
  78. package/template/README.md +332 -0
  79. package/template/app-manifest.json +32 -0
  80. package/template/dev-assets/images/avatar-placeholder.png +0 -0
  81. package/template/dev-assets/images/background-placeholder.jpg +0 -0
  82. package/template/dev-assets/images/banner-placeholder.jpg +0 -0
  83. package/template/dev-assets/images/icon-placeholder.png +0 -0
  84. package/template/dev-assets/images/logo-placeholder.png +0 -0
  85. package/template/dev-assets/images/product-placeholder.jpg +0 -0
  86. package/template/dev-assets/images/thumbnail-placeholder.jpg +0 -0
  87. package/template/env.example +51 -0
  88. package/template/gitignore +53 -0
  89. package/template/index.html +22 -0
  90. package/template/main.js +28 -0
  91. package/template/src/DemoPage.vue +459 -0
  92. package/template/src/Plugin.vue +38 -0
  93. package/template/src/stores/index.js +9 -0
  94. package/template/src/stores/test-data.json +173 -0
  95. package/template/theme-layouts/AdditionalStyling.css +0 -0
  96. package/template/theme-layouts/PrivateLayout.vue +39 -0
  97. package/template/theme-layouts/PublicLayout.vue +39 -0
  98. package/template/theme-layouts/SystemLayout.vue +39 -0
  99. package/template/vite.config.js +333 -0
@@ -0,0 +1,562 @@
1
+ <template>
2
+ <div class="socket-simulator">
3
+ <div class="simulator-header">
4
+ <div class="connection-status" :class="{ connected: isConnected }">
5
+ <span class="status-dot"></span>
6
+ {{ isConnected ? 'Connected' : 'Disconnected' }}
7
+ </div>
8
+ <span class="socket-port">Port: {{ socketPort }}</span>
9
+ </div>
10
+
11
+ <div class="event-list">
12
+ <h4>Available Events</h4>
13
+ <p class="helper-text">
14
+ Click an event to send it. Events are loaded from <code>socket-events/</code> directory.
15
+ </p>
16
+
17
+ <div v-if="events.length === 0" class="empty-state">
18
+ <p>No socket events found.</p>
19
+ <p class="hint">Create JSON files in <code>socket-events/</code> to add events.</p>
20
+ </div>
21
+
22
+ <div v-else class="events-grid">
23
+ <div
24
+ v-for="event in events"
25
+ :key="event.name"
26
+ class="event-card"
27
+ @click="selectEvent(event)"
28
+ :class="{ selected: selectedEvent?.name === event.name }"
29
+ >
30
+ <div class="event-name">{{ event.name }}</div>
31
+ <div class="event-type">{{ event.event }}</div>
32
+ </div>
33
+ </div>
34
+ </div>
35
+
36
+ <div v-if="selectedEvent" class="event-editor">
37
+ <h4>Event Details: {{ selectedEvent.name }}</h4>
38
+
39
+ <div class="editor-field">
40
+ <label>Event Type:</label>
41
+ <input v-model="editableEvent.event" class="field-input" />
42
+ </div>
43
+
44
+ <div class="editor-field">
45
+ <label>Channel:</label>
46
+ <input v-model="editableEvent.channel" class="field-input" />
47
+ </div>
48
+
49
+ <div class="editor-field">
50
+ <label>Data (JSON):</label>
51
+ <textarea
52
+ v-model="editableEventData"
53
+ class="field-textarea"
54
+ rows="8"
55
+ @input="validateJson"
56
+ ></textarea>
57
+ <span v-if="jsonError" class="json-error">{{ jsonError }}</span>
58
+ </div>
59
+
60
+ <div class="editor-actions">
61
+ <button class="btn btn-primary" @click="sendEvent" :disabled="!!jsonError">
62
+ Send Event
63
+ </button>
64
+ <button class="btn btn-secondary" @click="resetEvent">
65
+ Reset
66
+ </button>
67
+ </div>
68
+ </div>
69
+
70
+ <div class="event-log">
71
+ <div class="log-header">
72
+ <h4>Event Log</h4>
73
+ <button class="btn-clear" @click="clearLog">Clear</button>
74
+ </div>
75
+ <div class="log-entries">
76
+ <div v-if="eventLog.length === 0" class="empty-log">
77
+ No events sent yet
78
+ </div>
79
+ <div
80
+ v-for="(entry, index) in eventLog"
81
+ :key="index"
82
+ class="log-entry"
83
+ :class="entry.type"
84
+ >
85
+ <span class="log-time">{{ entry.time }}</span>
86
+ <span class="log-direction">{{ entry.direction }}</span>
87
+ <span class="log-event">{{ entry.event }}</span>
88
+ <span class="log-status">{{ entry.status }}</span>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </template>
94
+
95
+ <script setup>
96
+ import { ref, reactive, computed, onMounted } from 'vue';
97
+
98
+ const props = defineProps({
99
+ store: {
100
+ type: Object,
101
+ required: true
102
+ }
103
+ });
104
+
105
+ const socketPort = ref(3069);
106
+ const isConnected = ref(false);
107
+ const events = ref([]);
108
+ const selectedEvent = ref(null);
109
+ const editableEvent = reactive({
110
+ event: '',
111
+ channel: '',
112
+ data: {}
113
+ });
114
+ const editableEventData = ref('');
115
+ const jsonError = ref('');
116
+ const eventLog = ref([]);
117
+
118
+ // Default events if none are loaded
119
+ const defaultEvents = [
120
+ {
121
+ name: 'AiSessionMessageCreated',
122
+ event: 'AiSessionMessageCreated',
123
+ channel: 'private.ai_session.1',
124
+ data: {
125
+ id: 1,
126
+ message: 'Test AI response',
127
+ session_id: 1,
128
+ created_at: new Date().toISOString()
129
+ }
130
+ },
131
+ {
132
+ name: 'SocialStreamPostCreated',
133
+ event: 'SocialStreamPostCreated',
134
+ channel: 'private.social_stream.1',
135
+ data: {
136
+ id: 1,
137
+ content: 'Test social post',
138
+ author: 'Test User',
139
+ created_at: new Date().toISOString()
140
+ }
141
+ },
142
+ {
143
+ name: 'StateChange',
144
+ event: 'state-change',
145
+ channel: 'broadcast',
146
+ data: {
147
+ key: 'test_key',
148
+ value: 'test_value',
149
+ timestamp: new Date().toISOString()
150
+ }
151
+ }
152
+ ];
153
+
154
+ onMounted(() => {
155
+ // Load events - in a real implementation, this would load from socket-events directory
156
+ events.value = defaultEvents;
157
+
158
+ // Check socket connection
159
+ checkConnection();
160
+ });
161
+
162
+ function checkConnection() {
163
+ // Try to connect to socket server
164
+ const socket = props.store?.sockets?.primary;
165
+ isConnected.value = !!socket;
166
+ }
167
+
168
+ function selectEvent(event) {
169
+ selectedEvent.value = event;
170
+ editableEvent.event = event.event;
171
+ editableEvent.channel = event.channel;
172
+ editableEvent.data = { ...event.data };
173
+ editableEventData.value = JSON.stringify(event.data, null, 2);
174
+ jsonError.value = '';
175
+ }
176
+
177
+ function validateJson() {
178
+ try {
179
+ JSON.parse(editableEventData.value);
180
+ jsonError.value = '';
181
+ } catch (e) {
182
+ jsonError.value = 'Invalid JSON: ' + e.message;
183
+ }
184
+ }
185
+
186
+ function resetEvent() {
187
+ if (selectedEvent.value) {
188
+ selectEvent(selectedEvent.value);
189
+ }
190
+ }
191
+
192
+ async function sendEvent() {
193
+ if (jsonError.value) return;
194
+
195
+ let data;
196
+ try {
197
+ data = JSON.parse(editableEventData.value);
198
+ } catch {
199
+ return;
200
+ }
201
+
202
+ const eventPayload = {
203
+ event: editableEvent.event,
204
+ channel: editableEvent.channel,
205
+ data: data
206
+ };
207
+
208
+ // Log the send attempt
209
+ addLogEntry('send', editableEvent.event, 'pending');
210
+
211
+ try {
212
+ // Try to send via the store's socket
213
+ const socket = props.store?.sockets?.primary;
214
+ if (socket && socket.broadcast) {
215
+ socket.broadcast(editableEvent.event, data);
216
+ updateLastLogEntry('success');
217
+ console.log('[DevTools] Socket event sent:', eventPayload);
218
+ } else {
219
+ // Fallback: try to send via HTTP to the socket server
220
+ const response = await fetch(`https://localhost:${socketPort.value}/emit`, {
221
+ method: 'POST',
222
+ headers: {
223
+ 'Content-Type': 'application/json'
224
+ },
225
+ body: JSON.stringify(eventPayload)
226
+ });
227
+
228
+ if (response.ok) {
229
+ updateLastLogEntry('success');
230
+ console.log('[DevTools] Socket event sent via HTTP:', eventPayload);
231
+ } else {
232
+ throw new Error('HTTP request failed');
233
+ }
234
+ }
235
+ } catch (err) {
236
+ updateLastLogEntry('error');
237
+ console.error('[DevTools] Failed to send event:', err);
238
+ }
239
+ }
240
+
241
+ function addLogEntry(direction, event, status) {
242
+ const now = new Date();
243
+ const time = now.toLocaleTimeString('en-US', { hour12: false });
244
+
245
+ eventLog.value.unshift({
246
+ time,
247
+ direction: direction === 'send' ? '→' : '←',
248
+ event,
249
+ status,
250
+ type: status
251
+ });
252
+
253
+ // Keep only last 50 entries
254
+ if (eventLog.value.length > 50) {
255
+ eventLog.value.pop();
256
+ }
257
+ }
258
+
259
+ function updateLastLogEntry(status) {
260
+ if (eventLog.value.length > 0) {
261
+ eventLog.value[0].status = status;
262
+ eventLog.value[0].type = status;
263
+ }
264
+ }
265
+
266
+ function clearLog() {
267
+ eventLog.value = [];
268
+ }
269
+ </script>
270
+
271
+ <style scoped>
272
+ .socket-simulator {
273
+ display: flex;
274
+ flex-direction: column;
275
+ gap: 20px;
276
+ }
277
+
278
+ .simulator-header {
279
+ display: flex;
280
+ justify-content: space-between;
281
+ align-items: center;
282
+ padding: 12px 16px;
283
+ background: #2d2d2d;
284
+ border-radius: 8px;
285
+ }
286
+
287
+ .connection-status {
288
+ display: flex;
289
+ align-items: center;
290
+ gap: 8px;
291
+ font-size: 13px;
292
+ color: #ff6b6b;
293
+ }
294
+
295
+ .connection-status.connected {
296
+ color: #51cf66;
297
+ }
298
+
299
+ .status-dot {
300
+ width: 8px;
301
+ height: 8px;
302
+ border-radius: 50%;
303
+ background: currentColor;
304
+ }
305
+
306
+ .socket-port {
307
+ font-size: 12px;
308
+ color: #888;
309
+ font-family: 'SF Mono', Monaco, monospace;
310
+ }
311
+
312
+ .event-list h4,
313
+ .event-editor h4,
314
+ .event-log h4 {
315
+ margin: 0 0 8px 0;
316
+ font-size: 13px;
317
+ color: #e0e0e0;
318
+ }
319
+
320
+ .helper-text {
321
+ font-size: 12px;
322
+ color: #888;
323
+ margin: 0 0 12px 0;
324
+ }
325
+
326
+ .helper-text code,
327
+ .hint code {
328
+ background: #3d3d3d;
329
+ padding: 2px 6px;
330
+ border-radius: 3px;
331
+ font-family: 'SF Mono', Monaco, monospace;
332
+ font-size: 11px;
333
+ }
334
+
335
+ .empty-state {
336
+ padding: 20px;
337
+ text-align: center;
338
+ color: #666;
339
+ background: #2d2d2d;
340
+ border-radius: 8px;
341
+ }
342
+
343
+ .empty-state p {
344
+ margin: 0;
345
+ }
346
+
347
+ .hint {
348
+ font-size: 11px;
349
+ margin-top: 8px !important;
350
+ }
351
+
352
+ .events-grid {
353
+ display: grid;
354
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
355
+ gap: 12px;
356
+ }
357
+
358
+ .event-card {
359
+ background: #2d2d2d;
360
+ border-radius: 8px;
361
+ padding: 12px;
362
+ cursor: pointer;
363
+ border: 2px solid transparent;
364
+ transition: all 0.2s;
365
+ }
366
+
367
+ .event-card:hover {
368
+ border-color: #3d3d3d;
369
+ background: #333;
370
+ }
371
+
372
+ .event-card.selected {
373
+ border-color: #61dafb;
374
+ background: #2a3a4a;
375
+ }
376
+
377
+ .event-name {
378
+ font-size: 13px;
379
+ font-weight: 500;
380
+ color: #e0e0e0;
381
+ margin-bottom: 4px;
382
+ }
383
+
384
+ .event-type {
385
+ font-size: 11px;
386
+ color: #888;
387
+ font-family: 'SF Mono', Monaco, monospace;
388
+ }
389
+
390
+ .event-editor {
391
+ background: #2d2d2d;
392
+ border-radius: 8px;
393
+ padding: 16px;
394
+ }
395
+
396
+ .editor-field {
397
+ margin-bottom: 12px;
398
+ }
399
+
400
+ .editor-field label {
401
+ display: block;
402
+ font-size: 12px;
403
+ color: #888;
404
+ margin-bottom: 4px;
405
+ }
406
+
407
+ .field-input,
408
+ .field-textarea {
409
+ width: 100%;
410
+ background: #1e1e1e;
411
+ border: 1px solid #3d3d3d;
412
+ color: #e0e0e0;
413
+ padding: 8px 12px;
414
+ border-radius: 4px;
415
+ font-family: 'SF Mono', Monaco, monospace;
416
+ font-size: 12px;
417
+ box-sizing: border-box;
418
+ }
419
+
420
+ .field-input:focus,
421
+ .field-textarea:focus {
422
+ outline: none;
423
+ border-color: #61dafb;
424
+ }
425
+
426
+ .field-textarea {
427
+ resize: vertical;
428
+ min-height: 100px;
429
+ }
430
+
431
+ .json-error {
432
+ display: block;
433
+ color: #ff6b6b;
434
+ font-size: 11px;
435
+ margin-top: 4px;
436
+ }
437
+
438
+ .editor-actions {
439
+ display: flex;
440
+ gap: 8px;
441
+ margin-top: 16px;
442
+ }
443
+
444
+ .btn {
445
+ padding: 8px 16px;
446
+ border: none;
447
+ border-radius: 4px;
448
+ cursor: pointer;
449
+ font-size: 12px;
450
+ transition: all 0.2s;
451
+ }
452
+
453
+ .btn-primary {
454
+ background: #61dafb;
455
+ color: #1e1e1e;
456
+ }
457
+
458
+ .btn-primary:hover {
459
+ background: #4fc3f7;
460
+ }
461
+
462
+ .btn-primary:disabled {
463
+ background: #3d3d3d;
464
+ color: #666;
465
+ cursor: not-allowed;
466
+ }
467
+
468
+ .btn-secondary {
469
+ background: #3d3d3d;
470
+ color: #e0e0e0;
471
+ }
472
+
473
+ .btn-secondary:hover {
474
+ background: #4d4d4d;
475
+ }
476
+
477
+ .event-log {
478
+ background: #2d2d2d;
479
+ border-radius: 8px;
480
+ overflow: hidden;
481
+ }
482
+
483
+ .log-header {
484
+ display: flex;
485
+ justify-content: space-between;
486
+ align-items: center;
487
+ padding: 12px 16px;
488
+ border-bottom: 1px solid #3d3d3d;
489
+ }
490
+
491
+ .log-header h4 {
492
+ margin: 0;
493
+ }
494
+
495
+ .btn-clear {
496
+ background: transparent;
497
+ border: none;
498
+ color: #888;
499
+ cursor: pointer;
500
+ font-size: 11px;
501
+ }
502
+
503
+ .btn-clear:hover {
504
+ color: #e0e0e0;
505
+ }
506
+
507
+ .log-entries {
508
+ max-height: 200px;
509
+ overflow-y: auto;
510
+ }
511
+
512
+ .empty-log {
513
+ padding: 20px;
514
+ text-align: center;
515
+ color: #666;
516
+ font-size: 12px;
517
+ }
518
+
519
+ .log-entry {
520
+ display: flex;
521
+ gap: 12px;
522
+ padding: 8px 16px;
523
+ font-size: 11px;
524
+ font-family: 'SF Mono', Monaco, monospace;
525
+ border-bottom: 1px solid #252525;
526
+ }
527
+
528
+ .log-entry:last-child {
529
+ border-bottom: none;
530
+ }
531
+
532
+ .log-time {
533
+ color: #666;
534
+ min-width: 70px;
535
+ }
536
+
537
+ .log-direction {
538
+ color: #61dafb;
539
+ }
540
+
541
+ .log-event {
542
+ color: #e0e0e0;
543
+ flex: 1;
544
+ }
545
+
546
+ .log-status {
547
+ min-width: 60px;
548
+ text-align: right;
549
+ }
550
+
551
+ .log-entry.success .log-status {
552
+ color: #51cf66;
553
+ }
554
+
555
+ .log-entry.error .log-status {
556
+ color: #ff6b6b;
557
+ }
558
+
559
+ .log-entry.pending .log-status {
560
+ color: #ffd43b;
561
+ }
562
+ </style>