@aimeloic/monkey-tester 1.0.6 → 1.0.8
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 +40 -31
- package/index.js +1 -6
- package/package.json +5 -8
package/htmlTemplate.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export function getHtmlTemplate(endpoints) {
|
|
2
|
+
// Safe stringification for HTML attribute encoding to prevent script engine parsing breaks
|
|
2
3
|
const safeJsonString = Buffer.from(JSON.stringify(endpoints)).toString('base64');
|
|
3
4
|
|
|
4
5
|
return `
|
|
@@ -148,13 +149,10 @@ function buildSidebar() {
|
|
|
148
149
|
if (keys.length > 0) renderPanel(keys[0]);
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
function
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (placeholder) el.placeholder = placeholder;
|
|
156
|
-
if (defaultValue !== undefined) el.value = defaultValue;
|
|
157
|
-
return el.outerHTML;
|
|
152
|
+
function makeInputString(type, id, placeholder, defaultValue) {
|
|
153
|
+
const pAttr = placeholder ? ' placeholder="' + placeholder + '"' : '';
|
|
154
|
+
const vAttr = defaultValue !== undefined ? ' value=\'' + defaultValue + '\'' : '';
|
|
155
|
+
return '<input type="' + type + '" id="' + id + '"' + pAttr + vAttr + ' />';
|
|
158
156
|
}
|
|
159
157
|
|
|
160
158
|
function renderPanel(epKey) {
|
|
@@ -163,39 +161,50 @@ function renderPanel(epKey) {
|
|
|
163
161
|
const main = document.getElementById('main-panel');
|
|
164
162
|
if (!ep) return;
|
|
165
163
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
164
|
+
// Render core elements utilizing un-escaped container tokens safely
|
|
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
|
+
\`;
|
|
172
173
|
|
|
173
174
|
if (ep.params && ep.params.length) {
|
|
174
|
-
html +=
|
|
175
|
+
html += \`<div class="form-section"><div class="form-section-title">Path Parameters</div>\`;
|
|
175
176
|
ep.params.forEach(function(p) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
+
\`;
|
|
180
184
|
});
|
|
181
|
-
html +=
|
|
185
|
+
html += \`</div>\`;
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
if (ep.fields && ep.fields.length) {
|
|
185
|
-
html +=
|
|
189
|
+
html += \`<div class="form-section"><div class="form-section-title">JSON Request Body Raw Payload</div>\`;
|
|
186
190
|
ep.fields.forEach(function(f) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
+
\`;
|
|
191
198
|
});
|
|
192
|
-
html +=
|
|
199
|
+
html += \`</div>\`;
|
|
193
200
|
}
|
|
194
201
|
|
|
195
|
-
html +=
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
+
\`;
|
|
199
208
|
|
|
200
209
|
main.innerHTML = html;
|
|
201
210
|
}
|
|
@@ -212,7 +221,7 @@ async function sendRequest() {
|
|
|
212
221
|
}
|
|
213
222
|
}
|
|
214
223
|
|
|
215
|
-
const baseUrl = document.getElementById('base-url').value.replace(
|
|
224
|
+
const baseUrl = document.getElementById('base-url').value.replace(/[/]+$/, '');
|
|
216
225
|
const url = baseUrl + path;
|
|
217
226
|
const headers = { 'Content-Type': 'application/json' };
|
|
218
227
|
|
|
@@ -274,7 +283,7 @@ function clearResponse() {
|
|
|
274
283
|
|
|
275
284
|
function highlightJson(str) {
|
|
276
285
|
return str
|
|
277
|
-
.replace(/&/g, '&').replace(
|
|
286
|
+
.replace(/&/g, '&').replace(/[<]/g, '<').replace(/[>]/g, '>')
|
|
278
287
|
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function(match) {
|
|
279
288
|
if (/^"/.test(match)) {
|
|
280
289
|
if (/:$/.test(match)) return '<span class="json-key">' + match + '</span>';
|
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.8",
|
|
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
|
}
|