@gxp-dev/tools 2.0.5
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/.github/workflows/npm-publish.yml +48 -0
- package/CLAUDE.md +400 -0
- package/README.md +247 -0
- package/REFACTOR_PLAN.md +194 -0
- package/bin/gx-devtools.js +87 -0
- package/bin/lib/cli.js +251 -0
- package/bin/lib/commands/assets.js +337 -0
- package/bin/lib/commands/build.js +259 -0
- package/bin/lib/commands/datastore.js +433 -0
- package/bin/lib/commands/dev.js +328 -0
- package/bin/lib/commands/extensions.js +298 -0
- package/bin/lib/commands/index.js +35 -0
- package/bin/lib/commands/init.js +307 -0
- package/bin/lib/commands/publish.js +189 -0
- package/bin/lib/commands/socket.js +158 -0
- package/bin/lib/commands/ssl.js +47 -0
- package/bin/lib/constants.js +120 -0
- package/bin/lib/tui/App.tsx +600 -0
- package/bin/lib/tui/components/CommandInput.tsx +278 -0
- package/bin/lib/tui/components/GeminiPanel.tsx +161 -0
- package/bin/lib/tui/components/Header.tsx +27 -0
- package/bin/lib/tui/components/LogPanel.tsx +122 -0
- package/bin/lib/tui/components/TabBar.tsx +56 -0
- package/bin/lib/tui/components/WelcomeScreen.tsx +80 -0
- package/bin/lib/tui/index.tsx +63 -0
- package/bin/lib/tui/services/ExtensionService.ts +122 -0
- package/bin/lib/tui/services/GeminiService.ts +395 -0
- package/bin/lib/tui/services/ServiceManager.ts +336 -0
- package/bin/lib/tui/services/SocketService.ts +204 -0
- package/bin/lib/tui/services/ViteService.ts +107 -0
- package/bin/lib/tui/services/index.ts +13 -0
- package/bin/lib/utils/files.js +180 -0
- package/bin/lib/utils/index.js +17 -0
- package/bin/lib/utils/paths.js +138 -0
- package/bin/lib/utils/prompts.js +71 -0
- package/bin/lib/utils/ssl.js +233 -0
- 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/docs/DOCUSAURUS_IMPORT.md +378 -0
- package/docs/_category_.json +8 -0
- package/docs/app-manifest.md +272 -0
- package/docs/building-for-platform.md +315 -0
- package/docs/dev-tools.md +291 -0
- package/docs/getting-started.md +180 -0
- package/docs/gxp-store.md +305 -0
- package/docs/index.md +44 -0
- package/package.json +77 -0
- 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
- package/tsconfig.tui.json +21 -0
- package/vite.config.js +164 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates placeholder images as SVG (no external dependencies).
|
|
5
|
+
* Supports configurable colors, text overlays, and formats.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generate a random hex color
|
|
10
|
+
* @returns {string} Hex color
|
|
11
|
+
*/
|
|
12
|
+
function randomColor() {
|
|
13
|
+
const colors = [
|
|
14
|
+
"#3498db", // Blue
|
|
15
|
+
"#2ecc71", // Green
|
|
16
|
+
"#e74c3c", // Red
|
|
17
|
+
"#9b59b6", // Purple
|
|
18
|
+
"#f39c12", // Orange
|
|
19
|
+
"#1abc9c", // Teal
|
|
20
|
+
"#34495e", // Dark gray
|
|
21
|
+
"#e91e63", // Pink
|
|
22
|
+
"#00bcd4", // Cyan
|
|
23
|
+
"#ff5722", // Deep orange
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
return colors[Math.floor(Math.random() * colors.length)];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get contrasting text color for a background
|
|
31
|
+
* @param {string} hexColor - Background color
|
|
32
|
+
* @returns {string} Text color (black or white)
|
|
33
|
+
*/
|
|
34
|
+
function getContrastColor(hexColor) {
|
|
35
|
+
// Remove # if present
|
|
36
|
+
const hex = hexColor.replace("#", "");
|
|
37
|
+
|
|
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);
|
|
42
|
+
|
|
43
|
+
// Calculate luminance
|
|
44
|
+
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
45
|
+
|
|
46
|
+
return luminance > 0.5 ? "#000000" : "#ffffff";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validate and parse hex color
|
|
51
|
+
* @param {string} color - Color input
|
|
52
|
+
* @returns {string} Valid hex color
|
|
53
|
+
*/
|
|
54
|
+
function parseColor(color) {
|
|
55
|
+
if (!color) return randomColor();
|
|
56
|
+
|
|
57
|
+
// Remove # if present
|
|
58
|
+
let hex = color.replace("#", "");
|
|
59
|
+
|
|
60
|
+
// Expand 3-digit hex
|
|
61
|
+
if (hex.length === 3) {
|
|
62
|
+
hex = hex
|
|
63
|
+
.split("")
|
|
64
|
+
.map((c) => c + c)
|
|
65
|
+
.join("");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Validate
|
|
69
|
+
if (/^[0-9a-fA-F]{6}$/.test(hex)) {
|
|
70
|
+
return `#${hex}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return randomColor();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generate SVG placeholder image
|
|
78
|
+
* @param {number} width - Image width
|
|
79
|
+
* @param {number} height - Image height
|
|
80
|
+
* @param {object} options - Options
|
|
81
|
+
* @param {string} options.color - Background color
|
|
82
|
+
* @param {string} options.text - Text to display
|
|
83
|
+
* @param {string} options.textColor - Text color (auto if not specified)
|
|
84
|
+
* @param {number} options.fontSize - Font size (auto-calculated if not specified)
|
|
85
|
+
* @returns {string} SVG string
|
|
86
|
+
*/
|
|
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}`;
|
|
91
|
+
|
|
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));
|
|
95
|
+
|
|
96
|
+
// Calculate text position
|
|
97
|
+
const textX = width / 2;
|
|
98
|
+
const textY = height / 2;
|
|
99
|
+
|
|
100
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
101
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
102
|
+
<rect width="100%" height="100%" fill="${bgColor}"/>
|
|
103
|
+
<text
|
|
104
|
+
x="${textX}"
|
|
105
|
+
y="${textY}"
|
|
106
|
+
font-family="Arial, sans-serif"
|
|
107
|
+
font-size="${fontSize}"
|
|
108
|
+
fill="${textColor}"
|
|
109
|
+
text-anchor="middle"
|
|
110
|
+
dominant-baseline="middle"
|
|
111
|
+
>${escapeXml(text)}</text>
|
|
112
|
+
</svg>`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Escape XML special characters
|
|
117
|
+
* @param {string} text - Text to escape
|
|
118
|
+
* @returns {string} Escaped text
|
|
119
|
+
*/
|
|
120
|
+
function escapeXml(text) {
|
|
121
|
+
return text
|
|
122
|
+
.replace(/&/g, "&")
|
|
123
|
+
.replace(/</g, "<")
|
|
124
|
+
.replace(/>/g, ">")
|
|
125
|
+
.replace(/"/g, """)
|
|
126
|
+
.replace(/'/g, "'");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Parse dimension string (e.g., "400x300", "400", "400:300")
|
|
131
|
+
* @param {string} dimStr - Dimension string
|
|
132
|
+
* @returns {object} { width, height }
|
|
133
|
+
*/
|
|
134
|
+
function parseDimensions(dimStr) {
|
|
135
|
+
if (!dimStr) {
|
|
136
|
+
return { width: 400, height: 300 };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Try width x height format
|
|
140
|
+
const match = dimStr.match(/^(\d+)[xĆ:](\d+)$/i);
|
|
141
|
+
if (match) {
|
|
142
|
+
return {
|
|
143
|
+
width: parseInt(match[1], 10),
|
|
144
|
+
height: parseInt(match[2], 10),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Single number = square
|
|
149
|
+
const single = parseInt(dimStr, 10);
|
|
150
|
+
if (!isNaN(single)) {
|
|
151
|
+
return { width: single, height: single };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return { width: 400, height: 300 };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Express route handler for image generation
|
|
159
|
+
* @param {object} req - Express request
|
|
160
|
+
* @param {object} res - Express response
|
|
161
|
+
*/
|
|
162
|
+
function imageHandler(req, res) {
|
|
163
|
+
// Parse dimensions from URL
|
|
164
|
+
const { width: widthParam, height: heightParam } = req.params;
|
|
165
|
+
|
|
166
|
+
let width, height;
|
|
167
|
+
|
|
168
|
+
if (heightParam) {
|
|
169
|
+
// /image/:width/:height format
|
|
170
|
+
width = parseInt(widthParam, 10) || 400;
|
|
171
|
+
height = parseInt(heightParam, 10) || 300;
|
|
172
|
+
} else {
|
|
173
|
+
// /image/:dimensions format (e.g., 400x300)
|
|
174
|
+
const dims = parseDimensions(widthParam);
|
|
175
|
+
width = dims.width;
|
|
176
|
+
height = dims.height;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Clamp dimensions
|
|
180
|
+
width = Math.min(Math.max(width, 1), 4000);
|
|
181
|
+
height = Math.min(Math.max(height, 1), 4000);
|
|
182
|
+
|
|
183
|
+
// Parse options from query string
|
|
184
|
+
const options = {
|
|
185
|
+
color: req.query.color || req.query.bg,
|
|
186
|
+
text: req.query.text,
|
|
187
|
+
textColor: req.query.textColor || req.query.fg,
|
|
188
|
+
fontSize: req.query.fontSize ? parseInt(req.query.fontSize, 10) : undefined,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// Generate SVG
|
|
192
|
+
const svg = generateSvg(width, height, options);
|
|
193
|
+
|
|
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);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Generate a data URL for an image
|
|
202
|
+
* @param {number} width - Image width
|
|
203
|
+
* @param {number} height - Image height
|
|
204
|
+
* @param {object} options - Options
|
|
205
|
+
* @returns {string} Data URL
|
|
206
|
+
*/
|
|
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}`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
module.exports = {
|
|
214
|
+
generateSvg,
|
|
215
|
+
imageHandler,
|
|
216
|
+
parseDimensions,
|
|
217
|
+
parseColor,
|
|
218
|
+
generateDataUrl,
|
|
219
|
+
randomColor,
|
|
220
|
+
getContrastColor,
|
|
221
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock API Server
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for the mock API functionality.
|
|
5
|
+
* Creates an Express router that mounts onto the existing server.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const express = require("express");
|
|
9
|
+
const {
|
|
10
|
+
loadSpecs,
|
|
11
|
+
refreshSpecs,
|
|
12
|
+
getCacheStatus,
|
|
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");
|
|
18
|
+
|
|
19
|
+
// Store state for status endpoint
|
|
20
|
+
let currentSpecs = null;
|
|
21
|
+
let currentSocketTriggers = null;
|
|
22
|
+
let routeStats = null;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create the mock API router
|
|
26
|
+
* @param {object} io - Socket.IO server instance
|
|
27
|
+
* @param {object} options - Options
|
|
28
|
+
* @param {string} options.projectRoot - Project root directory
|
|
29
|
+
* @returns {express.Router} Express router
|
|
30
|
+
*/
|
|
31
|
+
async function createMockApiRouter(io, options = {}) {
|
|
32
|
+
const router = express.Router();
|
|
33
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
34
|
+
|
|
35
|
+
console.log("\nš Initializing Mock API Server...");
|
|
36
|
+
|
|
37
|
+
// Load specs
|
|
38
|
+
const specs = await loadSpecs(projectRoot);
|
|
39
|
+
currentSpecs = specs;
|
|
40
|
+
|
|
41
|
+
// Parse socket triggers from AsyncAPI
|
|
42
|
+
if (specs.asyncApi) {
|
|
43
|
+
currentSocketTriggers = parseSocketTriggers(specs.asyncApi);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Generate routes from OpenAPI
|
|
47
|
+
if (specs.openApi) {
|
|
48
|
+
console.log("\nš Generating mock routes from OpenAPI spec:");
|
|
49
|
+
const apiRouter = generateRoutes(specs.openApi, {
|
|
50
|
+
io,
|
|
51
|
+
socketTriggers: currentSocketTriggers,
|
|
52
|
+
});
|
|
53
|
+
routeStats = getRouteStats(specs.openApi);
|
|
54
|
+
|
|
55
|
+
// Mount API routes under /api
|
|
56
|
+
router.use("/api", apiRouter);
|
|
57
|
+
} else {
|
|
58
|
+
console.log("ā ļø No OpenAPI spec available, mock API routes not generated");
|
|
59
|
+
routeStats = { total: 0, byMethod: {}, paths: [] };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Status endpoint
|
|
63
|
+
router.get("/_mock/status", (req, res) => {
|
|
64
|
+
const cacheStatus = getCacheStatus();
|
|
65
|
+
const triggerStats = getTriggerStats(currentSocketTriggers);
|
|
66
|
+
|
|
67
|
+
res.json({
|
|
68
|
+
enabled: true,
|
|
69
|
+
environment: process.env.API_ENV || "production",
|
|
70
|
+
specs: {
|
|
71
|
+
openApi: !!currentSpecs?.openApi,
|
|
72
|
+
asyncApi: !!currentSpecs?.asyncApi,
|
|
73
|
+
webhooks: !!currentSpecs?.webhooks,
|
|
74
|
+
},
|
|
75
|
+
routes: routeStats,
|
|
76
|
+
socketTriggers: triggerStats,
|
|
77
|
+
cache: cacheStatus,
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Refresh endpoint
|
|
82
|
+
router.post("/_mock/refresh", async (req, res) => {
|
|
83
|
+
console.log("\nš Refreshing mock API specs...");
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const newSpecs = await refreshSpecs(projectRoot);
|
|
87
|
+
currentSpecs = newSpecs;
|
|
88
|
+
|
|
89
|
+
// Re-parse socket triggers
|
|
90
|
+
if (newSpecs.asyncApi) {
|
|
91
|
+
currentSocketTriggers = parseSocketTriggers(newSpecs.asyncApi);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Update route stats
|
|
95
|
+
if (newSpecs.openApi) {
|
|
96
|
+
routeStats = getRouteStats(newSpecs.openApi);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
res.json({
|
|
100
|
+
success: true,
|
|
101
|
+
message: "Specs refreshed successfully",
|
|
102
|
+
specs: {
|
|
103
|
+
openApi: !!newSpecs.openApi,
|
|
104
|
+
asyncApi: !!newSpecs.asyncApi,
|
|
105
|
+
webhooks: !!newSpecs.webhooks,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error("ā Failed to refresh specs:", error.message);
|
|
110
|
+
res.status(500).json({
|
|
111
|
+
success: false,
|
|
112
|
+
error: error.message,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Image generation endpoints
|
|
118
|
+
router.get("/_mock/image/:width/:height", imageHandler);
|
|
119
|
+
router.get("/_mock/image/:width", imageHandler); // Square or WxH format
|
|
120
|
+
|
|
121
|
+
// Info endpoint
|
|
122
|
+
router.get("/_mock/info", (req, res) => {
|
|
123
|
+
res.json({
|
|
124
|
+
name: "GxP Toolkit Mock API",
|
|
125
|
+
version: "1.0.0",
|
|
126
|
+
description: "Mock API server based on OpenAPI/AsyncAPI specs",
|
|
127
|
+
endpoints: {
|
|
128
|
+
status: "GET /_mock/status",
|
|
129
|
+
refresh: "POST /_mock/refresh",
|
|
130
|
+
image: "GET /_mock/image/:width/:height",
|
|
131
|
+
api: "* /api/*",
|
|
132
|
+
},
|
|
133
|
+
configuration: {
|
|
134
|
+
API_ENV: process.env.API_ENV || "production",
|
|
135
|
+
MOCK_API_DELAY: process.env.MOCK_API_DELAY || "0",
|
|
136
|
+
MOCK_API_CACHE_TTL: process.env.MOCK_API_CACHE_TTL || "300000",
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Spec endpoints (for debugging)
|
|
142
|
+
router.get("/_mock/specs/openapi", (req, res) => {
|
|
143
|
+
if (currentSpecs?.openApi) {
|
|
144
|
+
res.json(currentSpecs.openApi);
|
|
145
|
+
} else {
|
|
146
|
+
res.status(404).json({ error: "OpenAPI spec not loaded" });
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
router.get("/_mock/specs/asyncapi", (req, res) => {
|
|
151
|
+
if (currentSpecs?.asyncApi) {
|
|
152
|
+
res.json(currentSpecs.asyncApi);
|
|
153
|
+
} else {
|
|
154
|
+
res.status(404).json({ error: "AsyncAPI spec not loaded" });
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
router.get("/_mock/specs/webhooks", (req, res) => {
|
|
159
|
+
if (currentSpecs?.webhooks) {
|
|
160
|
+
res.json(currentSpecs.webhooks);
|
|
161
|
+
} else {
|
|
162
|
+
res.status(404).json({ error: "Webhook spec not loaded" });
|
|
163
|
+
}
|
|
164
|
+
});
|
|
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");
|
|
170
|
+
if (routeStats?.total > 0) {
|
|
171
|
+
console.log(` API Routes: ${routeStats.total} endpoints under /api/*`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return router;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Get current specs (for external access)
|
|
179
|
+
* @returns {object} Current specs
|
|
180
|
+
*/
|
|
181
|
+
function getSpecs() {
|
|
182
|
+
return currentSpecs;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get current socket triggers (for external access)
|
|
187
|
+
* @returns {object} Current socket triggers
|
|
188
|
+
*/
|
|
189
|
+
function getSocketTriggers() {
|
|
190
|
+
return currentSocketTriggers;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
module.exports = {
|
|
194
|
+
createMockApiRouter,
|
|
195
|
+
getSpecs,
|
|
196
|
+
getSocketTriggers,
|
|
197
|
+
};
|