@edge-base/server 0.2.5 → 0.2.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.
- package/admin-build/_app/immutable/chunks/{DILS_-VJ.js → B3CvhH3c.js} +1 -1
- package/admin-build/_app/immutable/chunks/BN_-k-Ck.js +1 -0
- package/admin-build/_app/immutable/chunks/{Dt4vL4Df.js → BYL_uBga.js} +1 -1
- package/admin-build/_app/immutable/chunks/{C72lTcG0.js → Bcs4KYNp.js} +1 -1
- package/admin-build/_app/immutable/chunks/{B8s_s9QY.js → BkZCgsc3.js} +1 -1
- package/admin-build/_app/immutable/chunks/{D2j3I1VQ.js → BvoGcDFV.js} +1 -1
- package/admin-build/_app/immutable/chunks/{B2TnDKF7.js → CCUxCptE.js} +1 -1
- package/admin-build/_app/immutable/chunks/CLHN9MVr.js +1 -0
- package/admin-build/_app/immutable/chunks/{J2Gw0SMu.js → CR37B8DX.js} +1 -1
- package/admin-build/_app/immutable/chunks/CbfX3ELZ.js +1 -0
- package/admin-build/_app/immutable/chunks/CjcrXziO.js +2 -0
- package/admin-build/_app/immutable/chunks/CrwlCAM0.js +1 -0
- package/admin-build/_app/immutable/chunks/{B0HRJ657.js → DOOPbWwG.js} +1 -1
- package/admin-build/_app/immutable/chunks/DQVP4KC-.js +1 -0
- package/admin-build/_app/immutable/chunks/{B6MschND.js → DdvsFblq.js} +1 -1
- package/admin-build/_app/immutable/chunks/DemDWbs-.js +128 -0
- package/admin-build/_app/immutable/chunks/{CaVKAiCe.js → DmDTovpg.js} +1 -1
- package/admin-build/_app/immutable/chunks/{B94PilAN.js → Ff90owjx.js} +1 -1
- package/admin-build/_app/immutable/chunks/{BqTb6Mxk.js → LL3ulaxa.js} +1 -1
- package/admin-build/_app/immutable/chunks/Q3vAxeY-.js +1 -0
- package/admin-build/_app/immutable/chunks/SQVAC3Cv.js +1 -0
- package/admin-build/_app/immutable/chunks/{Z41NK6i6.js → bguI1TeA.js} +1 -1
- package/admin-build/_app/immutable/chunks/{_teD5ji5.js → nlAMTi52.js} +1 -1
- package/admin-build/_app/immutable/chunks/{Cdm5zBRA.js → qBm6xof8.js} +1 -1
- package/admin-build/_app/immutable/entry/{app.D3flihMw.js → app.CP83Ni80.js} +2 -2
- package/admin-build/_app/immutable/entry/start.DY6YakU0.js +1 -0
- package/admin-build/_app/immutable/nodes/{0.CdczqZLK.js → 0.DiRq7puO.js} +1 -1
- package/admin-build/_app/immutable/nodes/1.BFeyKLGT.js +1 -0
- package/admin-build/_app/immutable/nodes/10.zcee7hJx.js +1 -0
- package/admin-build/_app/immutable/nodes/11.BW7wLs2Y.js +1 -0
- package/admin-build/_app/immutable/nodes/12.CxJRlYSd.js +1 -0
- package/admin-build/_app/immutable/nodes/13.pp0F_5hn.js +110 -0
- package/admin-build/_app/immutable/nodes/14.t3AfGiGo.js +3 -0
- package/admin-build/_app/immutable/nodes/15.B3agc7NX.js +1 -0
- package/admin-build/_app/immutable/nodes/{16.BR7WwQrS.js → 16.C4uG2-i8.js} +1 -1
- package/admin-build/_app/immutable/nodes/{17.Cm57KKXV.js → 17.CwGxi1Bn.js} +1 -1
- package/admin-build/_app/immutable/nodes/18.CrQyN_gU.js +1 -0
- package/admin-build/_app/immutable/nodes/19.NEPUOXl7.js +2 -0
- package/admin-build/_app/immutable/nodes/{20.DnHeFlTv.js → 20.DGHO8ipr.js} +1 -1
- package/admin-build/_app/immutable/nodes/21.UVKBDvp4.js +1 -0
- package/admin-build/_app/immutable/nodes/22.Dri5It7a.js +1 -0
- package/admin-build/_app/immutable/nodes/{23.CWSGMcKJ.js → 23.BPQP_Zte.js} +2 -2
- package/admin-build/_app/immutable/nodes/24.D580FdSS.js +2 -0
- package/admin-build/_app/immutable/nodes/25.BMNPOZwF.js +2 -0
- package/admin-build/_app/immutable/nodes/26.XcpEcbiz.js +1 -0
- package/admin-build/_app/immutable/nodes/27.C1zHHcYv.js +1 -0
- package/admin-build/_app/immutable/nodes/28.CuKzzrY8.js +1 -0
- package/admin-build/_app/immutable/nodes/29.nLpBMXnM.js +1 -0
- package/admin-build/_app/immutable/nodes/{3.B6q-7qr8.js → 3.5G_aseoL.js} +1 -1
- package/admin-build/_app/immutable/nodes/30.CQC4nLoU.js +1 -0
- package/admin-build/_app/immutable/nodes/31.Bet8kxOK.js +1 -0
- package/admin-build/_app/immutable/nodes/4.nmJDYJpC.js +1 -0
- package/admin-build/_app/immutable/nodes/5.CnbYLG4E.js +1 -0
- package/admin-build/_app/immutable/nodes/6.KA01b-3y.js +1 -0
- package/admin-build/_app/immutable/nodes/7.CP9fkn1L.js +1 -0
- package/admin-build/_app/immutable/nodes/8.BTzDb---.js +1 -0
- package/admin-build/_app/immutable/nodes/9.DkNJg_J6.js +1 -0
- package/admin-build/_app/version.json +1 -1
- package/admin-build/index.html +7 -7
- package/package.json +3 -3
- package/src/__tests__/push-handlers.test.ts +1 -1
- package/src/__tests__/room-runtime-routing.test.ts +23 -0
- package/src/__tests__/route-parser.test.ts +6 -0
- package/src/__tests__/schema.test.ts +15 -6
- package/src/durable-objects/database-do.ts +7 -1
- package/src/durable-objects/room-runtime-base.ts +49 -40
- package/src/durable-objects/rooms-do.ts +32 -1
- package/src/index.ts +23 -9
- package/src/lib/d1-handler.ts +32 -17
- package/src/lib/postgres-handler.ts +24 -12
- package/src/lib/route-parser.ts +3 -0
- package/src/lib/schemas.ts +12 -2
- package/src/middleware/captcha-verify.ts +16 -3
- package/src/middleware/error-handler.ts +1 -1
- package/src/middleware/rules.ts +28 -9
- package/src/routes/admin-auth.ts +3 -3
- package/src/routes/admin.ts +13 -8
- package/src/routes/analytics-api.ts +3 -3
- package/src/routes/auth.ts +1 -1
- package/src/routes/backup.ts +1 -1
- package/src/routes/d1.ts +14 -7
- package/src/routes/database-live.ts +13 -6
- package/src/routes/kv.ts +21 -10
- package/src/routes/oauth.ts +1 -1
- package/src/routes/push.ts +119 -77
- package/src/routes/room.ts +215 -7
- package/src/routes/schema-endpoint.ts +2 -2
- package/src/routes/sql.ts +10 -6
- package/src/routes/storage.ts +4 -2
- package/src/routes/vectorize.ts +16 -4
- package/admin-build/_app/immutable/chunks/6oMK_164.js +0 -1
- package/admin-build/_app/immutable/chunks/BEW7Ez_g.js +0 -1
- package/admin-build/_app/immutable/chunks/BoOooyH6.js +0 -1
- package/admin-build/_app/immutable/chunks/BvHnF5tV.js +0 -1
- package/admin-build/_app/immutable/chunks/CoI6jjbg.js +0 -2
- package/admin-build/_app/immutable/chunks/CrOZMmdF.js +0 -1
- package/admin-build/_app/immutable/chunks/Cw6OYcq-.js +0 -1
- package/admin-build/_app/immutable/chunks/DPdQ7z0T.js +0 -128
- package/admin-build/_app/immutable/chunks/pUxw8jfq.js +0 -1
- package/admin-build/_app/immutable/entry/start.Cl6sLxnz.js +0 -1
- package/admin-build/_app/immutable/nodes/1.DxcSsEqS.js +0 -1
- package/admin-build/_app/immutable/nodes/10.DuAd4aIm.js +0 -1
- package/admin-build/_app/immutable/nodes/11.0jgHQL92.js +0 -1
- package/admin-build/_app/immutable/nodes/12.CKNPqmyy.js +0 -1
- package/admin-build/_app/immutable/nodes/13.B1p2POXS.js +0 -110
- package/admin-build/_app/immutable/nodes/14.Bb-REBND.js +0 -3
- package/admin-build/_app/immutable/nodes/15.1uBFCX0X.js +0 -1
- package/admin-build/_app/immutable/nodes/18.CoiwfAuQ.js +0 -1
- package/admin-build/_app/immutable/nodes/19.B8ZdLlXj.js +0 -2
- package/admin-build/_app/immutable/nodes/21.CJFaf0Ia.js +0 -1
- package/admin-build/_app/immutable/nodes/22.CItETFzy.js +0 -1
- package/admin-build/_app/immutable/nodes/24.CWbEqNMB.js +0 -2
- package/admin-build/_app/immutable/nodes/25.DRkLEhKi.js +0 -2
- package/admin-build/_app/immutable/nodes/26.BRxO8AYH.js +0 -1
- package/admin-build/_app/immutable/nodes/27.BLs-nVHz.js +0 -1
- package/admin-build/_app/immutable/nodes/28.G79qkdBK.js +0 -1
- package/admin-build/_app/immutable/nodes/29.BOcI6g0N.js +0 -1
- package/admin-build/_app/immutable/nodes/30.DAIC7dKd.js +0 -1
- package/admin-build/_app/immutable/nodes/31.pl0XXjXF.js +0 -1
- package/admin-build/_app/immutable/nodes/4.DOdvVlZj.js +0 -1
- package/admin-build/_app/immutable/nodes/5.BW_zlgye.js +0 -1
- package/admin-build/_app/immutable/nodes/6.Dxy1CAI2.js +0 -1
- package/admin-build/_app/immutable/nodes/7.BG98w_o7.js +0 -1
- package/admin-build/_app/immutable/nodes/8.DoG5R2rG.js +0 -1
- package/admin-build/_app/immutable/nodes/9.Dmxf6zAC.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../chunks/CWj6FrbW.js";import{g as Nt,o as Gt}from"../chunks/Bn2NtlTj.js";import{p as at,d as u,M as Qe,a as rt,f as me,t as k,s,g as e,b as t,c as l,u as x,ae as j,r,w as Pt}from"../chunks/BdTBlfLy.js";import{d as ft,e as vt,a as W,s as M}from"../chunks/DtZk82gG.js";import{i as ie}from"../chunks/Y22E1hJM.js";import{t as Pe,b as et,e as Xe,i as Mt,a as Ye}from"../chunks/CrwlCAM0.js";import{a as n,t as ne,f as h,c as Tt}from"../chunks/DEELgv7K.js";import{d as Ee,s as Me,a as q,g as Zt,r as tt,h as xt,f as zt}from"../chunks/CjcrXziO.js";import{s as Bt,a as ut}from"../chunks/Cp8V0Xy2.js";import{p as qt}from"../chunks/DdvsFblq.js";import{g as Dt,a as pt,c as Jt,d as Qt}from"../chunks/CbfX3ELZ.js";import{d as Xt}from"../chunks/wJsUhbfZ.js";import{P as Yt}from"../chunks/BkZCgsc3.js";import{s as ea}from"../chunks/Q2nPFxS6.js";import{B as ce}from"../chunks/Bcs4KYNp.js";import{E as ta}from"../chunks/m9eWh0Cd.js";import{C as Ut}from"../chunks/B3CvhH3c.js";import{p as He}from"../chunks/F9_4wRrd.js";import{M as ht}from"../chunks/BYL_uBga.js";import{I as aa}from"../chunks/nlAMTi52.js";import{S as ra}from"../chunks/Ff90owjx.js";var la=h("<!> <!>",1),sa=h('<div class="key-input svelte-1myht9e"><!></div>'),oa=h('<img class="file-item__thumb svelte-1myht9e"/>'),ia=h('<div class="file-item__icon svelte-1myht9e"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline></svg></div>'),na=h('<div class="file-item svelte-1myht9e"><!> <div class="file-item__info svelte-1myht9e"><span class="file-item__name svelte-1myht9e"> </span> <span class="file-item__meta svelte-1myht9e"> </span></div> <button class="file-item__remove svelte-1myht9e" aria-label="Remove"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button></div>'),ca=h('<div class="file-list svelte-1myht9e"></div>'),da=h('<label><svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg> <p class="dropzone__text svelte-1myht9e">Drag & drop files here</p> <p class="dropzone__hint svelte-1myht9e">or click to browse</p> <input type="file" multiple="" class="dropzone__input svelte-1myht9e"/></label> <!> <!>',1);function va(ke,m){at(m,!0);const J=()=>ut(pt,"$authStore",Q),[Q,B]=Bt();let L=He(m,"open",15,!1),D=He(m,"onUploaded",3,()=>{}),_=u(Qe([])),K=u(""),de=u(!1),z=u(!1);const w=`file-upload-${Math.random().toString(36).slice(2,9)}`;let o=x(()=>e(_).map(d=>({name:d.name,size:O(d.size),type:d.type,isImage:d.type.startsWith("image/"),url:d.type.startsWith("image/")?URL.createObjectURL(d):""})));function F(){t(_,[],!0),t(K,""),t(z,!1)}function I(d){var f;d.preventDefault(),t(z,!1),(f=d.dataTransfer)!=null&&f.files&&t(_,[...e(_),...Array.from(d.dataTransfer.files)],!0)}function R(d){const f=d.target;f.files&&t(_,[...e(_),...Array.from(f.files)],!0),f.value=""}function y(d){t(_,e(_).filter((f,v)=>v!==d),!0)}async function ve(){if(e(_).length===0)return;t(de,!0);let d=0;for(const f of e(_))try{const v=new FormData;v.append("file",f),e(_).length===1&&e(K).trim()&&v.append("key",e(K).trim());const c=await fetch(Dt(`data/storage/buckets/${m.bucket}/upload`),{method:"POST",headers:{Authorization:`Bearer ${J().accessToken}`},body:v});if(!c.ok){const b=await c.json().catch(()=>({message:"Upload failed"}));throw new Error(b.message||"Upload failed")}d++}catch(v){Pe(Ee(v,`Failed to upload ${f.name}.`,{prefixKnownMessage:`Failed to upload ${f.name}`}))}t(de,!1),d>0&&(et(`Uploaded ${d} file${d>1?"s":""}`),L(!1),F(),D()())}function O(d){if(d===0)return"0 B";const f=["B","KB","MB","GB"],v=Math.floor(Math.log(d)/Math.log(1024));return`${(d/Math.pow(1024,v)).toFixed(v===0?0:1)} ${f[v]}`}ht(ke,{title:"Upload Files",onclose:F,get open(){return L()},set open(f){L(f)},footer:f=>{var v=la(),c=me(v);ce(c,{variant:"secondary",onclick:()=>{L(!1),F()},children:(N,ue)=>{j();var fe=ne("Cancel");n(N,fe)},$$slots:{default:!0}});var b=s(c,2);{let N=x(()=>e(_).length===0);ce(b,{variant:"primary",onclick:ve,get loading(){return e(de)},get disabled(){return e(N)},children:(ue,fe)=>{j();var U=ne();k(()=>M(U,`Upload ${e(_).length>0?`(${e(_).length})`:""}`)),n(ue,U)},$$slots:{default:!0}})}n(f,v)},children:(f,v)=>{var c=da(),b=me(c);let N;var ue=s(l(b),6);r(b);var fe=s(b,2);{var U=T=>{var E=sa(),Y=l(E);aa(Y,{label:"Custom key (optional)",get placeholder(){return e(_)[0].name},get value(){return e(K)},set value(H){t(K,H,!0)}}),r(E),n(T,E)};ie(fe,T=>{e(_).length===1&&T(U)})}var re=s(fe,2);{var X=T=>{var E=ca();Xe(E,21,()=>e(o),Mt,(Y,H,Te)=>{var De=na(),Ve=l(De);{var lt=pe=>{var ge=oa();k(()=>{q(ge,"src",e(H).url),q(ge,"alt",e(H).name)}),n(pe,ge)},Ce=pe=>{var ge=ia();n(pe,ge)};ie(Ve,pe=>{e(H).isImage?pe(lt):pe(Ce,!1)})}var Le=s(Ve,2),Be=l(Le),We=l(Be,!0);r(Be);var ee=s(Be,2),je=l(ee);r(ee),r(Le);var Ne=s(Le,2);r(De),k(()=>{M(We,e(H).name),M(je,`${e(H).size??""} · ${(e(H).type||"unknown")??""}`)}),W("click",Ne,()=>y(Te)),n(Y,De)}),r(E),n(T,E)};ie(re,T=>{e(o).length>0&&T(X)})}k(()=>{N=Me(b,1,"dropzone svelte-1myht9e",null,N,{"dropzone--active":e(z)}),q(b,"for",w),q(ue,"id",w)}),vt("dragover",b,T=>{T.preventDefault(),t(z,!0)}),vt("dragleave",b,()=>{t(z,!1)}),vt("drop",b,I),W("change",ue,R),n(f,c)},$$slots:{footer:!0,default:!0}}),rt(),B()}ft(["change","click"]);var ua=h("<img/>"),fa=h('<span><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" class="svelte-zoylhi"><rect x="2" y="2" width="12" height="12" rx="1.5" class="svelte-zoylhi"></rect><circle cx="5.5" cy="5.5" r="1" class="svelte-zoylhi"></circle><path d="M2 11l3-3 2 2 3-3 4 4" class="svelte-zoylhi"></path></svg></span>'),pa=h("<span></span>");function St(ke,m){at(m,!0);let J=He(m,"alt",3,""),Q=He(m,"class",3,""),B=u(null),L=u(!1);Pt(()=>{const w=m.src;let o=!1,F=null;t(B,null),t(L,!1);const I=Nt(pt);return fetch(w,{headers:I.accessToken?{Authorization:`Bearer ${I.accessToken}`}:{}}).then(R=>o||!R.ok?(o||t(L,!0),null):R.blob()).then(R=>{o||!R||(F=URL.createObjectURL(R),t(B,F,!0))}).catch(()=>{o||t(L,!0)}),()=>{o=!0,F&&URL.revokeObjectURL(F)}});var D=Tt(),_=me(D);{var K=w=>{var o=ua();k(()=>{q(o,"src",e(B)),q(o,"alt",J()),Me(o,1,Zt(Q()),"svelte-zoylhi")}),n(w,o)},de=w=>{var o=fa();k(()=>{Me(o,1,`auth-img-fallback ${Q()??""}`,"svelte-zoylhi"),q(o,"aria-label",J())}),n(w,o)},z=w=>{var o=pa();k(()=>Me(o,1,`auth-img-loading ${Q()??""}`,"svelte-zoylhi")),n(w,o)};ie(_,w=>{e(B)?w(K):e(L)?w(de,1):w(z,!1)})}n(ke,D),rt()}var ha=h('<div class="share__url-row svelte-vlp39"><input class="share__url-input svelte-vlp39" type="text" readonly=""/> <!></div>'),_a=h('<div class="share svelte-vlp39"><p class="share__filename svelte-vlp39"> </p> <div class="share__section svelte-vlp39"><div class="share__label svelte-vlp39"><span class="share__label-text svelte-vlp39">Public URL</span> <span class="share__hint svelte-vlp39">Works if bucket read rule allows public access</span></div> <div class="share__url-row svelte-vlp39"><input class="share__url-input svelte-vlp39" type="text" readonly=""/> <!></div></div> <div class="share__section svelte-vlp39"><div class="share__label svelte-vlp39"><span class="share__label-text svelte-vlp39">Signed URL</span> <span class="share__hint svelte-vlp39">Time-limited access, no auth required</span></div> <div class="share__signed-row svelte-vlp39"><!> <!></div> <!></div> <div class="share__usage svelte-vlp39"><p class="share__usage-title svelte-vlp39">Usage in HTML</p> <code class="share__code svelte-vlp39"><img src="<span class="share__code-url svelte-vlp39">…copied URL…</span>" /></code></div></div>');function ma(ke,m){at(m,!0);let J=He(m,"open",15,!1),Q=u("1h"),B=u(""),L=u(!1),D=u(null);const _=[{value:"1h",label:"1 hour"},{value:"1d",label:"1 day"},{value:"7d",label:"7 days"},{value:"30d",label:"30 days"}];let K=x(()=>Jt(`/api/storage/${m.bucket}/${m.fileKey}`)),de=x(()=>m.fileKey.includes("/")?m.fileKey.split("/").pop()??m.fileKey:m.fileKey);async function z(){t(L,!0),t(B,"");try{const o=await Ye.fetch(`data/storage/buckets/${m.bucket}/signed-url`,{method:"POST",body:{key:m.fileKey,expiresIn:e(Q)}});t(B,o.url,!0)}catch(o){Pe(Ee(o,"Failed to create signed URL."))}finally{t(L,!1)}}async function w(o,F){try{await navigator.clipboard.writeText(o),t(D,F,!0),et("URL copied to clipboard"),setTimeout(()=>{t(D,null)},2e3)}catch{Pe("Failed to copy URL")}}Pt(()=>{J()&&(t(B,""),t(D,null))}),ht(ke,{title:"Share File",get open(){return J()},set open(o){J(o)},children:(o,F)=>{var I=_a(),R=l(I),y=l(R,!0);r(R);var ve=s(R,2),O=s(l(ve),2),d=l(O);tt(d);var f=s(d,2);{let U=x(()=>e(D)==="public"?"primary":"secondary");ce(f,{get variant(){return e(U)},size:"sm",onclick:()=>w(e(K),"public"),children:(re,X)=>{j();var T=ne();k(()=>M(T,e(D)==="public"?"Copied!":"Copy")),n(re,T)},$$slots:{default:!0}})}r(O),r(ve);var v=s(ve,2),c=s(l(v),2),b=l(c);ra(b,{get options(){return _},get value(){return e(Q)},set value(U){t(Q,U,!0)}});var N=s(b,2);ce(N,{variant:"primary",size:"sm",get loading(){return e(L)},onclick:z,children:(U,re)=>{j();var X=ne("Generate");n(U,X)},$$slots:{default:!0}}),r(c);var ue=s(c,2);{var fe=U=>{var re=ha(),X=l(re);tt(X);var T=s(X,2);{let E=x(()=>e(D)==="signed"?"primary":"secondary");ce(T,{get variant(){return e(E)},size:"sm",onclick:()=>w(e(B),"signed"),children:(Y,H)=>{j();var Te=ne();k(()=>M(Te,e(D)==="signed"?"Copied!":"Copy")),n(Y,Te)},$$slots:{default:!0}})}r(re),k(()=>xt(X,e(B))),W("click",X,E=>E.currentTarget.select()),n(U,re)};ie(ue,U=>{e(B)&&U(fe)})}r(v),j(2),r(I),k(()=>{M(y,e(de)),xt(d,e(K))}),W("click",d,U=>U.currentTarget.select()),n(o,I)},$$slots:{default:!0}}),rt()}ft(["click"]);var ga=h("<!> <a><!></a>",1),wa=h('<span class="breadcrumb__sep svelte-f2o7w5">/</span> <button> </button>',1),ya=h('<div class="bulk-bar svelte-f2o7w5"><span class="bulk-bar__count svelte-f2o7w5"> </span> <div class="bulk-bar__actions svelte-f2o7w5"><!></div> <button class="bulk-bar__clear svelte-f2o7w5">Clear</button></div>'),ba=h('<div class="loading-state svelte-f2o7w5">Loading files...</div>'),ka=h('<tr class="folder-row svelte-f2o7w5"><td class="col-checkbox svelte-f2o7w5"></td><td class="col-preview svelte-f2o7w5"><span class="folder-icon svelte-f2o7w5"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M2 4V13H14V5H8L6.5 3H2V4Z" stroke-linejoin="round"></path></svg></span></td><td class="col-key svelte-f2o7w5" colspan="4"><button class="folder-btn svelte-f2o7w5"> </button></td><td class="col-actions svelte-f2o7w5"></td></tr>'),$a=h('<button type="button" class="thumb-button svelte-f2o7w5"><!></button>'),xa=h('<span class="file-icon svelte-f2o7w5"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M4 2H10L13 5V14H4V2Z" stroke-linejoin="round"></path><path d="M10 2V5H13"></path></svg></span>'),za=h('<tr><td class="col-checkbox svelte-f2o7w5"><input type="checkbox" class="svelte-f2o7w5"/></td><td class="col-preview svelte-f2o7w5"><!></td><td class="col-key svelte-f2o7w5"><span class="file-key svelte-f2o7w5"> </span></td><td class="col-size svelte-f2o7w5"> </td><td class="col-type svelte-f2o7w5"><span class="mime-type svelte-f2o7w5"> </span></td><td class="col-date svelte-f2o7w5"> </td><td class="col-actions svelte-f2o7w5"><div class="action-btns svelte-f2o7w5"><button class="icon-btn svelte-f2o7w5" title="Download"><svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M8 2v9M4 8l4 4 4-4" stroke-linecap="round" stroke-linejoin="round"></path><path d="M2 13h12" stroke-linecap="round"></path></svg></button> <button class="icon-btn svelte-f2o7w5" title="Share"><svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="4" cy="8" r="2"></circle><circle cx="12" cy="4" r="2"></circle><circle cx="12" cy="12" r="2"></circle><path d="M5.7 7l4.6-2M5.7 9l4.6 2"></path></svg></button> <!></div></td></tr>'),Ua=h('<div class="pagination svelte-f2o7w5"><!></div>'),Sa=h('<div class="table-wrapper svelte-f2o7w5"><table class="file-table svelte-f2o7w5"><thead class="svelte-f2o7w5"><tr><th class="col-checkbox svelte-f2o7w5"><input type="checkbox" aria-label="Select all files" class="svelte-f2o7w5"/></th><th class="col-preview svelte-f2o7w5"></th><th class="col-key svelte-f2o7w5">Name</th><th class="col-size svelte-f2o7w5">Size</th><th class="col-type svelte-f2o7w5">Type</th><th class="col-date svelte-f2o7w5">Uploaded</th><th class="col-actions svelte-f2o7w5"></th></tr></thead><tbody class="svelte-f2o7w5"><!><!></tbody></table></div> <!>',1),Pa=h('<nav class="breadcrumb svelte-f2o7w5"><button> </button> <!></nav> <!> <!>',1),Ma=h('<div class="image-preview svelte-f2o7w5"><div class="image-preview__frame svelte-f2o7w5"><!></div> <dl class="image-preview__meta svelte-f2o7w5"><div class="image-preview__meta-row svelte-f2o7w5"><dt class="svelte-f2o7w5">Path</dt> <dd class="svelte-f2o7w5"> </dd></div> <div class="image-preview__meta-row svelte-f2o7w5"><dt class="svelte-f2o7w5">Type</dt> <dd class="svelte-f2o7w5"> </dd></div> <div class="image-preview__meta-row svelte-f2o7w5"><dt class="svelte-f2o7w5">Size</dt> <dd class="svelte-f2o7w5"> </dd></div> <div class="image-preview__meta-row svelte-f2o7w5"><dt class="svelte-f2o7w5">Uploaded</dt> <dd class="svelte-f2o7w5"> </dd></div></dl></div>'),Ta=h("<!> <!> <!> <!> <!> <!>",1);function Xa(ke,m){at(m,!0);const J=()=>ut(qt,"$page",B),Q=()=>ut(pt,"$authStore",B),[B,L]=Bt();let D=u(!1),_=u(!1),K=u("");function de(a){return!!a&&a.startsWith("image/")}let z=x(()=>J().params.bucket??""),w=u(!0),o=u(Qe([])),F=u(Qe([])),I=u(null),R=u(!1),y=u(""),ve=u(!1),O=u(null),d=u(!1),f=u(!1),v=u(null),c=u(Qe(new Set)),b=u(!1),N=u(!1);function ue(a){const i=new Set(e(c));i.has(a)?i.delete(a):i.add(a),t(c,i,!0)}function fe(){e(c).size===e(o).length?t(c,new Set,!0):t(c,new Set(e(o).map(a=>a.key)),!0)}function U(){t(c,new Set,!0)}async function re(){t(b,!1),t(N,!0);const a=[...e(c)],i=await Promise.allSettled(a.map(async S=>{await Ye.fetch(`data/storage/buckets/${e(z)}/objects/${encodeURIComponent(S)}`,{method:"DELETE"})})),g=i.filter(S=>S.status==="fulfilled").length,$=i.filter(S=>S.status==="rejected").length;$===0?et(`Deleted ${g} file${g!==1?"s":""}`):Pe(`${g} succeeded, ${$} failed`),t(c,new Set,!0),t(N,!1),Y()}let X=x(()=>(()=>{if(!e(y))return[];const a=e(y).replace(/\/$/,"").split("/");return a.map((i,g)=>({label:i,prefix:a.slice(0,g+1).join("/")+"/"}))})());function T(a){return a?a.endsWith("/")?a:`${a}/`:""}function E(a){const i=new URL(window.location.href);a?i.searchParams.set("prefix",a):i.searchParams.delete("prefix"),history.replaceState(history.state,"",i.toString())}async function Y(a=!1){a?t(R,!0):t(w,!0);try{let i=`data/storage/buckets/${e(z)}/objects?limit=50&delimiter=/`;e(y)&&(i+=`&prefix=${encodeURIComponent(e(y))}`),a&&e(I)&&(i+=`&cursor=${encodeURIComponent(e(I))}`);const g=await Ye.fetch(i),$=(g.objects||[]).filter(S=>(e(y)?S.key.replace(e(y),""):S.key).length>0);a?t(o,[...e(o),...$],!0):(t(o,$,!0),t(F,g.folders||[],!0)),t(I,g.cursor,!0)}catch(i){Pe(Ee(i,"Failed to load storage objects."))}finally{t(w,!1),t(R,!1)}}function H(a){t(y,T(a),!0),E(e(y)),t(I,null),t(c,new Set,!0),Y()}function Te(a){t(O,a,!0),t(ve,!0)}function De(a){t(v,a,!0),t(f,!0)}function Ve(){t(f,!1),t(v,null)}async function lt(){if(e(O)){t(d,!0);try{await Ye.fetch(`data/storage/buckets/${e(z)}/objects/${encodeURIComponent(e(O))}`,{method:"DELETE"}),t(o,e(o).filter(a=>a.key!==e(O)),!0),e(c).delete(e(O)),t(c,new Set(e(c)),!0),et(`Deleted ${e(O)}`)}catch(a){Pe(Ee(a,"Failed to delete the storage object."))}finally{t(d,!1),t(O,null)}}}function Ce(a){return Dt(`data/storage/buckets/${e(z)}/objects/${encodeURIComponent(a)}`)}async function Le(a){try{const i=await fetch(Ce(a),{headers:{Authorization:`Bearer ${Q().accessToken}`}});if(!i.ok){const $=await i.json().catch(()=>({message:"Download failed"}));throw new Error($.message||"Download failed")}const g=await i.blob();Xt(g,ee(a))}catch(i){Pe(Ee(i,"Failed to download the file."))}}function Be(a){if(a===0)return"0 B";const i=["B","KB","MB","GB","TB"],g=Math.floor(Math.log(a)/Math.log(1024));return`${(a/Math.pow(1024,g)).toFixed(g===0?0:1)} ${i[g]}`}function We(a){try{return new Date(a).toLocaleString()}catch{return a}}function ee(a){return e(y)&&a.startsWith(e(y))?a.slice(e(y).length):a}Gt(()=>{t(y,T(J().url.searchParams.get("prefix")??""),!0),Y()});var je=Ta(),Ne=me(je);Yt(Ne,{get title(){return e(z)},description:"Browse files in this bucket",get docsHref(){return ea},actions:i=>{var g=ga(),$=me(g);ce($,{variant:"primary",size:"sm",onclick:()=>t(D,!0),children:(se,$e)=>{j();var he=ne("Upload Files");n(se,he)},$$slots:{default:!0}});var S=s($,2),le=l(S);ce(le,{variant:"secondary",size:"sm",children:(se,$e)=>{j();var he=ne("Back to Buckets");n(se,he)},$$slots:{default:!0}}),r(S),k(()=>q(S,"href",`${Qt}/storage`)),n(i,g)},children:(i,g)=>{var $=Pa(),S=me($),le=l(S);let se;var $e=l(le,!0);r(le);var he=s(le,2);Xe(he,17,()=>e(X),Mt,(P,C)=>{var A=wa(),G=s(me(A),2);let Z;var _e=l(G,!0);r(G),k(()=>{Z=Me(G,1,"breadcrumb__item svelte-f2o7w5",null,Z,{"breadcrumb__item--active":e(C).prefix===e(y)}),M(_e,e(C).label)}),W("click",G,()=>H(e(C).prefix)),n(P,A)}),r(S);var Ge=s(S,2);{var Ze=P=>{var C=ya(),A=l(C),G=l(A);r(A);var Z=s(A,2),_e=l(Z);ce(_e,{variant:"danger",size:"sm",onclick:()=>t(b,!0),get disabled(){return e(N)},children:(ze,Ue)=>{j();var we=ne("Delete Selected");n(ze,we)},$$slots:{default:!0}}),r(Z);var xe=s(Z,2);r(C),k(()=>M(G,`${e(c).size??""} selected`)),W("click",xe,U),n(P,C)};ie(Ge,P=>{e(c).size>0&&P(Ze)})}var Fe=s(Ge,2);{var qe=P=>{var C=ba();n(P,C)},st=P=>{{let C=x(()=>e(y)?"This folder is empty.":"This bucket is empty.");ta(P,{title:"No files",get description(){return e(C)}})}},Re=P=>{var C=Sa(),A=me(C),G=l(A),Z=l(G),_e=l(Z),xe=l(_e),ze=l(xe);tt(ze),r(xe),j(6),r(_e),r(Z);var Ue=s(Z),we=l(Ue);Xe(we,16,()=>e(F),te=>te,(te,p)=>{var oe=ka(),Se=s(l(oe),2),ye=l(Se),be=l(ye);r(ye),r(Se),j(),r(oe),k(Ie=>M(be,`${Ie??""}/`),[()=>p.replace(e(y),"").replace(/\/$/,"")]),W("click",ye,()=>H(p)),n(te,oe)});var Je=s(we);Xe(Je,17,()=>e(o),te=>te.key,(te,p)=>{var oe=za();let Se;var ye=l(oe),be=l(ye);tt(be),r(ye);var Ie=s(ye),Rt=l(Ie);{var It=V=>{var ae=$a(),Ae=l(ae);{let Ke=x(()=>Ce(e(p).key)),Oe=x(()=>ee(e(p).key));St(Ae,{class:"file-thumb",get src(){return e(Ke)},get alt(){return e(Oe)}})}r(ae),k((Ke,Oe)=>{q(ae,"aria-label",Ke),q(ae,"title",Oe)},[()=>`Preview ${ee(e(p).key)}`,()=>`Preview ${ee(e(p).key)}`]),W("click",ae,()=>De(e(p))),n(V,ae)},At=x(()=>{var V;return de((V=e(p).httpMetadata)==null?void 0:V.contentType)}),Kt=V=>{var ae=xa();n(V,ae)};ie(Rt,V=>{e(At)?V(It):V(Kt,!1)})}r(Ie);var ot=s(Ie),it=l(ot),Ot=l(it,!0);r(it),r(ot);var nt=s(ot),Et=l(nt,!0);r(nt);var ct=s(nt),gt=l(ct),Ht=l(gt,!0);r(gt),r(ct);var dt=s(ct),Vt=l(dt,!0);r(dt);var wt=s(dt),yt=l(wt),bt=l(yt),kt=s(bt,2),Wt=s(kt,2);ce(Wt,{variant:"danger",size:"sm",onclick:()=>Te(e(p).key),children:(V,ae)=>{j();var Ae=ne("Delete");n(V,Ae)},$$slots:{default:!0}}),r(yt),r(wt),r(oe),k((V,ae,Ae,Ke,Oe,jt)=>{var $t;Se=Me(oe,1,"svelte-f2o7w5",null,Se,V),zt(be,ae),q(be,"aria-label",`Select ${Ae??""}`),q(it,"title",e(p).key),M(Ot,Ke),M(Et,Oe),M(Ht,(($t=e(p).httpMetadata)==null?void 0:$t.contentType)??"--"),M(Vt,jt)},[()=>({"row--selected":e(c).has(e(p).key)}),()=>e(c).has(e(p).key),()=>ee(e(p).key),()=>ee(e(p).key),()=>Be(e(p).size),()=>We(e(p).uploaded)]),W("change",be,()=>ue(e(p).key)),W("click",bt,()=>Le(e(p).key)),W("click",kt,()=>{t(K,e(p).key,!0),t(_,!0)}),n(te,oe)}),r(Ue),r(G),r(A);var Lt=s(A,2);{var Ft=te=>{var p=Ua(),oe=l(p);ce(oe,{variant:"secondary",get loading(){return e(R)},onclick:()=>Y(!0),children:(Se,ye)=>{j();var be=ne("Load More");n(Se,be)},$$slots:{default:!0}}),r(p),n(te,p)};ie(Lt,te=>{e(I)&&te(Ft)})}k(()=>zt(ze,e(o).length>0&&e(c).size===e(o).length)),W("change",ze,fe),n(P,C)};ie(Fe,P=>{e(w)?P(qe):e(o).length===0&&e(F).length===0?P(st,1):P(Re,!1)})}k(()=>{se=Me(le,1,"breadcrumb__item svelte-f2o7w5",null,se,{"breadcrumb__item--active":!e(y)}),M($e,e(z))}),W("click",le,()=>H("")),n(i,$)}});var pe=s(Ne,2);{let a=x(()=>`Are you sure you want to delete "${e(O)??""}"? This action cannot be undone.`);Ut(pe,{title:"Delete File",get message(){return e(a)},confirmLabel:"Delete",confirmVariant:"danger",onconfirm:lt,get open(){return e(ve)},set open(i){t(ve,i,!0)}})}var ge=s(pe,2);{let a=x(()=>e(c).size),i=x(()=>e(c).size!==1?"s":""),g=x(()=>`Are you sure you want to delete ${e(c).size} selected file${e(c).size!==1?"s":""}? This action cannot be undone.`);Ut(ge,{get title(){return`Delete ${e(a)??""} File${e(i)??""}`},get message(){return e(g)},confirmLabel:"Delete All",confirmVariant:"danger",onconfirm:re,get open(){return e(b)},set open($){t(b,$,!0)}})}var _t=s(ge,2);va(_t,{get bucket(){return e(z)},onUploaded:()=>Y(),get open(){return e(D)},set open(a){t(D,a,!0)}});var mt=s(_t,2);{let a=x(()=>e(v)?ee(e(v).key):"Image Preview");ht(mt,{get title(){return e(a)},maxWidth:"min(92vw, 960px)",onclose:Ve,get open(){return e(f)},set open(i){t(f,i,!0)},children:(i,g)=>{var $=Tt(),S=me($);{var le=se=>{var $e=Ma(),he=l($e),Ge=l(he);{let Ue=x(()=>Ce(e(v).key)),we=x(()=>`Preview of ${ee(e(v).key)}`);St(Ge,{class:"image-preview__image",get src(){return e(Ue)},get alt(){return e(we)}})}r(he);var Ze=s(he,2),Fe=l(Ze),qe=s(l(Fe),2),st=l(qe,!0);r(qe),r(Fe);var Re=s(Fe,2),P=s(l(Re),2),C=l(P,!0);r(P),r(Re);var A=s(Re,2),G=s(l(A),2),Z=l(G,!0);r(G),r(A);var _e=s(A,2),xe=s(l(_e),2),ze=l(xe,!0);r(xe),r(_e),r(Ze),r($e),k((Ue,we)=>{var Je;M(st,e(v).key),M(C,((Je=e(v).httpMetadata)==null?void 0:Je.contentType)??"--"),M(Z,Ue),M(ze,we)},[()=>Be(e(v).size),()=>We(e(v).uploaded)]),n(se,$e)};ie(S,se=>{e(v)&&se(le)})}n(i,$)},$$slots:{default:!0}})}var Ct=s(mt,2);ma(Ct,{get bucket(){return e(z)},get fileKey(){return e(K)},get open(){return e(_)},set open(a){t(_,a,!0)}}),n(ke,je),rt(),L()}ft(["click","change"]);export{Xa as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../chunks/CWj6FrbW.js";import{o as $e}from"../chunks/Bn2NtlTj.js";import{p as Me,f as Y,a as ye,b as D,g as e,d as q,c as n,s as l,r as s,ae as je,t as H,u as v}from"../chunks/BdTBlfLy.js";import{s as m}from"../chunks/DtZk82gG.js";import{i as B}from"../chunks/Y22E1hJM.js";import{a as He,t as Be,e as ee,i as te}from"../chunks/CrwlCAM0.js";import{h as Ve}from"../chunks/DHWOQ9Ui.js";import{c as Te,a as h,f as p}from"../chunks/DEELgv7K.js";import{d as Re,a as F,s as re}from"../chunks/CjcrXziO.js";import{s as Se,a as Pe}from"../chunks/Cp8V0Xy2.js";import{b as L}from"../chunks/Q3vAxeY-.js";import{a as Ae}from"../chunks/CbfX3ELZ.js";import{g as De}from"../chunks/R6arueIl.js";import{P as qe}from"../chunks/BkZCgsc3.js";import{M as V,T as Fe}from"../chunks/LL3ulaxa.js";import{b as ae}from"../chunks/Q2nPFxS6.js";var Ee=p('<div class="overview-panel__loading svelte-1uha8ag">Loading...</div>'),Ue=p('<div class="overview-service svelte-1uha8ag"><span></span> <span class="overview-service__name svelte-1uha8ag"> </span> <span class="overview-service__detail svelte-1uha8ag"> </span></div>'),Oe=p('<div class="overview-services svelte-1uha8ag"></div>'),Ze=p('<div class="overview-info__row svelte-1uha8ag"><span class="overview-info__label svelte-1uha8ag">Auth</span> <span class="overview-info__value svelte-1uha8ag"> </span></div>'),Ke=p('<div class="overview-info__row svelte-1uha8ag"><span class="overview-info__label svelte-1uha8ag">Buckets</span> <span class="overview-info__value svelte-1uha8ag"> </span></div>'),Qe=p('<div class="overview-info svelte-1uha8ag"><!> <!> <div class="overview-info__row svelte-1uha8ag"><span class="overview-info__label svelte-1uha8ag">Service Keys</span> <span class="overview-info__value svelte-1uha8ag"> </span></div> <div class="overview-info__row svelte-1uha8ag"><span class="overview-info__label svelte-1uha8ag">Mode</span> <span> </span></div></div>'),ze=p('<a class="overview-action svelte-1uha8ag"><span class="overview-action__icon svelte-1uha8ag"><!></span> <span class="overview-action__label svelte-1uha8ag"> </span> <span class="overview-action__arrow svelte-1uha8ag"><svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M6 4L10 8L6 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></span></a>'),Ge=p('<div class="overview-metrics svelte-1uha8ag"><!> <!> <!> <!> <!></div> <div class="overview-chart svelte-1uha8ag"><!></div> <div class="overview-panels svelte-1uha8ag"><div class="overview-panel svelte-1uha8ag"><h3 class="overview-panel__title svelte-1uha8ag">Services</h3> <!> <!></div> <div class="overview-panel svelte-1uha8ag"><h3 class="overview-panel__title svelte-1uha8ag">Quick Actions</h3> <div class="overview-actions svelte-1uha8ag"></div></div></div>',1);function ct(oe,se){Me(se,!0);const ie=()=>Pe(Ae,"$authStore",ne),[ne,le]=Se();let E=q(!1),u=q(!0),i=q(null);const ve={"1h":{cardLabel:"1H",chartLabel:"Last 1 hour"},"6h":{cardLabel:"6H",chartLabel:"Last 6 hours"},"24h":{cardLabel:"24H",chartLabel:"Last 24 hours"}};async function ce(){try{const r=await He.fetch("data/overview");D(i,r,!0)}catch(r){Be(Re(r,"Failed to load the dashboard overview.",{hint:"Check your server connection and try reloading."}))}finally{D(u,!1)}}const de=v(()=>()=>{var _,$;if(!(($=(_=e(i))==null?void 0:_.traffic)!=null&&$.summary))return 0;const{totalRequests:r,totalErrors:b}=e(i).traffic.summary;return r>0?b/r*100:0}),he=v(()=>()=>{var r,b;return(b=(r=e(i))==null?void 0:r.traffic)!=null&&b.timeSeries?e(i).traffic.timeSeries.map(_=>({timestamp:_.timestamp,value:_.requests??_.value??0})):[]}),U=v(()=>{var r;return((r=e(i))==null?void 0:r.traffic.appliedRange)??"24h"}),O=v(()=>ve[e(U)]),ue=v(()=>De(e(U)));$e(()=>{ie().accessToken&&(D(E,!0),ce())});const ge=[{label:"Users",href:`${L}/auth`,icon:'<svg width="18" height="18" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="5" r="2.5" stroke="currentColor" stroke-width="1.5"/><path d="M3 14C3 11.2386 5.23858 9 8 9C10.7614 9 13 11.2386 13 14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'},{label:"Schema",href:`${L}/database/tables`,icon:'<svg width="18" height="18" viewBox="0 0 16 16" fill="none"><rect x="2" y="2" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5"/><rect x="9" y="9" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5"/><path d="M7 4.5H9.5V9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>'},{label:"ERD",href:`${L}/database/erd`,icon:'<svg width="18" height="18" viewBox="0 0 16 16" fill="none"><rect x="1" y="2" width="5" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/><rect x="10" y="10" width="5" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/><path d="M6 4H8.5V12H10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>'},{label:"Files",href:`${L}/storage`,icon:'<svg width="18" height="18" viewBox="0 0 16 16" fill="none"><path d="M2 4L8 2L14 4V12L8 14L2 12V4Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M2 4L8 6L14 4" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8 6V14" stroke="currentColor" stroke-width="1.5"/></svg>'},{label:"Analytics",href:`${L}/analytics`,icon:'<svg width="18" height="18" viewBox="0 0 16 16" fill="none"><rect x="2" y="9" width="3" height="5" rx="0.5" stroke="currentColor" stroke-width="1.5"/><rect x="6.5" y="5" width="3" height="9" rx="0.5" stroke="currentColor" stroke-width="1.5"/><rect x="11" y="2" width="3" height="12" rx="0.5" stroke="currentColor" stroke-width="1.5"/></svg>'},{label:"Logs",href:`${L}/logs`,icon:'<svg width="18" height="18" viewBox="0 0 16 16" fill="none"><path d="M4 4H12M4 7H10M4 10H12M4 13H8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'},{label:"Docs",href:ae,external:!0,icon:'<svg width="18" height="18" viewBox="0 0 16 16" fill="none"><path d="M3 2H10L13 5V14H3V2Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M10 2V5H13" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8H10M6 10.5H9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'}],pe=v(()=>()=>{if(!e(i))return[];const r=e(i).project;return[{name:"Auth",active:!0,detail:`${r.authProviders.length} provider${r.authProviders.length!==1?"s":""}`},{name:"Database",active:r.totalTables>0,detail:`${r.totalTables} table${r.totalTables!==1?"s":""}`},{name:"Storage",active:r.storageBuckets.length>0,detail:`${r.storageBuckets.length} bucket${r.storageBuckets.length!==1?"s":""}`},{name:"Live",active:!0,detail:`${r.liveConnections} conn${r.liveConnections!==1?"s":""}`}]});var Z=Te(),_e=Y(Z);{var we=r=>{qe(r,{title:"Overview",description:"Project dashboard",get docsHref(){return ae},children:(b,_)=>{var $=Ge(),T=Y($),K=n(T);{let a=v(()=>{var t,o;return((o=(t=e(i))==null?void 0:t.project)==null?void 0:o.totalUsers)??0});V(K,{label:"Total Users",get value(){return e(a)},get loading(){return e(u)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="5" r="2.5" stroke="currentColor" stroke-width="1.5"/><path d="M3 14C3 11.2386 5.23858 9 8 9C10.7614 9 13 11.2386 13 14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'})}var Q=l(K,2);{let a=v(()=>{var t,o;return((o=(t=e(i))==null?void 0:t.project)==null?void 0:o.totalTables)??0});V(Q,{label:"Tables",get value(){return e(a)},get loading(){return e(u)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="2" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5"/><rect x="9" y="9" width="5" height="5" rx="1" stroke="currentColor" stroke-width="1.5"/><path d="M7 4.5H9.5V9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>'})}var z=l(Q,2);{let a=v(()=>`Requests (${e(O).cardLabel})`),t=v(()=>{var o,c,d;return((d=(c=(o=e(i))==null?void 0:o.traffic)==null?void 0:c.summary)==null?void 0:d.totalRequests)??0});V(z,{get label(){return e(a)},get value(){return e(t)},get loading(){return e(u)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14V8L5 4L8 7L11 2L14 6V14H2Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg>'})}var G=l(z,2);{let a=v(()=>e(de)().toFixed(1));V(G,{label:"5xx Rate",get value(){return e(a)},unit:"%",get loading(){return e(u)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5"/><path d="M8 5V9M8 11V11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'})}var fe=l(G,2);{let a=v(()=>{var t,o;return((o=(t=e(i))==null?void 0:t.project)==null?void 0:o.liveConnections)??0});V(fe,{label:"Live",get value(){return e(a)},unit:"conns",get loading(){return e(u)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M1 8H3L5 3L8 13L11 6L13 8H15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>'})}s(T);var R=l(T,2),ke=n(R);{let a=v(()=>e(he)()),t=v(()=>`Requests — ${e(O).chartLabel}`);Fe(ke,{get data(){return e(a)},type:"line",height:240,get label(){return e(t)},get formatTime(){return e(ue)},get loading(){return e(u)}})}s(R);var I=l(R,2),S=n(I),J=l(n(S),2);{var me=a=>{var t=Ee();h(a,t)},be=a=>{var t=Oe();ee(t,21,()=>e(pe)(),te,(o,c)=>{var d=Ue(),w=n(d);let g;var x=l(w,2),P=n(x,!0);s(x);var M=l(x,2),y=n(M,!0);s(M),s(d),H(()=>{g=re(w,1,"overview-service__dot svelte-1uha8ag",null,g,{"overview-service__dot--active":e(c).active}),m(P,e(c).name),m(y,e(c).detail)}),h(o,d)}),s(t),h(a,t)};B(J,a=>{e(u)?a(me):a(be,!1)})}var xe=l(J,2);{var Ce=a=>{var t=Qe(),o=n(t);{var c=f=>{var k=Ze(),j=l(n(k),2),A=n(j,!0);s(j),s(k),H(C=>m(A,C),[()=>e(i).project.authProviders.map(C=>C.charAt(0).toUpperCase()+C.slice(1)).join(", ")]),h(f,k)};B(o,f=>{e(i).project.authProviders.length>0&&f(c)})}var d=l(o,2);{var w=f=>{var k=Ke(),j=l(n(k),2),A=n(j,!0);s(j),s(k),H(C=>m(A,C),[()=>e(i).project.storageBuckets.join(", ")]),h(f,k)};B(d,f=>{e(i).project.storageBuckets.length>0&&f(w)})}var g=l(d,2),x=l(n(g),2),P=n(x,!0);s(x),s(g);var M=l(g,2),y=l(n(M),2);let X;var Le=n(y,!0);s(y),s(M),s(t),H(()=>{m(P,e(i).project.serviceKeyCount),X=re(y,1,"overview-info__value overview-info__badge svelte-1uha8ag",null,X,{"overview-info__badge--dev":e(i).project.devMode}),m(Le,e(i).project.devMode?"Development":"Production")}),h(a,t)};B(xe,a=>{var t;(t=e(i))!=null&&t.project&&a(Ce)})}s(S);var N=l(S,2),W=l(n(N),2);ee(W,21,()=>ge,te,(a,t)=>{var o=ze(),c=n(o),d=n(c);Ve(d,()=>e(t).icon),s(c);var w=l(c,2),g=n(w,!0);s(w),je(2),s(o),H(()=>{F(o,"href",e(t).href),F(o,"target",e(t).external?"_blank":void 0),F(o,"rel",e(t).external?"noreferrer":void 0),m(g,e(t).label)}),h(a,o)}),s(W),s(N),s(I),h(b,$)}})};B(_e,r=>{e(E)&&r(we)})}h(oe,Z),ye(),le()}export{ct as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../chunks/CWj6FrbW.js";import{o as nt}from"../chunks/Bn2NtlTj.js";import{p as it,a as lt,g as t,f as ct,c as h,s as c,r as d,u as l,t as S,b as m,d as y,ae as ut}from"../chunks/BdTBlfLy.js";import{d as vt,s as j,a as U}from"../chunks/DtZk82gG.js";import{i as B}from"../chunks/Y22E1hJM.js";import{a as dt,t as z,e as mt,i as gt}from"../chunks/CrwlCAM0.js";import{a as x,f as C}from"../chunks/DEELgv7K.js";import{d as pt,s as Z,a as ht,r as G}from"../chunks/CjcrXziO.js";import{b as J}from"../chunks/CYatlt7w.js";import{g as ft}from"../chunks/R6arueIl.js";import{P as _t}from"../chunks/BkZCgsc3.js";import{a as bt}from"../chunks/Q2nPFxS6.js";import{M as H,T as yt}from"../chunks/LL3ulaxa.js";import{D as kt,T as wt}from"../chunks/BvoGcDFV.js";var xt=C("<button> </button>"),Ct=C('<div class="analytics-actions__custom svelte-1m0gshv"><input type="datetime-local" class="custom-date-input svelte-1m0gshv"/> <span class="custom-date-sep svelte-1m0gshv">→</span> <input type="datetime-local" class="custom-date-input svelte-1m0gshv"/> <button class="custom-date-apply svelte-1m0gshv">Apply</button></div>'),Tt=C('<span class="analytics-actions__updated svelte-1m0gshv"> </span>'),Dt=C('<span class="analytics-actions__dot svelte-1m0gshv"></span>'),$t=C('<div class="analytics-actions svelte-1m0gshv"><div class="analytics-actions__ranges svelte-1m0gshv"></div> <button type="button">Exclude admin traffic</button> <!> <div class="analytics-actions__status svelte-1m0gshv"><!> <button><!> ⟳</button></div></div>'),At=C('<p class="analytics-custom-error svelte-1m0gshv"> </p>'),Mt=C('<div class="analytics-grid svelte-1m0gshv"><!> <!> <!> <!></div> <div class="analytics-chart svelte-1m0gshv"><!></div> <!> <div class="analytics-bottom svelte-1m0gshv"><!> <!></div>',1);function jt(K,Q){it(Q,!0);let v=y(!0),u=y(null),f=y("24h"),T=y(!0),P=y(""),E=y(!1);const W=[{value:"1h",label:"1H"},{value:"6h",label:"6H"},{value:"24h",label:"24H"},{value:"7d",label:"7D"},{value:"30d",label:"30D"},{value:"custom",label:"Custom"}];let g=y(""),p=y("");const D=l(()=>()=>{if(t(f)!=="custom"||!t(g)||!t(p))return"";const a=new Date(t(g)).getTime(),r=new Date(t(p)).getTime();return Number.isNaN(a)||Number.isNaN(r)?"Enter a valid start and end time.":r<a?"End time must be after the start time.":""});async function M(){try{const a=new URLSearchParams({metric:"overview"});t(f)==="custom"&&t(g)&&t(p)?(a.set("start",new Date(t(g)).toISOString()),a.set("end",new Date(t(p)).toISOString())):a.set("range",t(f)),t(E)&&a.set("excludeCategory","admin");const r=`data/analytics?${a.toString()}`,_=await dt.fetch(r);m(u,_,!0),m(P,new Date().toLocaleTimeString(),!0)}catch(a){z(pt(a,"Failed to load analytics data."))}finally{m(v,!1)}}function X(a){m(f,a,!0),a!=="custom"&&(m(v,!0),M())}function Y(){m(E,!t(E)),(t(f)!=="custom"||t(g)&&t(p)&&!t(D)())&&(m(v,!0),M())}function tt(){if(!(!t(g)||!t(p))){if(t(D)()){z(t(D)());return}m(v,!0),M()}}nt(()=>{M();const a=setInterval(()=>{t(T)&&M()},3e4);return()=>clearInterval(a)});const et=l(()=>()=>{var _;if(!((_=t(u))!=null&&_.summary))return 0;const{totalRequests:a,totalErrors:r}=t(u).summary;return a>0?r/a*100:0}),at=l(()=>()=>{var a;return(a=t(u))!=null&&a.timeSeries?t(u).timeSeries.map(r=>({timestamp:r.timestamp,value:r.requests??r.value??0})):[]}),rt=l(()=>ft(t(f),t(g),t(p))),st=l(()=>()=>{var a;return(a=t(u))!=null&&a.breakdown?t(u).breakdown.map(r=>({label:r.label||"other",value:r.count})):[]}),ot=l(()=>()=>{var a;return(a=t(u))!=null&&a.topItems?t(u).topItems.map(r=>({label:r.label,count:r.count,secondary:`${Math.round(r.avgLatency)}ms avg · ${r.errorRate.toFixed(1)}% 5xx`})):[]});_t(K,{title:"Analytics",description:"API traffic and performance overview",get docsHref(){return bt},actions:r=>{var _=$t(),$=h(_);mt($,21,()=>W,gt,(o,n)=>{var e=xt();let s;var i=h(e,!0);d(e),S(()=>{s=Z(e,1,"analytics-actions__range-btn svelte-1m0gshv",null,s,{"analytics-actions__range-btn--active":t(f)===t(n).value}),j(i,t(n).label)}),U("click",e,()=>X(t(n).value)),x(o,e)}),d($);var k=c($,2);let L;var R=c(k,2);{var I=o=>{var n=Ct(),e=h(n);G(e);var s=c(e,4);G(s);var i=c(s,2);d(n),S(w=>i.disabled=w,[()=>!t(g)||!t(p)||!!t(D)()]),J(e,()=>t(g),w=>m(g,w)),J(s,()=>t(p),w=>m(p,w)),U("click",i,tt),x(o,n)};B(R,o=>{t(f)==="custom"&&o(I)})}var q=c(R,2),A=h(q);{var V=o=>{var n=Tt(),e=h(n);d(n),S(()=>j(e,`Updated ${t(P)??""}`)),x(o,n)};B(A,o=>{t(P)&&o(V)})}var b=c(A,2);let F;var O=h(b);{var N=o=>{var n=Dt();x(o,n)};B(O,o=>{t(T)&&o(N)})}ut(),d(b),d(q),d(_),S(()=>{L=Z(k,1,"analytics-actions__filter-btn svelte-1m0gshv",null,L,{"analytics-actions__filter-btn--active":t(E)}),F=Z(b,1,"analytics-actions__refresh-btn svelte-1m0gshv",null,F,{"analytics-actions__refresh-btn--active":t(T)}),ht(b,"title",t(T)?"Auto-refresh ON (30s)":"Auto-refresh OFF")}),U("click",k,Y),U("click",b,()=>m(T,!t(T))),x(r,_)},children:(r,_)=>{var $=Mt(),k=ct($),L=h(k);{let e=l(()=>{var s,i;return((i=(s=t(u))==null?void 0:s.summary)==null?void 0:i.totalRequests)??0});H(L,{label:"Total Requests",get value(){return t(e)},get loading(){return t(v)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14V8L5 4L8 7L11 2L14 6V14H2Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg>'})}var R=c(L,2);{let e=l(()=>{var s,i;return((i=(s=t(u))==null?void 0:s.summary)==null?void 0:i.uniqueUsers)??0});H(R,{label:"Unique Users",get value(){return t(e)},get loading(){return t(v)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="5" r="2.5" stroke="currentColor" stroke-width="1.5"/><path d="M3 14C3 11.2386 5.23858 9 8 9C10.7614 9 13 11.2386 13 14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'})}var I=c(R,2);{let e=l(()=>t(et)().toFixed(1));H(I,{label:"5xx Rate",get value(){return t(e)},unit:"%",get loading(){return t(v)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5"/><path d="M8 5V9M8 11V11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'})}var q=c(I,2);{let e=l(()=>{var s,i;return Math.round(((i=(s=t(u))==null?void 0:s.summary)==null?void 0:i.avgLatency)??0)});H(q,{label:"Avg Latency",get value(){return t(e)},unit:"ms",get loading(){return t(v)},icon:'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5"/><path d="M8 4V8L10.5 10.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>'})}d(k);var A=c(k,2),V=h(A);{let e=l(()=>t(at)());yt(V,{get data(){return t(e)},type:"line",height:260,label:"Requests over time",get formatTime(){return t(rt)},get loading(){return t(v)}})}d(A);var b=c(A,2);{var F=e=>{var s=At(),i=h(s,!0);d(s),S(w=>j(i,w),[()=>t(D)()]),x(e,s)},O=l(()=>t(f)==="custom"&&t(D)());B(b,e=>{t(O)&&e(F)})}var N=c(b,2),o=h(N);{let e=l(()=>t(st)());kt(o,{get items(){return t(e)},title:"Category Distribution",get loading(){return t(v)}})}var n=c(o,2);{let e=l(()=>t(ot)());wt(n,{get items(){return t(e)},title:"Top Endpoints",get loading(){return t(v)}})}d(N),x(r,$)}}),lt()}vt(["click"]);export{jt as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../chunks/CWj6FrbW.js";import{o as z}from"../chunks/Bn2NtlTj.js";import{p as B,a as O,f as j,c as f,g as t,s as m,r as g,u as s,b as y,d as x,t as G}from"../chunks/BdTBlfLy.js";import{d as J,s as K,a as N}from"../chunks/DtZk82gG.js";import{a as Q,t as V,e as W,i as X}from"../chunks/CrwlCAM0.js";import{a as D,f as T}from"../chunks/DEELgv7K.js";import{d as Y,s as Z}from"../chunks/CjcrXziO.js";import{g as tt}from"../chunks/R6arueIl.js";import{P as et}from"../chunks/BkZCgsc3.js";import{a as at}from"../chunks/Q2nPFxS6.js";import{M as _,T as rt}from"../chunks/LL3ulaxa.js";import{D as st,T as ot}from"../chunks/BvoGcDFV.js";var nt=T("<button> </button>"),it=T('<div class="range-selector"></div>'),lt=T('<div class="analytics-grid"><!> <!> <!> <!></div> <div class="analytics-chart"><!></div> <div class="analytics-bottom"><!> <!></div>',1);function At(F,I){B(I,!0);let o=x(!0),n=x(null),h=x("24h");const M=[{value:"1h",label:"1H"},{value:"6h",label:"6H"},{value:"24h",label:"24H"},{value:"7d",label:"7D"},{value:"30d",label:"30D"}];async function A(){try{const e=await Q.fetch(`data/analytics?range=${t(h)}&category=auth&metric=overview`);y(n,e,!0)}catch(e){V(Y(e,"Failed to load auth analytics."))}finally{y(o,!1)}}function k(e){y(h,e,!0),y(o,!0),A()}z(()=>{A();const e=setInterval(()=>void A(),3e4);return()=>clearInterval(e)});const w=s(()=>()=>{var c;if(!((c=t(n))!=null&&c.summary))return 0;const{totalRequests:e,totalErrors:a}=t(n).summary;return e>0?a/e*100:0}),H=s(()=>()=>{var e;return(((e=t(n))==null?void 0:e.timeSeries)||[]).map(a=>({timestamp:a.timestamp,value:a.requests??a.value??0}))}),L=s(()=>tt(t(h))),C=s(()=>()=>{var e;return(((e=t(n))==null?void 0:e.breakdown)||[]).map(a=>({label:a.label||"other",value:a.count}))}),E=s(()=>()=>{var e;return(((e=t(n))==null?void 0:e.topItems)||[]).map(a=>({label:a.label,count:a.count,secondary:`${Math.round(a.avgLatency)}ms · ${a.errorRate.toFixed(1)}% 5xx`}))});et(F,{title:"Auth Analytics",description:"Authentication and authorization metrics",get docsHref(){return at},actions:a=>{var c=it();W(c,21,()=>M,X,(p,d)=>{var i=nt();let v;var b=f(i,!0);g(i),G(()=>{v=Z(i,1,"range-btn",null,v,{"range-btn--active":t(h)===t(d).value}),K(b,t(d).label)}),N("click",i,()=>k(t(d).value)),D(p,i)}),g(c),D(a,c)},children:(a,c)=>{var p=lt(),d=j(p),i=f(d);{let r=s(()=>{var l,u;return((u=(l=t(n))==null?void 0:l.summary)==null?void 0:u.totalRequests)??0});_(i,{label:"Auth Requests",get value(){return t(r)},get loading(){return t(o)}})}var v=m(i,2);{let r=s(()=>{var l,u;return((u=(l=t(n))==null?void 0:l.summary)==null?void 0:u.uniqueUsers)??0});_(v,{label:"Unique Users",get value(){return t(r)},get loading(){return t(o)}})}var b=m(v,2);{let r=s(()=>t(w)().toFixed(1));_(b,{label:"5xx Rate",get value(){return t(r)},unit:"%",get loading(){return t(o)}})}var P=m(b,2);{let r=s(()=>{var l,u;return Math.round(((u=(l=t(n))==null?void 0:l.summary)==null?void 0:u.avgLatency)??0)});_(P,{label:"Avg Latency",get value(){return t(r)},unit:"ms",get loading(){return t(o)}})}g(d);var $=m(d,2),U=f($);{let r=s(()=>t(H)());rt(U,{get data(){return t(r)},type:"line",height:240,label:"Auth requests over time",get formatTime(){return t(L)},get loading(){return t(o)},color:"#7c3aed"})}g($);var q=m($,2),R=f(q);{let r=s(()=>t(C)());st(R,{get items(){return t(r)},title:"Action Distribution (signup, signin, oauth...)",get loading(){return t(o)}})}var S=m(R,2);{let r=s(()=>t(E)());ot(S,{get items(){return t(r)},title:"Top Auth Operations",get loading(){return t(o)}})}g(q),D(a,p)}}),O()}J(["click"]);export{At as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../chunks/CWj6FrbW.js";import{o as S}from"../chunks/Bn2NtlTj.js";import{p as O,a as Q,f as j,c as h,g as t,s as m,r as g,u as s,b as y,d as x,t as z}from"../chunks/BdTBlfLy.js";import{d as G,s as J,a as K}from"../chunks/DtZk82gG.js";import{a as N,t as V,e as W,i as X}from"../chunks/CrwlCAM0.js";import{a as A,f as R}from"../chunks/DEELgv7K.js";import{d as Y,s as Z}from"../chunks/CjcrXziO.js";import{g as tt}from"../chunks/R6arueIl.js";import{P as et}from"../chunks/BkZCgsc3.js";import{a as at}from"../chunks/Q2nPFxS6.js";import{M as _,T as rt}from"../chunks/LL3ulaxa.js";import{D as st,T as ot}from"../chunks/BvoGcDFV.js";var lt=R("<button> </button>"),nt=R('<div class="range-selector"></div>'),it=R('<div class="analytics-grid"><!> <!> <!> <!></div> <div class="analytics-chart"><!></div> <div class="analytics-bottom"><!> <!></div>',1);function Dt(C,F){O(F,!0);let o=x(!0),l=x(null),b=x("24h");const I=[{value:"1h",label:"1H"},{value:"6h",label:"6H"},{value:"24h",label:"24H"},{value:"7d",label:"7D"},{value:"30d",label:"30D"}];async function D(){try{const e=await N.fetch(`data/analytics?range=${t(b)}&category=db&metric=overview`);y(l,e,!0)}catch(e){V(Y(e,"Failed to load database analytics."))}finally{y(o,!1)}}function k(e){y(b,e,!0),y(o,!0),D()}S(()=>{D();const e=setInterval(()=>void D(),3e4);return()=>clearInterval(e)});const q=s(()=>()=>{var u;if(!((u=t(l))!=null&&u.summary))return 0;const{totalRequests:e,totalErrors:a}=t(l).summary;return e>0?a/e*100:0}),w=s(()=>()=>{var e;return(((e=t(l))==null?void 0:e.timeSeries)||[]).map(a=>({timestamp:a.timestamp,value:a.requests??a.value??0}))}),H=s(()=>tt(t(b))),L=s(()=>()=>{var e;return(((e=t(l))==null?void 0:e.breakdown)||[]).map(a=>({label:a.label||"other",value:a.count}))}),U=s(()=>()=>{var e;return(((e=t(l))==null?void 0:e.topItems)||[]).map(a=>({label:a.label,count:a.count,secondary:`${Math.round(a.avgLatency)}ms · ${a.errorRate.toFixed(1)}% 5xx`}))});et(C,{title:"Database Analytics",description:"CRUD operations and table usage metrics",get docsHref(){return at},actions:a=>{var u=nt();W(u,21,()=>I,X,(p,d)=>{var n=lt();let v;var f=h(n,!0);g(n),z(()=>{v=Z(n,1,"range-btn",null,v,{"range-btn--active":t(b)===t(d).value}),J(f,t(d).label)}),K("click",n,()=>k(t(d).value)),A(p,n)}),g(u),A(a,u)},children:(a,u)=>{var p=it(),d=j(p),n=h(d);{let r=s(()=>{var i,c;return((c=(i=t(l))==null?void 0:i.summary)==null?void 0:c.totalRequests)??0});_(n,{label:"DB Queries",get value(){return t(r)},get loading(){return t(o)}})}var v=m(n,2);{let r=s(()=>{var i,c;return((c=(i=t(l))==null?void 0:i.summary)==null?void 0:c.uniqueUsers)??0});_(v,{label:"Active Users",get value(){return t(r)},get loading(){return t(o)}})}var f=m(v,2);{let r=s(()=>t(q)().toFixed(1));_(f,{label:"5xx Rate",get value(){return t(r)},unit:"%",get loading(){return t(o)}})}var E=m(f,2);{let r=s(()=>{var i,c;return Math.round(((c=(i=t(l))==null?void 0:i.summary)==null?void 0:c.avgLatency)??0)});_(E,{label:"Avg Latency",get value(){return t(r)},unit:"ms",get loading(){return t(o)}})}g(d);var $=m(d,2),P=h($);{let r=s(()=>t(w)());rt(P,{get data(){return t(r)},type:"bar",height:240,label:"Database operations over time",get formatTime(){return t(H)},get loading(){return t(o)},color:"#16a34a"})}g($);var T=m($,2),M=h(T);{let r=s(()=>t(L)());st(M,{get items(){return t(r)},title:"Operation Distribution (CRUD)",get loading(){return t(o)}})}var B=m(M,2);{let r=s(()=>t(U)());ot(B,{get items(){return t(r)},title:"Most Accessed Tables",get loading(){return t(o)}})}g(T),A(a,p)}}),Q()}G(["click"]);export{Dt as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../chunks/CWj6FrbW.js";import{o as be}from"../chunks/Bn2NtlTj.js";import{p as Se,d as g,M as q,a as we,f as De,c as o,b as c,g as e,s as d,r as i,ae as z,t as h,u as G}from"../chunks/BdTBlfLy.js";import{d as Ee,s as p,a as Ie}from"../chunks/DtZk82gG.js";import{i as E}from"../chunks/Y22E1hJM.js";import{e as $e,a as Be,t as Le}from"../chunks/CrwlCAM0.js";import{t as K,a as u,f as m}from"../chunks/DEELgv7K.js";import{d as Te,s as Oe,a as Pe}from"../chunks/CjcrXziO.js";import{P as Me}from"../chunks/BkZCgsc3.js";import{a as ke}from"../chunks/Q2nPFxS6.js";import{B as Ae}from"../chunks/Bcs4KYNp.js";import{S as Q}from"../chunks/Ff90owjx.js";import{I as Ce}from"../chunks/nlAMTi52.js";import{E as He}from"../chunks/m9eWh0Cd.js";import{B as Ne}from"../chunks/DOOPbWwG.js";var Re=m('<div class="loading-state svelte-1tn2f4x">Loading events...</div>'),Fe=m('<span class="timeline-item__line svelte-1tn2f4x"></span>'),Ue=m('<span class="timeline-item__user svelte-1tn2f4x"> </span>'),Je=m('<span class="timeline-item__user svelte-1tn2f4x"> </span>'),je=m('<pre class="timeline-item__detail svelte-1tn2f4x"> </pre>'),Ve=m('<pre class="timeline-item__detail svelte-1tn2f4x"> </pre>'),qe=m('<button type="button"><div class="timeline-item__connector svelte-1tn2f4x"><span class="timeline-item__icon svelte-1tn2f4x"> </span> <!></div> <div class="timeline-item__content svelte-1tn2f4x"><div class="timeline-item__header svelte-1tn2f4x"><!> <!> <span class="timeline-item__time svelte-1tn2f4x"> </span></div> <!></div></button>'),ze=m('<div class="timeline svelte-1tn2f4x"></div>'),Ge=m('<div class="controls svelte-1tn2f4x"><div class="controls__fields svelte-1tn2f4x"><!> <!> <!></div> <div class="controls__actions svelte-1tn2f4x"><!></div></div> <!>',1);function ut(W,X){Se(X,!0);let I=g(!0),x=g(q([])),S=g("all"),$=g("24h"),w=g(""),D=g(q(new Set));const Y=[{value:"all",label:"All Events"},{value:"signup",label:"Signup"},{value:"signin",label:"Sign In"},{value:"signout",label:"Sign Out"},{value:"password_reset",label:"Password Reset"},{value:"oauth",label:"OAuth"},{value:"custom",label:"Custom"}],Z=[{value:"1h",label:"Last 1 Hour"},{value:"6h",label:"Last 6 Hours"},{value:"24h",label:"Last 24 Hours"},{value:"7d",label:"Last 7 Days"},{value:"30d",label:"Last 30 Days"}];async function C(){c(I,!0);try{let r=`data/analytics/events?range=${e($)}&limit=100`;e(S)!=="all"&&(r+=`&type=${encodeURIComponent(e(S))}`),e(w).trim()&&(r+=`&userId=${encodeURIComponent(e(w).trim())}`);const n=await Be.fetch(r);c(x,n.events??n.data??[],!0)}catch(r){Le(Te(r,"Failed to load analytics events.")),c(x,[],!0)}finally{c(I,!1)}}function ee(){c(D,new Set,!0),C()}function te(r){const n=new Set(e(D));n.has(r)?n.delete(r):n.add(r),c(D,n,!0)}be(()=>{C()});function ae(r){try{return new Date(r).toLocaleString()}catch{return String(r)}}function re(r){try{const n=Date.now()-new Date(r).getTime();return n<6e4?"just now":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?`${Math.floor(n/36e5)}h ago`:`${Math.floor(n/864e5)}d ago`}catch{return""}}function se(r){switch(r){case"signup":return"success";case"signin":return"primary";case"signout":return"default";case"password_reset":return"warning";case"oauth":return"primary";case"error":case"failed":return"danger";default:return"default"}}function ne(r){switch(r){case"signup":return"➕";case"signin":return"→";case"signout":return"←";case"password_reset":return"🔑";case"oauth":return"🔗";default:return"○"}}Me(W,{title:"Event Timeline",description:"Browse auth and custom events chronologically",get docsHref(){return ke},children:(r,n)=>{var H=Ge(),B=De(H),L=o(B),N=o(L);Q(N,{label:"Event Type",get options(){return Y},get value(){return e(S)},set value(s){c(S,s,!0)}});var R=d(N,2);Q(R,{label:"Time Range",get options(){return Z},get value(){return e($)},set value(s){c($,s,!0)}});var le=d(R,2);Ce(le,{label:"User ID",placeholder:"Filter by user...",get value(){return e(w)},set value(s){c(w,s,!0)}}),i(L);var F=d(L,2),ie=o(F);Ae(ie,{variant:"primary",onclick:ee,children:(s,f)=>{z();var y=K("Search");u(s,y)},$$slots:{default:!0}}),i(F),i(B);var oe=d(B,2);{var ue=s=>{var f=Re();u(s,f)},ve=s=>{He(s,{title:"No events found",description:"No events match the current filters."})},ce=s=>{var f=ze();$e(f,23,()=>e(x),(y,l)=>y.id??l,(y,l,T)=>{const O=G(()=>e(D).has(e(T)));var b=qe();let U;var P=o(b),M=o(P),de=o(M,!0);i(M);var me=d(M,2);{var pe=t=>{var a=Fe();u(t,a)};E(me,t=>{e(T)<e(x).length-1&&t(pe)})}i(P);var J=d(P,2),k=o(J),j=o(k);{let t=G(()=>se(e(l).type));Ne(j,{get variant(){return e(t)},children:(a,v)=>{z();var _=K();h(()=>p(_,e(l).type)),u(a,_)},$$slots:{default:!0}})}var V=d(j,2);{var fe=t=>{var a=Ue(),v=o(a,!0);i(a),h(()=>p(v,e(l).userEmail)),u(t,a)},_e=t=>{var a=Je(),v=o(a,!0);i(a),h(()=>p(v,e(l).userId)),u(t,a)};E(V,t=>{e(l).userEmail?t(fe):e(l).userId&&t(_e,1)})}var A=d(V,2),ge=o(A,!0);i(A),i(k);var he=d(k,2);{var xe=t=>{var a=je(),v=o(a,!0);i(a),h(_=>p(v,_),[()=>JSON.stringify(e(l).metadata,null,2)]),u(t,a)},ye=t=>{var a=Ve(),v=o(a,!0);i(a),h(_=>p(v,_),[()=>JSON.stringify(e(l),null,2)]),u(t,a)};E(he,t=>{e(O)&&e(l).metadata?t(xe):e(O)&&t(ye,1)})}i(J),i(b),h((t,a,v)=>{U=Oe(b,1,"timeline-item svelte-1tn2f4x",null,U,{"timeline-item--expanded":e(O)}),p(de,t),Pe(A,"title",a),p(ge,v)},[()=>ne(e(l).type),()=>ae(e(l).timestamp),()=>re(e(l).timestamp)]),Ie("click",b,()=>te(e(T))),u(y,b)}),i(f),u(s,f)};E(oe,s=>{e(I)?s(ue):e(x).length===0?s(ve,1):s(ce,!1)})}u(r,H)}}),we()}Ee(["click"]);export{ut as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../chunks/CWj6FrbW.js";import{o as U}from"../chunks/Bn2NtlTj.js";import{p as j,a as z,f as G,c as b,g as t,s as m,r as g,u as n,b as y,d as D,t as J}from"../chunks/BdTBlfLy.js";import{d as K,s as N,a as O}from"../chunks/DtZk82gG.js";import{a as Q,t as V,e as W,i as X}from"../chunks/CrwlCAM0.js";import{a as F,f as I}from"../chunks/DEELgv7K.js";import{d as Y,s as Z}from"../chunks/CjcrXziO.js";import{P as tt}from"../chunks/BkZCgsc3.js";import{a as et}from"../chunks/Q2nPFxS6.js";import{M as _,T as at}from"../chunks/LL3ulaxa.js";import{D as rt,T as nt}from"../chunks/BvoGcDFV.js";var st=I("<button> </button>"),ot=I('<div class="range-selector"></div>'),lt=I('<div class="analytics-grid"><!> <!> <!> <!></div> <div class="analytics-chart"><!></div> <div class="analytics-bottom"><!> <!></div>',1);function yt(w,A){j(A,!0);let s=D(!0),o=D(null),p=D("24h");const M=[{value:"1h",label:"1H"},{value:"6h",label:"6H"},{value:"24h",label:"24H"},{value:"7d",label:"7D"},{value:"30d",label:"30D"}],T=n(()=>()=>{switch(t(p)){case"1h":return"minute";case"6h":case"24h":return"hour";default:return"day"}});async function $(){try{const e=await Q.fetch(`data/analytics?range=${t(p)}&category=function&metric=overview&groupBy=${t(T)()}`);y(o,e,!0)}catch(e){V(Y(e,"Failed to load functions analytics."))}finally{y(s,!1)}}function k(e){y(p,e,!0),y(s,!0),$()}U(()=>{$();const e=setInterval($,3e4);return()=>clearInterval(e)});const H=n(()=>()=>{var c;if(!((c=t(o))!=null&&c.summary))return 0;const{totalRequests:e,totalErrors:a}=t(o).summary;return e>0?a/e*100:0}),B=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.timeSeries)||[]).map(a=>({timestamp:a.timestamp,value:a.requests??a.value??0}))}),C=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.breakdown)||[]).map(a=>({label:a.label||"other",value:a.count}))}),E=n(()=>()=>{var e;return(((e=t(o))==null?void 0:e.topItems)||[]).map(a=>({label:a.label,count:a.count,secondary:`${Math.round(a.avgLatency)}ms · ${a.errorRate.toFixed(1)}% 5xx`}))});tt(w,{title:"Functions Analytics",description:"Serverless function execution and performance metrics",get docsHref(){return et},actions:a=>{var c=ot();W(c,21,()=>M,X,(f,d)=>{var l=st();let v;var h=b(l,!0);g(l),J(()=>{v=Z(l,1,"range-btn",null,v,{"range-btn--active":t(p)===t(d).value}),N(h,t(d).label)}),O("click",l,()=>k(t(d).value)),F(f,l)}),g(c),F(a,c)},children:(a,c)=>{var f=lt(),d=G(f),l=b(d);{let r=n(()=>{var i,u;return((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.totalRequests)??0});_(l,{label:"Invocations",get value(){return t(r)},get loading(){return t(s)}})}var v=m(l,2);{let r=n(()=>{var i,u;return((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.uniqueUsers)??0});_(v,{label:"Unique Users",get value(){return t(r)},get loading(){return t(s)}})}var h=m(v,2);{let r=n(()=>t(H)().toFixed(1));_(h,{label:"5xx Rate",get value(){return t(r)},unit:"%",get loading(){return t(s)}})}var L=m(h,2);{let r=n(()=>{var i,u;return Math.round(((u=(i=t(o))==null?void 0:i.summary)==null?void 0:u.avgLatency)??0)});_(L,{label:"Avg Duration",get value(){return t(r)},unit:"ms",get loading(){return t(s)}})}g(d);var x=m(d,2),P=b(x);{let r=n(()=>t(B)());at(P,{get data(){return t(r)},type:"bar",height:240,label:"Function invocations over time",get loading(){return t(s)},color:"#dc2626"})}g(x);var R=m(x,2),q=b(R);{let r=n(()=>t(C)());rt(q,{get items(){return t(r)},title:"Functions by invocation count",get loading(){return t(s)}})}var S=m(q,2);{let r=n(()=>t(E)());nt(S,{get items(){return t(r)},title:"Top Functions",get loading(){return t(s)}})}g(R),F(a,f)}}),z()}K(["click"]);export{yt as component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"1774560919084"}
|
package/admin-build/index.html
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>EdgeBase Admin</title>
|
|
7
7
|
<link rel="icon" href="/admin/favicon.svg" type="image/svg+xml" />
|
|
8
|
-
<link href="/admin/_app/immutable/entry/start.
|
|
9
|
-
<link href="/admin/_app/immutable/chunks/
|
|
8
|
+
<link href="/admin/_app/immutable/entry/start.DY6YakU0.js" rel="modulepreload">
|
|
9
|
+
<link href="/admin/_app/immutable/chunks/SQVAC3Cv.js" rel="modulepreload">
|
|
10
10
|
<link href="/admin/_app/immutable/chunks/BdTBlfLy.js" rel="modulepreload">
|
|
11
11
|
<link href="/admin/_app/immutable/chunks/Bn2NtlTj.js" rel="modulepreload">
|
|
12
|
-
<link href="/admin/_app/immutable/chunks/
|
|
13
|
-
<link href="/admin/_app/immutable/entry/app.
|
|
12
|
+
<link href="/admin/_app/immutable/chunks/Q3vAxeY-.js" rel="modulepreload">
|
|
13
|
+
<link href="/admin/_app/immutable/entry/app.CP83Ni80.js" rel="modulepreload">
|
|
14
14
|
<link href="/admin/_app/immutable/chunks/B2bEC_Hm.js" rel="modulepreload">
|
|
15
15
|
<link href="/admin/_app/immutable/chunks/Bb0e0sAP.js" rel="modulepreload">
|
|
16
16
|
<link href="/admin/_app/immutable/chunks/DtZk82gG.js" rel="modulepreload">
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<div style="display: contents">
|
|
27
27
|
<script>
|
|
28
28
|
{
|
|
29
|
-
|
|
29
|
+
__sveltekit_hkuxmm = {
|
|
30
30
|
base: "/admin",
|
|
31
31
|
assets: "/admin"
|
|
32
32
|
};
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
const element = document.currentScript.parentElement;
|
|
35
35
|
|
|
36
36
|
Promise.all([
|
|
37
|
-
import("/admin/_app/immutable/entry/start.
|
|
38
|
-
import("/admin/_app/immutable/entry/app.
|
|
37
|
+
import("/admin/_app/immutable/entry/start.DY6YakU0.js"),
|
|
38
|
+
import("/admin/_app/immutable/entry/app.CP83Ni80.js")
|
|
39
39
|
]).then(([kit, app]) => {
|
|
40
40
|
kit.start(app, element);
|
|
41
41
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edge-base/server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "EdgeBase runtime assets consumed by the EdgeBase CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"jose": "^6.0.0",
|
|
35
35
|
"pg": "^8.16.3",
|
|
36
36
|
"zod": "^4.3.6",
|
|
37
|
-
"@edge-base/core": "0.2.
|
|
38
|
-
"@edge-base/shared": "0.2.
|
|
37
|
+
"@edge-base/core": "0.2.6",
|
|
38
|
+
"@edge-base/shared": "0.2.6"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@cloudflare/vitest-pool-workers": "^0.8.71",
|
|
@@ -173,7 +173,7 @@ describe('Push handlers route integration', () => {
|
|
|
173
173
|
|
|
174
174
|
expect(response.status).toBe(400);
|
|
175
175
|
await expect(response.json()).resolves.toMatchObject({
|
|
176
|
-
message: 'beforeSend must return topic and payload',
|
|
176
|
+
message: 'push.hooks.beforeSend must return a topic and payload when overriding topic delivery.',
|
|
177
177
|
});
|
|
178
178
|
});
|
|
179
179
|
});
|
|
@@ -98,6 +98,29 @@ describe('room route runtime routing', () => {
|
|
|
98
98
|
await expect(response.json()).resolves.toEqual({ runtime: 'rooms' });
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
+
it('routes summary requests to the rooms runtime', async () => {
|
|
102
|
+
setConfig(defineConfig({
|
|
103
|
+
rooms: {
|
|
104
|
+
game: {
|
|
105
|
+
runtime: {
|
|
106
|
+
target: 'rooms',
|
|
107
|
+
},
|
|
108
|
+
public: {
|
|
109
|
+
metadata: true,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
}));
|
|
114
|
+
|
|
115
|
+
const app = createRoomApp();
|
|
116
|
+
const response = await app.request('/api/room/summary?namespace=game&id=room-1', {
|
|
117
|
+
method: 'GET',
|
|
118
|
+
}, createRoomRuntimeEnv());
|
|
119
|
+
|
|
120
|
+
expect(response.status).toBe(201);
|
|
121
|
+
await expect(response.json()).resolves.toEqual({ runtime: 'rooms' });
|
|
122
|
+
});
|
|
123
|
+
|
|
101
124
|
it('routes websocket upgrades to the rooms runtime', async () => {
|
|
102
125
|
setConfig(defineConfig({
|
|
103
126
|
rooms: {
|
|
@@ -360,6 +360,12 @@ describe('parseRoute — room', () => {
|
|
|
360
360
|
expect(r.subcategory).toBe('metadata');
|
|
361
361
|
expect(r.operation).toBe('getMetadata');
|
|
362
362
|
});
|
|
363
|
+
|
|
364
|
+
it('GET /api/room/summary', () => {
|
|
365
|
+
const r = parseRoute('GET', '/api/room/summary');
|
|
366
|
+
expect(r.subcategory).toBe('summary');
|
|
367
|
+
expect(r.operation).toBe('getSummary');
|
|
368
|
+
});
|
|
363
369
|
});
|
|
364
370
|
|
|
365
371
|
// ─── K. Other feature routes ────────────────────────────────────────────────
|
|
@@ -825,10 +825,10 @@ describe('zodDefaultHook', () => {
|
|
|
825
825
|
const c = mockContext();
|
|
826
826
|
const result = zodDefaultHook({
|
|
827
827
|
success: false,
|
|
828
|
-
error: { issues: [{ message: 'field required' }, { message: 'invalid type' }] },
|
|
828
|
+
error: { issues: [{ message: 'field required', path: ['body', 'email'] }, { message: 'invalid type' }] },
|
|
829
829
|
}, c);
|
|
830
830
|
expect(result).toBeDefined();
|
|
831
|
-
expect(c.lastJson).toEqual({ code: 400, message: 'field required, invalid type' });
|
|
831
|
+
expect(c.lastJson).toEqual({ code: 400, message: 'body.email: field required, invalid type' });
|
|
832
832
|
expect(c.lastStatus).toBe(400);
|
|
833
833
|
});
|
|
834
834
|
|
|
@@ -841,13 +841,13 @@ describe('zodDefaultHook', () => {
|
|
|
841
841
|
expect(c.lastJson).toEqual({ code: 400, message: 'too short' });
|
|
842
842
|
});
|
|
843
843
|
|
|
844
|
-
it('handles empty issues →
|
|
844
|
+
it('handles empty issues → default message', () => {
|
|
845
845
|
const c = mockContext();
|
|
846
846
|
zodDefaultHook({
|
|
847
847
|
success: false,
|
|
848
848
|
error: { issues: [] },
|
|
849
849
|
}, c);
|
|
850
|
-
expect(c.lastJson).toEqual({ code: 400, message: '' });
|
|
850
|
+
expect(c.lastJson).toEqual({ code: 400, message: 'Request validation failed.' });
|
|
851
851
|
});
|
|
852
852
|
|
|
853
853
|
it('handles missing error.issues and error.errors', () => {
|
|
@@ -856,7 +856,7 @@ describe('zodDefaultHook', () => {
|
|
|
856
856
|
success: false,
|
|
857
857
|
error: {},
|
|
858
858
|
}, c);
|
|
859
|
-
expect(c.lastJson).toEqual({ code: 400, message: '' });
|
|
859
|
+
expect(c.lastJson).toEqual({ code: 400, message: 'Request validation failed.' });
|
|
860
860
|
});
|
|
861
861
|
|
|
862
862
|
it('handles undefined error', () => {
|
|
@@ -864,7 +864,16 @@ describe('zodDefaultHook', () => {
|
|
|
864
864
|
zodDefaultHook({
|
|
865
865
|
success: false,
|
|
866
866
|
}, c);
|
|
867
|
-
expect(c.lastJson).toEqual({ code: 400, message: '' });
|
|
867
|
+
expect(c.lastJson).toEqual({ code: 400, message: 'Request validation failed.' });
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
it('formats array indexes in issue paths', () => {
|
|
871
|
+
const c = mockContext();
|
|
872
|
+
zodDefaultHook({
|
|
873
|
+
success: false,
|
|
874
|
+
error: { issues: [{ message: 'Expected string', path: ['body', 'members', 0, 'email'] }] },
|
|
875
|
+
}, c);
|
|
876
|
+
expect(c.lastJson).toEqual({ code: 400, message: 'body.members[0].email: Expected string' });
|
|
868
877
|
});
|
|
869
878
|
});
|
|
870
879
|
|
|
@@ -1936,7 +1936,13 @@ export class DatabaseDO extends DurableObject<DOEnv> {
|
|
|
1936
1936
|
return c.json(normalizedDbError.toJSON(), normalizedDbError.code as 400);
|
|
1937
1937
|
}
|
|
1938
1938
|
console.error('DatabaseDO Error:', err);
|
|
1939
|
-
return c.json(
|
|
1939
|
+
return c.json(
|
|
1940
|
+
{
|
|
1941
|
+
code: 500,
|
|
1942
|
+
message: `Database request failed while handling '${c.req.path}'. Check the worker logs for the original exception.`,
|
|
1943
|
+
},
|
|
1944
|
+
500,
|
|
1945
|
+
);
|
|
1940
1946
|
});
|
|
1941
1947
|
|
|
1942
1948
|
return app;
|
|
@@ -114,6 +114,22 @@ function getRoomTimerHandlers(namespaceConfig?: RoomNamespaceConfig | null) {
|
|
|
114
114
|
return namespaceConfig?.state?.timers ?? namespaceConfig?.handlers?.timers;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
function warnRoomDevelopmentFallback(
|
|
118
|
+
namespace: string,
|
|
119
|
+
operation: 'join' | 'action',
|
|
120
|
+
): void {
|
|
121
|
+
const warningKey = `${namespace}:${operation}`;
|
|
122
|
+
if (roomFallbackWarnings.has(warningKey)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
roomFallbackWarnings.add(warningKey);
|
|
126
|
+
console.warn(
|
|
127
|
+
`[Room] ${warningKey} is allowed because release=false and no explicit room rule was found. `
|
|
128
|
+
+ `This fallback is local-dev only. Add rooms.${namespace}.access.${operation} or set `
|
|
129
|
+
+ `rooms.${namespace}.public.${operation}=true to make the behavior explicit.`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
117
133
|
function resolveRoomAuthTimeoutMs(config?: EdgeBaseConfig): number {
|
|
118
134
|
const value = config?.databaseLive?.authTimeoutMs;
|
|
119
135
|
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
@@ -307,30 +323,39 @@ export class RoomRuntimeBaseDO extends DurableObject<RoomDOEnv> {
|
|
|
307
323
|
this.ctx.waitUntil(persistRoomMonitoringSnapshot(this.env.KV, snapshotToPersist));
|
|
308
324
|
}
|
|
309
325
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
private async handleGetMetadata(url: URL): Promise<Response> {
|
|
313
|
-
// Resolve namespace if not set (DO may have been cold-started via HTTP)
|
|
326
|
+
protected hydrateRoomIdentityFromUrl(url: URL): void {
|
|
314
327
|
const roomFullName = url.searchParams.get('room');
|
|
315
|
-
if (roomFullName
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
this.
|
|
328
|
+
if (!roomFullName || this.namespace) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const separatorIdx = roomFullName.indexOf('::');
|
|
333
|
+
if (separatorIdx >= 0) {
|
|
334
|
+
this.namespace = roomFullName.substring(0, separatorIdx);
|
|
335
|
+
this.roomId = roomFullName.substring(separatorIdx + 2);
|
|
336
|
+
} else {
|
|
337
|
+
this.namespace = roomFullName;
|
|
338
|
+
this.roomId = roomFullName;
|
|
325
339
|
}
|
|
340
|
+
this.namespaceConfig = this.config.rooms?.[this.namespace] ?? null;
|
|
341
|
+
}
|
|
326
342
|
|
|
327
|
-
|
|
343
|
+
protected async getRoomMetadataSnapshot(): Promise<Record<string, unknown>> {
|
|
328
344
|
if (Object.keys(this._metadata).length === 0) {
|
|
329
345
|
const saved = await this.ctx.storage.get('roomMetadata') as Record<string, unknown> | undefined;
|
|
330
346
|
if (saved) this._metadata = saved;
|
|
331
347
|
}
|
|
332
348
|
|
|
333
|
-
return
|
|
349
|
+
return cloneState(this._metadata);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ─── Metadata HTTP Handler ───
|
|
353
|
+
|
|
354
|
+
private async handleGetMetadata(url: URL): Promise<Response> {
|
|
355
|
+
this.hydrateRoomIdentityFromUrl(url);
|
|
356
|
+
const metadata = await this.getRoomMetadataSnapshot();
|
|
357
|
+
|
|
358
|
+
return new Response(JSON.stringify(metadata), {
|
|
334
359
|
headers: { 'Content-Type': 'application/json' },
|
|
335
360
|
});
|
|
336
361
|
}
|
|
@@ -339,19 +364,7 @@ export class RoomRuntimeBaseDO extends DurableObject<RoomDOEnv> {
|
|
|
339
364
|
|
|
340
365
|
private handleWebSocketUpgrade(request: Request): Response {
|
|
341
366
|
const url = new URL(request.url);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
if (roomFullName) {
|
|
345
|
-
const separatorIdx = roomFullName.indexOf('::');
|
|
346
|
-
if (separatorIdx >= 0) {
|
|
347
|
-
this.namespace = roomFullName.substring(0, separatorIdx);
|
|
348
|
-
this.roomId = roomFullName.substring(separatorIdx + 2);
|
|
349
|
-
} else {
|
|
350
|
-
this.namespace = roomFullName;
|
|
351
|
-
this.roomId = roomFullName;
|
|
352
|
-
}
|
|
353
|
-
this.namespaceConfig = this.config.rooms?.[this.namespace] ?? null;
|
|
354
|
-
}
|
|
367
|
+
this.hydrateRoomIdentityFromUrl(url);
|
|
355
368
|
|
|
356
369
|
// Check max players
|
|
357
370
|
const maxPlayers = this.namespaceConfig?.maxPlayers ?? DEFAULT_MAX_PLAYERS;
|
|
@@ -378,9 +391,13 @@ export class RoomRuntimeBaseDO extends DurableObject<RoomDOEnv> {
|
|
|
378
391
|
};
|
|
379
392
|
|
|
380
393
|
// Accept with Hibernation API
|
|
394
|
+
const roomFullName =
|
|
395
|
+
this.namespace && this.roomId
|
|
396
|
+
? `${this.namespace}::${this.roomId}`
|
|
397
|
+
: url.searchParams.get('room') ?? '';
|
|
381
398
|
const tags = [
|
|
382
399
|
`conn:${connectionId}`,
|
|
383
|
-
`room:${roomFullName
|
|
400
|
+
`room:${roomFullName}`,
|
|
384
401
|
];
|
|
385
402
|
if (meta.ip) {
|
|
386
403
|
tags.push(`ip:${encodeURIComponent(meta.ip)}`);
|
|
@@ -794,11 +811,7 @@ export class RoomRuntimeBaseDO extends DurableObject<RoomDOEnv> {
|
|
|
794
811
|
return;
|
|
795
812
|
}
|
|
796
813
|
if (!this.config.release && this.namespace) {
|
|
797
|
-
|
|
798
|
-
if (!roomFallbackWarnings.has(warningKey)) {
|
|
799
|
-
roomFallbackWarnings.add(warningKey);
|
|
800
|
-
console.warn(`[Room] ${warningKey} is using development-mode allow-by-default. Add rooms.${this.namespace}.access.join or public.join to make this explicit.`);
|
|
801
|
-
}
|
|
814
|
+
warnRoomDevelopmentFallback(this.namespace, 'join');
|
|
802
815
|
}
|
|
803
816
|
}
|
|
804
817
|
if (joinAccess && this.roomId) {
|
|
@@ -947,11 +960,7 @@ export class RoomRuntimeBaseDO extends DurableObject<RoomDOEnv> {
|
|
|
947
960
|
return;
|
|
948
961
|
}
|
|
949
962
|
if (!this.config.release && this.namespace) {
|
|
950
|
-
|
|
951
|
-
if (!roomFallbackWarnings.has(warningKey)) {
|
|
952
|
-
roomFallbackWarnings.add(warningKey);
|
|
953
|
-
console.warn(`[Room] ${warningKey} is using development-mode allow-by-default. Add rooms.${this.namespace}.access.action or public.action to make this explicit.`);
|
|
954
|
-
}
|
|
963
|
+
warnRoomDevelopmentFallback(this.namespace, 'action');
|
|
955
964
|
}
|
|
956
965
|
}
|
|
957
966
|
if (actionAccess && this.roomId) {
|
|
@@ -94,6 +94,17 @@ interface RoomMemberPresence {
|
|
|
94
94
|
state: Record<string, unknown>;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
interface RoomSummaryResponse {
|
|
98
|
+
namespace: string;
|
|
99
|
+
roomId: string;
|
|
100
|
+
metadata: Record<string, unknown>;
|
|
101
|
+
occupancy: {
|
|
102
|
+
activeMembers: number;
|
|
103
|
+
activeConnections: number;
|
|
104
|
+
};
|
|
105
|
+
updatedAt: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
97
108
|
interface RoomMemberRealtimeSession {
|
|
98
109
|
sessionId: string;
|
|
99
110
|
connectionId?: string;
|
|
@@ -155,6 +166,10 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
155
166
|
override async fetch(request: Request): Promise<Response> {
|
|
156
167
|
const url = new URL(request.url);
|
|
157
168
|
|
|
169
|
+
if (url.pathname === '/summary' && request.method === 'GET') {
|
|
170
|
+
return this.handleSummaryGet(url);
|
|
171
|
+
}
|
|
172
|
+
|
|
158
173
|
if (url.pathname === '/media/cloudflare_realtimekit/session' && request.method === 'POST') {
|
|
159
174
|
return this.handleCloudflareRealtimeKitSessionCreate(request, url);
|
|
160
175
|
}
|
|
@@ -184,6 +199,22 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
184
199
|
return super.fetch(request);
|
|
185
200
|
}
|
|
186
201
|
|
|
202
|
+
private async handleSummaryGet(url: URL): Promise<Response> {
|
|
203
|
+
this.hydrateRoomIdentityFromUrl(url);
|
|
204
|
+
const metadata = await this.getRoomMetadataSnapshot();
|
|
205
|
+
|
|
206
|
+
return this.jsonResponse<RoomSummaryResponse>(200, {
|
|
207
|
+
namespace: this.namespace ?? '',
|
|
208
|
+
roomId: this.roomId ?? '',
|
|
209
|
+
metadata,
|
|
210
|
+
occupancy: {
|
|
211
|
+
activeMembers: this.members.size,
|
|
212
|
+
activeConnections: this.joinedConnectionIds.size,
|
|
213
|
+
},
|
|
214
|
+
updatedAt: new Date().toISOString(),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
187
218
|
private async handleCloudflareRealtimeKitSessionCreate(request: Request, url: URL): Promise<Response> {
|
|
188
219
|
try {
|
|
189
220
|
const body = await this.readJsonBody<{
|
|
@@ -639,7 +670,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
639
670
|
|
|
640
671
|
const token = this.extractBearerToken(request);
|
|
641
672
|
if (!token) {
|
|
642
|
-
throw new Error('Authentication required');
|
|
673
|
+
throw new Error('Authentication required before the room connection could be established.');
|
|
643
674
|
}
|
|
644
675
|
|
|
645
676
|
const { resolveAuthContextFromToken } = await import('../middleware/auth.js');
|