@undefineds.co/xpod 0.4.25 → 0.4.28
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/api/ApiServer.d.ts +1 -0
- package/dist/api/ApiServer.js +38 -0
- package/dist/api/ai-config/AiConfigStore.js +18 -6
- package/dist/api/ai-gateway/connect/index.d.ts +1 -0
- package/dist/api/ai-gateway/connect/index.js +39 -18
- package/dist/api/ai-gateway/models/ProviderModelsAdapter.js +5 -2
- package/dist/api/container/common.js +8 -2
- package/dist/api/container/index.js +2 -2
- package/dist/api/container/local.js +6 -3
- package/dist/api/handlers/AiGatewayHandler.d.ts +1 -0
- package/dist/api/handlers/AiGatewayHandler.js +53 -3
- package/dist/api/handlers/AiGatewayManagementHandler.js +9 -0
- package/dist/api/handlers/TaskHandler.js +15 -10
- package/dist/api/network/NetworkEnvironmentConfigurationStore.js +1 -1
- package/dist/api/runs/ManagedRunWorker.d.ts +0 -1
- package/dist/api/runs/ManagedRunWorker.js +2 -14
- package/dist/api/runs/PiAgentRuntimeDriver.d.ts +0 -8
- package/dist/api/runs/PiAgentRuntimeDriver.js +65 -21
- package/dist/api/runs/RunStateCenter.js +1 -0
- package/dist/api/runs/store.d.ts +1 -0
- package/dist/api/runs/store.js +13 -0
- package/dist/api/tasks/TaskMaterializer.js +13 -6
- package/dist/api/tasks/TaskResumeDiagnostics.d.ts +28 -0
- package/dist/api/tasks/TaskResumeDiagnostics.js +148 -0
- package/dist/api/tasks/TaskService.js +40 -23
- package/dist/storage/conditions/StorageETagHandler.d.ts +1 -1
- package/dist/storage/conditions/StorageETagHandler.js +13 -4
- package/dist/util/task-model-diagnostics.d.ts +67 -0
- package/dist/util/task-model-diagnostics.js +118 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.js +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectDialog.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.js +10 -10
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeyRow.d.ts +3 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeyRow.js +2 -2
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.js +77 -23
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiSortableCredentialList.js +59 -59
- package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.js +2 -0
- package/node_modules/@undefineds.co/ai-connections/dist/collections.js +14 -6
- package/node_modules/@undefineds.co/ai-connections/dist/contract/ai-connections-client.d.ts +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/contract/ai-connections-client.js +1 -0
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/gateway-model-roles.d.ts +11 -0
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/gateway-model-roles.js +11 -0
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/normalize.d.ts +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/normalize.js +12 -5
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/request.js +10 -2
- package/node_modules/@undefineds.co/ai-connections/dist/contract/client/types.d.ts +10 -0
- package/node_modules/@undefineds.co/ai-connections/package.json +1 -1
- package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +1 -0
- package/node_modules/@undefineds.co/extension-sdk/package.json +1 -1
- package/node_modules/@undefineds.co/pod-collections/dist/index.cjs +60 -13
- package/node_modules/@undefineds.co/pod-collections/dist/mapping.d.ts +16 -1
- package/node_modules/@undefineds.co/pod-collections/dist/mapping.js +51 -0
- package/node_modules/@undefineds.co/pod-collections/dist/mutations.js +14 -18
- package/node_modules/@undefineds.co/pod-collections/package.json +1 -1
- package/node_modules/@undefineds.co/shared-ui/dist/list.d.ts +8 -1
- package/node_modules/@undefineds.co/shared-ui/dist/list.js +4 -1
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpChrome.d.ts +1 -1
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpChrome.js +2 -2
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/IdpViews.js +2 -2
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignInFrame.d.ts +3 -3
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/PodSignInFrame.js +5 -5
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/parts.d.ts +5 -5
- package/node_modules/@undefineds.co/shared-ui/dist/pod-sign-in/parts.js +5 -5
- package/node_modules/@undefineds.co/shared-ui/dist/section-header.js +1 -1
- package/node_modules/@undefineds.co/shared-ui/dist/theme.css +5 -32
- package/node_modules/@undefineds.co/shared-ui/package.json +1 -1
- package/node_modules/@undefineds.co/solid-sdk/package.json +1 -1
- package/package.json +2 -2
- package/static/app/assets/main.css +1 -1
- package/static/app/assets/main.js +1 -1
- package/static/dashboard/assets/AccountAuthBoundary-Dv52SZc6.js +1 -0
- package/static/dashboard/assets/DesktopOidcCallback-DaT_Rumf.js +1 -0
- package/static/dashboard/assets/DevicePages-HjclpIVm.js +2 -0
- package/static/dashboard/assets/ModelsPage-Be2TPd-x.js +11 -0
- package/static/dashboard/assets/{PaneListHeader-Dn5O0mwy.js → PaneListHeader-DtvnRmFq.js} +1 -1
- package/static/dashboard/assets/{PodDeletionAuthorizationPanel-D3NOG6ZM.js → PodDeletionAuthorizationPanel-BJk_8rJq.js} +3 -3
- package/static/dashboard/assets/PodPage-C4gzEspV.js +1 -0
- package/static/dashboard/assets/{SystemSettingsPage-BNQP_Yuc.js → SystemSettingsPage-HaNrP1H1.js} +1 -1
- package/static/dashboard/assets/TasksPage-BdO5K2L7.js +1 -0
- package/static/dashboard/assets/{WebDesktopEntry-vnb4CZWp.js → WebDesktopEntry-Cj9_ZfJU.js} +1 -1
- package/static/dashboard/assets/XpodAiConnectionsPodStore-B7gmXBmC.js +3 -0
- package/static/dashboard/assets/XpodShellApp-D_KY4nCW.js +4 -0
- package/static/dashboard/assets/{account-session-DCUmCop1.js → account-session-DlcKNG7k.js} +1 -1
- package/static/dashboard/assets/{button-By5Bgvmb.js → button-wslF55uZ.js} +1 -1
- package/static/dashboard/assets/collection-runtime-uxxgEu13.js +1 -0
- package/static/dashboard/assets/{createLucideIcon-bunMzPms.js → createLucideIcon-BJQl82Qk.js} +1 -1
- package/static/dashboard/assets/dashboard-CbJ-JkrI.css +1 -0
- package/static/dashboard/assets/{dashboard-mlsg3yaw.js → dashboard-Or0gnkou.js} +2 -2
- package/static/dashboard/assets/index-BqFeOML9.js +1 -0
- package/static/dashboard/assets/{index-DvMG5pHk.js → index-DgKn1twH.js} +2 -2
- package/static/dashboard/assets/{label-Bj03L9xs.js → label-CS6Sx6Zb.js} +1 -1
- package/static/dashboard/assets/list-UyhlCFKk.js +1 -0
- package/static/dashboard/assets/{nav-item-style-BNqWQY6p.js → nav-item-style-CW1Nnorq.js} +1 -1
- package/static/dashboard/assets/{pod-collections-host-KnnGFZHL.js → pod-collections-host-DjK2xf-b.js} +6 -6
- package/static/dashboard/assets/{safe-continuation-D9AhcWiB.js → safe-continuation-ClWAhcma.js} +1 -1
- package/static/dashboard/assets/{section-header-CLCzbOp_.js → section-header-CEIEcco-.js} +1 -1
- package/static/dashboard/assets/{setting-row-DTCec8A2.js → setting-row-CaYv3dfF.js} +1 -1
- package/static/dashboard/assets/xpod-remembered-login-BUF9fin1.js +310 -0
- package/static/dashboard/dashboard.html +2 -2
- package/static/settings/assets/{AccountAuthBoundary-C0og_gIA.js → AccountAuthBoundary-Chqd38oU.js} +1 -1
- package/static/settings/assets/{DesktopOidcCallback-C5q4oFZ0.js → DesktopOidcCallback-VUrOSM_q.js} +1 -1
- package/static/settings/assets/DevicePages-C6qwvWwu.js +2 -0
- package/static/settings/assets/ModelsPage-Ry_dObRQ.js +11 -0
- package/static/settings/assets/{PaneListHeader-DqVlMe2D.js → PaneListHeader-B5RkRqr4.js} +1 -1
- package/static/settings/assets/{PodDeletionAuthorizationPanel-DgVvarVY.js → PodDeletionAuthorizationPanel-DPM-5Izt.js} +3 -3
- package/static/settings/assets/PodPage-CxND6wwc.js +1 -0
- package/static/settings/assets/{SystemSettingsPage-Crzm_DrI.js → SystemSettingsPage-C8EdMkW7.js} +1 -1
- package/static/settings/assets/TasksPage-DuqptEm8.js +1 -0
- package/static/settings/assets/{WebDesktopEntry-BGC5eRF2.js → WebDesktopEntry-BRcyktkv.js} +1 -1
- package/static/settings/assets/XpodAiConnectionsPodStore-CyA_BJVC.js +3 -0
- package/static/settings/assets/XpodShellApp-CsivHJl0.js +4 -0
- package/static/settings/assets/XpodThemeProvider-CbJ-JkrI.css +1 -0
- package/static/settings/assets/{XpodThemeProvider-CB6LepTA.js → XpodThemeProvider-DK3pIdRG.js} +2 -2
- package/static/settings/assets/{account-session-BcLjCj0x.js → account-session-DJOZ03xr.js} +1 -1
- package/static/settings/assets/auth-callback-GIBYEz_7.js +1 -0
- package/static/settings/assets/{button-BObT8pTE.js → button-D3yW-2o1.js} +1 -1
- package/static/settings/assets/collection-runtime-DfGo25mh.js +1 -0
- package/static/settings/assets/{createLucideIcon-BVsUxXpZ.js → createLucideIcon-CacwLsmB.js} +1 -1
- package/static/settings/assets/{index-ktjMkj7-.js → index-r5KRYsKC.js} +1 -1
- package/static/settings/assets/{label-BrqO8_m_.js → label-MJjUmvzG.js} +1 -1
- package/static/settings/assets/list-Ce-5k1MX.js +1 -0
- package/static/settings/assets/{nav-item-style-Di2CxkDU.js → nav-item-style-ZUbL8KOZ.js} +1 -1
- package/static/settings/assets/{pod-collections-host-KnnGFZHL.js → pod-collections-host-DjK2xf-b.js} +6 -6
- package/static/settings/assets/{safe-continuation-Dx6ceJpY.js → safe-continuation-vlBZFSlU.js} +1 -1
- package/static/settings/assets/{section-header-Dtl7yjVr.js → section-header-DGJdEvQw.js} +1 -1
- package/static/settings/assets/{setting-row-BL6Hhe8N.js → setting-row-C7tuFiho.js} +1 -1
- package/static/settings/assets/{settings-DaRBxoZk.js → settings-CyQPih1O.js} +1 -1
- package/static/settings/assets/xpod-remembered-login-D-TzzT5K.js +567 -0
- package/static/settings/auth-callback.html +3 -3
- package/static/settings/settings.html +3 -3
- package/static/dashboard/assets/AccountAuthBoundary-BvoDydRz.js +0 -1
- package/static/dashboard/assets/DesktopOidcCallback-BwIj874x.js +0 -1
- package/static/dashboard/assets/DevicePages-jOjMcvsr.js +0 -2
- package/static/dashboard/assets/ModelsPage-CMTdfqBR.js +0 -11
- package/static/dashboard/assets/PodPage-BueBdJ9_.js +0 -1
- package/static/dashboard/assets/TasksPage-CxtLJiSF.js +0 -1
- package/static/dashboard/assets/XpodAiConnectionsPodStore-wx3Ttupm.js +0 -18
- package/static/dashboard/assets/XpodShellApp-5FWY8-d5.js +0 -4
- package/static/dashboard/assets/collection-runtime-BnomuB0E.js +0 -1
- package/static/dashboard/assets/dashboard-C64R553B.css +0 -1
- package/static/dashboard/assets/xpod-remembered-login-Dr69A0Rv.js +0 -295
- package/static/settings/assets/DevicePages-fyHjjucT.js +0 -2
- package/static/settings/assets/ModelsPage-EyOByLyE.js +0 -11
- package/static/settings/assets/PodPage-DY4Oi9wg.js +0 -1
- package/static/settings/assets/TasksPage-CfXJbnlt.js +0 -1
- package/static/settings/assets/XpodAiConnectionsPodStore-CXcmgKmQ.js +0 -3
- package/static/settings/assets/XpodShellApp-D1PS3Iut.js +0 -4
- package/static/settings/assets/XpodThemeProvider-C64R553B.css +0 -1
- package/static/settings/assets/auth-callback-DSPQ28ar.js +0 -1
- package/static/settings/assets/collection-runtime-DzNbdZGe.js +0 -1
- package/static/settings/assets/index-browser-3WfrNbcG.js +0 -273
- package/static/settings/assets/xpod-remembered-login-Q66DH12t.js +0 -295
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as m,j as e}from"./dashboard-Or0gnkou.js";import{B as v,c as F}from"./button-wslF55uZ.js";import{a as K,c as I,u as z,r as Z,e as Q,d as ee}from"./account-session-DlcKNG7k.js";import{W as te,Y as U,I as re,Z as se,_ as ae,$ as ne,K as oe,a0 as ie,a1 as W,a2 as ce,X as le,a3 as de}from"./xpod-remembered-login-BUF9fin1.js";import{C as ue,b as me,d as fe,e as pe,I as H,f as he,x as xe,g as ge,h as we,s as M}from"./PodDeletionAuthorizationPanel-BJk_8rJq.js";import{L as _}from"./label-CS6Sx6Zb.js";import"./createLucideIcon-BJQl82Qk.js";import"@comunica/query-sparql-solid";function je({frame:r,children:t}){return r==="bare"?e.jsx("div",{"data-account-credentials-frame":"bare",className:"w-full text-card-foreground",children:t}):e.jsx(he,{"data-account-credentials-frame":"card",className:"w-full border-border bg-card text-card-foreground",children:t})}function $(r,t,s,a,n){a({...r,[t]:s}),n?.(t,s)}function B({id:r,message:t}){return t?e.jsxs("p",{id:r,role:"alert","aria-live":"polite",className:"flex items-center gap-1.5 text-sm text-destructive",children:[e.jsx(re,{"aria-hidden":"true",className:"h-4 w-4 shrink-0"}),t]}):null}function be({id:r,label:t,error:s,children:a}){return e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{"data-floating-field":"true",className:"relative",children:[a,e.jsx(_,{htmlFor:r,className:"pointer-events-none absolute left-3 top-0 z-[1] -translate-y-1/2 bg-card px-1 text-xs leading-none text-muted-foreground transition-[color,font-size,top,transform] duration-150 peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:text-sm peer-focus:top-0 peer-focus:-translate-y-1/2 peer-focus:text-xs peer-focus:text-ring peer-disabled:opacity-50 peer-aria-[invalid=true]:text-destructive",children:t})]}),e.jsx(B,{id:`${r}-error`,message:s})]})}function ve({id:r,label:t,error:s,children:a}){return e.jsxs("div",{className:"space-y-2",children:[e.jsx(_,{htmlFor:r,children:t}),a,e.jsx(B,{id:`${r}-error`,message:s})]})}function D({id:r,label:t,error:s,floating:a,children:n}){const o=a?be:ve;return e.jsx(o,{id:r,label:t,error:s,children:n})}function ye({mode:r,values:t,onChange:s,onSubmit:a,onFieldChange:n,onModeChange:o,rememberAccount:d=!0,onRememberAccountChange:h,pending:u=!1,errors:c,copy:i,frame:p="card",showHeader:E=!0,presentation:R="standard"}){const[y,A]=m.useState(!1),[C,P]=m.useState(!1),N=m.useId(),j=m.useId(),x=m.useId(),b=m.useId(),f=r==="register",S=f&&t.password.length>0&&t.confirmation!==void 0&&t.password!==t.confirmation,w=S&&(y||C)?i.mismatchError:void 0,T=f?i.registerAction:i.loginAction,l=R==="compact",X=l?"peer h-11 rounded-xl px-3 pb-2 pt-4":void 0,G=g=>{if(g?.preventDefault(),!u){if(f&&S){A(!0);return}A(!1),a(t)}},J=e.jsxs(e.Fragment,{children:[E?e.jsxs(ue,{children:[e.jsx(me,{children:f?i.registerTitle:i.loginTitle}),e.jsx(fe,{children:i.productName})]}):null,e.jsx(pe,{className:F(p==="bare"?"p-0":E?void 0:"pt-6"),children:e.jsxs("form",{onSubmit:G,className:l?"space-y-3":"space-y-4",children:[e.jsx(D,{floating:l,id:N,label:i.emailLabel,error:c?.email,children:e.jsx(te,{id:N,name:"email",autoComplete:"email",placeholder:l?" ":i.emailPlaceholder,title:i.emailPlaceholder,value:t.email??"",disabled:u,"aria-invalid":c?.email?!0:void 0,"aria-describedby":c?.email?`${N}-error`:void 0,className:X,onChange:g=>$(t,"email",g.currentTarget.value,s,n)})}),e.jsx(D,{floating:l,id:j,label:i.passwordLabel,error:c?.password,children:e.jsx(H,{id:j,name:"password",type:"password",autoComplete:f?"new-password":"current-password",placeholder:l?" ":i.passwordPlaceholder,title:i.passwordPlaceholder,value:t.password,disabled:u,"aria-invalid":c?.password?!0:void 0,"aria-describedby":c?.password?`${j}-error`:void 0,className:X,onChange:g=>$(t,"password",g.currentTarget.value,s,n)})}),f?e.jsx(D,{floating:l,id:x,label:i.confirmationLabel,error:w??c?.confirmation,children:e.jsx(H,{id:x,name:"confirmation",type:"password",autoComplete:"new-password",placeholder:l?" ":i.confirmationPlaceholder,title:i.confirmationPlaceholder,value:t.confirmation??"",onBlur:()=>P(!0),disabled:u,"aria-invalid":w||c?.confirmation?!0:void 0,"aria-describedby":w||c?.confirmation?`${x}-error`:void 0,className:X,onChange:g=>{A(!1),$(t,"confirmation",g.currentTarget.value,s,n)}})}):null,!f&&h?e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",name:"remember",checked:d,disabled:u,onChange:g=>h(g.currentTarget.checked)}),"记住账号"]}):null,e.jsx(B,{id:b,message:c?.form}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs(v,{type:"submit",className:F("w-full",l&&"h-10 rounded-xl"),disabled:u,children:[u?e.jsx(U,{"aria-hidden":"true",className:"mr-2 h-4 w-4 animate-spin"}):null,T]}),o?e.jsx(v,{type:"button",variant:"ghost",className:F("w-full",l&&"h-9 rounded-lg text-xs"),disabled:u,onClick:()=>o(f?"login":"register"),children:f?i.switchToLogin:i.switchToRegister}):null]})]})})]});return e.jsx(je,{frame:p,children:J})}function Ae(){const[r,t]=m.useState(!1),[s,a]=m.useState(!1),n=m.useRef(!1);if(!window.xpodDesktop?.cancelLogin)return null;const o=async()=>{const d=window.xpodDesktop;if(!(n.current||!d?.cancelLogin)){n.current=!0,t(!0),a(!1);try{await d.cancelLogin()}catch{a(!0)}finally{n.current=!1,t(!1)}}};return e.jsxs("div",{className:"space-y-2",children:[s&&e.jsx("p",{role:"alert",className:"text-sm text-destructive",children:"返回应用未完成,请重试。"}),e.jsx(v,{type:"button",variant:"ghost",className:"w-full",disabled:r,"aria-busy":r,onClick:()=>{o()},children:r?"正在返回…":"返回应用"})]})}function Ce(r,t){const s=Y(r,t),[a,n]=m.useState();s&&a&&a.issuer===void 0&&n({issuer:s,value:a.value});const o=s?se(s):void 0;return[a&&(a.issuer===s||a.issuer===void 0)?a.value:o??!1,u=>n({issuer:s,value:u})]}function Y(r,t){const s=t?void 0:K(r);return s?new URL(s).origin:void 0}function Ne(r,t,s){const a=Y(r,t),n=c=>ae(void 0,c)??"",[o,d]=m.useState(()=>({issuer:a,values:{email:s??(a?n(a):""),password:"",confirmation:""},emailEdited:!1}));let h=o;if(a&&o.issuer!==a){const c=o.issuer===void 0;h={issuer:a,values:c?{...o.values,email:o.emailEdited?o.values.email:s??n(a)}:{email:n(a),password:"",confirmation:""},emailEdited:c&&o.emailEdited},d(h)}const u=c=>{d(i=>{const p=typeof c=="function"?c(i.values):c;return{...i,values:p,emailEdited:i.emailEdited||p.email!==i.values.email}})};return[h.values,u,a]}class Se extends Error{code;constructor(t,s){super(t),this.name="RegistrationError",this.code=s}}async function Ee(r){const t=await r.json().catch(()=>{});return t?.message||t?.error}async function Re(r){const s=await(r.fetchImpl??fetch)(I(r.loginUrl),{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},credentials:"include",body:JSON.stringify({email:r.email,password:r.password,...r.remember===void 0?{}:{remember:r.remember}})});if(!s.ok){const o=await Ee(s);throw r.duplicateEmailRecovery?new Se(xe.emailAlreadyRegisteredPasswordMismatch,"EMAIL_ALREADY_REGISTERED"):new Error(o||"Auto-login failed")}const a=await s.json().catch(()=>({})),n=typeof a.authorization=="string"?a.authorization:"";if(!n)throw new Error("Account token not returned after login");return{accountToken:n}}class V extends Error{status;constructor(t){super(`Password login failed with status ${t}`),this.name="PasswordLoginStatusError",this.status=t}}function O({surface:r,onAuthenticated:t,initialEmail:s}){const{controls:a,idpIndex:n,refetchControls:o,isInitializing:d}=z(),[h,u,c]=Ne(n,d,s),[i,p]=m.useState(),[E,R]=m.useState(!1),[y,A]=Ce(n,d),C=m.useRef(!1),P=async x=>{if(!(C.current||d)){C.current=!0,R(!0),p(void 0);try{const b=await Z(a?.password?.login,fetch,n)??I("/.account/login/password/"),f=await Re({email:x.email?.trim()??"",password:x.password,loginUrl:b,remember:y,fetchImpl:async(w,T)=>{const l=await fetch(typeof w=="string"||w instanceof URL?I(w):w,T);if(!l.ok)throw new V(l.status);return l}});Q(f.accountToken),ie(x.email?.trim()??"",void 0,n,y);const S=await o();if(S?.status!=="authenticated"){S?.status==="anonymous"&&ee(),p("登录失败,请重试。");return}await t?.()}catch(b){p(b instanceof V?M(b.status):M(500))}finally{C.current=!1,R(!1)}}},N=x=>{u(x),i&&p(void 0)},j={surface:"page",surfaceTitle:"登录 Xpod",copy:ge,registerHref:r==="embedded"?void 0:k("register"),forgotHref:r==="embedded"?void 0:k("forgot"),mode:"login",values:h,onChange:N,onSubmit:P,pending:E,rememberAccount:y,onRememberAccountChange:A,errors:i?{form:i}:void 0};return r==="embedded"?e.jsx(ye,{...j,presentation:"compact",frame:"bare",showHeader:!1}):e.jsx(ne,{...j},c??"bootstrap")}function k(r){let t="";try{const s=oe(`${window.location.pathname}${window.location.search}`);s&&(t=`?${new URLSearchParams({returnTo:s})}`)}catch{}return I(`/.account/login/password/${r}/${t}`)}function Le(){return e.jsxs("div",{className:"flex items-center justify-center gap-3 text-xs text-muted-foreground",children:[e.jsx(v,{asChild:!0,variant:"ghost",className:"h-auto px-2 py-1 text-xs font-normal text-muted-foreground hover:text-foreground",children:e.jsx("a",{href:k("register"),children:"创建账号"})}),e.jsx("span",{"aria-hidden":"true",className:"text-border",children:"·"}),e.jsx(v,{asChild:!0,variant:"ghost",className:"h-auto px-2 py-1 text-xs font-normal text-muted-foreground hover:text-foreground",children:e.jsx("a",{href:k("forgot"),children:we.forgotPassword})})]})}function ze({children:r}){return W().state.status==="authenticated"?e.jsx(e.Fragment,{children:r}):e.jsx(q,{children:r})}function Be({children:r}){const t=W(),s=z();return t.state.status==="authenticated"||s.accountState.status==="authenticated"||!Ie()?e.jsx(e.Fragment,{children:r}):e.jsx(q,{})}function Ie(){return typeof window>"u"?!1:new URLSearchParams(window.location.search).get("account")==="open"}function q({children:r,accountState:t,retry:s,surface:a="page"}){const n=z(),o=t??n.accountState,d=s??n.retry;return o.status==="authenticated"?e.jsx(e.Fragment,{children:r}):o.status==="submitting"?e.jsx(L,{surface:a,children:e.jsxs("div",{role:"status","aria-live":"polite",className:"flex items-center justify-center gap-2 p-6 text-sm text-muted-foreground",children:[e.jsx(U,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"正在登录…"]})}):o.status==="initializing"?e.jsx(L,{surface:a,children:e.jsxs("div",{role:"status","aria-live":"polite",className:"flex items-center justify-center gap-2 p-6 text-sm text-muted-foreground",children:[e.jsx(U,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"正在加载账号"]})}):o.status==="error"?e.jsx(L,{surface:a,children:e.jsxs("div",{className:"space-y-4 p-6",children:[e.jsx("p",{role:"alert",className:"text-sm text-destructive",children:o.message}),e.jsx(v,{className:"w-full",type:"button",onClick:()=>{d()},children:"重试"}),e.jsx(Ae,{})]})}):a==="embedded"?e.jsxs(L,{surface:a,children:[e.jsx(O,{surface:"embedded"}),e.jsx("div",{className:"mt-6 space-y-3 border-t pt-5",children:e.jsx(Le,{})})]}):e.jsx(O,{surface:"page"})}function L({children:r,surface:t}){return t==="embedded"?e.jsx(ce,{title:"登录 Xpod",presentation:"compact",serviceIcon:e.jsx(le,{}),children:r}):e.jsx(de,{title:"登录 Xpod",presentation:"compact",children:r})}export{q as AccountAuthBoundary,ze as AccountWorkspaceBoundary,Be as LocalServiceSurfaceBoundary};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as l,r as v}from"./dashboard-Or0gnkou.js";import{X as oe,H as V,I as ce,J as de,K as U,L as le,M,N as H,O as ue,Q as fe,R as me,T as ge,U as pe,V as he}from"./xpod-remembered-login-BUF9fin1.js";import{C as we,s as ve,c as k,X,r as xe,a as Q,p as be,b as Re}from"./XpodShellApp-D_KY4nCW.js";import{X as ye}from"./account-session-DlcKNG7k.js";import{B as K}from"./button-wslF55uZ.js";import"./createLucideIcon-BJQl82Qk.js";import"./PodDeletionAuthorizationPanel-BJk_8rJq.js";import"@comunica/query-sparql-solid";import"./safe-continuation-ClWAhcma.js";import"./nav-item-style-CW1Nnorq.js";function Z({compact:e=!1,showSubtitle:t=!e,subtitle:n="使用 WebID 登录"}){const r=e&&t;return l.jsx("div",{"data-testid":"xpod-login-brand","data-presentation":e?"compact":"standard",className:r?"flex flex-col items-center justify-center gap-1 text-center":e?"flex items-center justify-center gap-2 text-center":"flex flex-col items-center gap-3 text-center",children:l.jsx(oe,{renderLogo:a=>l.jsxs("div",{className:r?"flex flex-col items-center gap-1":e?"flex items-center gap-2":"flex flex-col items-center gap-3",children:[l.jsx(ye,{className:e?r?"h-16 w-16":"h-7 w-7":"h-11 w-11"}),l.jsxs("div",{className:r?"space-y-1 text-center":e?"text-left":"space-y-1",children:[l.jsx("h1",{className:e?"text-base font-semibold leading-none text-foreground":"text-lg font-semibold text-foreground",children:"Xpod"}),l.jsx("p",{className:"text-[9px] leading-none text-primary",children:a}),t?l.jsx("p",{className:"text-xs text-primary/80",children:n}):null]})]})})})}const $="xpod.auth.callback.identity.v1.",Se=new Set(["provision-status-unavailable","profile-read-failed","no-usable-access-route","pod-open-failed"]),I="xpod.auth.callback.completed.v1.",ee=600*1e3,F="solidClientAuthn:currentUrl",S=new Map,q=new Set(["webid-mismatch","binding-mismatch"]),T={"missing-transaction":{title:"登录请求已失效",message:"这次登录请求已经失效,请重新登录。",action:"重新登录"},"replayed-transaction":{title:"登录请求已使用",message:"这次登录请求已经完成,不能再次使用。请重新登录。",action:"重新登录"},"expired-transaction":{title:"登录请求已过期",message:"登录等待时间过长,请重新登录。",action:"重新登录"},"malformed-transaction":{title:"登录请求无效",message:"登录信息不完整或已被修改,请重新登录。",action:"重新登录"},"oidc-state-invalid":{title:"登录验证已失效",message:"登录页面与当前会话不再匹配,请重新登录。",action:"重新登录"},"oidc-provider-error":{title:"授权未完成",message:"身份服务未能完成此次授权,请重新登录。",action:"重新登录"},unauthenticated:{title:"登录没有完成",message:"Xpod 没有收到有效的 WebID,请重新登录。",action:"重新登录"},"unsafe-route":{title:"登录请求不安全",message:"Xpod 已阻止异常的登录来源,请从应用内重新登录。",action:"重新登录"},"unsafe-return-to":{title:"登录请求不安全",message:"Xpod 已阻止异常的返回地址,请从应用内重新登录。",action:"重新登录"},"missing-storage":{title:"没有可用的 Pod",message:"当前账号还没有可用于本次登录的 Pod,请返回后重试。",action:"返回并重试"},"provision-status-unavailable":{title:"暂时无法确认本机 Pod",message:"Xpod 暂时无法读取存储服务状态,请稍后重试。",action:"重试连接"},"local-binding-missing":{title:"本机绑定尚未完成",message:"当前账号还没有绑定到这台 Xpod。请先修复本机初始化,再重新登录。",action:"修复本机绑定"},"webid-mismatch":{title:"身份与 Pod 不匹配",message:"本次登录身份与所选 Pod 不一致,请重新登录。",action:"重新登录"},"binding-mismatch":{title:"身份与 Pod 不匹配",message:"Xpod 无法确认当前身份拥有所选 Pod,请重新登录。",action:"重新登录"},"profile-read-failed":{title:"暂时无法读取身份资料",message:"未能读取你的 WebID 资料,暂时无法确认 Pod 地址。请稍后重试,不需要重新创建 Pod。",action:"重试连接"},"no-usable-access-route":{title:"暂时无法连接本机 Pod",message:"Xpod 找不到可用的访问通道,请确认本机服务正在运行后重试。你的资料没有丢失。",action:"重试连接"},"pod-open-failed":{title:"暂时无法打开 Pod",message:"Xpod 无法连接到你的 Pod,请检查服务状态后重试。",action:"重试连接"},"storage-unavailable":{title:"无法保存登录状态",message:"当前环境无法保存本次登录状态,请重新打开 Xpod 后重试。",action:"重新登录"},"redirect-failed":{title:"登录已完成",message:"身份验证已经完成,但目标页面没有正常打开。",action:"返回概览"}};async function J(e){const t=new URL(e.href),n=t.origin,r=$e(),a=re(t,e.storage,e.now);if(a)return e.locationReplace?.(a),{status:"redirected",destination:a};let c=t.searchParams.get("transaction");const o=t.searchParams.has("code")||t.searchParams.has("state")||t.searchParams.has("error"),s=o?j(t):void 0;let d,i,g;try{d=e.transactionStore??k({storage:e.storage,origin:n});const f=d.readSinglePending();!c&&f&&(c=f.id),c?!f||f.id!==c?(d.consume(c),g=u("missing-transaction")):i=f:g=u("missing-transaction")}catch(f){g=u(Oe(f))}const x=c?ne(t,c,e.storage,e.now):void 0;if(x){if(o&&s&&!i){const f=await D(e.runtime,e.href);if(f.status==="failure"){const m=await O({callbackUrl:t,destination:s,recoveryPointers:r,storage:e.storage,locationReplace:e.locationReplace});return m||f}return e.locationReplace?.(s),{status:"redirected",destination:s}}return e.locationReplace?.(x),{status:"redirected",destination:x}}if(!i){if(s){const f=await D(e.runtime,e.href);if(f.status==="failure"){const m=await O({callbackUrl:t,destination:s,recoveryPointers:r,storage:e.storage,locationReplace:e.locationReplace});return m||f}return e.locationReplace?.(s),{status:"redirected",destination:s}}return g??u("missing-transaction")}if(!d||!c)return u("missing-transaction");const R=await Ie(e,i);if(R.status==="failure"){const f=await O({callbackUrl:t,destination:Ee(i,n),recoveryPointers:r,transactionStore:d,transactionId:c,storage:e.storage,locationReplace:e.locationReplace});return f||R}const h=R.webId,P=e.runtime.session.createAuthenticatedFetch(h);let b=!1;const y=e.runtime.session.subscribe(()=>{b=!0,e.runtime.pod.clear({webId:h})});try{try{le(i.route,n)}catch{return u("unsafe-route")}let f;try{f=U(i.returnTo)}catch{return u("unsafe-return-to")}const m=i.selectedStorage&&new URL(i.selectedStorage.storageUrl).origin===n?{storageRoot:n,available:!0}:await Ae(e.fetch??fetch,n);if(b)return u("pod-open-failed");if(!m.available)return u("provision-status-unavailable");const p=m.storageRoot;e.runtime.setLocalPodRoutes(M(p,m));let w;try{w=i.selectedStorage??await _e(P,h,p)}catch(W){return W instanceof H?u("no-usable-access-route"):u("profile-read-failed")}if(b)return u("pod-open-failed");if(w&&!G(w,n,p))return u("binding-mismatch");if(w&&w.webId!==h)return u("webid-mismatch");if(!w)return m.managed?u("local-binding-missing",m.provisionUrl):u("missing-storage");let C;try{e.runtime.setLocalPodRoutes(M(w.storageUrl,m)),C=await e.runtime.pod.open({webId:h,podUrl:w.storageUrl,fetch:P})}catch{return{...u("pod-open-failed")}}if(b)return u("pod-open-failed");const L=w;if(!G(L,n,p)||C.webId!==L.webId||!Te(C.podUrl,L.storageUrl))return u("binding-mismatch");try{xe(L,{storage:e.storage,origin:n,storageRoot:p,now:e.now})}catch{return u("storage-unavailable")}const A=new URL(f??X,n).href;try{d.consume(c),Pe(c,A,t,e.storage,e.now),(e.storage??window.sessionStorage).removeItem(`${$}${c}`),e.locationReplace?.(A)}catch{return Q({storage:e.storage}),u("redirect-failed")}return{status:"redirected",destination:A,transaction:i,selectedStorage:L,pod:C}}finally{y()}}async function Ie(e,t){const n=new URL(e.href),r=e.storage??window.sessionStorage,a=`${$}${t.id}`,c=E(n),o=e.now??Date.now;try{const d=r.getItem(a);if(d){const i=JSON.parse(d);if(!B(i)||i.callback!==c||typeof i.webId!="string"||typeof i.completedAt!="number"||!Number.isFinite(i.completedAt))return u("oidc-state-invalid");if(o()<i.completedAt||o()-i.completedAt>ee)return u("expired-transaction");const g=e.runtime.session.getSnapshot();return g.status!=="authenticated"?u("unauthenticated"):g.webId!==i.webId?u("webid-mismatch"):{status:"success",webId:g.webId}}}catch{return u("storage-unavailable")}const s=await D(e.runtime,e.href);if(s.status==="failure")return s;try{r.setItem(a,JSON.stringify({callback:c,webId:s.webId,completedAt:o()}))}catch{return u("storage-unavailable")}return s}function z(e){const t=new URL(e.href);if(re(t,e.storage,e.now))return J(e);const n=te(t,e.transactionStore),r=S.get(n);if(r)return r;const a=J(e);return S.set(n,a),a}function te(e,t){let n=e.searchParams.get("transaction");if(!n)try{n=t?.readSinglePending()?.id??k({origin:e.origin}).readSinglePending()?.id??(j(e)?"<silent>":"<missing>")}catch{n=j(e)?"<silent>":"<missing>"}return`${e.origin}:${n}`}function E(e){return`${e.origin}${e.pathname}?state=${encodeURIComponent(e.searchParams.get("state")??"")}`}function re(e,t,n){if(e.searchParams.get("state"))try{const r=t??window.sessionStorage,a=e.searchParams.get("transaction");for(let c=0;c<r.length;c+=1){const o=r.key(c);if(!o?.startsWith(I))continue;const s=o.slice(I.length);if(a&&a!==s)continue;const d=r.getItem(o);if(!d)continue;const i=JSON.parse(d);if(B(i)&&i.callback===E(e))return ne(e,s,r,n)}}catch{}}function ne(e,t,n,r=()=>Date.now()){try{const a=n??window.sessionStorage,c=`${I}${t}`,o=a.getItem(c);if(!o)return;const s=JSON.parse(o);if(s.callback!==void 0&&s.callback!==E(e)||typeof s.destination!="string"||typeof s.completedAt!="number"||!Number.isFinite(s.completedAt))return;if(r()<s.completedAt||r()-s.completedAt>ee){a.removeItem(c);return}const d=new URL(s.destination);if(d.origin!==e.origin||d.username||d.password)return;const i=U(`${d.pathname}${d.search}${d.hash}`);return i?new URL(i,e.origin).href:void 0}catch{return}}function j(e){try{const t=window.localStorage.getItem(F);if(!t)return;const n=new URL(t,e.origin);if(n.origin!==e.origin)return;const r=`${n.pathname}${n.search}`,a=U(r);return a===void 0?void 0:new URL(a,e.origin).href}catch{return}}function Pe(e,t,n,r,a=()=>Date.now()){(r??window.sessionStorage).setItem(`${I}${e}`,JSON.stringify({destination:t,callback:E(n),completedAt:a()}))}function Le({runtime:e,transactionStore:t,href:n,location:r=typeof window>"u"?void 0:window.location,restartSignIn:a,renderRedirected:c}){const[o]=v.useState(()=>n??(typeof window>"u"?"http://localhost/auth/callback":window.location.href)),[s]=v.useState(()=>e?void 0:De()),d=e??s,[i,g]=v.useState(),[x,R]=v.useState(!1),h=v.useRef(void 0),P=v.useRef(!1),[b]=v.useState(()=>{const m=new URL(o);return ae(m,t)?.id??m.searchParams.get("transaction")}),y=v.useMemo(()=>Ue({href:o,transactionStore:t}),[o,t]);if(v.useEffect(()=>{h.current||(h.current=z({href:o,runtime:d,transactionStore:t,locationReplace:r?.replace.bind(r)}),h.current.then(g))},[d,o,r,t]),v.useEffect(()=>{typeof document>"u"||i?.status==="redirected"&&c||(document.title=i?.status==="failure"?`Xpod - ${T[i.code].title}`:i?.status==="redirected"?"Xpod - 登录完成":"Xpod - 正在登录")},[c,i]),v.useEffect(()=>{!i||i.status!=="failure"||q.has(i.code)&&(P.current||(P.current=!0,queueMicrotask(()=>{R(!0),_({href:o,runtime:d,transactionStore:t,associatedTransactionId:b}).finally(()=>{(a??(p=>window.location.replace(p)))(y)})})))},[d,b,o,y,a,i,t]),!i)return l.jsx(N,{title:"正在完成登录",message:"请稍候,不要关闭这个窗口。"});if(i.status==="redirected")return c?.(i)??l.jsx(N,{title:"登录完成",message:"正在打开 Xpod。"});if(q.has(i.code))return l.jsx(N,{title:"正在重新登录",message:"Xpod 正在清理不匹配的登录状态。"});const f=T[i.code];return l.jsx(V,{mode:"modal",title:f.title,lead:l.jsx(Z,{compact:!0}),closeOnEscape:!1,children:l.jsxs("div",{className:"flex min-h-0 flex-1 flex-col px-5 pb-5",children:[l.jsx("div",{className:"flex min-h-0 flex-1 flex-col justify-center py-5",children:l.jsxs("div",{className:"min-w-0",children:[l.jsxs("div",{className:"flex items-center gap-2",children:[l.jsx(ce,{"aria-hidden":"true",className:"h-4 w-4 shrink-0 text-destructive"}),l.jsx("h2",{className:"text-[15px] font-semibold leading-6 text-foreground",children:f.title})]}),l.jsx("p",{role:"alert",className:"mt-2 text-xs leading-5 text-muted-foreground",children:f.message}),l.jsxs("details",{className:"group mt-3 text-[11px] leading-4 text-muted-foreground",children:[l.jsxs("summary",{className:"-ml-1 inline-flex min-h-8 cursor-pointer list-none items-center gap-1 rounded-md px-1 outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden",children:[l.jsx(we,{"aria-hidden":"true",className:"h-3 w-3 shrink-0 group-open:rotate-90"}),"技术详情"]}),l.jsxs("div",{className:"mt-1 max-h-24 overflow-y-auto overscroll-contain",children:[l.jsx("code",{className:"block break-all text-left",children:i.code}),!1]})]})]})}),l.jsx(K,{type:"button",className:"w-full shrink-0 rounded-xl",disabled:x,"aria-busy":x,onClick:()=>{if(!x){if(Se.has(i.code)){S.delete(te(new URL(o),t)),g(void 0),h.current=z({href:o,runtime:d,transactionStore:t,locationReplace:r?.replace.bind(r)}),h.current.then(g);return}R(!0),(i.code==="redirect-failed"?Promise.resolve():_({href:o,runtime:d,transactionStore:t,associatedTransactionId:b})).finally(()=>{if(i.actionUrl){(a??(w=>window.location.replace(w)))(i.actionUrl);return}(a??(p=>window.location.replace(p)))(y)})}},children:x?"正在重置…":f.action}),l.jsx(K,{type:"button",variant:"ghost",disabled:x,onClick:()=>{x||(R(!0),ve(!0),_({href:o,runtime:d,transactionStore:t,associatedTransactionId:b,preserveSession:!0}).finally(()=>{(a??(p=>window.location.replace(p)))(y)}))},children:"返回应用"})]})})}function Ue({href:e,transactionStore:t,basePath:n="/dashboard/"}){const r=new URL(e),c=ae(r,t)?.returnTo;if(c)try{const s=U(c);if(s)return s}catch{}const o=j(r);if(o)try{const s=new URL(o);if(s.origin===r.origin)return`${s.pathname}${s.search}${s.hash}`}catch{}return Ce(n,r.pathname)}function ae(e,t){try{const n=t?t.readSinglePending():k({origin:e.origin}).readSinglePending(),r=e.searchParams.get("transaction");return r&&n?.id!==r?void 0:n}catch{return}}function Ce(e,t){return Xe(e)==="/settings/"||t==="/settings/auth-callback.html"||t.startsWith("/settings/")?"/settings/":X}function Xe(e){if(e)try{const t=new URL(e,"https://xpod.local");return t.pathname.endsWith("/")?t.pathname:`${t.pathname}/`}catch{return}}function N({title:e,message:t}){return l.jsx(V,{mode:"modal",title:e,lead:l.jsx(Z,{compact:!0}),closeOnEscape:!1,children:l.jsxs("div",{className:"flex h-full flex-col items-center justify-center px-6 text-center",children:[l.jsx("h2",{className:"text-[15px] font-semibold text-foreground",children:e}),l.jsx("p",{role:"status","aria-live":"polite",className:"mt-2 max-w-[13rem] text-xs leading-5 text-muted-foreground",children:t})]})})}async function _({href:e,runtime:t,transactionStore:n,storage:r,preserveSession:a=!1,associatedTransactionId:c}){const o=new URL(e);let s=c===void 0?o.searchParams.get("transaction"):c;try{const d=n??k({storage:r,origin:o.origin}),i=d.readSinglePending();c===void 0&&!s&&i&&(s=i.id),i&&i.id===s&&d.cancel(i.id)}catch{}try{const d=r??window.sessionStorage;s&&(d.removeItem(`${I}${s}`),d.removeItem(`${$}${s}`)),window.localStorage.removeItem(F)}catch{}try{a||await t.session.logout()}catch{}S.delete(`${o.origin}:${s??"<missing>"}`),S.delete(`${o.origin}:<silent>`),S.delete(`${o.origin}:<missing>`)}async function D(e,t){let n="oidc-state-invalid";try{if(new URL(t).searchParams.has("error")&&(n="oidc-provider-error"),!e.session.handleIncomingRedirect)return u("oidc-state-invalid");const r=await e.session.handleIncomingRedirect(t);if(n==="oidc-provider-error")return u(n);const a=B(r)?r:void 0;if(a?.status==="error"||a?.status==="expired")return u("oidc-state-invalid");const c=a?.status==="authenticated"||a?.isLoggedIn===!0?Y(a.webId):void 0,o=e.session.getSnapshot();if(o.status==="error"||o.status==="expired")return u("oidc-state-invalid");const s=c??(o.status==="authenticated"?o.webId:void 0);return s?{status:"success",webId:s}:u("unauthenticated")}catch{return u(n)}}function B(e){return typeof e=="object"&&e!==null}async function O({callbackUrl:e,destination:t,recoveryPointers:n,transactionStore:r,transactionId:a,storage:c,locationReplace:o}){const s=e.searchParams.get("error");if(je(s)){ke({transactionStore:r,transactionId:a,storage:c});for(const{storage:d,key:i,value:g}of n)try{d.getItem(i)===g&&d.removeItem(i)}catch{}return o?.(t),{status:"redirected",destination:t}}}function je(e){return e==="login_required"||e==="interaction_required"||e==="consent_required"||e==="account_selection_required"}function ke({transactionStore:e,transactionId:t,storage:n}){try{const r=e?.readSinglePending(),a=t;a&&r?.id===a&&e?.cancel(a),a&&r?.id===a&&((n??window.sessionStorage).removeItem(`${I}${a}`),(n??window.sessionStorage).removeItem(`${$}${a}`))}catch{}Q({storage:n})}function $e(){const e=[];for(const t of["localStorage","sessionStorage"])try{const n=window[t];for(const r of[F,"solidClientAuthn:currentSession",ue,fe]){const a=n.getItem(r);a!==null&&e.push({storage:n,key:r,value:a})}}catch{}return e}function Ee(e,t){try{const n=U(e.returnTo);return new URL(n??X,t).href}catch{return new URL(X,t).href}}function Y(e){return typeof e=="string"&&e?e:void 0}function G(e,t,n){try{const r=new URL(e.storageUrl),a=new URL(e.webId);return(r.origin===t||pe(r.href,n))&&["http:","https:"].includes(r.protocol)&&["http:","https:"].includes(a.protocol)&&!r.username&&!r.password&&!r.hash&&!a.username&&!a.password}catch{return!1}}async function Ae(e,t){const n=await e(new URL("/provision/status",t),{headers:{Accept:"application/json"},credentials:"include"}).catch(()=>{});if(n?.status===404)return{storageRoot:t,available:!0};if(!n?.ok)return{storageRoot:t,available:!1};const r=await n.json().catch(()=>{});return!r||typeof r.managed!="boolean"&&typeof r.publicUrl!="string"?{storageRoot:t,available:!1}:{available:!0,storageRoot:typeof r?.publicUrl=="string"&&r.publicUrl?r.publicUrl:t,managed:r?.managed===!0,provisionUrl:Ne(r?.provisionUrl),routes:me(r?.routes)}}function Ne(e){if(!(typeof e!="string"||!e))try{const t=new URL(e);return t.protocol==="https:"&&!t.username&&!t.password?t.href:void 0}catch{return}}async function _e(e,t,n){let r=!1,a;const o=await ge(async(s,d)=>{const i=await e(s,d).catch(g=>{throw String(s)===t&&(r=!0,a=g),g});return String(s)===t&&!i.ok&&(r=!0),i},[t],n);if(a instanceof H)throw a;if(r)throw new Error("Unable to read WebID profile storage bindings");if(o.length===1)return o[0]}function Oe(e){switch(e?.code){case"consumed":return"replayed-transaction";case"expired":return"expired-transaction";case"malformed":return"malformed-transaction";default:return"missing-transaction"}}function u(e,t){return{status:"failure",code:e,message:T[e].message,...t?{actionUrl:t}:{}}}function Te(e,t){try{return new URL(e).href===new URL(t).href}catch{return e===t}}function De(){return de()}function Fe({location:e,history:t}){return{origin:e.origin,replace(n){const r=new URL(n,e.origin);if(r.origin===e.origin&&We(r.pathname)){t.replaceState({},"",`${r.pathname}${r.search}${r.hash}`);return}e.replace(r.href)}}}function Be(e,t){try{const n=new URL(e,t);if(n.origin!==t)return;const r=ie(n.pathname);return r?{app:r,pathname:n.pathname,target:`${n.pathname}${n.search}${n.hash}`}:void 0}catch{return}}function We(e){return ie(e)!==void 0}function ie(e){return be.find(({basename:t})=>e===t||e.startsWith(`${t}/`))?.app}const se=he(),Me=Fe({location:window.location,history:window.history});function Ke(e){const t=Be(e.destination,window.location.origin);return t?(`${window.location.pathname}${window.location.search}${window.location.hash}`!==t.target&&window.history.replaceState({},"",t.target),l.jsx(Re,{runtime:se,initialPathname:t.pathname},t.target)):l.jsx("main",{role:"status","aria-live":"polite",children:"Sign-in complete. Opening Xpod…"})}function tt(){return l.jsx(Le,{runtime:se,location:Me,renderRedirected:Ke})}export{tt as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{b as De,r as l,j as e,N as Re}from"./dashboard-Or0gnkou.js";import{T as Pe,u as Te,h as Le,b as Ae,c as Ee,d as $e,f as Me,e as Ie,t as _e}from"./nav-item-style-CW1Nnorq.js";import{P as Oe}from"./PaneListHeader-DtvnRmFq.js";import{c as C}from"./createLucideIcon-BJQl82Qk.js";import{t as H,m as re,R as qe,g as se,S as ze}from"./XpodShellApp-D_KY4nCW.js";import{B as y}from"./button-wslF55uZ.js";import{f as P,C as T,b as L,d as A,e as E}from"./PodDeletionAuthorizationPanel-BJk_8rJq.js";import{B as q,S as me}from"./section-header-CEIEcco-.js";import{L as ne,a as xe}from"./list-UyhlCFKk.js";import{a as he}from"./setting-row-CaYv3dfF.js";import"./xpod-remembered-login-BUF9fin1.js";import"./account-session-DlcKNG7k.js";import"@comunica/query-sparql-solid";import"./safe-continuation-ClWAhcma.js";const Ue=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]],be=C("activity",Ue);const He=[["path",{d:"M17 19a1 1 0 0 1-1-1v-2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2a1 1 0 0 1-1 1z",key:"trhst0"}],["path",{d:"M17 21v-2",key:"ds4u3f"}],["path",{d:"M19 14V6.5a1 1 0 0 0-7 0v11a1 1 0 0 1-7 0V10",key:"1mo9zo"}],["path",{d:"M21 21v-2",key:"eo0ou"}],["path",{d:"M3 5V3",key:"1k5hjh"}],["path",{d:"M4 10a2 2 0 0 1-2-2V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2a2 2 0 0 1-2 2z",key:"1dd30t"}],["path",{d:"M7 5V3",key:"1t1388"}]],Ve=C("cable",He);const Be=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],Fe=C("download",Be);const Xe=[["path",{d:"M21.54 15H17a2 2 0 0 0-2 2v4.54",key:"1djwo0"}],["path",{d:"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17",key:"1tzkfa"}],["path",{d:"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05",key:"14pb5j"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],ye=C("earth",Xe);const Ke=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],we=C("external-link",Ke);const We=[["circle",{cx:"12",cy:"16",r:"1",key:"1au0dj"}],["rect",{x:"3",y:"10",width:"18",height:"12",rx:"2",key:"6s8ecr"}],["path",{d:"M7 10V7a5 5 0 0 1 10 0v3",key:"1pqi11"}]],Ge=C("lock-keyhole",We);const Je=[["rect",{x:"16",y:"16",width:"6",height:"6",rx:"1",key:"4q2zg0"}],["rect",{x:"2",y:"16",width:"6",height:"6",rx:"1",key:"8cvhb9"}],["rect",{x:"9",y:"2",width:"6",height:"6",rx:"1",key:"1egb70"}],["path",{d:"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3",key:"1jsf9p"}],["path",{d:"M12 12V8",key:"2874zd"}]],Ne=C("network",Je);const Qe=[["path",{d:"M16.247 7.761a6 6 0 0 1 0 8.478",key:"1fwjs5"}],["path",{d:"M19.075 4.933a10 10 0 0 1 0 14.134",key:"ehdyv1"}],["path",{d:"M4.925 19.067a10 10 0 0 1 0-14.134",key:"1q22gi"}],["path",{d:"M7.753 16.239a6 6 0 0 1 0-8.478",key:"r2q7qm"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]],Ye=C("radio",Qe);const Ze=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],ea=C("rotate-ccw",Ze);const aa=[["circle",{cx:"6",cy:"19",r:"3",key:"1kj8tv"}],["path",{d:"M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15",key:"1d8sl"}],["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}]],ta=C("route",aa);const sa=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],na=C("shield-check",sa);const ia=[["path",{d:"m10.586 5.414-5.172 5.172",key:"4mc350"}],["path",{d:"m18.586 13.414-5.172 5.172",key:"8c96vv"}],["path",{d:"M6 12h12",key:"8npq4p"}],["circle",{cx:"12",cy:"20",r:"2",key:"144qzu"}],["circle",{cx:"12",cy:"4",r:"2",key:"muu5ef"}],["circle",{cx:"20",cy:"12",r:"2",key:"1xzzfp"}],["circle",{cx:"4",cy:"12",r:"2",key:"1hvhnz"}]],ra=C("waypoints",ia);const la=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],oa=C("wifi",la);async function da({fetchImpl:a}){return F(a,B("/api/network/settings/status"),{method:"GET",credentials:"include",headers:{accept:"application/json"}})}async function ca({fetchImpl:a}){return F(a,B("/api/network/settings/diagnose"),{method:"POST",credentials:"include",headers:{accept:"application/json"}})}async function ke({fetchImpl:a}){return F(a,B("/api/network/settings/tunnel-clients"),{method:"GET",credentials:"include",headers:{accept:"application/json"}})}async function ua({fetchImpl:a,provider:t}){return F(a,B(`/api/network/settings/tunnel-clients/${encodeURIComponent(t)}/install`),{method:"POST",credentials:"include",headers:{accept:"application/json"}})}async function ma({fetchImpl:a}){await F(a,B("/api/network/settings/certificate/renew"),{method:"POST",credentials:"include",headers:{accept:"application/json"}})}async function xa({podUrl:a,fetchImpl:t,patch:s}){return F(t,ha("/api/network/settings/configuration",a),{method:"PUT",credentials:"include",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(s)})}function B(a){const t=typeof window>"u"?"http://localhost":window.location.origin;return new URL(a,t).toString()}function ha(a,t){return t?new URL(a,t).toString():B(a)}async function F(a,t,s){const i=await a(t,s);if(!i.ok)throw await i.arrayBuffer(),new Error("Network settings request failed. Please try again.");if(!i.headers.get("content-type")?.includes("application/json"))throw await i.arrayBuffer(),new Error("Network settings request failed. Please try again.");return await i.json()}const ie=[{id:"overview",label:"Overview",path:"",icon:Ne},{id:"endpoints",label:"Endpoints",path:"endpoints",icon:Ve},{id:"addresses",label:"Addresses",path:"addresses",icon:ye},{id:"domain-dns",label:"Domain & DNS",path:"domain-dns",icon:ta},{id:"https",label:"HTTPS",path:"https",icon:Ge},{id:"tunnel-profiles",label:"Tunnel Profiles",path:"tunnel-profiles",icon:ra},{id:"p2p",label:"P2P",path:"p2p",icon:Ye},{id:"diagnostics",label:"Diagnostics",path:"diagnostics",icon:be}];function pa(a){const t=["Xpod Network Diagnostics",`Generated: ${a.generatedAt}`,`Canonical URL: ${a.endpoint??"Unavailable"}`],s=a.checks.flatMap(i=>["",`[${i.status.toUpperCase()}] ${i.label}`,...i.detail?[i.detail]:[]]);return[...t,...s].join(`
|
|
2
|
+
`)}function ga({embedded:a=!1}){const t=De(),[s,i]=l.useState(),[n,c]=l.useState([]),[o,g]=l.useState(),[f,d]=l.useState(),[m,v]=l.useState(!1),[b,$]=l.useState(!1),[x,N]=l.useState(!1),[u,r]=l.useState(!1),[h,D]=l.useState(),R=l.useRef(0),X=l.useRef(0),K=l.useRef(0),W=l.useRef(void 0),G=l.useRef(!0),J=typeof window>"u"?void 0:window.location.origin,M=J?`local-host:${J}`:void 0,_=globalThis.fetch;l.useEffect(()=>(G.current=!0,()=>{G.current=!1,R.current+=1,X.current+=1,K.current+=1}),[]);const Q=l.useCallback((p,j)=>G.current&&R.current===p&&W.current===j,[]),Y=l.useCallback((p,j)=>G.current&&X.current===p&&W.current===j,[]),Z=l.useCallback((p,j)=>G.current&&K.current===p&&W.current===j,[]),z=l.useCallback(async()=>{const p=M;if(!p)return;const j=R.current+1;R.current=j,v(!0),d(void 0);try{const I=await da({fetchImpl:_});Q(j,p)&&i(I)}catch{Q(j,p)&&d("网络设置请求失败,请重试。")}finally{Q(j,p)&&v(!1)}},[_,M,Q]);l.useEffect(()=>{let p=!1;return W.current=M,R.current+=1,X.current+=1,K.current+=1,queueMicrotask(()=>{p||W.current!==M||(i(void 0),c([]),g(void 0),d(void 0),v(!1),$(!1),N(!1),M&&z())}),()=>{p=!0}},[M,z]);const oe=l.useCallback(async()=>{const p=M;if(!p)return;const j=X.current+1;X.current=j,$(!0),d(void 0);try{const I=await ca({fetchImpl:_});Y(j,p)&&(c(I.checks),g(new Date),H({description:"诊断完成"}))}catch{Y(j,p)&&d("网络诊断失败,请重试。")}finally{Y(j,p)&&$(!1)}},[_,M,Y]),de=l.useCallback(async()=>{const p=M;if(!p)return;const j=K.current+1;K.current=j,N(!0),d(void 0);try{await ma({fetchImpl:_}),Z(j,p)&&(H({variant:"success",description:"证书续签成功"}),await z())}catch{Z(j,p)&&d("证书续签失败,请重试。")}finally{Z(j,p)&&N(!1)}},[_,M,Z,z]),O=l.useCallback(async p=>{if(J){r(!0),d(void 0);try{const j=await xa({fetchImpl:_,patch:p});i(I=>I&&{...I,configuration:j.configuration}),D(j.applyState),H({variant:"success",description:"Network configuration saved"})}catch{d("网络配置保存失败,请重试。")}finally{r(!1)}}},[_,J]),ce=l.useMemo(()=>[{key:"local",title:"本机",values:s?.addresses.local??[]},{key:"lan",title:"局域网",values:s?.addresses.lan??[]},{key:"public",title:"公网",values:s?.addresses.public??[]}],[s]),ue=t.pathname.split("/").filter(Boolean).at(-1),k=ie.some(p=>p.path===ue)?ue:"overview";return a?e.jsxs("section",{className:"space-y-5 p-6",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("p",{className:"text-sm leading-normal text-muted-foreground",children:"这台设备上的所有 Pod 共用"}),e.jsx(y,{variant:"outline",size:"sm",disabled:m,onClick:z,children:"刷新"})]}),f&&e.jsx("p",{role:"alert",className:"text-sm leading-normal text-destructive",children:f}),e.jsx("div",{className:"divide-y rounded-xl border border-border bg-card",children:ce.map(({key:p,values:j})=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 p-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm leading-normal font-medium",children:p==="local"?"这台电脑":p==="lan"?"局域网":"其他网络"}),e.jsx("div",{className:"mt-1 break-all text-xs leading-normal text-muted-foreground",children:j.join(" · ")||"暂无地址"})]}),e.jsx("span",{className:"text-xs leading-normal text-muted-foreground",children:p==="local"&&s&&["localhost","127.0.0.1","[::1]"].includes(window.location.hostname)?"可访问":p==="public"&&n.some(I=>I.id==="endpoint-reachability"&&I.status==="ok")?"本机检测通过":j.length?"待检测":"未配置"})]},p))}),e.jsx(fe,{configuration:s?.configuration,providers:s?.providers??[],ingress:s?.ingress,saving:u,applyState:h,onSave:O}),e.jsx(je,{status:s,endpoint:s?.endpoint,diagnostics:n,diagnosing:b,renewing:x,onDiagnose:oe,onRenewCertificate:de}),e.jsxs("details",{children:[e.jsx("summary",{className:"cursor-pointer text-sm leading-normal text-muted-foreground",children:"开发者模式:网络配置"}),e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsx(pe,{configuration:s?.configuration,saving:u,applyState:h,onSave:O}),e.jsx(ge,{configuration:s?.configuration,saving:u,applyState:h,onSave:O}),e.jsx(ve,{configuration:s?.configuration,saving:u,applyState:h,onSave:O})]})]})]}):e.jsx(Pe,{mode:"auto",listHeader:e.jsx(Oe,{title:"Network"}),list:e.jsx(fa,{}),mainHeader:e.jsx(va,{title:ie.find(p=>(p.path||"overview")===k)?.label??"Overview",loading:m,stale:m&&!!s,onRefresh:z}),main:e.jsxs("section",{className:"flex min-h-full flex-col gap-4 bg-background p-6",children:[f?e.jsx("div",{role:"alert",className:"rounded-md border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm leading-normal text-destructive",children:f}):null,(k==="overview"||k==="endpoints")&&e.jsx(Na,{endpoint:s?.endpoint,loading:m&&!s}),k==="overview"&&e.jsx(ja,{status:s}),(k==="overview"||k==="addresses")&&e.jsx(Ca,{sections:ce,loading:m&&!s,diagnostics:n,checkedAt:o}),k==="overview"&&e.jsx(Ta,{status:s}),k==="domain-dns"&&e.jsxs(e.Fragment,{children:[e.jsx(Ra,{status:s}),e.jsx(pe,{configuration:s?.configuration,saving:u,applyState:h,onSave:O})]}),k==="https"&&e.jsxs(e.Fragment,{children:[e.jsx(Pa,{status:s}),e.jsx(ge,{configuration:s?.configuration,saving:u,applyState:h,onSave:O})]}),k==="tunnel-profiles"&&e.jsxs(e.Fragment,{children:[e.jsx(ba,{title:"Observed tunnel",label:"Tunnel",capability:s?.tunnel}),e.jsx(fe,{configuration:s?.configuration,providers:s?.providers??[],ingress:s?.ingress,saving:u,applyState:h,onSave:O}),e.jsx(ya,{fetchImpl:_})]}),k==="p2p"&&e.jsx(ve,{configuration:s?.configuration,saving:u,applyState:h,onSave:O}),(k==="overview"||k==="diagnostics"||k==="https")&&e.jsx(je,{status:s,endpoint:s?.endpoint,diagnostics:n,diagnosing:b,renewing:x,onDiagnose:oe,onRenewCertificate:de})]}),className:"min-h-full"})}function fa(){const a=Te();return e.jsx("aside",{className:"h-full border-r border-border bg-muted/20 py-2",children:e.jsx("nav",{"aria-label":"Network sections","data-list-navigation":!0,children:ie.map(t=>{const s=t.icon,i=`/network${t.path?`/${t.path}`:""}`;return e.jsxs(Re,{to:i,onClick:()=>a.openMain(),onKeyDown:Le,className:({isActive:n})=>Ae(n,{compact:!1}),end:t.path==="",children:[e.jsx(s,{className:"h-4 w-4","aria-hidden":"true"}),t.label]},t.id)})})})}function va({title:a,loading:t,stale:s,onRefresh:i}){return e.jsxs("div",{className:"flex h-full min-w-0 items-center justify-between gap-4 px-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("h1",{className:"text-sm leading-normal font-semibold text-foreground",children:["Network · ",a]}),e.jsx("div",{className:"truncate text-xs leading-normal text-muted-foreground","aria-live":"polite",children:s?"Refreshing · showing previous snapshot":"接入点、DNS、TLS、隧道与连通性诊断"})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(y,{type:"button",size:"sm",variant:"outline",onClick:i,disabled:t,children:[e.jsx(qe,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),"刷新"]})})]})}function ja({status:a}){const t=a?.addresses.public[0]??a?.addresses.lan[0]??a?.addresses.local[0]??a?.endpoint,s=a?!a.dns.supported||a.dns.status==="unsupported"?"Configure Domain & DNS, then recheck observed DNS.":!a.tls.supported||!["valid","active","ready"].includes(a.tls.status)?"Review HTTPS configuration and certificate renewal evidence.":"No connectivity action is currently required.":"Refresh network status.",i=a?.tunnel.supported===!0;return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(L,{className:"text-base leading-normal",children:"Preferred access path"}),e.jsx(A,{className:"leading-normal",children:"First address this runtime has configured, in public → LAN → local order"})]}),e.jsxs(E,{className:"space-y-3 text-sm leading-normal",children:[e.jsx("div",{className:"break-words font-medium",children:t??"Not configured"}),e.jsxs("div",{className:"grid gap-2 sm:grid-cols-4",children:[e.jsxs(q,{variant:"outline",children:["Local ",a?.addresses.local.length?"configured":"not configured"]}),e.jsxs(q,{variant:"outline",children:["LAN ",a?.addresses.lan.length?"configured":"not configured"]}),e.jsxs(q,{variant:"outline",children:["Public ",a?.addresses.public.length?"configured":"not configured"]}),e.jsxs(q,{variant:"outline",children:["Tunnel ",i?a?.tunnel.status??"unknown":"not observed"]})]}),e.jsx("div",{className:"mt-1 text-xs leading-normal text-muted-foreground",children:"Configured addresses are not probe results; reachability is reported per route."}),e.jsxs("div",{className:"rounded-md border border-border bg-muted/30 p-3",children:[e.jsx("div",{className:"font-medium",children:"Next action"}),e.jsx("div",{className:"mt-1 text-muted-foreground",children:s})]})]})]})}function ba({title:a,label:t,capability:s,extra:i}){return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(L,{className:"text-base leading-normal",children:a}),e.jsx(A,{className:"leading-normal",children:"Observed runtime state"})]}),e.jsx(E,{children:e.jsx(V,{label:t,capability:s,extra:i})})]})}function ee({title:a}){return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(L,{className:"text-base leading-normal",children:a}),e.jsx(A,{className:"leading-normal",children:"设备配置"})]}),e.jsxs(E,{className:"text-sm leading-normal text-muted-foreground",children:["这台设备暂未提供",a,"配置。"]})]})}function pe({configuration:a,saving:t,applyState:s,onSave:i}){const[n,c]=l.useState(a?.domainDns),[o,g]=l.useState("");return l.useEffect(()=>{let f=!1;return queueMicrotask(()=>{f||c(a?.domainDns)}),()=>{f=!0}},[a]),n?e.jsxs(ae,{title:"Saved configuration",applyState:s,children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(S,{name:"domain",label:"Domain",value:n.domain,onChange:f=>c({...n,domain:f})}),e.jsx(S,{name:"provider",label:"DNS provider",value:n.provider,onChange:f=>c({...n,provider:f})}),e.jsx(Ce,{name:"recordTtl",label:"Record TTL (seconds)",value:n.recordTtl,min:30,max:86400,onChange:f=>c({...n,recordTtl:f})}),e.jsx(S,{name:"dnsCredential",label:n.credentialConfigured?"更换凭据(已配置)":"凭据",value:o,type:"password",onChange:g})]}),e.jsx(le,{label:"Enable DDNS",checked:n.ddnsEnabled,onChange:f=>c({...n,ddnsEnabled:f})}),e.jsx(te,{label:"Save DNS configuration",saving:t,onClick:()=>i({domainDns:{domain:n.domain,ddnsEnabled:n.ddnsEnabled,provider:n.provider,recordTtl:n.recordTtl,...o?{credential:o}:{}}})})]}):e.jsx(ee,{title:"Domain & DNS"})}function ge({configuration:a,saving:t,applyState:s,onSave:i}){const[n,c]=l.useState(a?.https);return l.useEffect(()=>{let o=!1;return queueMicrotask(()=>{o||c(a?.https)}),()=>{o=!0}},[a]),n?e.jsxs(ae,{title:"Saved configuration",applyState:s,children:[e.jsx(le,{label:"Enable HTTPS",checked:n.enabled,onChange:o=>c({...n,enabled:o})}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(S,{name:"acmeEmail",label:"ACME email",value:n.acmeEmail,onChange:o=>c({...n,acmeEmail:o})}),e.jsx(S,{name:"acmeDomains",label:"Certificate domains",value:n.domains.join(", "),onChange:o=>c({...n,domains:o.split(",").map(g=>g.trim()).filter(Boolean)})}),e.jsx(S,{name:"certificatePath",label:"Certificate path",value:n.certificatePath??"",onChange:o=>c({...n,certificatePath:o})}),e.jsx(S,{name:"certificateKeyPath",label:"Private-key path",value:n.certificateKeyPath??"",onChange:o=>c({...n,certificateKeyPath:o})}),e.jsx(Ce,{name:"renewBeforeDays",label:"Renew before (days)",value:n.renewBeforeDays,min:1,max:90,onChange:o=>c({...n,renewBeforeDays:o})})]}),e.jsx(te,{label:"Save HTTPS configuration",saving:t,onClick:()=>i({https:n})})]}):e.jsx(ee,{title:"HTTPS"})}function ya({fetchImpl:a}){const[t,s]=l.useState(void 0),[i,n]=l.useState(void 0),[c,o]=l.useState(void 0),g=async()=>{n("inspect"),o(void 0);try{const d=await ke({fetchImpl:a});s(d.clients)}catch(d){o(d instanceof Error?d.message:String(d))}finally{n(void 0)}},f=async d=>{n(d),o(void 0);try{const m=await ua({fetchImpl:a,provider:d});s(m.clients)}catch(m){o(m instanceof Error?m.message:String(m))}finally{n(void 0)}};return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(L,{className:"text-base leading-normal",children:"Tunnel clients"}),e.jsx(A,{className:"leading-normal",children:"Clients are not bundled with this build: check where one comes from, or download it into the plugin directory."})]}),e.jsxs(E,{className:"space-y-3 text-sm leading-normal",children:[e.jsx(y,{type:"button",size:"sm",variant:"outline",onClick:g,disabled:i==="inspect",children:i==="inspect"?"Checking…":"Check clients"}),c&&e.jsx("div",{className:"text-destructive",children:c}),t&&e.jsx("div",{className:"space-y-2",children:t.map(d=>e.jsxs("div",{className:"flex flex-wrap items-center gap-2 rounded-md border border-border p-2",children:[e.jsx(q,{variant:d.state==="ready"?"default":"outline",children:d.state==="ready"?"Ready":"Missing"}),e.jsx("span",{className:"font-medium",children:d.label}),e.jsxs("span",{className:"text-xs leading-normal text-muted-foreground",children:[d.path??d.binary,d.version?` · ${d.version}`:"",d.source==="bundled"?" · plugin directory":""]}),d.state==="missing"&&e.jsx("span",{className:"text-xs leading-normal text-muted-foreground",children:d.installHint}),d.state==="missing"&&d.installable&&e.jsx(y,{type:"button",size:"sm",onClick:()=>f(d.provider),disabled:i===d.provider,children:i===d.provider?"Downloading…":"Download"}),d.state==="missing"&&!d.installable&&e.jsxs("span",{className:"text-xs leading-normal text-muted-foreground",children:["(",d.installableReason,")"]})]},d.provider))})]})]})}function fe({configuration:a,providers:t,ingress:s,saving:i,applyState:n,onSave:c}){const[o,g]=l.useState(a?.tunnelProfiles.activeProfileId??""),[f,d]=l.useState(a?.tunnelProfiles.profiles??[]),[m,v]=l.useState({});if(l.useEffect(()=>{let r=!1;return queueMicrotask(()=>{r||(g(a?.tunnelProfiles.activeProfileId??""),d(a?.tunnelProfiles.profiles??[]),v({}))}),()=>{r=!0}},[a]),!a)return e.jsx(ee,{title:"隧道"});const b=(r,h)=>d(D=>D.map(R=>R.id===r?{...R,...h}:R)),$=t.filter(r=>r.runtimeSupported),x=r=>t.find(h=>h.id===r),N=()=>{const r=`tunnel-${Date.now()}`,h=$[0]?.id??"ngrok";d(D=>[...D,{id:r,provider:h,label:"新隧道",credentialConfigured:!1,parameters:{}}])},u=r=>{d(h=>h.filter(D=>D.id!==r)),o===r&&g("none")};return e.jsxs(ae,{title:"隧道",applyState:n,children:[e.jsxs("label",{className:"block space-y-2 text-sm leading-normal font-medium",children:["主地址",e.jsxs("select",{value:o||"none",onChange:r=>g(r.target.value),className:"block h-10 w-full rounded-md border border-input bg-background px-3 sm:max-w-sm",children:[e.jsx("option",{value:"none",children:"停用"}),f.map(r=>e.jsxs("option",{value:r.id,children:[r.label," · ",r.provider]},r.id))]})]}),e.jsx("div",{className:"space-y-3",children:f.map(r=>e.jsxs("div",{className:"space-y-3 rounded-md border border-border p-3 text-sm leading-normal",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(S,{name:`tunnel-label-${r.id}`,label:"名称",value:r.label,onChange:h=>b(r.id,{label:h})}),e.jsxs("label",{className:"block space-y-2 text-sm leading-normal font-medium",children:["隧道服务商",e.jsx("select",{value:r.provider,onChange:h=>b(r.id,{provider:h.target.value,parameters:{}}),className:"block h-10 w-full rounded-md border border-input bg-background px-3",children:t.map(h=>e.jsxs("option",{value:h.id,disabled:!h.runtimeSupported,children:[h.label,h.runtimeSupported?"":"(暂不支持)"]},h.id))})]}),x(r.provider)?.endpointSource==="declared"?e.jsx(S,{name:`tunnel-url-${r.id}`,label:"公网地址",value:r.publicUrl??"",onChange:h=>b(r.id,{publicUrl:h})}):e.jsx("p",{className:"text-xs leading-normal text-muted-foreground",children:"地址由隧道自动提供。"}),e.jsx(S,{name:`tunnel-credential-${r.id}`,label:r.credentialConfigured?"更换凭据(已配置)":"凭据",type:"password",value:m[r.id]??"",onChange:h=>v(D=>({...D,[r.id]:h}))})]}),e.jsxs("details",{children:[e.jsx("summary",{className:"cursor-pointer font-medium",children:"服务商参数"}),e.jsx("div",{className:"mt-3 grid gap-3 sm:grid-cols-2",children:(x(r.provider)?.parameterFields??[]).map(({key:h,label:D})=>e.jsx(S,{name:`tunnel-${h}-${r.id}`,label:D,value:r.parameters?.[h]??"",onChange:R=>b(r.id,{parameters:{...r.parameters,[h]:R}})},h))})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsxs("span",{className:"text-xs leading-normal text-muted-foreground",children:[o===r.id?"重启后启用":"已停用"," · ",r.credentialConfigured?"已配置凭据":"未配置凭据"]}),e.jsx(y,{type:"button",size:"sm",variant:"ghost",onClick:()=>u(r.id),children:"移除"})]})]},r.id))}),e.jsx(y,{type:"button",size:"sm",variant:"outline",onClick:N,children:"添加隧道"}),e.jsx(wa,{ingress:s,descriptor:x(f.find(r=>r.id===o)?.provider??"")}),e.jsx(te,{label:"保存隧道",saving:i,onClick:()=>c({tunnelProfiles:{activeProfileId:o,profiles:f.map(r=>({id:r.id,provider:r.provider,label:r.label,publicUrl:r.publicUrl,parameters:r.parameters,...m[r.id]?{credential:m[r.id]}:{}}))}})})]})}function wa({ingress:a,descriptor:t}){if(!a||t?.originOwner!=="console")return null;const s=async()=>{await window.navigator.clipboard.writeText(a.originUrl),H({description:"Tunnel origin copied"})};return e.jsxs("div",{className:"rounded-md border border-border bg-muted/30 p-3","data-testid":"ingress-origin",children:[e.jsx("div",{className:"text-xs leading-normal font-medium text-muted-foreground",children:"把隧道指向此地址"}),e.jsxs("div",{className:"mt-1 flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"break-all font-mono text-sm leading-normal",children:a.originUrl}),e.jsx("div",{className:"mt-1 text-xs leading-normal text-muted-foreground",children:"在服务商控制台填写此地址。"})]}),e.jsxs("div",{className:"flex shrink-0 gap-1",children:[e.jsx(y,{type:"button",size:"icon",variant:"ghost","aria-label":"Copy tunnel origin",onClick:()=>{s()},children:e.jsx(re,{className:"h-4 w-4","aria-hidden":"true"})}),t.consoleUrl?e.jsx(y,{type:"button",size:"icon",variant:"ghost","aria-label":`Open ${t.label} console`,onClick:()=>window.open(t.consoleUrl,"_blank","noopener,noreferrer"),children:e.jsx(we,{className:"h-4 w-4","aria-hidden":"true"})}):null]})]})]})}function ve({configuration:a,saving:t,applyState:s,onSave:i}){const[n,c]=l.useState(a?.p2p);return l.useEffect(()=>{let o=!1;return queueMicrotask(()=>{o||c(a?.p2p)}),()=>{o=!0}},[a]),n?e.jsxs(ae,{title:"Saved P2P configuration",applyState:s,children:[e.jsx(le,{label:"Enable P2P fallback",checked:n.enabled,onChange:o=>c({...n,enabled:o})}),e.jsx(S,{name:"signalService",label:"Signal service",value:n.signalService,onChange:o=>c({...n,signalService:o})}),e.jsxs("label",{className:"block space-y-2 text-sm leading-normal font-medium",children:["Fallback policy",e.jsxs("select",{value:n.fallbackPolicy,onChange:o=>c({...n,fallbackPolicy:o.target.value}),className:"block h-10 w-full rounded-md border border-input bg-background px-3 sm:max-w-sm",children:[e.jsx("option",{value:"never",children:"Never"}),e.jsx("option",{value:"when-direct-unavailable",children:"When direct is unavailable"}),e.jsx("option",{value:"prefer-p2p",children:"Prefer P2P"})]})]}),e.jsx(te,{label:"Save P2P configuration",saving:t,onClick:()=>i({p2p:n})})]}):e.jsx(ee,{title:"P2P"})}function ae({title:a,applyState:t,children:s}){return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(L,{className:"text-base leading-normal",children:a}),e.jsx(A,{className:"leading-normal",children:"保存后重启 Xpod 生效"})]}),e.jsxs(E,{className:"space-y-4",children:[t==="restart-required"?e.jsx("div",{role:"status",className:"rounded-md border border-warning/40 bg-warning/10 px-3 py-2 text-sm leading-normal text-warning dark:bg-warning/20 dark:text-warning",children:"已保存,需要重启"}):null,s]})]})}function S({name:a,label:t,value:s,type:i="text",onChange:n}){return e.jsxs("label",{className:"block space-y-2 text-sm leading-normal font-medium",children:[t,e.jsx("input",{name:a,type:i,value:s,onChange:c=>n(c.target.value),className:"block h-10 w-full rounded-md border border-input bg-background px-3 text-sm leading-normal"})]})}function Ce({name:a,label:t,value:s,min:i,max:n,onChange:c}){return e.jsxs("label",{className:"block space-y-2 text-sm leading-normal font-medium",children:[t,e.jsx("input",{name:a,type:"number",value:s,min:i,max:n,onChange:o=>c(o.target.valueAsNumber),className:"block h-10 w-full rounded-md border border-input bg-background px-3 text-sm leading-normal"})]})}function le({label:a,checked:t,onChange:s}){return e.jsxs("label",{className:"flex items-center justify-between gap-3 rounded-md border border-border p-3 text-sm leading-normal font-medium",children:[a,e.jsx("input",{type:"checkbox",checked:t,onChange:i=>s(i.target.checked)})]})}function te({label:a,saving:t,onClick:s}){return e.jsx("div",{className:"flex justify-end",children:e.jsx(y,{type:"button",onClick:s,disabled:t,children:t?"正在保存…":a})})}function Na({endpoint:a,loading:t}){const s=[{label:"Canonical URL",value:a},{label:"API endpoint",value:a?ka(a,"/api/"):void 0}],i=async(n,c)=>{await window.navigator.clipboard.writeText(c),H({description:`${n} copied`})};return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsxs(L,{className:"flex items-center gap-2 text-base leading-normal",children:[e.jsx(ye,{className:"h-4 w-4","aria-hidden":"true"}),"接入点"]}),e.jsx(A,{className:"leading-normal",children:t?"正在解析接入点":"Observed endpoints · Currently effective route is the canonical URL"})]}),e.jsx(E,{className:"space-y-3",children:s.map(({label:n,value:c})=>e.jsxs("div",{className:"flex items-start justify-between gap-3 rounded-md border border-border p-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-xs leading-normal font-medium text-muted-foreground",children:n}),e.jsx("div",{className:"mt-1 break-words text-sm leading-normal text-foreground",children:c||"Unavailable"})]}),c?e.jsxs("div",{className:"flex shrink-0 gap-1",children:[e.jsx(y,{type:"button",size:"icon",variant:"ghost","aria-label":`Copy ${n}`,onClick:()=>{i(n,c)},children:e.jsx(re,{className:"h-4 w-4","aria-hidden":"true"})}),e.jsx(y,{type:"button",size:"icon",variant:"ghost","aria-label":`Open ${n}`,onClick:()=>window.open(c,"_blank","noopener,noreferrer"),children:e.jsx(we,{className:"h-4 w-4","aria-hidden":"true"})})]}):null]},n))})]})}function ka(a,t){try{return new URL(t,a).toString()}catch{return a}}function Ca({sections:a,loading:t,diagnostics:s,checkedAt:i}){return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsxs(L,{className:"flex items-center gap-2 text-base leading-normal",children:[e.jsx(oa,{className:"h-4 w-4","aria-hidden":"true"}),"网络地址"]}),e.jsx(A,{className:"leading-normal",children:t?"正在刷新地址":"由运行时网络能力上报"})]}),e.jsx(E,{className:"space-y-4",children:a.map(n=>e.jsxs("div",{children:[e.jsx("div",{className:"text-xs leading-normal font-medium text-muted-foreground",children:n.title}),n.values.length>0?e.jsx("div",{className:"mt-1 space-y-1",children:n.values.map(c=>e.jsx(Sa,{scope:n.key,value:c,diagnostics:s,checkedAt:i},c))}):e.jsx("div",{className:"mt-1 text-sm leading-normal text-muted-foreground",children:"未提供"})]},n.key))})]})}function Sa({scope:a,value:t,diagnostics:s,checkedAt:i}){const n=Da(t),c=s.find(o=>o.id==="address-configuration");return e.jsxs("div",{className:"rounded-md border border-border p-3 text-sm leading-normal",children:[e.jsx("div",{className:"break-words font-medium text-foreground",children:t}),e.jsxs("dl",{className:"mt-2 grid gap-x-4 gap-y-1 text-xs leading-normal sm:grid-cols-2",children:[e.jsx(w,{label:"Interface",value:a==="local"?"Loopback":a==="lan"?"LAN interface (name not reported)":"Public route"}),e.jsx(w,{label:"IP version",value:n.ipVersion}),e.jsx(w,{label:"Port",value:n.port}),e.jsx(w,{label:"Configured",value:c?c.status==="ok"?"Yes":"No":"Not checked"}),e.jsx(w,{label:"Reachability",value:"Not probed"}),e.jsx(w,{label:"Configuration checked",value:c?.checkedAt?U(c.checkedAt):i?i.toLocaleString():"Not checked"})]})]})}function w({label:a,value:t}){return e.jsxs("div",{className:"flex justify-between gap-3",children:[e.jsx("dt",{className:"text-muted-foreground",children:a}),e.jsx("dd",{className:"text-right text-foreground",children:t})]})}function Da(a){try{const t=new URL(a),s=t.hostname.replace(/^\[|\]$/g,"");return{ipVersion:s.includes(":")?"IPv6":/^\d{1,3}(?:\.\d{1,3}){3}$/.test(s)?"IPv4":"Resolved hostname",port:t.port||(t.protocol==="https:"?"443":t.protocol==="http:"?"80":"Not reported")}}catch{return{ipVersion:"Not reported",port:"Not reported"}}}function Ra({status:a}){const t=a?.configuration?.domainDns,s=(a?.addresses.public??[]).map(i=>{try{return new URL(i).hostname}catch{return i}});return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(L,{className:"text-base leading-normal",children:"Observed DNS"}),e.jsx(A,{className:"leading-normal",children:"Observed state is kept separate from desired DNS policy."})]}),e.jsxs(E,{className:"space-y-3",children:[e.jsx(V,{label:"Runtime status",capability:a?.dns}),e.jsxs("dl",{className:"grid gap-2 text-sm leading-normal sm:grid-cols-2",children:[e.jsx(w,{label:"Observed hostnames",value:s.join(", ")||"Not reported"}),e.jsx(w,{label:"Expected domain",value:t?.domain||"Not configured"}),e.jsx(w,{label:"Expected value",value:a?.addresses.public[0]||"Not reported"}),e.jsx(w,{label:"Provider",value:t?.provider||"Not configured"})]})]})]})}function Pa({status:a}){const t=a?.configuration?.https;return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsx(L,{className:"text-base leading-normal",children:"Observed HTTPS"}),e.jsx(A,{className:"leading-normal",children:"Certificate evidence reported by the active runtime."})]}),e.jsxs(E,{className:"space-y-3",children:[e.jsx(V,{label:"TLS",capability:a?.tls,extra:a?.tls.expiresAt?`Expires ${U(a.tls.expiresAt)}`:void 0}),e.jsxs("dl",{className:"grid gap-2 text-sm leading-normal sm:grid-cols-2",children:[e.jsx(w,{label:"Certificate domains",value:a?.tls.domains?.join(", ")||t?.domains.join(", ")||"Not reported"}),e.jsx(w,{label:"Issuer",value:a?.tls.issuer||"Not reported by runtime"}),e.jsx(w,{label:"Validity",value:a?.tls.validFrom?`${U(a.tls.validFrom)} — ${a.tls.expiresAt?U(a.tls.expiresAt):"open"}`:a?.tls.status??"Not reported"}),e.jsx(w,{label:"Expiry",value:a?.tls.expiresAt?U(a.tls.expiresAt):"Not reported"}),e.jsx(w,{label:"Renewal status",value:a?.tls.renewalStatus||(a?.actions.renewCertificate?"Renewal available":"Renewal unavailable")}),e.jsx(w,{label:"Renewal policy",value:t?`${t.renewBeforeDays} days before expiry`:"Not configured"})]})]})]})}function Ta({status:a}){return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsxs(L,{className:"flex items-center gap-2 text-base leading-normal",children:[e.jsx(Ne,{className:"h-4 w-4","aria-hidden":"true"}),"网络能力"]}),e.jsx(A,{className:"leading-normal",children:"服务端声明的网络支持"})]}),e.jsxs(E,{className:"grid gap-3 text-sm leading-normal",children:[e.jsx(V,{label:"TLS",capability:a?.tls,extra:a?.tls.expiresAt?`到期时间 ${U(a.tls.expiresAt)}`:void 0}),e.jsx(V,{label:"DNS",capability:a?.dns}),e.jsx(V,{label:"Tunnel",capability:a?.tunnel})]})]})}function je({status:a,endpoint:t,diagnostics:s,diagnosing:i,renewing:n,onDiagnose:c,onRenewCertificate:o}){const g=s.length>0?pa({generatedAt:new Date().toISOString(),endpoint:t,checks:s}):void 0,f=async()=>{g&&(await window.navigator.clipboard.writeText(g),H({description:"Diagnostic report copied"}))},d=()=>{if(!g)return;const m=URL.createObjectURL(new Blob([g],{type:"text/plain;charset=utf-8"})),v=document.createElement("a");v.href=m,v.download=`xpod-network-diagnostics-${new Date().toISOString().replace(/[:.]/g,"-")}.txt`,v.click(),URL.revokeObjectURL(m)};return e.jsxs(P,{children:[e.jsxs(T,{children:[e.jsxs(L,{className:"flex items-center gap-2 text-base leading-normal",children:[e.jsx(be,{className:"h-4 w-4","aria-hidden":"true"}),"操作"]}),e.jsx(A,{className:"leading-normal",children:"仅显示网络能力允许的操作"})]}),e.jsxs(E,{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[a?.actions.diagnose?e.jsxs(y,{type:"button",size:"sm",variant:"outline",onClick:c,disabled:i,children:[e.jsx(na,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),"连通性诊断"]}):null,a?.actions.renewCertificate?e.jsxs(y,{type:"button",size:"sm",variant:"subtle",onClick:o,disabled:n,children:[e.jsx(ea,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),"续签证书"]}):null,e.jsxs(y,{type:"button",size:"sm",variant:"outline",onClick:()=>{f()},disabled:!g,children:[e.jsx(re,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),"复制诊断"]}),e.jsxs(y,{type:"button",size:"sm",variant:"outline",onClick:d,disabled:!g,children:[e.jsx(Fe,{className:"mr-2 h-4 w-4","aria-hidden":"true"}),"导出诊断"]})]}),s.length>0?e.jsx("div",{className:"space-y-2",children:s.map(m=>e.jsxs("div",{className:"rounded-md border border-border bg-muted/30 p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-sm leading-normal font-medium text-foreground",children:m.label}),e.jsx(q,{variant:m.status==="ok"?"secondary":"outline",children:m.status})]}),m.detail?e.jsx("div",{className:"mt-1 break-words text-xs leading-normal text-muted-foreground",children:m.detail}):null]},m.id))}):e.jsx("div",{className:"text-sm leading-normal text-muted-foreground",children:"尚未运行过诊断。"})]})]})}function V({label:a,capability:t,extra:s}){const i=t?.supported===!0;return e.jsxs("div",{className:"rounded-md border border-border bg-muted/30 p-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm leading-normal font-medium text-foreground",children:i?a:`${a} 不支持`}),e.jsxs("div",{className:"text-xs leading-normal text-muted-foreground",children:[t?.status??"读取中",t?.detail?` · ${t.detail}`:""]})]}),e.jsx(q,{variant:i?"secondary":"outline",children:i?"支持":"不支持"})]}),s?e.jsx("div",{className:"mt-2 text-xs leading-normal text-muted-foreground",children:s}):null]})}function U(a){if(!a)return"暂无记录";const t=new Date(a);return Number.isNaN(t.getTime())?"暂无记录":t.toLocaleString()}function Ka(){return e.jsx(ga,{embedded:!0})}const Se=[["gateway","入口网关"],["css","Solid 服务"],["api","API 服务"],["qlever","查询引擎(QLever)"],["inngest","任务调度(Inngest)"]],La={running:"运行中",stopped:"已停止",starting:"启动中",crashed:"运行异常",failed:"运行异常"};function Wa(){const[a,t]=l.useState(),[s,i]=l.useState([]),[n,c]=l.useState(),[o,g]=l.useState(!1),[f,d]=l.useState(""),m=l.useCallback(async()=>{g(!0),d("");try{const[x,N,u]=await Promise.all([Me(),ke({fetchImpl:fetch}).catch(()=>{}),globalThis.xpodDesktop?.deviceRuntime?.getRuntimeSettings?.()]);t(x),i(N?.clients??[]),c(u),!x.adminData&&!u&&d("暂时无法读取设备状态,请重试。")}catch{d("暂时无法读取设备状态,请重试。")}finally{g(!1)}},[]);l.useEffect(()=>{let x=!0;return queueMicrotask(()=>{x&&m()}),()=>{x=!1}},[m]);const v=async x=>{if(!(x!=="start"&&!window.confirm(`${x==="stop"?"停止":"重启"}这台设备上的 Xpod?正在进行的请求会中断。`))){g(!0),d("");try{if(globalThis.xpodDesktop?.deviceRuntime?.runtimeAction)await globalThis.xpodDesktop.deviceRuntime.runtimeAction(x);else if(x!=="restart"||!await _e())throw new Error;await m()}catch{d("操作未完成,请重试。")}finally{g(!1)}}},b=Array.from(new Map(s.map(x=>[x.binary,x])).values()),$=n?.state==="stopped"||n?.state==="failed";return e.jsxs("section",{className:"space-y-6 p-6",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[$?e.jsx(y,{className:"h-auto min-h-9 py-1 leading-normal",disabled:o,onClick:()=>{v("start")},children:"启动 Xpod"}):e.jsxs(e.Fragment,{children:[e.jsx(y,{className:"h-auto min-h-9 py-1 leading-normal",variant:"outline",disabled:o,onClick:()=>{v("restart")},children:"重启 Xpod"}),e.jsx(y,{className:"h-auto min-h-9 py-1 leading-normal",variant:"outline",disabled:o||n?.ownership!=="desktop",onClick:()=>{v("stop")},children:"停止 Xpod"})]}),e.jsx(y,{className:"h-auto min-h-9 py-1 leading-normal",variant:"ghost",disabled:o,onClick:m,children:"刷新"})]}),f&&e.jsx("p",{role:"alert",className:"text-sm leading-normal text-destructive",children:f}),e.jsxs("section",{children:[e.jsx(me,{level:2,title:"核心服务",className:"mb-2",titleClassName:"text-muted-foreground"}),e.jsx(ne,{children:Se.map(([x,N])=>{const u=a?.servicesData?.find(r=>r.name===x)?.status??(x==="gateway"&&a?.adminData?"running":void 0);return e.jsx(xe,{title:N,trailing:e.jsx("span",{className:u==="running"?"text-success":"text-muted-foreground",children:u?La[u]:"未报告"})},x)})})]}),e.jsxs("section",{children:[e.jsx(me,{level:2,title:"可选组件",className:"mb-2",titleClassName:"text-muted-foreground"}),e.jsxs(ne,{children:[b.map(x=>e.jsx(xe,{title:x.binary,trailing:e.jsx("span",{children:x.state==="missing"?"未安装":a?.servicesData?.some(N=>N.name===x.binary&&N.status==="running")?"运行中":"未使用"}),children:x.state==="missing"&&e.jsxs("details",{children:[e.jsx("summary",{className:"cursor-pointer text-primary",children:"安装方法"}),e.jsx("p",{className:"mt-2 break-words text-xs leading-normal text-muted-foreground",children:x.installHint})]})},x.binary)),!b.length&&e.jsx("p",{className:"p-4 text-sm leading-normal text-muted-foreground",children:"暂未读取到可选组件状态"})]})]}),e.jsx("p",{className:"text-xs leading-normal text-muted-foreground",children:"停止只影响这台设备;Xpod 云端和其他设备上的 Pod 不受影响。"})]})}function Ga(){const[a,t]=l.useState(),[s,i]=l.useState(""),[n,c]=l.useState(""),[o,g]=l.useState(""),[f,d]=l.useState("");l.useEffect(()=>{Promise.all([globalThis.xpodDesktop?.deviceRuntime?.getRuntimeSettings?.(),$e()]).then(([v,b])=>{t(v),i(v?.dataDirectory??b?.env.CSS_ROOT_FILE_PATH??""),c(b?.env.XPOD_EDITION??"")}).catch(()=>g("无法读取运行设置,请重试。"))},[]);const m=async()=>{g("");try{const v=await globalThis.xpodDesktop?.deviceRuntime?.selectDataDirectory?.();if(!v)return;if(!await Ie({CSS_ROOT_FILE_PATH:v}))throw new Error;i(v),d("已保存,重启后使用新位置;原有数据不会自动迁移。")}catch{g("无法更改数据位置,请重试。")}};return e.jsxs("section",{className:"space-y-5 p-6 text-sm leading-normal",children:[o&&e.jsx("p",{role:"alert",className:"text-destructive",children:o}),f&&e.jsx("p",{role:"status",children:f}),e.jsx(he,{label:"开机时启动 Xpod",checked:a?.launchAtLogin??!1,disabled:!a||!globalThis.xpodDesktop?.deviceRuntime?.setLaunchAtLogin,onCheckedChange:async v=>{try{await globalThis.xpodDesktop?.deviceRuntime?.setLaunchAtLogin?.(v),t(b=>b&&{...b,launchAtLogin:v})}catch{g("无法保存开机启动设置。")}}}),e.jsx(he,{label:"意外退出时自动重启",description:"你手动停止的不会被重启",checked:a?.autoRestart??!1,disabled:!a||!globalThis.xpodDesktop?.deviceRuntime?.setAutoRestart,onCheckedChange:async v=>{try{await globalThis.xpodDesktop?.deviceRuntime?.setAutoRestart(v),t(b=>b&&{...b,autoRestart:v})}catch{g("无法保存自动重启设置。")}}}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{children:"数据位置"}),e.jsx("p",{className:"break-all text-muted-foreground",children:s||"未报告"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(y,{className:"h-auto min-h-9 py-1 leading-normal",variant:"outline",disabled:!globalThis.xpodDesktop?.deviceRuntime?.showDataDirectory,onClick:()=>{globalThis.xpodDesktop?.deviceRuntime?.showDataDirectory?.().catch(()=>g("无法打开数据位置。"))},children:["在",globalThis.xpodDesktop?.platform==="darwin"?"访达":"文件管理器","中显示"]}),e.jsx(y,{className:"h-auto min-h-9 py-1 leading-normal",variant:"outline",disabled:!globalThis.xpodDesktop?.deviceRuntime?.selectDataDirectory,onClick:()=>{m()},children:"更改"})]})]}),e.jsxs("div",{className:"flex justify-between border-t border-border pt-4",children:[e.jsx("span",{children:"运行方式"}),e.jsx("span",{children:n==="cloud"?"Xpod 云端":n==="local"?"这台设备":n==="standalone"?"Xpod 独立运行":"未报告"})]}),e.jsxs("details",{children:[e.jsx("summary",{className:"cursor-pointer text-muted-foreground",children:"开发者模式"}),e.jsxs("dl",{className:"mt-3 space-y-2",children:[e.jsxs("div",{children:["访问地址:",window.location.origin]}),e.jsxs("div",{children:["端口:",window.location.port||(window.location.protocol==="https:"?"443":"80")]})]})]})]})}function Ja(){const[a,t]=l.useState([]),[s,i]=l.useState(()=>new URLSearchParams(window.location.search).get("source")??"all"),[n,c]=l.useState("all"),[o,g]=l.useState("all"),[f,d]=l.useState(()=>Date.now()),[m,v]=l.useState(""),[b,$]=l.useState(!1),x=l.useCallback(async()=>{$(!0);try{t(await Ee({source:s,level:n,limit:500})),d(Date.now())}finally{$(!1)}},[s,n]);l.useEffect(()=>{let u=!0;return queueMicrotask(()=>{u&&x()}),()=>{u=!1}},[x]);const N=a.filter(u=>(o==="all"||new Date(u.timestamp).getTime()>=f-Number(o))&&`${u.source} ${u.message}`.toLowerCase().includes(m.toLowerCase()));return e.jsxs("section",{className:"space-y-4 p-6",children:[e.jsxs("div",{className:"flex flex-wrap gap-3 text-sm leading-normal",children:[e.jsxs("label",{className:"grid w-full min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-2 sm:w-auto",children:["来源",e.jsxs(se,{value:s,onChange:u=>i(u.target.value),children:[e.jsx("option",{value:"all",children:"全部来源"}),Se.map(([u,r])=>e.jsx("option",{value:u,children:r},u))]})]}),e.jsxs("label",{className:"grid w-full min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-2 sm:w-auto",children:["级别",e.jsxs(se,{value:n,onChange:u=>c(u.target.value),children:[e.jsx("option",{value:"all",children:"全部级别"}),e.jsx("option",{value:"error",children:"错误"}),e.jsx("option",{value:"warn",children:"警告"}),e.jsx("option",{value:"info",children:"信息"}),e.jsx("option",{value:"debug",children:"调试"})]})]}),e.jsxs("label",{className:"grid w-full min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-2 sm:w-auto",children:["时间",e.jsxs(se,{value:o,onChange:u=>g(u.target.value),children:[e.jsx("option",{value:"all",children:"全部时间"}),e.jsx("option",{value:"3600000",children:"最近一小时"}),e.jsx("option",{value:"86400000",children:"最近一天"}),e.jsx("option",{value:"604800000",children:"最近七天"})]})]}),e.jsx(ze,{"aria-label":"搜索日志",value:m,onChange:u=>v(u.target.value),placeholder:"搜索日志"}),e.jsx(y,{className:"h-auto min-h-9 py-1 leading-normal",variant:"outline",disabled:b,onClick:x,children:"刷新"})]}),e.jsxs(ne,{children:[N.map((u,r)=>e.jsxs("div",{className:"p-3 text-xs leading-normal",children:[e.jsxs("div",{className:"text-muted-foreground",children:[new Date(u.timestamp).toLocaleString()," · ",u.source," · ",u.level]}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-words font-mono leading-normal",children:u.message})]},`${u.timestamp}-${r}`)),!N.length&&e.jsx("p",{className:"p-4 text-sm leading-normal text-muted-foreground",children:b?"正在读取日志…":"没有匹配的日志"})]}),e.jsx("p",{className:"text-xs leading-normal text-muted-foreground",children:"显示最近 500 条日志中的匹配结果"})]})}export{Ja as DeviceLogsPage,Ka as DeviceNetworkPage,Ga as DeviceRuntimePage,Wa as DeviceServicesPage};
|