@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 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
- let html = '<div class="endpoint-title">' + ep.title + '</div>' +
166
- '<div class="endpoint-path">' +
167
- ' <span class="method-badge ' + ep.method + '">' + ep.method + '</span>' +
168
- ' <span>' + ep.path + '</span>' +
169
- '</div>' +
170
- '<div class="endpoint-desc">' + ep.desc + '</div>';
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 += '<div class="form-section"><div class="form-section-title">Path Parameters</div>';
175
+ html += \`<div class="form-section"><div class="form-section-title">Path Parameters</div>\`;
174
176
  ep.params.forEach(function(p) {
175
- html += '<div class="field-row">' +
176
- ' <label class="field-label">' + p.label + '</label>' +
177
- makeInputString('text', 'param-' + p.name, p.placeholder, '') +
178
- '</div>';
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 += '</div>';
185
+ html += \`</div>\`;
181
186
  }
182
187
 
183
188
  if (ep.fields && ep.fields.length) {
184
- html += '<div class="form-section"><div class="form-section-title">JSON Request Body Raw Payload</div>';
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
- html += '<div class="field-row">' +
187
- ' <label class="field-label">' + f.label + '</label>' +
188
- makeInputString('text', 'field-' + f.name, '', '{"key": "value"}') +
189
- '</div>';
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 += '</div>';
199
+ html += \`</div>\`;
192
200
  }
193
201
 
194
- html += '<div class="btn-row">' +
195
- ' <button class="btn" onclick="sendRequest()">Execute Route</button>' +
196
- ' <button class="btn btn-secondary" onclick="clearResponse()">Clear Context</button>' +
197
- '</div>';
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; // Skip ourselves
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.7",
4
- "description": "Embedded interactive API testing UI for Node.js backends",
3
+ "version": "1.0.9",
4
+ "description": "Auto route scanning visual runner dashboard.",
5
5
  "main": "index.js",
6
- "type":"module",
7
- "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1"
9
- },
10
- "keywords": [],
11
- "author": "",
6
+ "type": "module",
7
+ "keywords": ["express", "tester", "autodiscover"],
8
+ "author": "aimeloic",
12
9
  "license": "ISC"
13
10
  }