@aimeloic/monkey-tester 2.0.6 → 2.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 +8 -2
- package/index.js +2 -1
- package/monkey.js +19 -25
- package/package.json +1 -1
package/htmlTemplate.js
CHANGED
|
@@ -296,14 +296,20 @@ function getHtmlTemplate(endpoints) {
|
|
|
296
296
|
let body = undefined;
|
|
297
297
|
if (['POST', 'PUT', 'PATCH'].includes(ep.method) && ep.fields && ep.fields.length) {
|
|
298
298
|
const payload = {};
|
|
299
|
+
let hasData = false;
|
|
300
|
+
|
|
299
301
|
ep.fields.forEach(function(f) {
|
|
300
302
|
const el = document.getElementById('field-' + f.name);
|
|
301
303
|
if (!el) return;
|
|
302
304
|
let v = el.value.trim();
|
|
303
|
-
if (
|
|
305
|
+
if (v === '') return; // Avoid submitting empty strings for unfilled fields
|
|
306
|
+
|
|
307
|
+
if (f.type === 'number') v = Number(v);
|
|
304
308
|
payload[f.name] = v;
|
|
309
|
+
hasData = true;
|
|
305
310
|
});
|
|
306
|
-
|
|
311
|
+
|
|
312
|
+
if (hasData) body = JSON.stringify(payload);
|
|
307
313
|
}
|
|
308
314
|
|
|
309
315
|
setResponse(null, 'loading');
|
package/index.js
CHANGED
package/monkey.js
CHANGED
|
@@ -41,7 +41,6 @@ function extractBodyFields(handler) {
|
|
|
41
41
|
let m;
|
|
42
42
|
while ((m = destructRe.exec(source)) !== null) {
|
|
43
43
|
m[1].split(',').forEach(part => {
|
|
44
|
-
// handle rename (email: userEmail) and default (name = '')
|
|
45
44
|
const name = part.split(':')[0].split('=')[0].trim();
|
|
46
45
|
if (name && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) && !seen.has(name)) {
|
|
47
46
|
seen.set(name, buildField(name));
|
|
@@ -84,25 +83,22 @@ function fallbackFields(path) {
|
|
|
84
83
|
return [];
|
|
85
84
|
}
|
|
86
85
|
|
|
87
|
-
// ─── Extract router prefix from Express layer
|
|
86
|
+
// ─── Extract router prefix safely from Express layer ─────────────────────────
|
|
88
87
|
function extractRouterPrefix(layer) {
|
|
89
88
|
if (!layer.regexp) return '';
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Fallback: check .regexp property stored by Express (Express 5 style)
|
|
104
|
-
if (layer.regexp && layer.regexp.fast_slash) return '';
|
|
105
|
-
return '';
|
|
89
|
+
if (layer.path) return layer.path; // If explicit paths exist
|
|
90
|
+
|
|
91
|
+
let src = layer.regexp.source;
|
|
92
|
+
|
|
93
|
+
// Strip out boilerplate generated patterns from default express mounting structures
|
|
94
|
+
src = src
|
|
95
|
+
.replace('^\\/', '/')
|
|
96
|
+
.replace('\\/?(?=\\/|$)', '')
|
|
97
|
+
.replace('(?:\\/(?=$))?(?=\\/|$)', '')
|
|
98
|
+
.replace('\\/', '/');
|
|
99
|
+
|
|
100
|
+
const cleanPath = src.split('(?')[0].replace(/\\/g, '');
|
|
101
|
+
return cleanPath === '/' ? '' : cleanPath;
|
|
106
102
|
}
|
|
107
103
|
|
|
108
104
|
// ─── Walk the Express router stack recursively ────────────────────────────────
|
|
@@ -118,7 +114,6 @@ function parseStack(stack, detectedEndpoints, prefix = '') {
|
|
|
118
114
|
|
|
119
115
|
const fullPath = (prefix + rawPath).replace(/\/+/g, '/') || '/';
|
|
120
116
|
|
|
121
|
-
// skip the tester's own route
|
|
122
117
|
if (fullPath.startsWith('/api/tester')) continue;
|
|
123
118
|
|
|
124
119
|
const methods = Object.keys(layer.route.methods || {});
|
|
@@ -127,11 +122,12 @@ function parseStack(stack, detectedEndpoints, prefix = '') {
|
|
|
127
122
|
const httpMethod = method.toUpperCase();
|
|
128
123
|
const key = `${httpMethod}::${fullPath}`;
|
|
129
124
|
|
|
130
|
-
// ── Path params (:id, :slug …)
|
|
125
|
+
// ── Path params (:id, :slug …) safely parsed using matchAll ─────────
|
|
131
126
|
const pathParams = [];
|
|
132
127
|
const paramRe = /:([a-zA-Z_$][a-zA-Z0-9_$]*)/g;
|
|
133
|
-
|
|
134
|
-
|
|
128
|
+
const matches = [...fullPath.matchAll(paramRe)];
|
|
129
|
+
|
|
130
|
+
for (const pm of matches) {
|
|
135
131
|
pathParams.push({
|
|
136
132
|
name: pm[1],
|
|
137
133
|
label: pm[1].charAt(0).toUpperCase() + pm[1].slice(1),
|
|
@@ -146,14 +142,12 @@ function parseStack(stack, detectedEndpoints, prefix = '') {
|
|
|
146
142
|
for (const handler of handlers) {
|
|
147
143
|
bodyFields.push(...extractBodyFields(handler));
|
|
148
144
|
}
|
|
149
|
-
// deduplicate by name
|
|
150
145
|
const seen = new Map();
|
|
151
146
|
bodyFields = bodyFields.filter(f => {
|
|
152
147
|
if (seen.has(f.name)) return false;
|
|
153
148
|
seen.set(f.name, true);
|
|
154
149
|
return true;
|
|
155
150
|
});
|
|
156
|
-
// fallback if extraction produced nothing
|
|
157
151
|
if (bodyFields.length === 0) {
|
|
158
152
|
bodyFields = fallbackFields(fullPath);
|
|
159
153
|
}
|
|
@@ -190,7 +184,7 @@ function endtesterExpress() {
|
|
|
190
184
|
|
|
191
185
|
const rootStack =
|
|
192
186
|
(app._router && app._router.stack) || // Express 4
|
|
193
|
-
(app.router && app.router.stack) || // Express 5
|
|
187
|
+
(app.router && app.router.stack) || // Express 5
|
|
194
188
|
[];
|
|
195
189
|
|
|
196
190
|
parseStack(rootStack, detectedEndpoints);
|