@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
package/runtime/main.js CHANGED
@@ -1,40 +1,42 @@
1
- import { createApp } from "vue";
2
- import * as Vue from "vue";
3
- import * as Pinia from "pinia";
4
- import { createPinia, setActivePinia } from "pinia";
1
+ import { createApp } from "vue"
2
+ import * as Vue from "vue"
3
+ import * as Pinia from "pinia"
4
+ import { createPinia, setActivePinia } from "pinia"
5
5
 
6
6
  // Create and configure Pinia before any store imports
7
- const pinia = createPinia();
8
- setActivePinia(pinia);
7
+ const pinia = createPinia()
8
+ setActivePinia(pinia)
9
9
 
10
10
  // Expose Vue and Pinia to window for dynamically loaded plugins
11
- window.Vue = Vue;
12
- window.Pinia = Pinia;
13
- window.pinia = pinia;
11
+ window.Vue = Vue
12
+ window.Pinia = Pinia
13
+ window.pinia = pinia
14
14
 
15
15
  // Dynamic imports ensure pinia is set up before stores load
16
16
  async function init() {
17
- const { default: App } = await import("@gx-runtime/PortalContainer.vue");
18
- const { useGxpStore } = await import("@/stores/index.js");
19
- const { createGxpStringsPlugin } = await import("@gx-runtime/gxpStringsPlugin.js");
17
+ const { default: App } = await import("@gx-runtime/PortalContainer.vue")
18
+ const { useGxpStore } = await import("@/stores/index.js")
19
+ const { createGxpStringsPlugin } =
20
+ await import("@gx-runtime/gxpStringsPlugin.js")
20
21
 
21
- window.useGxpStore = useGxpStore;
22
+ window.useGxpStore = useGxpStore
22
23
 
23
- const app = createApp(App);
24
- app.use(pinia);
24
+ const app = createApp(App)
25
+ app.use(pinia)
25
26
 
26
- const gxpStore = useGxpStore();
27
+ const gxpStore = useGxpStore()
27
28
 
28
29
  // Build the dev server base URL so gxp-src default paths resolve to the
29
30
  // local dev server instead of the current domain (important when the app
30
31
  // is injected into the cloud platform via browser extension).
31
- const devProtocol = import.meta.env.VITE_USE_HTTPS !== "false" ? "https" : "http";
32
- const devPort = import.meta.env.VITE_NODE_PORT || "3060";
33
- const devServerBaseUrl = `${devProtocol}://localhost:${devPort}`;
32
+ const devProtocol =
33
+ import.meta.env.VITE_USE_HTTPS !== "false" ? "https" : "http"
34
+ const devPort = import.meta.env.VITE_NODE_PORT || "3060"
35
+ const devServerBaseUrl = `${devProtocol}://localhost:${devPort}`
34
36
 
35
- app.use(createGxpStringsPlugin(gxpStore, { devServerBaseUrl }));
37
+ app.use(createGxpStringsPlugin(gxpStore, { devServerBaseUrl }))
36
38
 
37
- app.mount("#app");
39
+ app.mount("#app")
38
40
  }
39
41
 
40
- init();
42
+ init()
@@ -12,7 +12,7 @@
12
12
  * @param {function} next - Next middleware
13
13
  */
14
14
  function authMiddleware(req, res, next) {
15
- const auth = req.headers.authorization;
15
+ const auth = req.headers.authorization
16
16
 
17
17
  // Check if Authorization header exists
18
18
  if (!auth) {
@@ -20,7 +20,7 @@ function authMiddleware(req, res, next) {
20
20
  error: "Unauthorized",
21
21
  message: "Missing Authorization header",
22
22
  hint: "Include 'Authorization: Bearer <token>' header",
23
- });
23
+ })
24
24
  }
25
25
 
26
26
  // Check Bearer token format
@@ -29,11 +29,11 @@ function authMiddleware(req, res, next) {
29
29
  error: "Unauthorized",
30
30
  message: "Invalid Authorization format",
31
31
  hint: "Use 'Bearer <token>' format",
32
- });
32
+ })
33
33
  }
34
34
 
35
35
  // Extract token
36
- const token = auth.slice(7).trim();
36
+ const token = auth.slice(7).trim()
37
37
 
38
38
  // Check token is not empty
39
39
  if (!token) {
@@ -41,14 +41,14 @@ function authMiddleware(req, res, next) {
41
41
  error: "Unauthorized",
42
42
  message: "Empty token",
43
43
  hint: "Provide a non-empty token after 'Bearer '",
44
- });
44
+ })
45
45
  }
46
46
 
47
47
  // Token format is valid, attach to request for potential use
48
- req.mockToken = token;
48
+ req.mockToken = token
49
49
 
50
50
  // Continue to next middleware/handler
51
- next();
51
+ next()
52
52
  }
53
53
 
54
54
  /**
@@ -58,13 +58,13 @@ function authMiddleware(req, res, next) {
58
58
  * @param {function} next - Next middleware
59
59
  */
60
60
  function optionalAuthMiddleware(req, res, next) {
61
- const auth = req.headers.authorization;
61
+ const auth = req.headers.authorization
62
62
 
63
63
  if (auth && auth.startsWith("Bearer ")) {
64
- req.mockToken = auth.slice(7).trim();
64
+ req.mockToken = auth.slice(7).trim()
65
65
  }
66
66
 
67
- next();
67
+ next()
68
68
  }
69
69
 
70
70
  /**
@@ -74,24 +74,24 @@ function optionalAuthMiddleware(req, res, next) {
74
74
  */
75
75
  function createAuthMiddleware(operation) {
76
76
  // Check if operation has security requirements
77
- const security = operation.security;
77
+ const security = operation.security
78
78
 
79
79
  // If security is explicitly empty array, no auth required
80
80
  if (Array.isArray(security) && security.length === 0) {
81
- return optionalAuthMiddleware;
81
+ return optionalAuthMiddleware
82
82
  }
83
83
 
84
84
  // If security is defined, require auth
85
85
  if (security && security.length > 0) {
86
- return authMiddleware;
86
+ return authMiddleware
87
87
  }
88
88
 
89
89
  // Default: require auth (safer default for mock API)
90
- return authMiddleware;
90
+ return authMiddleware
91
91
  }
92
92
 
93
93
  module.exports = {
94
94
  authMiddleware,
95
95
  optionalAuthMiddleware,
96
96
  createAuthMiddleware,
97
- };
97
+ }
@@ -21,9 +21,9 @@ function randomColor() {
21
21
  "#e91e63", // Pink
22
22
  "#00bcd4", // Cyan
23
23
  "#ff5722", // Deep orange
24
- ];
24
+ ]
25
25
 
26
- return colors[Math.floor(Math.random() * colors.length)];
26
+ return colors[Math.floor(Math.random() * colors.length)]
27
27
  }
28
28
 
29
29
  /**
@@ -33,17 +33,17 @@ function randomColor() {
33
33
  */
34
34
  function getContrastColor(hexColor) {
35
35
  // Remove # if present
36
- const hex = hexColor.replace("#", "");
36
+ const hex = hexColor.replace("#", "")
37
37
 
38
38
  // Convert to RGB
39
- const r = parseInt(hex.substr(0, 2), 16);
40
- const g = parseInt(hex.substr(2, 2), 16);
41
- const b = parseInt(hex.substr(4, 2), 16);
39
+ const r = parseInt(hex.substr(0, 2), 16)
40
+ const g = parseInt(hex.substr(2, 2), 16)
41
+ const b = parseInt(hex.substr(4, 2), 16)
42
42
 
43
43
  // Calculate luminance
44
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
44
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
45
45
 
46
- return luminance > 0.5 ? "#000000" : "#ffffff";
46
+ return luminance > 0.5 ? "#000000" : "#ffffff"
47
47
  }
48
48
 
49
49
  /**
@@ -52,25 +52,25 @@ function getContrastColor(hexColor) {
52
52
  * @returns {string} Valid hex color
53
53
  */
54
54
  function parseColor(color) {
55
- if (!color) return randomColor();
55
+ if (!color) return randomColor()
56
56
 
57
57
  // Remove # if present
58
- let hex = color.replace("#", "");
58
+ let hex = color.replace("#", "")
59
59
 
60
60
  // Expand 3-digit hex
61
61
  if (hex.length === 3) {
62
62
  hex = hex
63
63
  .split("")
64
64
  .map((c) => c + c)
65
- .join("");
65
+ .join("")
66
66
  }
67
67
 
68
68
  // Validate
69
69
  if (/^[0-9a-fA-F]{6}$/.test(hex)) {
70
- return `#${hex}`;
70
+ return `#${hex}`
71
71
  }
72
72
 
73
- return randomColor();
73
+ return randomColor()
74
74
  }
75
75
 
76
76
  /**
@@ -85,17 +85,17 @@ function parseColor(color) {
85
85
  * @returns {string} SVG string
86
86
  */
87
87
  function generateSvg(width, height, options = {}) {
88
- const bgColor = parseColor(options.color);
89
- const textColor = options.textColor || getContrastColor(bgColor);
90
- const text = options.text || `${width}×${height}`;
88
+ const bgColor = parseColor(options.color)
89
+ const textColor = options.textColor || getContrastColor(bgColor)
90
+ const text = options.text || `${width}×${height}`
91
91
 
92
92
  // Calculate font size based on dimensions
93
- const minDim = Math.min(width, height);
94
- const fontSize = options.fontSize || Math.max(12, Math.floor(minDim / 8));
93
+ const minDim = Math.min(width, height)
94
+ const fontSize = options.fontSize || Math.max(12, Math.floor(minDim / 8))
95
95
 
96
96
  // Calculate text position
97
- const textX = width / 2;
98
- const textY = height / 2;
97
+ const textX = width / 2
98
+ const textY = height / 2
99
99
 
100
100
  return `<?xml version="1.0" encoding="UTF-8"?>
101
101
  <svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
@@ -109,7 +109,7 @@ function generateSvg(width, height, options = {}) {
109
109
  text-anchor="middle"
110
110
  dominant-baseline="middle"
111
111
  >${escapeXml(text)}</text>
112
- </svg>`;
112
+ </svg>`
113
113
  }
114
114
 
115
115
  /**
@@ -123,7 +123,7 @@ function escapeXml(text) {
123
123
  .replace(/</g, "&lt;")
124
124
  .replace(/>/g, "&gt;")
125
125
  .replace(/"/g, "&quot;")
126
- .replace(/'/g, "&apos;");
126
+ .replace(/'/g, "&apos;")
127
127
  }
128
128
 
129
129
  /**
@@ -133,25 +133,25 @@ function escapeXml(text) {
133
133
  */
134
134
  function parseDimensions(dimStr) {
135
135
  if (!dimStr) {
136
- return { width: 400, height: 300 };
136
+ return { width: 400, height: 300 }
137
137
  }
138
138
 
139
139
  // Try width x height format
140
- const match = dimStr.match(/^(\d+)[x×:](\d+)$/i);
140
+ const match = dimStr.match(/^(\d+)[x×:](\d+)$/i)
141
141
  if (match) {
142
142
  return {
143
143
  width: parseInt(match[1], 10),
144
144
  height: parseInt(match[2], 10),
145
- };
145
+ }
146
146
  }
147
147
 
148
148
  // Single number = square
149
- const single = parseInt(dimStr, 10);
149
+ const single = parseInt(dimStr, 10)
150
150
  if (!isNaN(single)) {
151
- return { width: single, height: single };
151
+ return { width: single, height: single }
152
152
  }
153
153
 
154
- return { width: 400, height: 300 };
154
+ return { width: 400, height: 300 }
155
155
  }
156
156
 
157
157
  /**
@@ -161,24 +161,24 @@ function parseDimensions(dimStr) {
161
161
  */
162
162
  function imageHandler(req, res) {
163
163
  // Parse dimensions from URL
164
- const { width: widthParam, height: heightParam } = req.params;
164
+ const { width: widthParam, height: heightParam } = req.params
165
165
 
166
- let width, height;
166
+ let width, height
167
167
 
168
168
  if (heightParam) {
169
169
  // /image/:width/:height format
170
- width = parseInt(widthParam, 10) || 400;
171
- height = parseInt(heightParam, 10) || 300;
170
+ width = parseInt(widthParam, 10) || 400
171
+ height = parseInt(heightParam, 10) || 300
172
172
  } else {
173
173
  // /image/:dimensions format (e.g., 400x300)
174
- const dims = parseDimensions(widthParam);
175
- width = dims.width;
176
- height = dims.height;
174
+ const dims = parseDimensions(widthParam)
175
+ width = dims.width
176
+ height = dims.height
177
177
  }
178
178
 
179
179
  // Clamp dimensions
180
- width = Math.min(Math.max(width, 1), 4000);
181
- height = Math.min(Math.max(height, 1), 4000);
180
+ width = Math.min(Math.max(width, 1), 4000)
181
+ height = Math.min(Math.max(height, 1), 4000)
182
182
 
183
183
  // Parse options from query string
184
184
  const options = {
@@ -186,15 +186,15 @@ function imageHandler(req, res) {
186
186
  text: req.query.text,
187
187
  textColor: req.query.textColor || req.query.fg,
188
188
  fontSize: req.query.fontSize ? parseInt(req.query.fontSize, 10) : undefined,
189
- };
189
+ }
190
190
 
191
191
  // Generate SVG
192
- const svg = generateSvg(width, height, options);
192
+ const svg = generateSvg(width, height, options)
193
193
 
194
194
  // Send response
195
- res.set("Content-Type", "image/svg+xml");
196
- res.set("Cache-Control", "public, max-age=86400"); // Cache for 24 hours
197
- res.send(svg);
195
+ res.set("Content-Type", "image/svg+xml")
196
+ res.set("Cache-Control", "public, max-age=86400") // Cache for 24 hours
197
+ res.send(svg)
198
198
  }
199
199
 
200
200
  /**
@@ -205,9 +205,9 @@ function imageHandler(req, res) {
205
205
  * @returns {string} Data URL
206
206
  */
207
207
  function generateDataUrl(width, height, options = {}) {
208
- const svg = generateSvg(width, height, options);
209
- const base64 = Buffer.from(svg).toString("base64");
210
- return `data:image/svg+xml;base64,${base64}`;
208
+ const svg = generateSvg(width, height, options)
209
+ const base64 = Buffer.from(svg).toString("base64")
210
+ return `data:image/svg+xml;base64,${base64}`
211
211
  }
212
212
 
213
213
  module.exports = {
@@ -218,4 +218,4 @@ module.exports = {
218
218
  generateDataUrl,
219
219
  randomColor,
220
220
  getContrastColor,
221
- };
221
+ }
@@ -5,21 +5,21 @@
5
5
  * Creates an Express router that mounts onto the existing server.
6
6
  */
7
7
 
8
- const express = require("express");
8
+ const express = require("express")
9
9
  const {
10
10
  loadSpecs,
11
11
  refreshSpecs,
12
12
  getCacheStatus,
13
13
  getCachedSpecs,
14
- } = require("./spec-loader");
15
- const { generateRoutes, getRouteStats } = require("./route-generator");
16
- const { parseSocketTriggers, getTriggerStats } = require("./socket-triggers");
17
- const { imageHandler } = require("./image-generator");
14
+ } = require("./spec-loader")
15
+ const { generateRoutes, getRouteStats } = require("./route-generator")
16
+ const { parseSocketTriggers, getTriggerStats } = require("./socket-triggers")
17
+ const { imageHandler } = require("./image-generator")
18
18
 
19
19
  // Store state for status endpoint
20
- let currentSpecs = null;
21
- let currentSocketTriggers = null;
22
- let routeStats = null;
20
+ let currentSpecs = null
21
+ let currentSocketTriggers = null
22
+ let routeStats = null
23
23
 
24
24
  /**
25
25
  * Create the mock API router
@@ -29,40 +29,40 @@ let routeStats = null;
29
29
  * @returns {express.Router} Express router
30
30
  */
31
31
  async function createMockApiRouter(io, options = {}) {
32
- const router = express.Router();
33
- const projectRoot = options.projectRoot || process.cwd();
32
+ const router = express.Router()
33
+ const projectRoot = options.projectRoot || process.cwd()
34
34
 
35
- console.log("\n🎭 Initializing Mock API Server...");
35
+ console.log("\n🎭 Initializing Mock API Server...")
36
36
 
37
37
  // Load specs
38
- const specs = await loadSpecs(projectRoot);
39
- currentSpecs = specs;
38
+ const specs = await loadSpecs(projectRoot)
39
+ currentSpecs = specs
40
40
 
41
41
  // Parse socket triggers from AsyncAPI
42
42
  if (specs.asyncApi) {
43
- currentSocketTriggers = parseSocketTriggers(specs.asyncApi);
43
+ currentSocketTriggers = parseSocketTriggers(specs.asyncApi)
44
44
  }
45
45
 
46
46
  // Generate routes from OpenAPI
47
47
  if (specs.openApi) {
48
- console.log("\n📍 Generating mock routes from OpenAPI spec:");
48
+ console.log("\n📍 Generating mock routes from OpenAPI spec:")
49
49
  const apiRouter = generateRoutes(specs.openApi, {
50
50
  io,
51
51
  socketTriggers: currentSocketTriggers,
52
- });
53
- routeStats = getRouteStats(specs.openApi);
52
+ })
53
+ routeStats = getRouteStats(specs.openApi)
54
54
 
55
55
  // Mount API routes under /api
56
- router.use("/api", apiRouter);
56
+ router.use("/api", apiRouter)
57
57
  } else {
58
- console.log("⚠️ No OpenAPI spec available, mock API routes not generated");
59
- routeStats = { total: 0, byMethod: {}, paths: [] };
58
+ console.log("⚠️ No OpenAPI spec available, mock API routes not generated")
59
+ routeStats = { total: 0, byMethod: {}, paths: [] }
60
60
  }
61
61
 
62
62
  // Status endpoint
63
63
  router.get("/_mock/status", (req, res) => {
64
- const cacheStatus = getCacheStatus();
65
- const triggerStats = getTriggerStats(currentSocketTriggers);
64
+ const cacheStatus = getCacheStatus()
65
+ const triggerStats = getTriggerStats(currentSocketTriggers)
66
66
 
67
67
  res.json({
68
68
  enabled: true,
@@ -75,25 +75,25 @@ async function createMockApiRouter(io, options = {}) {
75
75
  routes: routeStats,
76
76
  socketTriggers: triggerStats,
77
77
  cache: cacheStatus,
78
- });
79
- });
78
+ })
79
+ })
80
80
 
81
81
  // Refresh endpoint
82
82
  router.post("/_mock/refresh", async (req, res) => {
83
- console.log("\n🔄 Refreshing mock API specs...");
83
+ console.log("\n🔄 Refreshing mock API specs...")
84
84
 
85
85
  try {
86
- const newSpecs = await refreshSpecs(projectRoot);
87
- currentSpecs = newSpecs;
86
+ const newSpecs = await refreshSpecs(projectRoot)
87
+ currentSpecs = newSpecs
88
88
 
89
89
  // Re-parse socket triggers
90
90
  if (newSpecs.asyncApi) {
91
- currentSocketTriggers = parseSocketTriggers(newSpecs.asyncApi);
91
+ currentSocketTriggers = parseSocketTriggers(newSpecs.asyncApi)
92
92
  }
93
93
 
94
94
  // Update route stats
95
95
  if (newSpecs.openApi) {
96
- routeStats = getRouteStats(newSpecs.openApi);
96
+ routeStats = getRouteStats(newSpecs.openApi)
97
97
  }
98
98
 
99
99
  res.json({
@@ -104,19 +104,19 @@ async function createMockApiRouter(io, options = {}) {
104
104
  asyncApi: !!newSpecs.asyncApi,
105
105
  webhooks: !!newSpecs.webhooks,
106
106
  },
107
- });
107
+ })
108
108
  } catch (error) {
109
- console.error("❌ Failed to refresh specs:", error.message);
109
+ console.error("❌ Failed to refresh specs:", error.message)
110
110
  res.status(500).json({
111
111
  success: false,
112
112
  error: error.message,
113
- });
113
+ })
114
114
  }
115
- });
115
+ })
116
116
 
117
117
  // Image generation endpoints
118
- router.get("/_mock/image/:width/:height", imageHandler);
119
- router.get("/_mock/image/:width", imageHandler); // Square or WxH format
118
+ router.get("/_mock/image/:width/:height", imageHandler)
119
+ router.get("/_mock/image/:width", imageHandler) // Square or WxH format
120
120
 
121
121
  // Info endpoint
122
122
  router.get("/_mock/info", (req, res) => {
@@ -135,43 +135,43 @@ async function createMockApiRouter(io, options = {}) {
135
135
  MOCK_API_DELAY: process.env.MOCK_API_DELAY || "0",
136
136
  MOCK_API_CACHE_TTL: process.env.MOCK_API_CACHE_TTL || "300000",
137
137
  },
138
- });
139
- });
138
+ })
139
+ })
140
140
 
141
141
  // Spec endpoints (for debugging)
142
142
  router.get("/_mock/specs/openapi", (req, res) => {
143
143
  if (currentSpecs?.openApi) {
144
- res.json(currentSpecs.openApi);
144
+ res.json(currentSpecs.openApi)
145
145
  } else {
146
- res.status(404).json({ error: "OpenAPI spec not loaded" });
146
+ res.status(404).json({ error: "OpenAPI spec not loaded" })
147
147
  }
148
- });
148
+ })
149
149
 
150
150
  router.get("/_mock/specs/asyncapi", (req, res) => {
151
151
  if (currentSpecs?.asyncApi) {
152
- res.json(currentSpecs.asyncApi);
152
+ res.json(currentSpecs.asyncApi)
153
153
  } else {
154
- res.status(404).json({ error: "AsyncAPI spec not loaded" });
154
+ res.status(404).json({ error: "AsyncAPI spec not loaded" })
155
155
  }
156
- });
156
+ })
157
157
 
158
158
  router.get("/_mock/specs/webhooks", (req, res) => {
159
159
  if (currentSpecs?.webhooks) {
160
- res.json(currentSpecs.webhooks);
160
+ res.json(currentSpecs.webhooks)
161
161
  } else {
162
- res.status(404).json({ error: "Webhook spec not loaded" });
162
+ res.status(404).json({ error: "Webhook spec not loaded" })
163
163
  }
164
- });
164
+ })
165
165
 
166
- console.log("\n✅ Mock API Server initialized");
167
- console.log(" Status: GET /_mock/status");
168
- console.log(" Refresh: POST /_mock/refresh");
169
- console.log(" Images: GET /_mock/image/:width/:height");
166
+ console.log("\n✅ Mock API Server initialized")
167
+ console.log(" Status: GET /_mock/status")
168
+ console.log(" Refresh: POST /_mock/refresh")
169
+ console.log(" Images: GET /_mock/image/:width/:height")
170
170
  if (routeStats?.total > 0) {
171
- console.log(` API Routes: ${routeStats.total} endpoints under /api/*`);
171
+ console.log(` API Routes: ${routeStats.total} endpoints under /api/*`)
172
172
  }
173
173
 
174
- return router;
174
+ return router
175
175
  }
176
176
 
177
177
  /**
@@ -179,7 +179,7 @@ async function createMockApiRouter(io, options = {}) {
179
179
  * @returns {object} Current specs
180
180
  */
181
181
  function getSpecs() {
182
- return currentSpecs;
182
+ return currentSpecs
183
183
  }
184
184
 
185
185
  /**
@@ -187,11 +187,11 @@ function getSpecs() {
187
187
  * @returns {object} Current socket triggers
188
188
  */
189
189
  function getSocketTriggers() {
190
- return currentSocketTriggers;
190
+ return currentSocketTriggers
191
191
  }
192
192
 
193
193
  module.exports = {
194
194
  createMockApiRouter,
195
195
  getSpecs,
196
196
  getSocketTriggers,
197
- };
197
+ }