@aimeloic/monkey-tester 4.0.5 → 4.0.6

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 (2) hide show
  1. package/htmlTemplate.js +11 -21
  2. package/package.json +1 -1
package/htmlTemplate.js CHANGED
@@ -1,13 +1,11 @@
1
1
  'use strict';
2
2
 
3
- // Original Sandbox Runtime — Stringified safely to browser context
4
3
  function runtimeClientSandbox() {
5
4
  const ENDPOINTS = JSON.parse(atob(document.getElementById('__monkey_data__').getAttribute('data-payload')));
6
5
  let currentKey = null;
7
6
 
8
7
  document.getElementById('base-url').value = window.location.origin;
9
8
 
10
- // Auto-paste Token directly if it exists in local storage
11
9
  const savedToken = localStorage.getItem('__auth_token__');
12
10
  if (savedToken) {
13
11
  document.getElementById('jwt-input').value = savedToken;
@@ -151,7 +149,6 @@ function runtimeClientSandbox() {
151
149
  buildSidebar();
152
150
  }
153
151
 
154
- // Global UI layouts object
155
152
  const UI = {
156
153
  tester: (endpointsJsonB64) => `<!DOCTYPE html>
157
154
  <html lang="en">
@@ -232,8 +229,8 @@ const UI = {
232
229
  button { background: #e8a838; color: #0e0c09; border: none; padding: 12px; width: 100%; border-radius: 6px; font-weight: 600; cursor: pointer; margin-top: 10px; }
233
230
  .footer { text-align: center; margin-top: 20px; font-size: 13px; color: #9a8c78; } a { color: #e8a838; text-decoration: none; }</style></head>
234
231
  <body><div class="card"><h2>Sign In</h2><div id="err" style="color:#d45c3c; font-size:13px; margin-bottom:15px; text-align:center;"></div>
235
- <div class="field"><label>Email</label><input type="email" id="email" value="customer@bakery.com"></div>
236
- <div class="field"><label>Password</label><input type="password" id="password" value="secret123"></div>
232
+ <div class="field"><label>Email</label><input type="email" id="email" value="admin@bakery.com"></div>
233
+ <div class="field"><label>Password</label><input type="password" id="password" value="password123"></div>
237
234
  <button onclick="handleLogin()">Log In</button><div class="footer">Need an account? <a href="/signup">Sign up</a></div></div>
238
235
  <script>async function handleLogin() {
239
236
  const email = document.getElementById('email').value;
@@ -271,7 +268,6 @@ const UI = {
271
268
  } else { msgDiv.style.color = '#d45c3c'; msgDiv.textContent = data.error || 'Registration failed'; }
272
269
  }</script></body></html>`,
273
270
 
274
- // DYNAMIC CRUD DASHBOARD — Reads fields and paths from runtime ENDPOINTS definition instead of static products paths
275
271
  dashboard: (endpointsJsonB64) => `<!DOCTYPE html><html><head><title>Dynamic Admin Dashboard</title>
276
272
  <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap" rel="stylesheet">
277
273
  <style>
@@ -306,7 +302,7 @@ const UI = {
306
302
  <body>
307
303
  <div id="__monkey_data__" data-payload="${endpointsJsonB64}" style="display:none;"></div>
308
304
  <header>
309
- <h1>🐒 Universal Management Dashboard</h1>
305
+ <h1>Universal Management Dashboard</h1>
310
306
  <div class="nav-links">
311
307
  <a href="/api/tester" target="_blank">🛠 Open Tester Sandbox</a>
312
308
  <button class="logout-btn" onclick="localStorage.removeItem('__auth_token__'); window.location.href='/login'">Log Out</button>
@@ -343,10 +339,8 @@ const UI = {
343
339
  let activeCollectionPath = '';
344
340
  let activeEditId = null;
345
341
 
346
- // Group discovery metadata into unified conceptual resource targets
347
342
  function resolveRoutes() {
348
343
  Object.values(ENDPOINTS).forEach(ep => {
349
- // Identify root paths that are collection containers (e.g., /api/v1/products, /api/v1/users)
350
344
  if (!ep.path.includes(':')) {
351
345
  if (!dynamicCollections[ep.path]) {
352
346
  dynamicCollections[ep.path] = { get: null, post: null, put: null, del: null, modelFields: ep.fields || [] };
@@ -357,7 +351,6 @@ const UI = {
357
351
  if (ep.fields && ep.fields.length) dynamicCollections[ep.path].modelFields = ep.fields;
358
352
  }
359
353
  } else {
360
- // Match corresponding parameterized items to complete the sub-resource route setup (e.g., /api/v1/products/:id)
361
354
  const basePath = ep.path.split('/:')[0];
362
355
  if (!dynamicCollections[basePath]) {
363
356
  dynamicCollections[basePath] = { get: null, post: null, put: null, del: null, modelFields: [] };
@@ -367,7 +360,6 @@ const UI = {
367
360
  }
368
361
  });
369
362
 
370
- // Clean out incomplete route profiles from selector options
371
363
  const selector = document.getElementById('route-selector');
372
364
  Object.keys(dynamicCollections).forEach(path => {
373
365
  if (dynamicCollections[path].get) {
@@ -397,7 +389,7 @@ const UI = {
397
389
  const fields = dynamicCollections[activeCollectionPath].modelFields;
398
390
 
399
391
  if (!fields || fields.length === 0) {
400
- container.innerHTML = '<p style="font-size:12px; color:var(--text-dim);">No input properties found for this resource schema.</p>';
392
+ container.innerHTML = '<p style="font-size:12px; color:var(--text-dim);">No input properties found.</p>';
401
393
  return;
402
394
  }
403
395
 
@@ -415,16 +407,17 @@ const UI = {
415
407
  const head = document.getElementById('table-head');
416
408
  const body = document.getElementById('table-body');
417
409
  head.innerHTML = '';
418
- body.innerHTML = '<tr><td style="padding:20px; color:var(--text-dim)">Loading live system schemas...</td></tr>';
410
+ body.innerHTML = '<tr><td style="padding:20px; color:var(--text-dim)">Loading layout schemas...</td></tr>';
419
411
 
420
412
  try {
421
413
  const res = await fetch(activeCollectionPath, { headers: { 'Authorization': 'Bearer ' + token } });
422
414
  const rawData = await res.json();
423
415
 
424
- // Flatten standard array wrapping logic safely
425
416
  let list = [];
426
- if (Array.isArray(rawData)) list = rawData;
427
- else if (rawData && typeof rawData === 'object') {
417
+ if (Array.isArray(rawData)) {
418
+ list = rawData;
419
+ } else if (rawData && typeof rawData === 'object') {
420
+ // UNIFIED RESPONSE FLATTENER: Extracts arrays even if nested inside object counts
428
421
  const arrayKey = Object.keys(rawData).find(k => Array.isArray(rawData[k]));
429
422
  list = arrayKey ? rawData[arrayKey] : [rawData];
430
423
  }
@@ -434,16 +427,13 @@ const UI = {
434
427
  return;
435
428
  }
436
429
 
437
- // Gather unique keys from database entities dynamically
438
430
  let keys = Object.keys(list[0]).filter(k => typeof list[0][k] !== 'object');
439
431
 
440
- // Generate headers
441
432
  let trHead = '<tr>';
442
433
  keys.forEach(k => trHead += \`<th>\${k}</th>\`);
443
434
  trHead += '<th style="text-align:right; padding-right:20px;">Actions</th></tr>';
444
435
  head.innerHTML = trHead;
445
436
 
446
- // Populate row fields
447
437
  body.innerHTML = '';
448
438
  list.forEach(row => {
449
439
  let trBody = '<tr>';
@@ -496,7 +486,7 @@ const UI = {
496
486
  body: JSON.stringify(payload)
497
487
  });
498
488
 
499
- if (res.ok) { resetDataForm(); fetchData(); } else { alert('Submission declined by target stack route operations.'); }
489
+ if (res.ok) { resetDataForm(); fetchData(); } else { alert('Submission declined.'); }
500
490
  }
501
491
 
502
492
  async function deleteRow(id) {
@@ -506,7 +496,7 @@ const UI = {
506
496
  const url = delTemplate.replace(\`:\${paramName}\`, id);
507
497
 
508
498
  const res = await fetch(url, { method: 'DELETE', headers: { 'Authorization': 'Bearer ' + token } });
509
- if (res.ok) fetchData(); else alert('Delete request blocked by resource server.');
499
+ if (res.ok) fetchData(); else alert('Delete request blocked.');
510
500
  }
511
501
 
512
502
  function startRowEdit(id, encodedJson) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aimeloic/monkey-tester",
3
- "version": "4.0.5",
3
+ "version": "4.0.6",
4
4
  "description": "Auto route scanning visual runner dashboard.",
5
5
  "main": "index.js",
6
6
  "type": "module",