@aimeloic/monkey-tester 1.0.7 → 1.0.9
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/htmlTemplate.js +34 -24
- package/index.js +1 -6
- package/package.json +5 -8
package/htmlTemplate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function getHtmlTemplate(endpoints) {
|
|
2
|
-
// Safe stringification for HTML attribute encoding
|
|
2
|
+
// Safe stringification for HTML attribute encoding to prevent script engine parsing breaks
|
|
3
3
|
const safeJsonString = Buffer.from(JSON.stringify(endpoints)).toString('base64');
|
|
4
4
|
|
|
5
5
|
return `
|
|
@@ -149,7 +149,6 @@ function buildSidebar() {
|
|
|
149
149
|
if (keys.length > 0) renderPanel(keys[0]);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
// FIXED: Elements are explicitly assigned attributes to enforce string literal values cleanly
|
|
153
152
|
function makeInputString(type, id, placeholder, defaultValue) {
|
|
154
153
|
const pAttr = placeholder ? ' placeholder="' + placeholder + '"' : '';
|
|
155
154
|
const vAttr = defaultValue !== undefined ? ' value=\'' + defaultValue + '\'' : '';
|
|
@@ -162,39 +161,50 @@ function renderPanel(epKey) {
|
|
|
162
161
|
const main = document.getElementById('main-panel');
|
|
163
162
|
if (!ep) return;
|
|
164
163
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
// FIXED: Escaped template strings (\`) prevent string concatenation mismatch errors
|
|
165
|
+
let html = \`
|
|
166
|
+
<div class="endpoint-title">\${ep.title}</div>
|
|
167
|
+
<div class="endpoint-path">
|
|
168
|
+
<span class="method-badge \${ep.method}">\${ep.method}</span>
|
|
169
|
+
<span>\${ep.path}</span>
|
|
170
|
+
</div>
|
|
171
|
+
<div class="endpoint-desc">\${ep.desc}</div>
|
|
172
|
+
\`;
|
|
171
173
|
|
|
172
174
|
if (ep.params && ep.params.length) {
|
|
173
|
-
html +=
|
|
175
|
+
html += \`<div class="form-section"><div class="form-section-title">Path Parameters</div>\`;
|
|
174
176
|
ep.params.forEach(function(p) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
const inputHtml = makeInputString('text', 'param-' + p.name, p.placeholder, '');
|
|
178
|
+
html += \`
|
|
179
|
+
<div class="field-row">
|
|
180
|
+
<label class="field-label">\${p.label}</label>
|
|
181
|
+
\${inputHtml}
|
|
182
|
+
</div>
|
|
183
|
+
\`;
|
|
179
184
|
});
|
|
180
|
-
html +=
|
|
185
|
+
html += \`</div>\`;
|
|
181
186
|
}
|
|
182
187
|
|
|
183
188
|
if (ep.fields && ep.fields.length) {
|
|
184
|
-
html +=
|
|
189
|
+
html += \`<div class="form-section"><div class="form-section-title">JSON Request Body Raw Payload</div>\`;
|
|
185
190
|
ep.fields.forEach(function(f) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
191
|
+
const inputHtml = makeInputString('text', 'field-' + f.name, '', '{"key": "value"}');
|
|
192
|
+
html += \`
|
|
193
|
+
<div class="field-row">
|
|
194
|
+
<label class="field-label">\${f.label}</label>
|
|
195
|
+
\${inputHtml}
|
|
196
|
+
</div>
|
|
197
|
+
\`;
|
|
190
198
|
});
|
|
191
|
-
html +=
|
|
199
|
+
html += \`</div>\`;
|
|
192
200
|
}
|
|
193
201
|
|
|
194
|
-
html +=
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
html += \`
|
|
203
|
+
<div class="btn-row">
|
|
204
|
+
<button class="btn" onclick="sendRequest()">Execute Route</button>
|
|
205
|
+
<button class="btn btn-secondary" onclick="clearResponse()">Clear Context</button>
|
|
206
|
+
</div>
|
|
207
|
+
\`;
|
|
198
208
|
|
|
199
209
|
main.innerHTML = html;
|
|
200
210
|
}
|
package/index.js
CHANGED
|
@@ -9,17 +9,15 @@ export function endtesterExpress() {
|
|
|
9
9
|
const expressApp = req.app;
|
|
10
10
|
const detectedEndpoints = {};
|
|
11
11
|
|
|
12
|
-
// Recursive function to dig through all layers of Express routes
|
|
13
12
|
function parseStack(stack, prefix = '') {
|
|
14
13
|
if (!stack) return;
|
|
15
14
|
|
|
16
15
|
stack.forEach((layer) => {
|
|
17
16
|
if (layer.route) {
|
|
18
|
-
// It's a direct route (e.g., app.get('/path'))
|
|
19
17
|
const methods = Object.keys(layer.route.methods);
|
|
20
18
|
const path = (prefix + layer.route.path).replace(/\/+/g, '/');
|
|
21
19
|
|
|
22
|
-
if (path.includes('/api/tester')) return;
|
|
20
|
+
if (path.includes('/api/tester')) return;
|
|
23
21
|
|
|
24
22
|
methods.forEach((method) => {
|
|
25
23
|
const httpMethod = method.toUpperCase();
|
|
@@ -42,10 +40,8 @@ export function endtesterExpress() {
|
|
|
42
40
|
};
|
|
43
41
|
});
|
|
44
42
|
} else if (layer.name === 'router' && layer.handle && layer.handle.stack) {
|
|
45
|
-
// It's a router middleware (e.g., app.use('/api', myRouter))
|
|
46
43
|
let routerPath = '';
|
|
47
44
|
if (layer.regexp) {
|
|
48
|
-
// Extract the base path string from the router regex safely
|
|
49
45
|
const match = layer.regexp.toString().match(/^\/\^\\(.*?)\\\/\?/);
|
|
50
46
|
if (match && match[1]) {
|
|
51
47
|
routerPath = match[1].replace(/\\/g, '');
|
|
@@ -56,7 +52,6 @@ export function endtesterExpress() {
|
|
|
56
52
|
});
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
// Fire the scanner on the main app router stack
|
|
60
55
|
if (expressApp._router && expressApp._router.stack) {
|
|
61
56
|
parseStack(expressApp._router.stack);
|
|
62
57
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aimeloic/monkey-tester",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.9",
|
|
4
|
+
"description": "Auto route scanning visual runner dashboard.",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"type":"module",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
},
|
|
10
|
-
"keywords": [],
|
|
11
|
-
"author": "",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"keywords": ["express", "tester", "autodiscover"],
|
|
8
|
+
"author": "aimeloic",
|
|
12
9
|
"license": "ISC"
|
|
13
10
|
}
|