web_plsql 1.7.0 → 1.7.1

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.
@@ -144,4 +144,4 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
144
144
  <td class="text-right font-mono">${r}</td>
145
145
  </tr>
146
146
  `}).join(``)}catch(e){console.error(`Failed to load stats history:`,e),t&&(t.textContent=`Failed to load stats`)}}async function AC(){let e=document.getElementById(`access-filter`),t=document.getElementById(`access-limit`),n=e?.value??``,r=t?Number.parseInt(t.value):100,i=await Qp.getAccessLogs(r,n),a=document.getElementById(`access-log-view`),o=document.getElementById(`access-log-range`);if(!a)return;let s=0;Array.isArray(i)?(a.textContent=i.join(`
147
- `),s=i.length):i&&typeof i==`object`&&`message`in i?(a.textContent=i.message,s=0):(a.textContent=`No logs available`,s=0),o&&(o.textContent=s>0?`Showing last ${s} log entries`:`No logs available`),a.parentElement&&(a.parentElement.scrollTop=a.parentElement.scrollHeight)}async function jC(){let e=document.getElementById(`trace-filter`),t=document.getElementById(`trace-limit`),n=document.getElementById(`trace-status-toggle`),r=e?.value??``,i=t?Number.parseInt(t.value):100;try{let{enabled:e}=await Qp.getTraceStatus();n&&(n.textContent=e?`Tracing: ON`:`Tracing: OFF`,n.dataset.enabled=String(e),n.className=`px-4 py-2 rounded-lg text-sm font-bold transition-colors ${e?`bg-success text-black hover:bg-success/80`:`bg-white/10 text-white hover:bg-white/20`}`)}catch(e){console.error(`Failed to get trace status`,e)}let a=await Qp.getTraceLogs(i,r);new DC(`trace-table`,{columns:[{id:`timestamp`,header:`Timestamp`,headerTitle:`Time of request`,width:`1%`,accessor:e=>new Date(e.timestamp).toLocaleString(),className:`font-mono text-xs text-dim whitespace-nowrap`},{id:`source`,header:`Source`,headerTitle:`Request source (IP/User)`,width:`1%`,accessor:e=>e.source,className:`text-dim text-xs truncate max-w-[150px]`,cellTitle:e=>e.source},{id:`method`,header:`Method`,headerTitle:`HTTP Method`,width:`1%`,accessor:e=>e.method,className:`font-mono text-xs whitespace-nowrap`},{id:`url`,header:`Request URL`,headerTitle:`Request URL`,accessor:e=>e.url,className:`text-bright font-mono text-xs truncate max-w-[800px]`,cellTitle:e=>e.url},{id:`status`,header:`Status`,headerTitle:`HTTP Status Code`,width:`1%`,accessor:e=>e.status,className:e=>`font-bold text-xs uppercase whitespace-nowrap ${e.status===`success`?`text-success`:`text-danger`}`},{id:`duration`,header:`Duration`,headerTitle:`Execution time in ms`,width:`1%`,align:`right`,accessor:e=>gC(e.duration),className:`font-mono text-xs text-dim whitespace-nowrap`}],dense:!0,tableLayout:`auto`,onRowClick:e=>{let t=document.getElementById(`trace-modal`),n=document.getElementById(`trace-detail-content`);t&&n&&(n.textContent=JSON.stringify(e,null,2),t.style.display=`flex`)}}).render(a)}function MC(e){let t=document.getElementById(`pools-container`);!t||!e.pools||(t.innerHTML=e.pools.map(e=>SC(e)).join(``))}function NC(e){let t=e.status.config;if(!t)return;let n=document.getElementById(`config-view`);n&&(n.innerHTML=EC(t))}function PC(e){if(e===0)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return`${Number.parseFloat((e/t**+r).toFixed(2))} ${n[r]}`}function FC(e){return gC(e/1e3)}function IC(e,t){let n=document.getElementById(`middleware-version`);n&&e.version&&(n.textContent=`${e.version} (4/8/2026, 11:51:20 AM)`,n.title=`The version of the web_plsql gateway and admin console build time`);let r=document.getElementById(`node-version`);r&&e.system&&(r.textContent=e.system.nodeVersion,r.title=`The version of the Node.js runtime`);let i=document.getElementById(`platform-info`);i&&e.system&&(i.textContent=`${e.system.platform} (${e.system.arch})`,i.title=`The operating system and architecture`);let a=document.getElementById(`system-uptime`);a&&e.uptime&&(a.textContent=hC(e.uptime));let o=document.getElementById(`system-start-time`);o&&e.startTime&&(o.textContent=_C(e.startTime));let s=document.getElementById(`system-status-text`);s&&(s.textContent=e.status?.toUpperCase()??`-`);let c=document.getElementById(`total-requests`);c&&e.metrics&&(c.textContent=e.metrics.requestCount.toLocaleString(),c.title=`Cumulative number of requests handled by the server`);let l=document.getElementById(`total-errors`);l&&e.metrics&&(l.textContent=e.metrics.errorCount.toLocaleString(),l.title=`Cumulative number of failed requests`);let u=document.getElementById(`active-pools`);if(u&&e.pools&&(u.textContent=e.pools.length.toString(),u.title=`Number of database connection pools currently active`),e.system){let t=e.system,n={heapUsed:t.memory.heapUsed,heapTotal:t.memory.heapTotal,rss:t.memory.rss,external:t.memory.external,cpuUser:t.cpu.user,cpuSystem:t.cpu.system},r=(e,r,i)=>{let a=n[r],o=t.memory[i],s=document.getElementById(e),c=document.getElementById(`${e}-max`);s&&(s.textContent=PC(a)),c&&typeof o==`number`&&(c.textContent=PC(o))},i=(e,r,i)=>{let a=n[r],o=document.getElementById(e);if(o&&(o.textContent=FC(a)),i){let n=t.cpu[i],r=document.getElementById(`${e}-max`);r&&typeof n==`number`&&(r.textContent=FC(n))}};r(`memory-heap-used`,`heapUsed`,`heapUsedMax`),r(`memory-heap-total`,`heapTotal`,`heapTotalMax`),r(`memory-rss`,`rss`,`rssMax`),r(`memory-external`,`external`,`externalMax`),i(`cpu-user`,`cpuUser`,`userMax`),i(`cpu-system`,`cpuSystem`,`systemMax`);let a=document.getElementById(`cpu-percent`);a&&t.cpu.max!==void 0&&(a.textContent=`${t.cpu.max.toFixed(1)}%`,a.title=`Max System CPU usage`);let o=document.getElementById(`memory-percent`);o&&t.memory.totalMemory&&(o.textContent=`${(t.memory.rss/t.memory.totalMemory*100).toFixed(1)}%`,o.title=`System Memory Used relative to Total (${PC(t.memory.totalMemory)})`);let s=document.getElementById(`cpu-cores-info`);s&&t.cpuCores&&(s.textContent=`${t.cpuCores} Cores`)}}async function LC(e,t){let n=e.querySelector(`.material-symbols-rounded`),r=n?.textContent;e.disabled=!0,e.classList.add(`loading`),n&&(n.textContent=`sync`,n.classList.add(`animate-spin`));try{return await t()}finally{e.disabled=!1,e.classList.remove(`loading`),n&&(n.textContent=r??``,n.classList.remove(`animate-spin`))}}function RC(e,t){let n=document.getElementById(e);return n&&n.addEventListener(`click`,()=>void LC(n,t)),n}var zC={overview:`dashboard`,trace:`bolt`,errors:`error`,access:`list_alt`,pools:`database`,stats:`query_stats`,config:`settings`,system:`terminal`},$={currentView:`overview`,status:{},maxHistoryPoints:30,lastRequestCount:0,lastErrorCount:0,lastUpdateTime:Date.now(),lastBucketTimestamp:0,nextRefreshTimeout:null,nextRefreshTime:0,countdownInterval:null,history:{labels:[],requests:[],avgResponseTimes:[],p95ResponseTimes:[],p99ResponseTimes:[],cpuUsage:[],memoryUsage:[],poolUsage:{}},charts:{},metricsMin:{},metricsMax:{}},BC={REFRESH_INTERVAL:`admin_refresh_interval`,HISTORY_DURATION:`admin_history_duration`,AUTO_REFRESH:`admin_auto_refresh`,THEME:`theme`,LAST_VIEW:`admin_last_view`};function VC(e){console.error(`Connection lost:`,e);let t=document.getElementById(`server-status-dot`),n=document.getElementById(`server-status-text`);t&&(t.className=`dot offline`),n&&(n.textContent=`OFFLINE`);let r=document.getElementById(`btn-pause`);r&&(r.style.display=`none`);let i=document.getElementById(`btn-resume`);i&&(i.style.display=`none`);let a=document.querySelector(`#system-status .dot`),o=document.getElementById(`system-status-text`);a&&(a.className=`dot offline`),o&&(o.textContent=`OFFLINE`);let s=document.getElementById(`offline-modal`);s&&s.style.display!==`flex`&&(s.style.display=`flex`),GC(6e4),HC(6e4)}function HC(e){$.countdownInterval&&clearInterval($.countdownInterval);let t=Date.now()+e,n=document.getElementById(`offline-countdown`),r=document.getElementById(`reconnect-text`);r&&(r.textContent=`Try Reconnect`);let i=()=>{if(!n)return;let e=Math.max(0,Math.ceil((t-Date.now())/1e3));n.textContent=`Retrying in ${e}s...`,e<=0&&$.countdownInterval&&(clearInterval($.countdownInterval),$.countdownInterval=null)};i(),$.countdownInterval=setInterval(i,1e3)}function UC(){$.countdownInterval&&=(clearInterval($.countdownInterval),null);let e=document.getElementById(`offline-countdown`);e&&(e.textContent=``)}async function WC(e=!1,t=!1){let n=document.getElementById(`reconnect-spinner`),r=document.getElementById(`reconnect-icon`),i=document.getElementById(`reconnect-text`);n&&(n.style.display=`inline-block`),r&&(r.style.display=`none`),i&&(i.textContent=`Connecting...`);try{let a=Date.now(),o=await Qp.getStatus(e,t),s=document.getElementById(`offline-modal`);if(s?.style.display===`flex`&&s&&(s.style.display=`none`,UC()),n&&(n.style.display=`none`),r&&(r.style.display=`inline-block`),i&&(i.textContent=`Try Reconnect`),o.history&&$.history.labels.length===0&&pC($,o.history),!o.config&&$.status.config&&(o.config=$.status.config),$.status=o,!o.metrics||!o.pools)return;let c=o.history?.at(-1),l=(o.intervalMs??5e3)/1e3,u=c?c.requests/l:0,d=c?c.durationAvg:o.metrics.avgResponseTime;if($.lastRequestCount=o.metrics.requestCount,$.lastErrorCount=o.metrics.errorCount,$.lastUpdateTime=a,o.system){let e=o.system;vC({heapUsed:e.memory.heapUsed,heapTotal:e.memory.heapTotal,rss:e.memory.rss,external:e.memory.external,cpuUser:e.cpu.user,cpuSystem:e.cpu.system},$.metricsMin,$.metricsMax)}c&&c.timestamp>$.lastBucketTimestamp?($.lastBucketTimestamp=c.timestamp,mC($,new Date(c.timestamp).toLocaleTimeString(),u,d,o.pools)):!c&&$.history.labels.length===0&&mC($,new Date().toLocaleTimeString(),0,0,o.pools);let f=document.getElementById(`sidebar-version`);f&&(f.textContent=`v${o.version}`);let p=document.getElementById(`uptime-val`);p&&(p.textContent=hC(o.uptime));let m=document.getElementById(`start-time-val`);m&&(m.textContent=`Started: ${_C(o.startTime)}`);let h=document.getElementById(`req-per-sec`);h&&(h.textContent=u.toFixed(2));let g=document.getElementById(`max-req-per-sec`);g&&(g.textContent=o.metrics.maxRequestsPerSecond.toFixed(2));let _=document.getElementById(`avg-resp-time`);_&&(_.textContent=`${o.metrics.avgResponseTime.toFixed(1)}ms`);let v=document.getElementById(`max-resp-time`);v&&(v.textContent=`${o.metrics.maxResponseTime.toFixed(1)}ms`);let y=document.getElementById(`err-count`);y&&(y.textContent=o.metrics.errorCount.toLocaleString());let b=0,x=0;o.pools.forEach(e=>{e.cache&&(b+=e.cache.procedureName.hits+e.cache.argument.hits,x+=e.cache.procedureName.misses+e.cache.argument.misses)});let S=b+x,C=S>0?Math.round(b/S*100):0,w=document.getElementById(`cache-hit-rate-val`);w&&(w.textContent=`${C}%`,w.style.color=C>80?`var(--success)`:C>50?`var(--warning)`:`var(--danger)`);let T=document.getElementById(`cache-hits-val`);T&&(T.textContent=b.toLocaleString());let E=document.getElementById(`cache-misses-val`);E&&(E.textContent=x.toLocaleString());let ee=document.getElementById(`server-status-dot`),te=document.getElementById(`server-status-text`);ee&&(ee.className=`dot `+o.status),te&&(te.textContent=o.status.toUpperCase());let ne=document.getElementById(`btn-pause`);ne&&(ne.style.display=o.status===`running`?`flex`:`none`);let re=document.getElementById(`btn-resume`);re&&(re.style.display=o.status===`paused`?`flex`:`none`),$.currentView===`errors`&&await OC(),$.currentView===`trace`&&await jC(),$.currentView===`pools`&&MC(o),$.currentView===`config`&&NC($),$.currentView===`system`&&IC(o,$),YC?.checked&&XC&&GC(Number.parseInt(XC.value,10))}catch(e){document.getElementById(`offline-modal`)?.style.display===`flex`?(GC(6e4),HC(6e4),n&&(n.style.display=`none`),r&&(r.style.display=`inline-block`),i&&(i.textContent=`Try Reconnect`)):VC(e)}}function GC(e){$.nextRefreshTimeout&&=(clearTimeout($.nextRefreshTimeout),null),$.nextRefreshTime=Date.now()+e,$.nextRefreshTimeout=setTimeout(()=>{WC()},e)}function KC(){let e=document.getElementById(`refresh-interval`);e&&GC(Number.parseInt(e.value))}function qC(){$.nextRefreshTimeout&&=(clearTimeout($.nextRefreshTimeout),null)}function JC(){let e=document.getElementById(`chart-history-points`);e&&Array.from(e.options).forEach(e=>{let t=Number.parseInt(e.value),n=``;if(t<60)n=`${t}s`;else if(t<3600)n=`${Math.round(t/60)} min`;else{let e=t/3600;n=e===Math.round(e)?`${e} hour${e>1?`s`:``}`:`${e.toFixed(1)} hours`}e.textContent=`Last ${n}`})}document.querySelectorAll(`nav button`).forEach(e=>{let t=e;t.addEventListener(`click`,async()=>{try{let e=t.dataset.view;if(!e)return;$.currentView=e,localStorage.setItem(BC.LAST_VIEW,e),document.querySelectorAll(`.view`).forEach(e=>{let t=e;t.style.display=`none`});let n=document.getElementById(`view-`+e);n&&(n.style.display=`block`),document.querySelectorAll(`nav button`).forEach(e=>e.classList.remove(`active`)),t.classList.add(`active`);let r=document.getElementById(`view-title`);if(r){let n=Array.from(t.childNodes).filter(e=>e.nodeType===Node.TEXT_NODE).map(e=>e.textContent?.trim()).join(``);r.innerHTML=`<span class="material-symbols-rounded">${zC[e]??`chevron_right`}</span>${n}`}e===`errors`&&await OC(),e===`trace`&&await jC(),e===`pools`&&MC($.status),e===`stats`&&await kC(),e===`config`&&NC($),e===`system`&&IC($.status,$)}catch(e){VC(e)}})});var YC=document.getElementById(`auto-refresh-toggle`);YC&&YC.addEventListener(`change`,e=>{let t=e.target;localStorage.setItem(BC.AUTO_REFRESH,String(t.checked)),t.checked?KC():qC()});var XC=document.getElementById(`refresh-interval`);XC&&XC.addEventListener(`change`,()=>{localStorage.setItem(BC.REFRESH_INTERVAL,XC.value);let e=Number.parseInt(XC.value),t=Number.parseInt(ZC?.value??`60`);$.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3))),$.history.labels=[],$.history.requests=[],$.history.avgResponseTimes=[],$.history.cpuUsage=[],$.history.memoryUsage=[],$.history.poolUsage={},JC(),IC($.status,$),WC()});var ZC=document.getElementById(`chart-history-points`);ZC&&ZC.addEventListener(`change`,()=>{localStorage.setItem(BC.HISTORY_DURATION,ZC.value);let e=document.getElementById(`refresh-interval`);if(!e)return;let t=Number.parseInt(e.value),n=Number.parseInt(ZC.value);$.maxHistoryPoints=Math.max(1,Math.floor(n/(t/1e3))),$.history.labels=[],$.history.requests=[],$.history.avgResponseTimes=[],$.history.cpuUsage=[],$.history.memoryUsage=[],$.history.poolUsage={},WC()});var QC=document.getElementById(`manual-refresh`);QC&&QC.addEventListener(`click`,()=>{LC(QC,WC)});var $C=document.getElementById(`error-filter`);$C&&$C.addEventListener(`keydown`,e=>{e.key===`Enter`&&OC()}),RC(`error-load-btn`,OC),RC(`trace-load-btn`,jC),RC(`access-load-btn`,AC),RC(`stats-load-btn`,kC);var ew=document.getElementById(`trace-filter`);ew&&ew.addEventListener(`keydown`,e=>{e.key===`Enter`&&jC()});var tw=document.getElementById(`trace-clear-btn`);tw&&tw.addEventListener(`click`,async()=>{confirm(`Are you sure you want to clear all traces?`)&&await LC(tw,async()=>{await Qp.clearTraces(),await jC()})});var nw=document.getElementById(`trace-status-toggle`);nw&&nw.addEventListener(`click`,async()=>{await LC(nw,async()=>{let{enabled:e}=await Qp.getTraceStatus();await Qp.toggleTrace(!e),await jC()})});var rw=document.getElementById(`access-filter`);rw&&rw.addEventListener(`keydown`,e=>{e.key===`Enter`&&AC()});var iw=document.getElementById(`stats-limit`);iw&&iw.addEventListener(`keydown`,e=>{e.key===`Enter`&&kC()}),RC(`btn-pause`,async()=>{confirm(`Are you sure you want to pause the server?`)&&(await Qp.post(`api/server/pause`),await WC())}),RC(`btn-resume`,async()=>{await Qp.post(`api/server/resume`),await WC()}),RC(`btn-stop`,async()=>{confirm(`Are you sure you want to STOP the server? This action cannot be undone from the web interface.`)&&(await Qp.post(`api/server/stop`),alert(`Server stop requested. The interface will now become unresponsive.`))}),RC(`btn-clear-all-cache`,async()=>{confirm(`Are you sure you want to clear ALL caches?`)&&(await Qp.post(`api/cache/clear`),await WC())});var aw=document.getElementById(`btn-reconnect`);aw&&aw.addEventListener(`click`,()=>{LC(aw,WC)}),globalThis.addEventListener(`keydown`,e=>{if(e.key===`Escape`){let e=document.getElementById(`error-modal`);e&&(e.style.display=`none`);let t=document.getElementById(`trace-modal`);t&&(t.style.display=`none`)}});var ow=localStorage.getItem(BC.REFRESH_INTERVAL);ow&&XC&&(XC.value=ow);var sw=localStorage.getItem(BC.HISTORY_DURATION);sw&&ZC&&(ZC.value=sw);var cw=localStorage.getItem(BC.AUTO_REFRESH);if(cw!==null&&YC&&(YC.checked=cw===`true`),xC($),fC($),JC(),XC&&ZC){let e=Number.parseInt(XC.value),t=Number.parseInt(ZC.value);$.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3)))}var lw=localStorage.getItem(BC.LAST_VIEW);if(lw){let e=document.querySelector(`nav button[data-view="${lw}"]`);e&&e.click()}WC(!0,!0).then(()=>{YC?.checked&&KC()}).catch(console.error);
147
+ `),s=i.length):i&&typeof i==`object`&&`message`in i?(a.textContent=i.message,s=0):(a.textContent=`No logs available`,s=0),o&&(o.textContent=s>0?`Showing last ${s} log entries`:`No logs available`),a.parentElement&&(a.parentElement.scrollTop=a.parentElement.scrollHeight)}async function jC(){let e=document.getElementById(`trace-filter`),t=document.getElementById(`trace-limit`),n=document.getElementById(`trace-status-toggle`),r=e?.value??``,i=t?Number.parseInt(t.value):100;try{let{enabled:e}=await Qp.getTraceStatus();n&&(n.textContent=e?`Tracing: ON`:`Tracing: OFF`,n.dataset.enabled=String(e),n.className=`px-4 py-2 rounded-lg text-sm font-bold transition-colors ${e?`bg-success text-black hover:bg-success/80`:`bg-white/10 text-white hover:bg-white/20`}`)}catch(e){console.error(`Failed to get trace status`,e)}let a=await Qp.getTraceLogs(i,r);new DC(`trace-table`,{columns:[{id:`timestamp`,header:`Timestamp`,headerTitle:`Time of request`,width:`1%`,accessor:e=>new Date(e.timestamp).toLocaleString(),className:`font-mono text-xs text-dim whitespace-nowrap`},{id:`source`,header:`Source`,headerTitle:`Request source (IP/User)`,width:`1%`,accessor:e=>e.source,className:`text-dim text-xs truncate max-w-[150px]`,cellTitle:e=>e.source},{id:`method`,header:`Method`,headerTitle:`HTTP Method`,width:`1%`,accessor:e=>e.method,className:`font-mono text-xs whitespace-nowrap`},{id:`url`,header:`Request URL`,headerTitle:`Request URL`,accessor:e=>e.url,className:`text-bright font-mono text-xs truncate max-w-[800px]`,cellTitle:e=>e.url},{id:`status`,header:`Status`,headerTitle:`HTTP Status Code`,width:`1%`,accessor:e=>e.status,className:e=>`font-bold text-xs uppercase whitespace-nowrap ${e.status===`success`?`text-success`:`text-danger`}`},{id:`duration`,header:`Duration`,headerTitle:`Execution time in ms`,width:`1%`,align:`right`,accessor:e=>gC(e.duration),className:`font-mono text-xs text-dim whitespace-nowrap`}],dense:!0,tableLayout:`auto`,onRowClick:e=>{let t=document.getElementById(`trace-modal`),n=document.getElementById(`trace-detail-content`);t&&n&&(n.textContent=JSON.stringify(e,null,2),t.style.display=`flex`)}}).render(a)}function MC(e){let t=document.getElementById(`pools-container`);!t||!e.pools||(t.innerHTML=e.pools.map(e=>SC(e)).join(``))}function NC(e){let t=e.status.config;if(!t)return;let n=document.getElementById(`config-view`);n&&(n.innerHTML=EC(t))}function PC(e){if(e===0)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return`${Number.parseFloat((e/t**+r).toFixed(2))} ${n[r]}`}function FC(e){return gC(e/1e3)}function IC(e,t){let n=document.getElementById(`middleware-version`);n&&e.version&&(n.textContent=`${e.version} (4/8/2026, 12:25:46 PM)`,n.title=`The version of the web_plsql gateway and admin console build time`);let r=document.getElementById(`node-version`);r&&e.system&&(r.textContent=e.system.nodeVersion,r.title=`The version of the Node.js runtime`);let i=document.getElementById(`platform-info`);i&&e.system&&(i.textContent=`${e.system.platform} (${e.system.arch})`,i.title=`The operating system and architecture`);let a=document.getElementById(`system-uptime`);a&&e.uptime&&(a.textContent=hC(e.uptime));let o=document.getElementById(`system-start-time`);o&&e.startTime&&(o.textContent=_C(e.startTime));let s=document.getElementById(`system-status-text`);s&&(s.textContent=e.status?.toUpperCase()??`-`);let c=document.getElementById(`total-requests`);c&&e.metrics&&(c.textContent=e.metrics.requestCount.toLocaleString(),c.title=`Cumulative number of requests handled by the server`);let l=document.getElementById(`total-errors`);l&&e.metrics&&(l.textContent=e.metrics.errorCount.toLocaleString(),l.title=`Cumulative number of failed requests`);let u=document.getElementById(`active-pools`);if(u&&e.pools&&(u.textContent=e.pools.length.toString(),u.title=`Number of database connection pools currently active`),e.system){let t=e.system,n={heapUsed:t.memory.heapUsed,heapTotal:t.memory.heapTotal,rss:t.memory.rss,external:t.memory.external,cpuUser:t.cpu.user,cpuSystem:t.cpu.system},r=(e,r,i)=>{let a=n[r],o=t.memory[i],s=document.getElementById(e),c=document.getElementById(`${e}-max`);s&&(s.textContent=PC(a)),c&&typeof o==`number`&&(c.textContent=PC(o))},i=(e,r,i)=>{let a=n[r],o=document.getElementById(e);if(o&&(o.textContent=FC(a)),i){let n=t.cpu[i],r=document.getElementById(`${e}-max`);r&&typeof n==`number`&&(r.textContent=FC(n))}};r(`memory-heap-used`,`heapUsed`,`heapUsedMax`),r(`memory-heap-total`,`heapTotal`,`heapTotalMax`),r(`memory-rss`,`rss`,`rssMax`),r(`memory-external`,`external`,`externalMax`),i(`cpu-user`,`cpuUser`,`userMax`),i(`cpu-system`,`cpuSystem`,`systemMax`);let a=document.getElementById(`cpu-percent`);a&&t.cpu.max!==void 0&&(a.textContent=`${t.cpu.max.toFixed(1)}%`,a.title=`Max System CPU usage`);let o=document.getElementById(`memory-percent`);o&&t.memory.totalMemory&&(o.textContent=`${(t.memory.rss/t.memory.totalMemory*100).toFixed(1)}%`,o.title=`System Memory Used relative to Total (${PC(t.memory.totalMemory)})`);let s=document.getElementById(`cpu-cores-info`);s&&t.cpuCores&&(s.textContent=`${t.cpuCores} Cores`)}}async function LC(e,t){let n=e.querySelector(`.material-symbols-rounded`),r=n?.textContent;e.disabled=!0,e.classList.add(`loading`),n&&(n.textContent=`sync`,n.classList.add(`animate-spin`));try{return await t()}finally{e.disabled=!1,e.classList.remove(`loading`),n&&(n.textContent=r??``,n.classList.remove(`animate-spin`))}}function RC(e,t){let n=document.getElementById(e);return n&&n.addEventListener(`click`,()=>void LC(n,t)),n}var zC={overview:`dashboard`,trace:`bolt`,errors:`error`,access:`list_alt`,pools:`database`,stats:`query_stats`,config:`settings`,system:`terminal`},$={currentView:`overview`,status:{},maxHistoryPoints:30,lastRequestCount:0,lastErrorCount:0,lastUpdateTime:Date.now(),lastBucketTimestamp:0,nextRefreshTimeout:null,nextRefreshTime:0,countdownInterval:null,history:{labels:[],requests:[],avgResponseTimes:[],p95ResponseTimes:[],p99ResponseTimes:[],cpuUsage:[],memoryUsage:[],poolUsage:{}},charts:{},metricsMin:{},metricsMax:{}},BC={REFRESH_INTERVAL:`admin_refresh_interval`,HISTORY_DURATION:`admin_history_duration`,AUTO_REFRESH:`admin_auto_refresh`,THEME:`theme`,LAST_VIEW:`admin_last_view`};function VC(e){console.error(`Connection lost:`,e);let t=document.getElementById(`server-status-dot`),n=document.getElementById(`server-status-text`);t&&(t.className=`dot offline`),n&&(n.textContent=`OFFLINE`);let r=document.getElementById(`btn-pause`);r&&(r.style.display=`none`);let i=document.getElementById(`btn-resume`);i&&(i.style.display=`none`);let a=document.querySelector(`#system-status .dot`),o=document.getElementById(`system-status-text`);a&&(a.className=`dot offline`),o&&(o.textContent=`OFFLINE`);let s=document.getElementById(`offline-modal`);s&&s.style.display!==`flex`&&(s.style.display=`flex`),GC(6e4),HC(6e4)}function HC(e){$.countdownInterval&&clearInterval($.countdownInterval);let t=Date.now()+e,n=document.getElementById(`offline-countdown`),r=document.getElementById(`reconnect-text`);r&&(r.textContent=`Try Reconnect`);let i=()=>{if(!n)return;let e=Math.max(0,Math.ceil((t-Date.now())/1e3));n.textContent=`Retrying in ${e}s...`,e<=0&&$.countdownInterval&&(clearInterval($.countdownInterval),$.countdownInterval=null)};i(),$.countdownInterval=setInterval(i,1e3)}function UC(){$.countdownInterval&&=(clearInterval($.countdownInterval),null);let e=document.getElementById(`offline-countdown`);e&&(e.textContent=``)}async function WC(e=!1,t=!1){let n=document.getElementById(`reconnect-spinner`),r=document.getElementById(`reconnect-icon`),i=document.getElementById(`reconnect-text`);n&&(n.style.display=`inline-block`),r&&(r.style.display=`none`),i&&(i.textContent=`Connecting...`);try{let a=Date.now(),o=await Qp.getStatus(e,t),s=document.getElementById(`offline-modal`);if(s?.style.display===`flex`&&s&&(s.style.display=`none`,UC()),n&&(n.style.display=`none`),r&&(r.style.display=`inline-block`),i&&(i.textContent=`Try Reconnect`),o.history&&$.history.labels.length===0&&pC($,o.history),!o.config&&$.status.config&&(o.config=$.status.config),$.status=o,!o.metrics||!o.pools)return;let c=o.history?.at(-1),l=(o.intervalMs??5e3)/1e3,u=c?c.requests/l:0,d=c?c.durationAvg:o.metrics.avgResponseTime;if($.lastRequestCount=o.metrics.requestCount,$.lastErrorCount=o.metrics.errorCount,$.lastUpdateTime=a,o.system){let e=o.system;vC({heapUsed:e.memory.heapUsed,heapTotal:e.memory.heapTotal,rss:e.memory.rss,external:e.memory.external,cpuUser:e.cpu.user,cpuSystem:e.cpu.system},$.metricsMin,$.metricsMax)}c&&c.timestamp>$.lastBucketTimestamp?($.lastBucketTimestamp=c.timestamp,mC($,new Date(c.timestamp).toLocaleTimeString(),u,d,o.pools)):!c&&$.history.labels.length===0&&mC($,new Date().toLocaleTimeString(),0,0,o.pools);let f=document.getElementById(`sidebar-version`);f&&(f.textContent=`v${o.version}`);let p=document.getElementById(`uptime-val`);p&&(p.textContent=hC(o.uptime));let m=document.getElementById(`start-time-val`);m&&(m.textContent=`Started: ${_C(o.startTime)}`);let h=document.getElementById(`req-per-sec`);h&&(h.textContent=u.toFixed(2));let g=document.getElementById(`max-req-per-sec`);g&&(g.textContent=o.metrics.maxRequestsPerSecond.toFixed(2));let _=document.getElementById(`avg-resp-time`);_&&(_.textContent=`${o.metrics.avgResponseTime.toFixed(1)}ms`);let v=document.getElementById(`max-resp-time`);v&&(v.textContent=`${o.metrics.maxResponseTime.toFixed(1)}ms`);let y=document.getElementById(`err-count`);y&&(y.textContent=o.metrics.errorCount.toLocaleString());let b=0,x=0;o.pools.forEach(e=>{e.cache&&(b+=e.cache.procedureName.hits+e.cache.argument.hits,x+=e.cache.procedureName.misses+e.cache.argument.misses)});let S=b+x,C=S>0?Math.round(b/S*100):0,w=document.getElementById(`cache-hit-rate-val`);w&&(w.textContent=`${C}%`,w.style.color=C>80?`var(--success)`:C>50?`var(--warning)`:`var(--danger)`);let T=document.getElementById(`cache-hits-val`);T&&(T.textContent=b.toLocaleString());let E=document.getElementById(`cache-misses-val`);E&&(E.textContent=x.toLocaleString());let ee=document.getElementById(`server-status-dot`),te=document.getElementById(`server-status-text`);ee&&(ee.className=`dot `+o.status),te&&(te.textContent=o.status.toUpperCase());let ne=document.getElementById(`btn-pause`);ne&&(ne.style.display=o.status===`running`?`flex`:`none`);let re=document.getElementById(`btn-resume`);re&&(re.style.display=o.status===`paused`?`flex`:`none`),$.currentView===`errors`&&await OC(),$.currentView===`trace`&&await jC(),$.currentView===`pools`&&MC(o),$.currentView===`config`&&NC($),$.currentView===`system`&&IC(o,$),YC?.checked&&XC&&GC(Number.parseInt(XC.value,10))}catch(e){document.getElementById(`offline-modal`)?.style.display===`flex`?(GC(6e4),HC(6e4),n&&(n.style.display=`none`),r&&(r.style.display=`inline-block`),i&&(i.textContent=`Try Reconnect`)):VC(e)}}function GC(e){$.nextRefreshTimeout&&=(clearTimeout($.nextRefreshTimeout),null),$.nextRefreshTime=Date.now()+e,$.nextRefreshTimeout=setTimeout(()=>{WC()},e)}function KC(){let e=document.getElementById(`refresh-interval`);e&&GC(Number.parseInt(e.value))}function qC(){$.nextRefreshTimeout&&=(clearTimeout($.nextRefreshTimeout),null)}function JC(){let e=document.getElementById(`chart-history-points`);e&&Array.from(e.options).forEach(e=>{let t=Number.parseInt(e.value),n=``;if(t<60)n=`${t}s`;else if(t<3600)n=`${Math.round(t/60)} min`;else{let e=t/3600;n=e===Math.round(e)?`${e} hour${e>1?`s`:``}`:`${e.toFixed(1)} hours`}e.textContent=`Last ${n}`})}document.querySelectorAll(`nav button`).forEach(e=>{let t=e;t.addEventListener(`click`,async()=>{try{let e=t.dataset.view;if(!e)return;$.currentView=e,localStorage.setItem(BC.LAST_VIEW,e),document.querySelectorAll(`.view`).forEach(e=>{let t=e;t.style.display=`none`});let n=document.getElementById(`view-`+e);n&&(n.style.display=`block`),document.querySelectorAll(`nav button`).forEach(e=>e.classList.remove(`active`)),t.classList.add(`active`);let r=document.getElementById(`view-title`);if(r){let n=Array.from(t.childNodes).filter(e=>e.nodeType===Node.TEXT_NODE).map(e=>e.textContent?.trim()).join(``);r.innerHTML=`<span class="material-symbols-rounded">${zC[e]??`chevron_right`}</span>${n}`}e===`errors`&&await OC(),e===`trace`&&await jC(),e===`pools`&&MC($.status),e===`stats`&&await kC(),e===`config`&&NC($),e===`system`&&IC($.status,$)}catch(e){VC(e)}})});var YC=document.getElementById(`auto-refresh-toggle`);YC&&YC.addEventListener(`change`,e=>{let t=e.target;localStorage.setItem(BC.AUTO_REFRESH,String(t.checked)),t.checked?KC():qC()});var XC=document.getElementById(`refresh-interval`);XC&&XC.addEventListener(`change`,()=>{localStorage.setItem(BC.REFRESH_INTERVAL,XC.value);let e=Number.parseInt(XC.value),t=Number.parseInt(ZC?.value??`60`);$.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3))),$.history.labels=[],$.history.requests=[],$.history.avgResponseTimes=[],$.history.cpuUsage=[],$.history.memoryUsage=[],$.history.poolUsage={},JC(),IC($.status,$),WC()});var ZC=document.getElementById(`chart-history-points`);ZC&&ZC.addEventListener(`change`,()=>{localStorage.setItem(BC.HISTORY_DURATION,ZC.value);let e=document.getElementById(`refresh-interval`);if(!e)return;let t=Number.parseInt(e.value),n=Number.parseInt(ZC.value);$.maxHistoryPoints=Math.max(1,Math.floor(n/(t/1e3))),$.history.labels=[],$.history.requests=[],$.history.avgResponseTimes=[],$.history.cpuUsage=[],$.history.memoryUsage=[],$.history.poolUsage={},WC()});var QC=document.getElementById(`manual-refresh`);QC&&QC.addEventListener(`click`,()=>{LC(QC,WC)});var $C=document.getElementById(`error-filter`);$C&&$C.addEventListener(`keydown`,e=>{e.key===`Enter`&&OC()}),RC(`error-load-btn`,OC),RC(`trace-load-btn`,jC),RC(`access-load-btn`,AC),RC(`stats-load-btn`,kC);var ew=document.getElementById(`trace-filter`);ew&&ew.addEventListener(`keydown`,e=>{e.key===`Enter`&&jC()});var tw=document.getElementById(`trace-clear-btn`);tw&&tw.addEventListener(`click`,async()=>{confirm(`Are you sure you want to clear all traces?`)&&await LC(tw,async()=>{await Qp.clearTraces(),await jC()})});var nw=document.getElementById(`trace-status-toggle`);nw&&nw.addEventListener(`click`,async()=>{await LC(nw,async()=>{let{enabled:e}=await Qp.getTraceStatus();await Qp.toggleTrace(!e),await jC()})});var rw=document.getElementById(`access-filter`);rw&&rw.addEventListener(`keydown`,e=>{e.key===`Enter`&&AC()});var iw=document.getElementById(`stats-limit`);iw&&iw.addEventListener(`keydown`,e=>{e.key===`Enter`&&kC()}),RC(`btn-pause`,async()=>{confirm(`Are you sure you want to pause the server?`)&&(await Qp.post(`api/server/pause`),await WC())}),RC(`btn-resume`,async()=>{await Qp.post(`api/server/resume`),await WC()}),RC(`btn-stop`,async()=>{confirm(`Are you sure you want to STOP the server? This action cannot be undone from the web interface.`)&&(await Qp.post(`api/server/stop`),alert(`Server stop requested. The interface will now become unresponsive.`))}),RC(`btn-clear-all-cache`,async()=>{confirm(`Are you sure you want to clear ALL caches?`)&&(await Qp.post(`api/cache/clear`),await WC())});var aw=document.getElementById(`btn-reconnect`);aw&&aw.addEventListener(`click`,()=>{LC(aw,WC)}),globalThis.addEventListener(`keydown`,e=>{if(e.key===`Escape`){let e=document.getElementById(`error-modal`);e&&(e.style.display=`none`);let t=document.getElementById(`trace-modal`);t&&(t.style.display=`none`)}});var ow=localStorage.getItem(BC.REFRESH_INTERVAL);ow&&XC&&(XC.value=ow);var sw=localStorage.getItem(BC.HISTORY_DURATION);sw&&ZC&&(ZC.value=sw);var cw=localStorage.getItem(BC.AUTO_REFRESH);if(cw!==null&&YC&&(YC.checked=cw===`true`),xC($),fC($),JC(),XC&&ZC){let e=Number.parseInt(XC.value),t=Number.parseInt(ZC.value);$.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3)))}var lw=localStorage.getItem(BC.LAST_VIEW);if(lw){let e=document.querySelector(`nav button[data-view="${lw}"]`);e&&e.click()}WC(!0,!0).then(()=>{YC?.checked&&KC()}).catch(console.error);
@@ -6,7 +6,7 @@
6
6
  <title>web_plsql Admin Console</title>
7
7
  <link rel="icon" type="image/svg+xml" href="/admin/assets/favicon-mQAM4tVu.svg" />
8
8
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
9
- <script type="module" crossorigin src="/admin/assets/main-DurwHchn.js"></script>
9
+ <script type="module" crossorigin src="/admin/assets/main-C1Ryd_4B.js"></script>
10
10
  <link rel="stylesheet" crossorigin href="/admin/assets/main-CoERzZAr.css">
11
11
  </head>
12
12
  <body class="dark">
Binary file
Binary file
package/dist/index.mjs CHANGED
@@ -11,12 +11,12 @@ import cookieParser from "cookie-parser";
11
11
  import compression from "compression";
12
12
  import expressStaticGzip from "express-static-gzip";
13
13
  import os from "node:os";
14
- import url, { URL, fileURLToPath } from "node:url";
15
14
  import util from "node:util";
16
15
  import stream, { Readable } from "node:stream";
17
16
  import fs, { existsSync, promises, readFileSync } from "node:fs";
18
17
  import * as rotatingFileStream from "rotating-file-stream";
19
18
  import path from "node:path";
19
+ import { URL as URL$1, fileURLToPath } from "node:url";
20
20
  import morgan from "morgan";
21
21
  import multer from "multer";
22
22
  import readline from "node:readline";
@@ -209,7 +209,7 @@ globalThis.__VERSION__ ??= "**development**";
209
209
  * Returns the current library version
210
210
  * @returns {string} - Version.
211
211
  */
212
- const getVersion = () => "1.7.0";
212
+ const getVersion = () => "1.7.1";
213
213
  //#endregion
214
214
  //#region src/backend/server/config.ts
215
215
  const paddedLine = (title, value) => {
@@ -2720,7 +2720,7 @@ const getCookieString = (req) => {
2720
2720
  * @returns The DAD structure.
2721
2721
  */
2722
2722
  const getPath = (req) => {
2723
- const pathname = new URL(`${req.protocol}://${os.hostname()}${req.originalUrl}`).pathname;
2723
+ const pathname = new URL$1(`${req.protocol}://${os.hostname()}${req.originalUrl}`).pathname;
2724
2724
  const tmp = trimPath(pathname.slice(0, Math.max(0, pathname.lastIndexOf("/") + 1)));
2725
2725
  return {
2726
2726
  script: `/${tmp}`,
@@ -2998,7 +2998,8 @@ const requestHandler = async (req, res, _next, connectionPool, options, procedur
2998
2998
  }
2999
2999
  }
3000
3000
  if (typeof req.params.name !== "string" || req.params.name.length === 0) if (typeof options.defaultPage === "string" && options.defaultPage.length > 0) {
3001
- const newUrl = url.resolve(`${req.originalUrl}/${options.defaultPage}`, "");
3001
+ const currentUrl = new URL(req.originalUrl, "http://localhost");
3002
+ const newUrl = `${currentUrl.pathname.endsWith("/") ? currentUrl.pathname : `${currentUrl.pathname}/`}${options.defaultPage.replace(/^\/+/, "")}${currentUrl.search}`;
3002
3003
  debug$1(`Redirect to the url "${newUrl}"`);
3003
3004
  res.redirect(newUrl);
3004
3005
  } else errorPage(req, res, options, new RequestError("No procedure name given and no default page has been specified"));