@aimeloic/monkey-tester 1.0.9 → 2.0.0

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 (3) hide show
  1. package/htmlTemplate.js +23 -14
  2. package/index.js +23 -2
  3. package/package.json +1 -1
package/htmlTemplate.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export function getHtmlTemplate(endpoints) {
2
- // Safe stringification for HTML attribute encoding to prevent script engine parsing breaks
3
2
  const safeJsonString = Buffer.from(JSON.stringify(endpoints)).toString('base64');
4
3
 
5
4
  return `
@@ -65,7 +64,8 @@ export function getHtmlTemplate(endpoints) {
65
64
  .field-label { font-family: 'DM Mono', monospace; font-size: 11px; color: var(--text-dim); text-align: right; }
66
65
  input[type=text], input[type=number], select { background: var(--surface2); border: 1px solid var(--border); color: var(--text); font-family: 'DM Mono', monospace; font-size: 12px; padding: 7px 10px; border-radius: var(--radius); width: 100%; outline: none; }
67
66
  .btn { background: var(--accent); color: #0e0c09; border: none; padding: 10px 22px; border-radius: var(--radius); font-size: 13px; font-weight: 500; cursor: pointer; }
68
- .btn-secondary { background: var(--surface2); color: var(--text-dim); border: 1px solid var(--border); margin-left: 8px; }
67
+ .btn-row { margin-top: 20px; display: flex; gap: 10px; }
68
+ .btn-secondary { background: var(--surface2); color: var(--text-dim); border: 1px solid var(--border); }
69
69
  .response-panel { border-left: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; }
70
70
  .response-header { padding: 14px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; background: var(--surface); }
71
71
  .response-header-title { font-size: 11px; font-family: 'DM Mono', monospace; color: var(--text-dim); text-transform: uppercase; }
@@ -151,7 +151,7 @@ function buildSidebar() {
151
151
 
152
152
  function makeInputString(type, id, placeholder, defaultValue) {
153
153
  const pAttr = placeholder ? ' placeholder="' + placeholder + '"' : '';
154
- const vAttr = defaultValue !== undefined ? ' value=\'' + defaultValue + '\'' : '';
154
+ const vAttr = defaultValue !== undefined ? ' value="' + defaultValue + '"' : '';
155
155
  return '<input type="' + type + '" id="' + id + '"' + pAttr + vAttr + ' />';
156
156
  }
157
157
 
@@ -161,7 +161,6 @@ function renderPanel(epKey) {
161
161
  const main = document.getElementById('main-panel');
162
162
  if (!ep) return;
163
163
 
164
- // FIXED: Escaped template strings (\`) prevent string concatenation mismatch errors
165
164
  let html = \`
166
165
  <div class="endpoint-title">\${ep.title}</div>
167
166
  <div class="endpoint-path">
@@ -171,6 +170,7 @@ function renderPanel(epKey) {
171
170
  <div class="endpoint-desc">\${ep.desc}</div>
172
171
  \`;
173
172
 
173
+ // Path Parameters
174
174
  if (ep.params && ep.params.length) {
175
175
  html += \`<div class="form-section"><div class="form-section-title">Path Parameters</div>\`;
176
176
  ep.params.forEach(function(p) {
@@ -185,13 +185,14 @@ function renderPanel(epKey) {
185
185
  html += \`</div>\`;
186
186
  }
187
187
 
188
+ // FIXED: Renders native, individual form fields instead of a single text payload editor block
188
189
  if (ep.fields && ep.fields.length) {
189
- html += \`<div class="form-section"><div class="form-section-title">JSON Request Body Raw Payload</div>\`;
190
+ html += \`<div class="form-section"><div class="form-section-title">HTTP JSON Request Payload Parameters</div>\`;
190
191
  ep.fields.forEach(function(f) {
191
- const inputHtml = makeInputString('text', 'field-' + f.name, '', '{"key": "value"}');
192
+ const inputHtml = makeInputString(f.type || 'text', 'field-' + f.name, f.placeholder || '', '');
192
193
  html += \`
193
194
  <div class="field-row">
194
- <label class="field-label">\${f.label}</label>
195
+ <label class="field-label">\--\${f.label}</label>
195
196
  \${inputHtml}
196
197
  </div>
197
198
  \`;
@@ -213,6 +214,7 @@ async function sendRequest() {
213
214
  const ep = ENDPOINTS[currentEp];
214
215
  let path = ep.path;
215
216
 
217
+ // Compile URL path parameter tags
216
218
  if (ep.params) {
217
219
  for (const p of ep.params) {
218
220
  const val = document.getElementById('param-' + p.name)?.value.trim();
@@ -228,16 +230,23 @@ async function sendRequest() {
228
230
  const jwt = document.getElementById('jwt-input').value.trim();
229
231
  if (jwt) headers['Authorization'] = 'Bearer ' + jwt;
230
232
 
233
+ // FIXED: Dynamically bundles inputs into a background payload object structure seamlessly
231
234
  let body = undefined;
232
235
  if (ep.fields && ep.fields.length && ['POST', 'PUT', 'PATCH'].includes(ep.method)) {
233
- const rawVal = document.getElementById('field-' + ep.fields[0].name).value.trim();
234
- try {
235
- JSON.parse(rawVal);
236
- body = rawVal;
237
- } catch(e) {
238
- showToast('Malformed JSON body structure provided.');
239
- return;
236
+ const payloadObject = {};
237
+
238
+ for (const f of ep.fields) {
239
+ const inputEl = document.getElementById('field-' + f.name);
240
+ if (inputEl) {
241
+ let value = inputEl.value.trim();
242
+ // Cast numerical parameters to prevent type validation parsing failures
243
+ if (f.type === 'number' && value !== '') {
244
+ value = Number(value);
245
+ }
246
+ payloadObject[f.name] = value;
247
+ }
240
248
  }
249
+ body = JSON.stringify(payloadObject);
241
250
  }
242
251
 
243
252
  setResponse(null, 'loading');
package/index.js CHANGED
@@ -29,14 +29,35 @@ export function endtesterExpress() {
29
29
  placeholder: 'value'
30
30
  })) : [];
31
31
 
32
+ // Context-aware field mapping for common endpoints
33
+ let bodyFields = [];
34
+ if (['POST', 'PUT', 'PATCH'].includes(httpMethod)) {
35
+ if (path.toLowerCase().includes('login') || path.toLowerCase().includes('auth')) {
36
+ bodyFields = [
37
+ { name: 'email', label: 'Email Address', type: 'text', placeholder: 'user@example.com' },
38
+ { name: 'password', label: 'Password', type: 'text', placeholder: '••••••••' }
39
+ ];
40
+ } else if (path.toLowerCase().includes('product')) {
41
+ bodyFields = [
42
+ { name: 'name', label: 'Product Name', type: 'text', placeholder: 'Sourdough Loaf' },
43
+ { name: 'price', label: 'Unit Price', type: 'number', placeholder: '5.50' },
44
+ { name: 'stock', label: 'Initial Inventory', type: 'number', placeholder: '10' }
45
+ ];
46
+ } else {
47
+ // Fallback default structure
48
+ bodyFields = [
49
+ { name: 'key', label: 'Property Key', type: 'text', placeholder: 'value' }
50
+ ];
51
+ }
52
+ }
53
+
32
54
  detectedEndpoints[key] = {
33
55
  method: httpMethod,
34
56
  path: path,
35
- auth: false,
36
57
  title: `${httpMethod} ${path}`,
37
58
  desc: `Auto-discovered endpoint: ${path}`,
38
59
  params: pathParams,
39
- fields: ['POST', 'PUT', 'PATCH'].includes(httpMethod) ? [{ name: 'payload', label: 'JSON Body', type: 'text' }] : []
60
+ fields: bodyFields
40
61
  };
41
62
  });
42
63
  } else if (layer.name === 'router' && layer.handle && layer.handle.stack) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aimeloic/monkey-tester",
3
- "version": "1.0.9",
3
+ "version": "2.0.0",
4
4
  "description": "Auto route scanning visual runner dashboard.",
5
5
  "main": "index.js",
6
6
  "type": "module",