web_plsql 1.3.1 → 1.3.2
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/dist/frontend/assets/{main-C8GKnEhz.js → main-D2PlS0b8.js} +1 -1
- package/dist/frontend/assets/main-D2PlS0b8.js.br +0 -0
- package/dist/frontend/assets/{main-C8GKnEhz.js.gz → main-D2PlS0b8.js.gz} +0 -0
- package/dist/frontend/index.html +1 -1
- package/dist/frontend/index.html.br +0 -0
- package/dist/frontend/index.html.gz +0 -0
- package/dist/index.mjs +73 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -6
- package/dist/frontend/assets/main-C8GKnEhz.js.br +0 -0
|
@@ -144,4 +144,4 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
144
144
|
<td class="text-right font-mono">${c}</td>
|
|
145
145
|
</tr>
|
|
146
146
|
`}).join("")}catch(n){console.error("Failed to load stats history:",n),t&&(t.textContent="Failed to load stats")}}async function tp(){const e=document.getElementById("access-filter"),t=document.getElementById("access-limit"),i=e?.value??"",r=t?Number.parseInt(t.value):100,n=await $e.getAccessLogs(r,i),o=document.getElementById("access-log-view"),a=document.getElementById("access-log-range");if(!o)return;let s=0;Array.isArray(n)?(o.textContent=n.join(`
|
|
147
|
-
`),s=n.length):n&&typeof n=="object"&&"message"in n?(o.textContent=n.message,s=0):(o.textContent="No logs available",s=0),a&&(a.textContent=s>0?`Showing last ${s} log entries`:"No logs available"),o.parentElement&&(o.parentElement.scrollTop=o.parentElement.scrollHeight)}async function Xt(){const e=document.getElementById("trace-filter"),t=document.getElementById("trace-limit"),i=document.getElementById("trace-status-toggle"),r=e?.value??"",n=t?Number.parseInt(t.value):100;try{const{enabled:c}=await $e.getTraceStatus();i&&(i.textContent=c?"Tracing: ON":"Tracing: OFF",i.dataset.enabled=String(c),i.className=`px-4 py-2 rounded-lg text-sm font-bold transition-colors ${c?"bg-success text-black hover:bg-success/80":"bg-white/10 text-white hover:bg-white/20"}`)}catch(c){console.error("Failed to get trace status",c)}const o=await $e.getTraceLogs(n,r),a=[{id:"timestamp",header:"Timestamp",headerTitle:"Time of request",width:"1%",accessor:c=>new Date(c.timestamp).toLocaleString(),className:"font-mono text-xs text-dim whitespace-nowrap"},{id:"source",header:"Source",headerTitle:"Request source (IP/User)",width:"1%",accessor:c=>c.source,className:"text-dim text-xs truncate max-w-[150px]",cellTitle:c=>c.source},{id:"method",header:"Method",headerTitle:"HTTP Method",width:"1%",accessor:c=>c.method,className:"font-mono text-xs whitespace-nowrap"},{id:"url",header:"Request URL",headerTitle:"Request URL",accessor:c=>c.url,className:"text-bright font-mono text-xs truncate max-w-[800px]",cellTitle:c=>c.url},{id:"status",header:"Status",headerTitle:"HTTP Status Code",width:"1%",accessor:c=>c.status,className:c=>`font-bold text-xs uppercase whitespace-nowrap ${c.status==="success"?"text-success":"text-danger"}`},{id:"duration",header:"Duration",headerTitle:"Execution time in ms",width:"1%",align:"right",accessor:c=>$s(c.duration),className:"font-mono text-xs text-dim whitespace-nowrap"}];new ep("trace-table",{columns:a,dense:!0,tableLayout:"auto",onRowClick:c=>{const l=document.getElementById("trace-modal"),u=document.getElementById("trace-detail-content");l&&u&&(u.textContent=JSON.stringify(c,null,2),l.style.display="flex")}}).render(o)}function np(e){const t=document.getElementById("pools-container");!t||!e.pools||(t.innerHTML=e.pools.map(i=>wS(i)).join(""))}function ip(e){const t=e.status.config;if(!t)return;const i=document.getElementById("config-view");i&&(i.innerHTML=TS(t))}function Jr(e){if(e===0)return"0 B";const t=1024,i=["B","KB","MB","GB"],r=Math.floor(Math.log(e)/Math.log(t));return`${Number.parseFloat((e/Math.pow(t,r)).toFixed(2))} ${i[r]}`}function sl(e){return $s(e/1e3)}function ks(e,t){const i=document.getElementById("middleware-version");i&&e.version&&(i.textContent=`${e.version} (2/18/2026, 7:14:55 PM)`,i.title="The version of the web_plsql gateway and admin console build time");const r=document.getElementById("node-version");r&&e.system&&(r.textContent=e.system.nodeVersion,r.title="The version of the Node.js runtime");const n=document.getElementById("platform-info");n&&e.system&&(n.textContent=`${e.system.platform} (${e.system.arch})`,n.title="The operating system and architecture");const o=document.getElementById("system-uptime");o&&e.uptime&&(o.textContent=_s(e.uptime));const a=document.getElementById("system-start-time");a&&e.startTime&&(a.textContent=Qg(e.startTime));const s=document.getElementById("system-status-text");s&&(s.textContent=e.status?.toUpperCase()??"-");const c=document.getElementById("total-requests");c&&e.metrics&&(c.textContent=e.metrics.requestCount.toLocaleString(),c.title="Cumulative number of requests handled by the server");const l=document.getElementById("total-errors");l&&e.metrics&&(l.textContent=e.metrics.errorCount.toLocaleString(),l.title="Cumulative number of failed requests");const 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){const d=e.system,f={heapUsed:d.memory.heapUsed,heapTotal:d.memory.heapTotal,rss:d.memory.rss,external:d.memory.external,cpuUser:d.cpu.user,cpuSystem:d.cpu.system},h=(_,k,x)=>{const y=f[k],z=d.memory[x],T=document.getElementById(_),I=document.getElementById(`${_}-max`);T&&(T.textContent=Jr(y)),I&&typeof z=="number"&&(I.textContent=Jr(z))},g=(_,k,x)=>{const y=f[k],z=document.getElementById(_);if(z&&(z.textContent=sl(y)),x){const T=d.cpu[x],I=document.getElementById(`${_}-max`);I&&typeof T=="number"&&(I.textContent=sl(T))}};h("memory-heap-used","heapUsed","heapUsedMax"),h("memory-heap-total","heapTotal","heapTotalMax"),h("memory-rss","rss","rssMax"),h("memory-external","external","externalMax"),g("cpu-user","cpuUser","userMax"),g("cpu-system","cpuSystem","systemMax");const m=document.getElementById("cpu-percent");if(m&&d.cpu.max!==void 0){const _=d.cpu.max;m.textContent=`${_.toFixed(1)}%`,m.title="Max System CPU usage"}const p=document.getElementById("memory-percent");if(p&&d.memory.totalMemory){const _=d.memory.rss/d.memory.totalMemory*100;p.textContent=`${_.toFixed(1)}%`,p.title=`System Memory Used relative to Total (${Jr(d.memory.totalMemory)})`}const b=document.getElementById("cpu-cores-info");b&&d.cpuCores&&(b.textContent=`${d.cpuCores} Cores`)}}async function Qn(e,t){const i=e.querySelector(".material-symbols-rounded"),r=i?.textContent;e.disabled=!0,e.classList.add("loading"),i&&(i.textContent="sync",i.classList.add("animate-spin"));try{return await t()}finally{e.disabled=!1,e.classList.remove("loading"),i&&(i.textContent=r??"",i.classList.remove("animate-spin"))}}function ot(e,t){const i=document.getElementById(e);return i&&i.addEventListener("click",()=>{Qn(i,t)}),i}const OS={overview:"dashboard",trace:"bolt",errors:"error",access:"list_alt",pools:"database",stats:"query_stats",config:"settings",system:"terminal"},O={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:{}},at={REFRESH_INTERVAL:"admin_refresh_interval",HISTORY_DURATION:"admin_history_duration",AUTO_REFRESH:"admin_auto_refresh",THEME:"theme",LAST_VIEW:"admin_last_view"};function rp(e){console.error("Connection lost:",e);const t=document.getElementById("server-status-dot"),i=document.getElementById("server-status-text");t&&(t.className="dot offline"),i&&(i.textContent="OFFLINE");const r=document.getElementById("btn-pause");r&&(r.style.display="none");const n=document.getElementById("btn-resume");n&&(n.style.display="none");const o=document.querySelector("#system-status .dot"),a=document.getElementById("system-status-text");o&&(o.className="dot offline"),a&&(a.textContent="OFFLINE");const s=document.getElementById("offline-modal");s&&s.style.display!=="flex"&&(s.style.display="flex"),Ai(6e4),op(6e4)}function op(e){O.countdownInterval&&clearInterval(O.countdownInterval);const t=Date.now()+e,i=document.getElementById("offline-countdown"),r=document.getElementById("reconnect-text");r&&(r.textContent="Try Reconnect");const n=()=>{if(!i)return;const o=Math.max(0,Math.ceil((t-Date.now())/1e3));i.textContent=`Retrying in ${o}s...`,o<=0&&O.countdownInterval&&(clearInterval(O.countdownInterval),O.countdownInterval=null)};n(),O.countdownInterval=setInterval(n,1e3)}function DS(){O.countdownInterval&&(clearInterval(O.countdownInterval),O.countdownInterval=null);const e=document.getElementById("offline-countdown");e&&(e.textContent="")}async function qe(e=!1,t=!1){const i=document.getElementById("reconnect-spinner"),r=document.getElementById("reconnect-icon"),n=document.getElementById("reconnect-text");i&&(i.style.display="inline-block"),r&&(r.style.display="none"),n&&(n.textContent="Connecting...");try{const o=Date.now(),a=await $e.getStatus(e,t),s=document.getElementById("offline-modal");if(s?.style.display==="flex"&&s&&(s.style.display="none",DS()),i&&(i.style.display="none"),r&&(r.style.display="inline-block"),n&&(n.textContent="Try Reconnect"),a.history&&O.history.labels.length===0&&_S(O,a.history),!a.config&&O.status.config&&(a.config=O.status.config),O.status=a,!a.metrics||!a.pools)return;const l=a.history?.at(-1),u=(a.intervalMs??Yg)/1e3,d=l?l.requests/u:0,f=l?l.durationAvg:a.metrics.avgResponseTime;if(O.lastRequestCount=a.metrics.requestCount,O.lastErrorCount=a.metrics.errorCount,O.lastUpdateTime=o,a.system){const U=a.system,Q={heapUsed:U.memory.heapUsed,heapTotal:U.memory.heapTotal,rss:U.memory.rss,external:U.memory.external,cpuUser:U.cpu.user,cpuSystem:U.cpu.system};$S(Q,O.metricsMin,O.metricsMax)}if(l&&l.timestamp>O.lastBucketTimestamp){O.lastBucketTimestamp=l.timestamp;const U=new Date(l.timestamp).toLocaleTimeString();ol(O,U,d,f,a.pools)}else if(!l&&O.history.labels.length===0){const U=new Date().toLocaleTimeString();ol(O,U,0,0,a.pools)}const h=document.getElementById("sidebar-version");h&&(h.textContent=`v${a.version}`);const g=document.getElementById("uptime-val");g&&(g.textContent=_s(a.uptime));const m=document.getElementById("start-time-val");m&&(m.textContent=`Started: ${Qg(a.startTime)}`);const p=document.getElementById("req-per-sec");p&&(p.textContent=d.toFixed(2));const b=document.getElementById("max-req-per-sec");b&&(b.textContent=a.metrics.maxRequestsPerSecond.toFixed(2));const _=document.getElementById("avg-resp-time");_&&(_.textContent=`${a.metrics.avgResponseTime.toFixed(1)}ms`);const k=document.getElementById("max-resp-time");k&&(k.textContent=`${a.metrics.maxResponseTime.toFixed(1)}ms`);const x=document.getElementById("err-count");x&&(x.textContent=a.metrics.errorCount.toLocaleString());let y=0,z=0;a.pools.forEach(U=>{U.cache&&(y+=U.cache.procedureName.hits+U.cache.argument.hits,z+=U.cache.procedureName.misses+U.cache.argument.misses)});const T=y+z,I=T>0?Math.round(y/T*100):0,E=document.getElementById("cache-hit-rate-val");E&&(E.textContent=`${I}%`,E.style.color=I>80?"var(--success)":I>50?"var(--warning)":"var(--danger)");const R=document.getElementById("cache-hits-val");R&&(R.textContent=y.toLocaleString());const A=document.getElementById("cache-misses-val");A&&(A.textContent=z.toLocaleString());const F=document.getElementById("server-status-dot"),ie=document.getElementById("server-status-text");F&&(F.className="dot "+a.status),ie&&(ie.textContent=a.status.toUpperCase());const se=document.getElementById("btn-pause");se&&(se.style.display=a.status==="running"?"flex":"none");const W=document.getElementById("btn-resume");if(W&&(W.style.display=a.status==="paused"?"flex":"none"),O.currentView==="errors"&&await Cr(),O.currentView==="trace"&&await Xt(),O.currentView==="pools"&&np(a),O.currentView==="config"&&ip(O),O.currentView==="system"&&ks(a,O),Vt?.checked&&Ue){const U=Number.parseInt(Ue.value);Ai(U)}}catch(o){document.getElementById("offline-modal")?.style.display==="flex"?(Ai(6e4),op(6e4),i&&(i.style.display="none"),r&&(r.style.display="inline-block"),n&&(n.textContent="Try Reconnect")):rp(o)}}function Ai(e){O.nextRefreshTimeout&&(clearTimeout(O.nextRefreshTimeout),O.nextRefreshTimeout=null),O.nextRefreshTime=Date.now()+e,O.nextRefreshTimeout=setTimeout(()=>{qe()},e)}function ap(){const e=document.getElementById("refresh-interval");if(e){const t=Number.parseInt(e.value);Ai(t)}}function PS(){O.nextRefreshTimeout&&(clearTimeout(O.nextRefreshTimeout),O.nextRefreshTimeout=null)}function sp(){const e=document.getElementById("chart-history-points");e&&Array.from(e.options).forEach(t=>{const i=Number.parseInt(t.value);let r="";if(i<60)r=`${i}s`;else if(i<3600)r=`${Math.round(i/60)} min`;else{const n=i/3600;r=n===Math.round(n)?`${n} hour${n>1?"s":""}`:`${n.toFixed(1)} hours`}t.textContent=`Last ${r}`})}document.querySelectorAll("nav button").forEach(e=>{const t=e;t.addEventListener("click",async()=>{try{const i=t.dataset.view;if(!i)return;O.currentView=i,localStorage.setItem(at.LAST_VIEW,i),document.querySelectorAll(".view").forEach(o=>{const a=o;a.style.display="none"});const r=document.getElementById("view-"+i);r&&(r.style.display="block"),document.querySelectorAll("nav button").forEach(o=>o.classList.remove("active")),t.classList.add("active");const n=document.getElementById("view-title");if(n){const a=Array.from(t.childNodes).filter(c=>c.nodeType===Node.TEXT_NODE).map(c=>c.textContent?.trim()).join(""),s=OS[i]??"chevron_right";n.innerHTML=`<span class="material-symbols-rounded">${s}</span>${a}`}i==="errors"&&await Cr(),i==="trace"&&await Xt(),i==="pools"&&np(O.status),i==="stats"&&await xs(),i==="config"&&ip(O),i==="system"&&ks(O.status,O)}catch(i){rp(i)}})});const Vt=document.getElementById("auto-refresh-toggle");Vt&&Vt.addEventListener("change",e=>{const t=e.target;localStorage.setItem(at.AUTO_REFRESH,String(t.checked)),t.checked?ap():PS()});const Ue=document.getElementById("refresh-interval");Ue&&Ue.addEventListener("change",()=>{localStorage.setItem(at.REFRESH_INTERVAL,Ue.value);const e=Number.parseInt(Ue.value),t=Number.parseInt(We?.value??"60");O.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3))),O.history.labels=[],O.history.requests=[],O.history.avgResponseTimes=[],O.history.cpuUsage=[],O.history.memoryUsage=[],O.history.poolUsage={},sp(),ks(O.status),qe()});const We=document.getElementById("chart-history-points");We&&We.addEventListener("change",()=>{localStorage.setItem(at.HISTORY_DURATION,We.value);const e=document.getElementById("refresh-interval");if(!e)return;const t=Number.parseInt(e.value),i=Number.parseInt(We.value);O.maxHistoryPoints=Math.max(1,Math.floor(i/(t/1e3))),O.history.labels=[],O.history.requests=[],O.history.avgResponseTimes=[],O.history.cpuUsage=[],O.history.memoryUsage=[],O.history.poolUsage={},qe()});const qr=document.getElementById("manual-refresh");qr&&qr.addEventListener("click",()=>{Qn(qr,qe)});const cl=document.getElementById("error-filter");cl&&cl.addEventListener("keydown",e=>{e.key==="Enter"&&Cr()});ot("error-load-btn",Cr);ot("trace-load-btn",Xt);ot("access-load-btn",tp);ot("stats-load-btn",xs);const ll=document.getElementById("trace-filter");ll&&ll.addEventListener("keydown",e=>{e.key==="Enter"&&Xt()});const Kr=document.getElementById("trace-clear-btn");Kr&&Kr.addEventListener("click",async()=>{confirm("Are you sure you want to clear all traces?")&&await Qn(Kr,async()=>{await $e.clearTraces(),await Xt()})});const Xr=document.getElementById("trace-status-toggle");Xr&&Xr.addEventListener("click",async()=>{await Qn(Xr,async()=>{const{enabled:e}=await $e.getTraceStatus();await $e.toggleTrace(!e),await Xt()})});const ul=document.getElementById("access-filter");ul&&ul.addEventListener("keydown",e=>{e.key==="Enter"&&tp()});const dl=document.getElementById("stats-limit");dl&&dl.addEventListener("keydown",e=>{e.key==="Enter"&&xs()});ot("btn-pause",async()=>{confirm("Are you sure you want to pause the server?")&&(await $e.post("api/server/pause"),await qe())});ot("btn-resume",async()=>{await $e.post("api/server/resume"),await qe()});ot("btn-stop",async()=>{confirm("Are you sure you want to STOP the server? This action cannot be undone from the web interface.")&&(await $e.post("api/server/stop"),alert("Server stop requested. The interface will now become unresponsive."))});ot("btn-clear-all-cache",async()=>{confirm("Are you sure you want to clear ALL caches?")&&(await $e.post("api/cache/clear"),await qe())});const Gr=document.getElementById("btn-reconnect");Gr&&Gr.addEventListener("click",()=>{Qn(Gr,qe)});globalThis.addEventListener("keydown",e=>{if(e.key==="Escape"){const t=document.getElementById("error-modal");t&&(t.style.display="none");const i=document.getElementById("trace-modal");i&&(i.style.display="none")}});const fl=localStorage.getItem(at.REFRESH_INTERVAL);fl&&Ue&&(Ue.value=fl);const hl=localStorage.getItem(at.HISTORY_DURATION);hl&&We&&(We.value=hl);const ml=localStorage.getItem(at.AUTO_REFRESH);ml!==null&&Vt&&(Vt.checked=ml==="true");SS(O);yS(O);sp();if(Ue&&We){const e=Number.parseInt(Ue.value),t=Number.parseInt(We.value);O.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3)))}const gl=localStorage.getItem(at.LAST_VIEW);if(gl){const e=document.querySelector(`nav button[data-view="${gl}"]`);e&&e.click()}qe(!0,!0).then(()=>{Vt?.checked&&ap()}).catch(console.error);
|
|
147
|
+
`),s=n.length):n&&typeof n=="object"&&"message"in n?(o.textContent=n.message,s=0):(o.textContent="No logs available",s=0),a&&(a.textContent=s>0?`Showing last ${s} log entries`:"No logs available"),o.parentElement&&(o.parentElement.scrollTop=o.parentElement.scrollHeight)}async function Xt(){const e=document.getElementById("trace-filter"),t=document.getElementById("trace-limit"),i=document.getElementById("trace-status-toggle"),r=e?.value??"",n=t?Number.parseInt(t.value):100;try{const{enabled:c}=await $e.getTraceStatus();i&&(i.textContent=c?"Tracing: ON":"Tracing: OFF",i.dataset.enabled=String(c),i.className=`px-4 py-2 rounded-lg text-sm font-bold transition-colors ${c?"bg-success text-black hover:bg-success/80":"bg-white/10 text-white hover:bg-white/20"}`)}catch(c){console.error("Failed to get trace status",c)}const o=await $e.getTraceLogs(n,r),a=[{id:"timestamp",header:"Timestamp",headerTitle:"Time of request",width:"1%",accessor:c=>new Date(c.timestamp).toLocaleString(),className:"font-mono text-xs text-dim whitespace-nowrap"},{id:"source",header:"Source",headerTitle:"Request source (IP/User)",width:"1%",accessor:c=>c.source,className:"text-dim text-xs truncate max-w-[150px]",cellTitle:c=>c.source},{id:"method",header:"Method",headerTitle:"HTTP Method",width:"1%",accessor:c=>c.method,className:"font-mono text-xs whitespace-nowrap"},{id:"url",header:"Request URL",headerTitle:"Request URL",accessor:c=>c.url,className:"text-bright font-mono text-xs truncate max-w-[800px]",cellTitle:c=>c.url},{id:"status",header:"Status",headerTitle:"HTTP Status Code",width:"1%",accessor:c=>c.status,className:c=>`font-bold text-xs uppercase whitespace-nowrap ${c.status==="success"?"text-success":"text-danger"}`},{id:"duration",header:"Duration",headerTitle:"Execution time in ms",width:"1%",align:"right",accessor:c=>$s(c.duration),className:"font-mono text-xs text-dim whitespace-nowrap"}];new ep("trace-table",{columns:a,dense:!0,tableLayout:"auto",onRowClick:c=>{const l=document.getElementById("trace-modal"),u=document.getElementById("trace-detail-content");l&&u&&(u.textContent=JSON.stringify(c,null,2),l.style.display="flex")}}).render(o)}function np(e){const t=document.getElementById("pools-container");!t||!e.pools||(t.innerHTML=e.pools.map(i=>wS(i)).join(""))}function ip(e){const t=e.status.config;if(!t)return;const i=document.getElementById("config-view");i&&(i.innerHTML=TS(t))}function Jr(e){if(e===0)return"0 B";const t=1024,i=["B","KB","MB","GB"],r=Math.floor(Math.log(e)/Math.log(t));return`${Number.parseFloat((e/Math.pow(t,r)).toFixed(2))} ${i[r]}`}function sl(e){return $s(e/1e3)}function ks(e,t){const i=document.getElementById("middleware-version");i&&e.version&&(i.textContent=`${e.version} (2/22/2026, 11:54:57 PM)`,i.title="The version of the web_plsql gateway and admin console build time");const r=document.getElementById("node-version");r&&e.system&&(r.textContent=e.system.nodeVersion,r.title="The version of the Node.js runtime");const n=document.getElementById("platform-info");n&&e.system&&(n.textContent=`${e.system.platform} (${e.system.arch})`,n.title="The operating system and architecture");const o=document.getElementById("system-uptime");o&&e.uptime&&(o.textContent=_s(e.uptime));const a=document.getElementById("system-start-time");a&&e.startTime&&(a.textContent=Qg(e.startTime));const s=document.getElementById("system-status-text");s&&(s.textContent=e.status?.toUpperCase()??"-");const c=document.getElementById("total-requests");c&&e.metrics&&(c.textContent=e.metrics.requestCount.toLocaleString(),c.title="Cumulative number of requests handled by the server");const l=document.getElementById("total-errors");l&&e.metrics&&(l.textContent=e.metrics.errorCount.toLocaleString(),l.title="Cumulative number of failed requests");const 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){const d=e.system,f={heapUsed:d.memory.heapUsed,heapTotal:d.memory.heapTotal,rss:d.memory.rss,external:d.memory.external,cpuUser:d.cpu.user,cpuSystem:d.cpu.system},h=(_,k,x)=>{const y=f[k],z=d.memory[x],T=document.getElementById(_),I=document.getElementById(`${_}-max`);T&&(T.textContent=Jr(y)),I&&typeof z=="number"&&(I.textContent=Jr(z))},g=(_,k,x)=>{const y=f[k],z=document.getElementById(_);if(z&&(z.textContent=sl(y)),x){const T=d.cpu[x],I=document.getElementById(`${_}-max`);I&&typeof T=="number"&&(I.textContent=sl(T))}};h("memory-heap-used","heapUsed","heapUsedMax"),h("memory-heap-total","heapTotal","heapTotalMax"),h("memory-rss","rss","rssMax"),h("memory-external","external","externalMax"),g("cpu-user","cpuUser","userMax"),g("cpu-system","cpuSystem","systemMax");const m=document.getElementById("cpu-percent");if(m&&d.cpu.max!==void 0){const _=d.cpu.max;m.textContent=`${_.toFixed(1)}%`,m.title="Max System CPU usage"}const p=document.getElementById("memory-percent");if(p&&d.memory.totalMemory){const _=d.memory.rss/d.memory.totalMemory*100;p.textContent=`${_.toFixed(1)}%`,p.title=`System Memory Used relative to Total (${Jr(d.memory.totalMemory)})`}const b=document.getElementById("cpu-cores-info");b&&d.cpuCores&&(b.textContent=`${d.cpuCores} Cores`)}}async function Qn(e,t){const i=e.querySelector(".material-symbols-rounded"),r=i?.textContent;e.disabled=!0,e.classList.add("loading"),i&&(i.textContent="sync",i.classList.add("animate-spin"));try{return await t()}finally{e.disabled=!1,e.classList.remove("loading"),i&&(i.textContent=r??"",i.classList.remove("animate-spin"))}}function ot(e,t){const i=document.getElementById(e);return i&&i.addEventListener("click",()=>{Qn(i,t)}),i}const OS={overview:"dashboard",trace:"bolt",errors:"error",access:"list_alt",pools:"database",stats:"query_stats",config:"settings",system:"terminal"},O={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:{}},at={REFRESH_INTERVAL:"admin_refresh_interval",HISTORY_DURATION:"admin_history_duration",AUTO_REFRESH:"admin_auto_refresh",THEME:"theme",LAST_VIEW:"admin_last_view"};function rp(e){console.error("Connection lost:",e);const t=document.getElementById("server-status-dot"),i=document.getElementById("server-status-text");t&&(t.className="dot offline"),i&&(i.textContent="OFFLINE");const r=document.getElementById("btn-pause");r&&(r.style.display="none");const n=document.getElementById("btn-resume");n&&(n.style.display="none");const o=document.querySelector("#system-status .dot"),a=document.getElementById("system-status-text");o&&(o.className="dot offline"),a&&(a.textContent="OFFLINE");const s=document.getElementById("offline-modal");s&&s.style.display!=="flex"&&(s.style.display="flex"),Ai(6e4),op(6e4)}function op(e){O.countdownInterval&&clearInterval(O.countdownInterval);const t=Date.now()+e,i=document.getElementById("offline-countdown"),r=document.getElementById("reconnect-text");r&&(r.textContent="Try Reconnect");const n=()=>{if(!i)return;const o=Math.max(0,Math.ceil((t-Date.now())/1e3));i.textContent=`Retrying in ${o}s...`,o<=0&&O.countdownInterval&&(clearInterval(O.countdownInterval),O.countdownInterval=null)};n(),O.countdownInterval=setInterval(n,1e3)}function DS(){O.countdownInterval&&(clearInterval(O.countdownInterval),O.countdownInterval=null);const e=document.getElementById("offline-countdown");e&&(e.textContent="")}async function qe(e=!1,t=!1){const i=document.getElementById("reconnect-spinner"),r=document.getElementById("reconnect-icon"),n=document.getElementById("reconnect-text");i&&(i.style.display="inline-block"),r&&(r.style.display="none"),n&&(n.textContent="Connecting...");try{const o=Date.now(),a=await $e.getStatus(e,t),s=document.getElementById("offline-modal");if(s?.style.display==="flex"&&s&&(s.style.display="none",DS()),i&&(i.style.display="none"),r&&(r.style.display="inline-block"),n&&(n.textContent="Try Reconnect"),a.history&&O.history.labels.length===0&&_S(O,a.history),!a.config&&O.status.config&&(a.config=O.status.config),O.status=a,!a.metrics||!a.pools)return;const l=a.history?.at(-1),u=(a.intervalMs??Yg)/1e3,d=l?l.requests/u:0,f=l?l.durationAvg:a.metrics.avgResponseTime;if(O.lastRequestCount=a.metrics.requestCount,O.lastErrorCount=a.metrics.errorCount,O.lastUpdateTime=o,a.system){const U=a.system,Q={heapUsed:U.memory.heapUsed,heapTotal:U.memory.heapTotal,rss:U.memory.rss,external:U.memory.external,cpuUser:U.cpu.user,cpuSystem:U.cpu.system};$S(Q,O.metricsMin,O.metricsMax)}if(l&&l.timestamp>O.lastBucketTimestamp){O.lastBucketTimestamp=l.timestamp;const U=new Date(l.timestamp).toLocaleTimeString();ol(O,U,d,f,a.pools)}else if(!l&&O.history.labels.length===0){const U=new Date().toLocaleTimeString();ol(O,U,0,0,a.pools)}const h=document.getElementById("sidebar-version");h&&(h.textContent=`v${a.version}`);const g=document.getElementById("uptime-val");g&&(g.textContent=_s(a.uptime));const m=document.getElementById("start-time-val");m&&(m.textContent=`Started: ${Qg(a.startTime)}`);const p=document.getElementById("req-per-sec");p&&(p.textContent=d.toFixed(2));const b=document.getElementById("max-req-per-sec");b&&(b.textContent=a.metrics.maxRequestsPerSecond.toFixed(2));const _=document.getElementById("avg-resp-time");_&&(_.textContent=`${a.metrics.avgResponseTime.toFixed(1)}ms`);const k=document.getElementById("max-resp-time");k&&(k.textContent=`${a.metrics.maxResponseTime.toFixed(1)}ms`);const x=document.getElementById("err-count");x&&(x.textContent=a.metrics.errorCount.toLocaleString());let y=0,z=0;a.pools.forEach(U=>{U.cache&&(y+=U.cache.procedureName.hits+U.cache.argument.hits,z+=U.cache.procedureName.misses+U.cache.argument.misses)});const T=y+z,I=T>0?Math.round(y/T*100):0,E=document.getElementById("cache-hit-rate-val");E&&(E.textContent=`${I}%`,E.style.color=I>80?"var(--success)":I>50?"var(--warning)":"var(--danger)");const R=document.getElementById("cache-hits-val");R&&(R.textContent=y.toLocaleString());const A=document.getElementById("cache-misses-val");A&&(A.textContent=z.toLocaleString());const F=document.getElementById("server-status-dot"),ie=document.getElementById("server-status-text");F&&(F.className="dot "+a.status),ie&&(ie.textContent=a.status.toUpperCase());const se=document.getElementById("btn-pause");se&&(se.style.display=a.status==="running"?"flex":"none");const W=document.getElementById("btn-resume");if(W&&(W.style.display=a.status==="paused"?"flex":"none"),O.currentView==="errors"&&await Cr(),O.currentView==="trace"&&await Xt(),O.currentView==="pools"&&np(a),O.currentView==="config"&&ip(O),O.currentView==="system"&&ks(a,O),Vt?.checked&&Ue){const U=Number.parseInt(Ue.value);Ai(U)}}catch(o){document.getElementById("offline-modal")?.style.display==="flex"?(Ai(6e4),op(6e4),i&&(i.style.display="none"),r&&(r.style.display="inline-block"),n&&(n.textContent="Try Reconnect")):rp(o)}}function Ai(e){O.nextRefreshTimeout&&(clearTimeout(O.nextRefreshTimeout),O.nextRefreshTimeout=null),O.nextRefreshTime=Date.now()+e,O.nextRefreshTimeout=setTimeout(()=>{qe()},e)}function ap(){const e=document.getElementById("refresh-interval");if(e){const t=Number.parseInt(e.value);Ai(t)}}function PS(){O.nextRefreshTimeout&&(clearTimeout(O.nextRefreshTimeout),O.nextRefreshTimeout=null)}function sp(){const e=document.getElementById("chart-history-points");e&&Array.from(e.options).forEach(t=>{const i=Number.parseInt(t.value);let r="";if(i<60)r=`${i}s`;else if(i<3600)r=`${Math.round(i/60)} min`;else{const n=i/3600;r=n===Math.round(n)?`${n} hour${n>1?"s":""}`:`${n.toFixed(1)} hours`}t.textContent=`Last ${r}`})}document.querySelectorAll("nav button").forEach(e=>{const t=e;t.addEventListener("click",async()=>{try{const i=t.dataset.view;if(!i)return;O.currentView=i,localStorage.setItem(at.LAST_VIEW,i),document.querySelectorAll(".view").forEach(o=>{const a=o;a.style.display="none"});const r=document.getElementById("view-"+i);r&&(r.style.display="block"),document.querySelectorAll("nav button").forEach(o=>o.classList.remove("active")),t.classList.add("active");const n=document.getElementById("view-title");if(n){const a=Array.from(t.childNodes).filter(c=>c.nodeType===Node.TEXT_NODE).map(c=>c.textContent?.trim()).join(""),s=OS[i]??"chevron_right";n.innerHTML=`<span class="material-symbols-rounded">${s}</span>${a}`}i==="errors"&&await Cr(),i==="trace"&&await Xt(),i==="pools"&&np(O.status),i==="stats"&&await xs(),i==="config"&&ip(O),i==="system"&&ks(O.status,O)}catch(i){rp(i)}})});const Vt=document.getElementById("auto-refresh-toggle");Vt&&Vt.addEventListener("change",e=>{const t=e.target;localStorage.setItem(at.AUTO_REFRESH,String(t.checked)),t.checked?ap():PS()});const Ue=document.getElementById("refresh-interval");Ue&&Ue.addEventListener("change",()=>{localStorage.setItem(at.REFRESH_INTERVAL,Ue.value);const e=Number.parseInt(Ue.value),t=Number.parseInt(We?.value??"60");O.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3))),O.history.labels=[],O.history.requests=[],O.history.avgResponseTimes=[],O.history.cpuUsage=[],O.history.memoryUsage=[],O.history.poolUsage={},sp(),ks(O.status),qe()});const We=document.getElementById("chart-history-points");We&&We.addEventListener("change",()=>{localStorage.setItem(at.HISTORY_DURATION,We.value);const e=document.getElementById("refresh-interval");if(!e)return;const t=Number.parseInt(e.value),i=Number.parseInt(We.value);O.maxHistoryPoints=Math.max(1,Math.floor(i/(t/1e3))),O.history.labels=[],O.history.requests=[],O.history.avgResponseTimes=[],O.history.cpuUsage=[],O.history.memoryUsage=[],O.history.poolUsage={},qe()});const qr=document.getElementById("manual-refresh");qr&&qr.addEventListener("click",()=>{Qn(qr,qe)});const cl=document.getElementById("error-filter");cl&&cl.addEventListener("keydown",e=>{e.key==="Enter"&&Cr()});ot("error-load-btn",Cr);ot("trace-load-btn",Xt);ot("access-load-btn",tp);ot("stats-load-btn",xs);const ll=document.getElementById("trace-filter");ll&&ll.addEventListener("keydown",e=>{e.key==="Enter"&&Xt()});const Kr=document.getElementById("trace-clear-btn");Kr&&Kr.addEventListener("click",async()=>{confirm("Are you sure you want to clear all traces?")&&await Qn(Kr,async()=>{await $e.clearTraces(),await Xt()})});const Xr=document.getElementById("trace-status-toggle");Xr&&Xr.addEventListener("click",async()=>{await Qn(Xr,async()=>{const{enabled:e}=await $e.getTraceStatus();await $e.toggleTrace(!e),await Xt()})});const ul=document.getElementById("access-filter");ul&&ul.addEventListener("keydown",e=>{e.key==="Enter"&&tp()});const dl=document.getElementById("stats-limit");dl&&dl.addEventListener("keydown",e=>{e.key==="Enter"&&xs()});ot("btn-pause",async()=>{confirm("Are you sure you want to pause the server?")&&(await $e.post("api/server/pause"),await qe())});ot("btn-resume",async()=>{await $e.post("api/server/resume"),await qe()});ot("btn-stop",async()=>{confirm("Are you sure you want to STOP the server? This action cannot be undone from the web interface.")&&(await $e.post("api/server/stop"),alert("Server stop requested. The interface will now become unresponsive."))});ot("btn-clear-all-cache",async()=>{confirm("Are you sure you want to clear ALL caches?")&&(await $e.post("api/cache/clear"),await qe())});const Gr=document.getElementById("btn-reconnect");Gr&&Gr.addEventListener("click",()=>{Qn(Gr,qe)});globalThis.addEventListener("keydown",e=>{if(e.key==="Escape"){const t=document.getElementById("error-modal");t&&(t.style.display="none");const i=document.getElementById("trace-modal");i&&(i.style.display="none")}});const fl=localStorage.getItem(at.REFRESH_INTERVAL);fl&&Ue&&(Ue.value=fl);const hl=localStorage.getItem(at.HISTORY_DURATION);hl&&We&&(We.value=hl);const ml=localStorage.getItem(at.AUTO_REFRESH);ml!==null&&Vt&&(Vt.checked=ml==="true");SS(O);yS(O);sp();if(Ue&&We){const e=Number.parseInt(Ue.value),t=Number.parseInt(We.value);O.maxHistoryPoints=Math.max(1,Math.floor(t/(e/1e3)))}const gl=localStorage.getItem(at.LAST_VIEW);if(gl){const e=document.querySelector(`nav button[data-view="${gl}"]`);e&&e.click()}qe(!0,!0).then(()=>{Vt?.checked&&ap()}).catch(console.error);
|
|
Binary file
|
|
Binary file
|
package/dist/frontend/index.html
CHANGED
|
@@ -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-
|
|
9
|
+
<script type="module" crossorigin src="/admin/assets/main-D2PlS0b8.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/admin/assets/main-bU4x_yEW.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body class="dark">
|
|
Binary file
|
|
Binary file
|
package/dist/index.mjs
CHANGED
|
@@ -211,7 +211,7 @@ globalThis.__VERSION__ ??= "**development**";
|
|
|
211
211
|
* Returns the current library version
|
|
212
212
|
* @returns {string} - Version.
|
|
213
213
|
*/
|
|
214
|
-
const getVersion = () => "1.3.
|
|
214
|
+
const getVersion = () => "1.3.2";
|
|
215
215
|
|
|
216
216
|
//#endregion
|
|
217
217
|
//#region src/backend/server/config.ts
|
|
@@ -2969,33 +2969,36 @@ const processRequest = async (req, res, options, connectionPool, procedureNameCa
|
|
|
2969
2969
|
debug$2("processRequest: ENTER");
|
|
2970
2970
|
if (typeof req.params.name !== "string") console.warn(`processRequest: WARNING: the req.params.name is not a string but an array of string: ${req.params.name}`);
|
|
2971
2971
|
const connection = await connectionPool.getConnection();
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
aggregator
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2972
|
+
try {
|
|
2973
|
+
const cgiObj = getCGI(req, options.documentTable, options.cgi ?? {}, authenticatedUser);
|
|
2974
|
+
debug$2("processRequest: cgiObj=", cgiObj);
|
|
2975
|
+
const filesToUpload = getFiles(req);
|
|
2976
|
+
debug$2("processRequest: filesToUpload=", filesToUpload);
|
|
2977
|
+
const argObj = {};
|
|
2978
|
+
Object.assign(argObj, req.query);
|
|
2979
|
+
filesToUpload.reduce((aggregator, file) => {
|
|
2980
|
+
aggregator[file.fieldname] = file.filename;
|
|
2981
|
+
return aggregator;
|
|
2982
|
+
}, argObj);
|
|
2983
|
+
Object.assign(argObj, normalizeBody(req));
|
|
2984
|
+
debug$2("processRequest: argObj=", argObj);
|
|
2985
|
+
await invokeProcedure(req, res, argObj, cgiObj, filesToUpload, options, connection, procedureNameCache, argumentCache);
|
|
2986
|
+
if (options.transactionMode === "rollback") {
|
|
2987
|
+
debug$2("transactionMode: rollback");
|
|
2988
|
+
await connection.rollback();
|
|
2989
|
+
} else if (typeof options.transactionMode === "function") {
|
|
2990
|
+
debug$2("transactionMode: callback");
|
|
2991
|
+
const procName = Array.isArray(req.params.name) ? req.params.name[0] : req.params.name;
|
|
2992
|
+
const result = options.transactionMode(connection, procName ?? "");
|
|
2993
|
+
debug$2("transactionMode: callback restult", result);
|
|
2994
|
+
if (result && typeof result.then === "function") await result;
|
|
2995
|
+
} else {
|
|
2996
|
+
debug$2("transactionMode: commit");
|
|
2997
|
+
await connection.commit();
|
|
2998
|
+
}
|
|
2999
|
+
} finally {
|
|
3000
|
+
await connection.release();
|
|
3001
|
+
}
|
|
2999
3002
|
debug$2("processRequest: EXIT");
|
|
3000
3003
|
};
|
|
3001
3004
|
|
|
@@ -3237,8 +3240,8 @@ const createAdminRouter = (adminContext) => {
|
|
|
3237
3240
|
const name = cache?.poolName ?? `pool-${index}`;
|
|
3238
3241
|
const p = pool;
|
|
3239
3242
|
const stats = typeof p.getStatistics === "function" ? p.getStatistics() : null;
|
|
3240
|
-
const procStats = cache?.procedureNameCache
|
|
3241
|
-
const argStats = cache?.argumentCache
|
|
3243
|
+
const procStats = cache?.procedureNameCache?.getStats();
|
|
3244
|
+
const argStats = cache?.argumentCache?.getStats();
|
|
3242
3245
|
return {
|
|
3243
3246
|
name,
|
|
3244
3247
|
stats,
|
|
@@ -3246,12 +3249,12 @@ const createAdminRouter = (adminContext) => {
|
|
|
3246
3249
|
connectionsInUse: pool.connectionsInUse,
|
|
3247
3250
|
cache: {
|
|
3248
3251
|
procedureName: {
|
|
3249
|
-
size: cache?.procedureNameCache
|
|
3252
|
+
size: cache?.procedureNameCache?.keys().length ?? 0,
|
|
3250
3253
|
hits: procStats?.hits ?? 0,
|
|
3251
3254
|
misses: procStats?.misses ?? 0
|
|
3252
3255
|
},
|
|
3253
3256
|
argument: {
|
|
3254
|
-
size: cache?.argumentCache
|
|
3257
|
+
size: cache?.argumentCache?.keys().length ?? 0,
|
|
3255
3258
|
hits: argStats?.hits ?? 0,
|
|
3256
3259
|
misses: argStats?.misses ?? 0
|
|
3257
3260
|
}
|
|
@@ -3458,32 +3461,45 @@ const handlerAdminConsole = (config, adminContext) => {
|
|
|
3458
3461
|
const resolvedStaticDir = config.staticDir ?? resolveAdminStaticDir();
|
|
3459
3462
|
if (adminRoute && !adminRoute.startsWith("/")) throw new Error("adminRoute must start with /");
|
|
3460
3463
|
if (!config.devMode && !existsSync(resolvedStaticDir)) throw new Error(`Admin console not built. Run 'npm run build:frontend' first.\nExpected: ${resolvedStaticDir}`);
|
|
3461
|
-
const
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
const
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3464
|
+
const statsManager = adminContext.statsManager;
|
|
3465
|
+
const currentRotate = statsManager.rotateBucket;
|
|
3466
|
+
if (!Object.prototype.hasOwnProperty.call(currentRotate, "_isWrapped")) {
|
|
3467
|
+
const originalRotate = statsManager.rotateBucket;
|
|
3468
|
+
const wrappedRotate = (poolSnapshots = []) => {
|
|
3469
|
+
const mergedSnapshots = [...adminContext.pools.map((pool, index) => {
|
|
3470
|
+
const cache = adminContext.caches[index];
|
|
3471
|
+
const name = cache?.poolName ?? `pool-${index}`;
|
|
3472
|
+
const procStats = cache?.procedureNameCache?.getStats();
|
|
3473
|
+
const argStats = cache?.argumentCache?.getStats();
|
|
3474
|
+
return {
|
|
3475
|
+
name,
|
|
3476
|
+
connectionsOpen: pool.connectionsOpen,
|
|
3477
|
+
connectionsInUse: pool.connectionsInUse,
|
|
3478
|
+
cache: {
|
|
3479
|
+
procedureName: {
|
|
3480
|
+
size: cache?.procedureNameCache?.keys().length ?? 0,
|
|
3481
|
+
hits: procStats?.hits ?? 0,
|
|
3482
|
+
misses: procStats?.misses ?? 0
|
|
3483
|
+
},
|
|
3484
|
+
argument: {
|
|
3485
|
+
size: cache?.argumentCache?.keys().length ?? 0,
|
|
3486
|
+
hits: argStats?.hits ?? 0,
|
|
3487
|
+
misses: argStats?.misses ?? 0
|
|
3488
|
+
}
|
|
3482
3489
|
}
|
|
3483
|
-
}
|
|
3484
|
-
};
|
|
3485
|
-
|
|
3486
|
-
|
|
3490
|
+
};
|
|
3491
|
+
})];
|
|
3492
|
+
if (Array.isArray(poolSnapshots)) {
|
|
3493
|
+
for (const ps of poolSnapshots) if (!mergedSnapshots.some((s) => s.name === ps.name)) mergedSnapshots.push(ps);
|
|
3494
|
+
}
|
|
3495
|
+
originalRotate.call(statsManager, mergedSnapshots);
|
|
3496
|
+
};
|
|
3497
|
+
Object.defineProperty(wrappedRotate, "_isWrapped", {
|
|
3498
|
+
value: true,
|
|
3499
|
+
writable: false
|
|
3500
|
+
});
|
|
3501
|
+
statsManager.rotateBucket = wrappedRotate;
|
|
3502
|
+
}
|
|
3487
3503
|
const router = Router();
|
|
3488
3504
|
router.use((req, res, next) => {
|
|
3489
3505
|
if (adminContext.paused && !req.path.startsWith(adminRoute)) {
|