apitestcenter 0.5.0 → 0.7.0
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/README.md +8 -1
- package/dist/THIRD-PARTY-NOTICES-UI.txt +3239 -0
- package/dist/THIRD-PARTY-NOTICES.txt +1484 -1
- package/dist/cli.mjs +107819 -49664
- package/dist/ui/404/index.html +1 -0
- package/dist/ui/404.html +1 -0
- package/dist/ui/__next.__PAGE__.txt +22 -0
- package/dist/ui/__next._full.txt +20 -0
- package/dist/ui/__next._tree.txt +6 -0
- package/dist/ui/_next/static/chunks/0-898cb98enjv.css +3 -0
- package/dist/ui/_next/static/chunks/02myfb0nlri-z.js +119 -0
- package/dist/ui/_next/static/chunks/08w_94tt7q8fk.js +1 -0
- package/dist/ui/_next/static/chunks/0cz1d0mv5g_q7.js +1 -0
- package/dist/ui/_next/static/chunks/0ezgetg09gtvn.js +1 -0
- package/dist/ui/_next/static/chunks/0kfr8kv4cj_kv.js +1 -0
- package/dist/ui/_next/static/chunks/0txpfp028djv6.js +291 -0
- package/dist/ui/_next/static/chunks/0vkcbl8nakdh1.js +2 -0
- package/dist/ui/_next/static/chunks/13nvl7bxr0ra-.js +1 -0
- package/dist/ui/_next/static/chunks/1l0uy37izo74u.js +22 -0
- package/dist/ui/_next/static/chunks/1w_q4qvvuinj2.js +1 -0
- package/dist/ui/_next/static/chunks/2idsynwg5lkk7.js +51 -0
- package/dist/ui/_next/static/chunks/2lw9bsrnh8k4u.js +1 -0
- package/dist/ui/_next/static/chunks/2nxnxp6p-40kg.js +1 -0
- package/dist/ui/_next/static/chunks/37izghagcat04.js +1 -0
- package/dist/ui/_next/static/chunks/3ad2zh-p8_xhv.js +59 -0
- package/dist/ui/_next/static/chunks/3eqn1h2-qx894.css +1 -0
- package/dist/ui/_next/static/chunks/3fb2986f7qg9x.js +1 -0
- package/dist/ui/_next/static/chunks/41ad2nnyaestx.js +31 -0
- package/dist/ui/_next/static/chunks/turbopack-2kiaj9_7vlslw.js +1 -0
- package/dist/ui/_next/static/lBYayPKoT6YJhgfHFuw6O/_buildManifest.js +11 -0
- package/dist/ui/_next/static/lBYayPKoT6YJhgfHFuw6O/_clientMiddlewareManifest.js +1 -0
- package/dist/ui/_next/static/lBYayPKoT6YJhgfHFuw6O/_ssgManifest.js +1 -0
- package/dist/ui/_next/static/media/02263ebadd758ea4-s.29yke99gs9qpn.woff2 +0 -0
- package/dist/ui/_next/static/media/03fc1b4a8d284b5e-s.p.0wiir8udbzjvx.woff2 +0 -0
- package/dist/ui/_next/static/media/1bcd0e671759a44c-s.2qt3tdwt-y9x_.woff2 +0 -0
- package/dist/ui/_next/static/media/2fe89d53234c61d4-s.1u30mmyq6lnsd.woff2 +0 -0
- package/dist/ui/_next/static/media/57215795b8570f5c-s.2rixgazldzomk.woff2 +0 -0
- package/dist/ui/_next/static/media/59b15b4bcd7b1eb5-s.2vemzm0itqzfy.woff2 +0 -0
- package/dist/ui/_next/static/media/5e05ae5b48faa55e-s.1yd4_i3e35931.woff2 +0 -0
- package/dist/ui/_next/static/media/68757d6cddeff913-s.1i-sca43-qwng.woff2 +0 -0
- package/dist/ui/_next/static/media/7fea77d1d19108bf-s.2y65deuc30pmy.woff2 +0 -0
- package/dist/ui/_next/static/media/90c51ce8fb754fe8-s.02z5rrbg5nt92.woff2 +0 -0
- package/dist/ui/_next/static/media/99e609270109b47d-s.p.40sczeszzbjw1.woff2 +0 -0
- package/dist/ui/_next/static/media/a7afbb44bec2bb18-s.1qc6dx89jd2qv.woff2 +0 -0
- package/dist/ui/_next/static/media/e15f58668ad64cb8-s.3cvcemwuzoywn.woff2 +0 -0
- package/dist/ui/_next/static/media/e390973e931a41c5-s.0rgnxg2b64rzs.woff2 +0 -0
- package/dist/ui/_next/static/media/e532fa1b9921e1cd-s.3cb5lpr2l6xud.woff2 +0 -0
- package/dist/ui/_next/static/media/effe91970fc4db64-s.p.0oace-s_gkfks.woff2 +0 -0
- package/dist/ui/_not-found/__next._full.txt +17 -0
- package/dist/ui/_not-found/__next._not-found.__PAGE__.txt +23 -0
- package/dist/ui/_not-found/__next._tree.txt +2 -0
- package/dist/ui/_not-found/index.html +1 -0
- package/dist/ui/_not-found/index.txt +17 -0
- package/dist/ui/compare/__next._full.txt +22 -0
- package/dist/ui/compare/__next._tree.txt +6 -0
- package/dist/ui/compare/__next.compare.__PAGE__.txt +25 -0
- package/dist/ui/compare/index.html +1 -0
- package/dist/ui/compare/index.txt +22 -0
- package/dist/ui/history/__next._full.txt +25 -0
- package/dist/ui/history/__next._tree.txt +6 -0
- package/dist/ui/history/__next.history.__PAGE__.txt +28 -0
- package/dist/ui/history/index.html +1 -0
- package/dist/ui/history/index.txt +25 -0
- package/dist/ui/index.html +1 -0
- package/dist/ui/index.txt +20 -0
- package/dist/ui/preview/__next._full.txt +25 -0
- package/dist/ui/preview/__next._tree.txt +6 -0
- package/dist/ui/preview/__next.preview.__PAGE__.txt +28 -0
- package/dist/ui/preview/index.html +1 -0
- package/dist/ui/preview/index.txt +25 -0
- package/dist/ui/suite/__next._full.txt +21 -0
- package/dist/ui/suite/__next._tree.txt +5 -0
- package/dist/ui/suite/__next.suite.__PAGE__.txt +24 -0
- package/dist/ui/suite/index.html +1 -0
- package/dist/ui/suite/index.txt +21 -0
- package/dist/ui/tests/__next._full.txt +21 -0
- package/dist/ui/tests/__next._tree.txt +5 -0
- package/dist/ui/tests/__next.tests.__PAGE__.txt +24 -0
- package/dist/ui/tests/index.html +1 -0
- package/dist/ui/tests/index.txt +21 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,63343,44794,60566,e=>{"use strict";var t=e.i(61666);e.i(24856);var s=e.i(59100),a=e.i(71189),n=e.i(87283),r=e.i(83067),l=e.i(22543),i=e.i(31753),o=e.i(28867);e.i(42674);var d=e.i(5305);let c={smoke:"2 users for 30s. Proves the endpoint works under a little concurrency.",average:"10 users for 5m. Typical day-to-day traffic.",stress:"Ramp to 20 users, hold 1m, ramp down. Looks for the breaking point.",spike:"5 users, a sudden jump to 50, then back to 5. Does it survive the burst and recover?",soak:"10 users for 30m. Finds memory leaks and slow degradation that short tests miss.",custom:"Your own numbers."};function u({label:e,value:s,min:a,max:n,onChange:r,hint:i}){return(0,t.jsxs)("label",{className:"block",children:[(0,t.jsxs)("span",{className:"mb-1 flex items-center gap-1 text-xs text-mute",children:[e,i?(0,t.jsx)(l.Hint,{label:`About ${e}`,text:i}):null]}),(0,t.jsx)("input",{type:"number",min:a,max:n,value:s,onChange:e=>r(h(e.target.value,a,n)),className:"input font-mono"})]})}function m({stages:e,unit:s,rate:r,onChange:l}){let i=(t,s)=>l(e.map((e,a)=>a===t?{...e,...s}:e));return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("p",{className:"text-xs text-mute",children:"Each stage moves linearly to its target over its duration. Hold steady by repeating the same target."}),(0,t.jsxs)("div",{className:"overflow-hidden rounded-md border border-line",children:[(0,t.jsxs)("div",{className:"grid grid-cols-[2.5rem_minmax(0,1fr)_minmax(0,1fr)_2rem] bg-panel-2 text-xs text-mute",children:[(0,t.jsx)("span",{className:"px-2 py-1.5",children:"#"}),(0,t.jsx)("span",{className:"border-l border-line px-2 py-1.5",children:"Duration"}),(0,t.jsxs)("span",{className:"border-l border-line px-2 py-1.5",children:["Target (",s,")"]}),(0,t.jsx)("span",{})]}),e.map((s,a)=>{let o=(0,d.durationError)(s.duration,!1);return(0,t.jsxs)("div",{className:"grid grid-cols-[2.5rem_minmax(0,1fr)_minmax(0,1fr)_2rem] border-t border-line",children:[(0,t.jsx)("span",{className:"px-2 py-1.5 font-mono text-xs text-mute",children:a+1}),(0,t.jsx)("input",{"aria-label":`Stage ${a+1} duration`,"aria-invalid":!!o||void 0,title:o,value:s.duration,onChange:e=>i(a,{duration:e.target.value}),className:`min-w-0 border-l border-line bg-transparent px-2 py-1.5 font-mono text-[13px] outline-none focus:bg-panel-2 ${o?"text-bad":"text-ink"}`}),(0,t.jsx)("input",{"aria-label":`Stage ${a+1} target`,type:"number",min:0,max:r?1e5:500,value:s.target,onChange:e=>i(a,{target:h(e.target.value,0,r?1e5:500)}),className:"min-w-0 border-l border-line bg-transparent px-2 py-1.5 font-mono text-[13px] text-ink outline-none focus:bg-panel-2"}),(0,t.jsx)("button",{type:"button","aria-label":`Remove stage ${a+1}`,disabled:e.length<=1,onClick:()=>l(e.filter((e,t)=>t!==a)),className:"grid place-items-center text-mute hover:text-bad disabled:opacity-30",children:(0,t.jsx)(n.X,{size:13})})]},a)})]}),(0,t.jsxs)("button",{type:"button",disabled:e.length>=20,onClick:()=>l([...e,{duration:"30s",target:e[e.length-1]?.target??1}]),className:"inline-flex items-center gap-1 text-xs text-accent hover:underline disabled:opacity-40",children:[(0,t.jsx)(a.Plus,{size:12,"aria-hidden":!0})," Add stage"]})]})}function h(e,t,s){let a=Math.round(Number(e));return Number.isFinite(a)?Math.min(s,Math.max(t,a)):t}function x(e){let t="rate"===e.mode;if(e.stages&&e.stages.length){let t=[[0,0]],a=0;for(let n of e.stages)a+=(0,s.durationToMs)(n.duration),t.push([a,n.target]);return{points:t,totalMs:a,peak:Math.max(0,...e.stages.map(e=>e.target))}}let a=t?e.rps??20:e.vus,n=(0,s.durationToMs)(e.rampUp),r=(0,s.durationToMs)(e.duration),l=(0,s.durationToMs)(e.rampDown);return{points:[[0,n>0?0:a],[n,a],[n+r,a],[n+r+l,l>0?0:a]],totalMs:n+r+l,peak:a}}function p(e){let{totalMs:t,peak:s}=x(e),a="rate"===e.mode?"req/s":1===s?"VU":"VUs";return`${e.stages?.length?"peak ":""}${s.toLocaleString()} ${a} \xb7 ${f(t)}`}function f(e){let t=Math.round(e/1e3);if(t<60)return`${t}s`;let s=Math.floor(t/60);return s<60?t%60?`${s}m ${t%60}s`:`${s}m`:`${Math.floor(s/60)}h ${s%60}m`}function b({load:e}){let{points:s,totalMs:a,peak:n}=x(e),r=s.map(([e,t])=>`${e/Math.max(a,1)*300},${56-t/Math.max(n,1)*50}`).join(" "),l=`0,56 ${r} 300,56`;return(0,t.jsxs)("figure",{className:"rounded-md border border-line bg-panel-2 px-3 py-2",children:[(0,t.jsxs)("figcaption",{className:"mb-1 flex justify-between text-xs text-mute",children:[(0,t.jsx)("span",{children:"Planned load"}),(0,t.jsx)("span",{className:"font-mono text-ink",children:p(e)})]}),(0,t.jsxs)("svg",{viewBox:"0 0 300 56",preserveAspectRatio:"none",className:"h-14 w-full",role:"img","aria-label":`Load profile: ${p(e)}`,children:[(0,t.jsx)("polygon",{points:l,fill:"var(--series-1)",fillOpacity:.15}),(0,t.jsx)("polyline",{points:r,fill:"none",stroke:"var(--series-1)",strokeWidth:2,vectorEffect:"non-scaling-stroke"})]}),(0,t.jsxs)("div",{className:"mt-1 flex justify-between font-mono text-[11px] text-mute",children:[(0,t.jsx)("span",{children:"0s"}),(0,t.jsx)("span",{children:"rate"===e.mode?"requests per second":"simulated users"}),(0,t.jsx)("span",{children:f(a)})]})]})}e.s(["LoadEditor",0,function({load:e,onChange:a}){let[n,h]=(0,r.useState)(!1),x=t=>a({...e,...t,preset:"custom"}),p="rate"===e.mode,f=!!(e.stages&&e.stages.length);return(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)(o.Segmented,{label:"Load preset",value:e.preset,onChange:t=>a((0,d.applyPreset)(e,t)),options:[{value:"smoke",label:"Smoke"},{value:"average",label:"Average"},{value:"stress",label:"Stress"},{value:"spike",label:"Spike"},{value:"soak",label:"Soak"},{value:"custom",label:"Custom"}]}),(0,t.jsx)("p",{className:"mt-2 text-xs text-mute",children:c[e.preset]})]}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-x-6 gap-y-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("span",{className:"mb-1 flex items-center gap-1 text-xs text-mute",children:["Drive load by",(0,t.jsx)(l.Hint,{label:"About users vs rate",text:"Simulated users (VUs): N clients each send, wait for the answer, and send again — a slow API gets fewer requests. Requests per second: k6 holds the rate whatever the API does — the honest way to test capacity."})]}),(0,t.jsx)(o.Segmented,{label:"Drive load by",value:e.mode??"users",onChange:e=>x({mode:e}),options:[{value:"users",label:"Simulated users"},{value:"rate",label:"Requests per second"}]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"mb-1 block text-xs text-mute",children:"Shape"}),(0,t.jsx)(o.Segmented,{label:"Load shape",value:f?"stages":"simple",onChange:function(t){if("simple"===t)return x({stages:null});let a=p?e.rps??20:e.vus,n=[];(0,s.durationToMs)(e.rampUp)>0&&n.push({duration:e.rampUp,target:a}),n.push({duration:e.duration,target:a}),(0,s.durationToMs)(e.rampDown)>0&&n.push({duration:e.rampDown,target:0}),x({stages:n})},options:[{value:"simple",label:"Ramp · hold · down"},{value:"stages",label:"Step by step"}]})]})]}),f?(0,t.jsx)(m,{stages:e.stages,unit:p?"req/s":"VUs",rate:p,onChange:e=>x({stages:e})}):(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-4",children:[p?(0,t.jsx)(u,{label:"Requests / second",value:e.rps??20,min:1,max:1e5,onChange:e=>x({rps:e})}):(0,t.jsx)(u,{label:"Simulated users",hint:"Concurrent clients running from this computer. 50+ will load both the API and this machine.",value:e.vus,min:1,max:500,onChange:e=>x({vus:e})}),(0,t.jsx)(i.LabeledInput,{label:"Hold for",mono:!0,value:e.duration,error:(0,d.durationError)(e.duration,!1),onChange:e=>x({duration:e})}),(0,t.jsx)(i.LabeledInput,{label:"Ramp up",mono:!0,value:e.rampUp,error:(0,d.durationError)(e.rampUp),onChange:e=>x({rampUp:e})}),(0,t.jsx)(i.LabeledInput,{label:"Ramp down",mono:!0,value:e.rampDown,error:(0,d.durationError)(e.rampDown),onChange:e=>x({rampDown:e})})]}),p?(0,t.jsx)("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-4",children:(0,t.jsx)(u,{label:"Max simulated users",hint:"k6 starts more VUs when responses slow down, up to this ceiling. If it runs out, requests are dropped and the report says how many.",value:e.maxVus??100,min:1,max:2e3,onChange:e=>x({maxVus:e})})}):null,(0,t.jsx)(b,{load:e}),(0,t.jsx)("button",{type:"button",className:"text-xs text-accent hover:underline",onClick:()=>h(e=>!e),"aria-expanded":n,children:n?"Hide pacing options":"Pacing options"}),n?(0,t.jsxs)("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-3",children:[p?(0,t.jsx)("p",{className:"text-xs text-mute sm:col-span-2",children:"Think time does not apply when holding a request rate — k6 paces the requests itself."}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(u,{label:"Think time (ms)",value:e.thinkTimeMs,min:0,max:6e5,onChange:e=>x({thinkTimeMs:e})}),(0,t.jsx)(u,{label:"Random extra (ms)",value:e.thinkJitterMs,min:0,max:6e5,onChange:e=>x({thinkJitterMs:e})})]}),(0,t.jsx)(i.LabeledInput,{label:"Graceful stop",mono:!0,value:e.gracefulStop,error:(0,d.durationError)(e.gracefulStop),onChange:e=>x({gracefulStop:e}),hint:"Time in-flight requests get to finish."})]}):null]})},"profileSummary",0,p],63343);var v=e.i(1675),g=e.i(80707);let j=null,y=null,k=new Set;function N(){return y??=fetch("/engine/local-servers",{cache:"no-store"}).then(e=>e.ok?e.json():null).then(e=>(e&&(j=e.servers),j)).catch(()=>j).finally(()=>{y=null,k.forEach(e=>e())}),k.forEach(e=>e()),y}var w=e.i(6278);let C=/^\{\{\s*([A-Za-z_][\w.-]*)\s*\}\}/,$=/^(https?):\/\/(localhost|127\.0\.0\.1)(?::(\d{1,5}))?(?=[/?#]|$)/i,S="\0none",E="\0local-other",q="apitestcenter-local-ports",R={GET:"text-ok",POST:"text-warn",PUT:"text-accent",PATCH:"text-accent",DELETE:"text-bad",HEAD:"text-mute",OPTIONS:"text-mute"};function T(){try{let e=JSON.parse(localStorage.getItem(q)??"[]");return(Array.isArray(e)?e.filter(e=>Number.isInteger(e)&&e>0&&e<65536):[]).slice(0,5)}catch{return[]}}function M(e){try{localStorage.setItem(q,JSON.stringify([e,...T().filter(t=>t!==e)].slice(0,5)))}catch{}}let L=(0,r.forwardRef)(function({draft:e,onChange:s,onImported:a,actions:l},i){let{vars:o,environments:c,activeEnv:u}=(0,w.useWorkspace)(),[m,h]=(0,r.useState)([]),[x,p]=(0,r.useState)(null),f=(0,r.useRef)(null);(0,r.useEffect)(()=>h(T()),[]),(0,r.useEffect)(()=>{x&&f.current?.focus()},[x]);let b=e.url,q=C.exec(b)?.[1],L=Object.entries(o).filter(([e,t])=>/^https?:\/\//i.test(t.trim())&&("practiceApi"!==e||q===e)),D=(()=>{let e=C.exec(b);if(e&&L.some(([t])=>t===e[1]))return{prefix:e[0],text:`{{${e[1]}}}`,value:e[1]};let t=$.exec(b);if(t){let e=t[1].toLowerCase(),s=t[3]??("https"===e?"443":"80");return{prefix:t[0],text:`${t[2]}${t[3]?`:${t[3]}`:""}`,value:`local:${e}:${s}`}}return null})(),P=b.startsWith("/"),z=P||""===b||null!=D,A=function(e){let[,t]=(0,r.useState)(0);(0,r.useEffect)(()=>{let e=()=>t(e=>e+1);return k.add(e),()=>void k.delete(e)},[]),(0,r.useEffect)(()=>{e&&null==j&&!y&&N()},[e]);let s=(0,r.useCallback)(()=>void N(),[]);return{servers:j??[],checked:null!=j,checking:null!=y,refresh:s}}(z),U=D?b.slice(D.prefix.length):b,O=e=>{let t=""===U||U.startsWith("/")||U.startsWith("?")?U:`/${U}`;return`${e}${t||(e.startsWith("{{")?"":"/")}`},F=A.servers,I=[...F.map(e=>({value:`local:${e.scheme}:${e.port}`,label:`localhost:${e.port}`,hint:[e.name,e.scheme,e.selfSigned?"self-signed":""].filter(Boolean).join(" · "),text:`localhost ${e.port} ${e.name??""}`,className:"font-mono",group:"local",inline:!0})),...m.filter(e=>!F.some(t=>t.port===e)).map(e=>({value:`local:http:${e}`,label:`localhost:${e}`,hint:A.checked?"used before · not running now":"used before",text:`localhost ${e}`,className:"font-mono text-mute",group:"local",inline:!0}))];D?.value.startsWith("local:")&&!I.some(e=>e.value===D.value)&&I.unshift({value:D.value,label:D.text,hint:"in this request",text:D.text,className:"font-mono",group:"local",inline:!0});let V=null!=D&&!D.value.startsWith("local:"),W=[...L.length?[{id:"env",label:u?.name??"Variables",text:u?.name??"variables",defaultOpen:V||null==D,action:c.length>1?{label:"switch",title:"Choose another environment",onClick:()=>setTimeout(()=>document.querySelector('button[role="combobox"][aria-label="Environment"]')?.click(),0)}:void 0}]:[],{id:"local",label:"Localhost",text:"localhost",hint:A.checking&&!A.checked?"checking…":`${F.length||"none"} running${A.checking?" · checking…":""}`,defaultOpen:!L.length&&null==D}],_=D?"text-accent":P?"text-warn":"text-mute";return(0,t.jsxs)("div",{className:"flex flex-wrap items-stretch gap-2",children:[(0,t.jsxs)("div",{className:"flex min-w-0 flex-[1_1_28rem] overflow-hidden rounded-lg border border-line bg-panel-2 focus-within:border-accent",children:[(0,t.jsx)(g.Select,{label:"Method",value:e.method,onChange:t=>s({...e,method:t}),options:d.METHODS.map(e=>({value:e,label:e,className:`font-mono font-medium ${R[e]}`})),minWidth:140,className:`shrink-0 border-r border-line px-3 font-mono text-sm font-medium outline-none focus-visible:bg-panel ${R[e.method]}`}),x?(0,t.jsxs)("form",{className:"flex shrink-0 items-center gap-1 border-r border-line px-2 font-mono text-xs",onSubmit:t=>{t.preventDefault(),(()=>{if(!x)return;let t=Number(x.port);!Number.isInteger(t)||t<1||t>65535||(M(t),h(T()),s((0,d.withUrl)(e,O(`${x.scheme}://localhost:${t}`))),p(null))})()},onKeyDown:e=>"Escape"===e.key&&p(null),children:[(0,t.jsx)("button",{type:"button",title:"Switch between http and https",onClick:()=>p({...x,scheme:"http"===x.scheme?"https":"http"}),className:"rounded px-1 text-accent hover:bg-panel",children:x.scheme}),(0,t.jsx)("span",{className:"text-mute",children:"://localhost:"}),(0,t.jsx)("input",{ref:f,value:x.port,onChange:e=>p({...x,port:e.target.value.replace(/\D/g,"").slice(0,5)}),inputMode:"numeric",placeholder:"8080","aria-label":"Port",className:"w-14 rounded border border-line bg-panel px-1.5 py-0.5 text-ink outline-none focus:border-accent"}),(0,t.jsx)("button",{type:"submit","aria-label":"Use this port",className:"rounded p-0.5 text-accent hover:bg-panel",children:(0,t.jsx)(v.Check,{size:14})}),(0,t.jsx)("button",{type:"button","aria-label":"Cancel",onClick:()=>p(null),className:"rounded p-0.5 text-mute hover:text-ink",children:(0,t.jsx)(n.X,{size:14})})]}):z?(0,t.jsx)(g.Select,{label:"Base URL",value:D?.value??S,onChange:t=>{if(t===E)return p({scheme:"http",port:""});if(t===S)return s((0,d.withUrl)(e,U));if(t.startsWith("local:")){let[,a,n]=t.split(":"),r=Number(n);return M(r),h(T()),s((0,d.withUrl)(e,O(`${a}://localhost:${r}`)))}s((0,d.withUrl)(e,O(`{{${t}}}`)))},onOpen:A.refresh,minWidth:320,buttonContent:D?.text??"Base URL",groups:W,options:[...L.map(([e,t])=>({value:e,label:`{{${e}}}`,hint:t,text:e,className:"font-mono text-accent",group:"env"})),...I,{value:E,label:"Another port…",text:"another port",group:"local"},{value:S,label:"No base URL — type the whole address",text:"no"}],className:`shrink-0 border-r border-line px-2.5 font-mono text-xs outline-none focus-visible:bg-panel ${_}`}):null,(0,t.jsx)("label",{className:"sr-only",htmlFor:"request-url",children:"Request URL"}),(0,t.jsx)("input",{ref:i,id:"request-url",value:U,spellCheck:!1,autoComplete:"off",onChange:t=>{let a=t.target.value,n=/^(https?:\/\/|\{\{)/i.test(a.trim())||""===U&&""!==a&&!/^[/?#]/.test(a);s((0,d.withUrl)(e,D&&!n?`${D.prefix}${a}`:a))},onPaste:t=>{let n=(0,d.withPaste)(e,t.clipboardData.getData("text"));n&&(t.preventDefault(),s(n.draft),n.note&&a?.(n.note))},placeholder:D?"/path — after the base URL":"Paste a URL or a curl command, or type a /path",className:"min-w-0 flex-1 bg-transparent px-3 py-2.5 font-mono text-sm text-ink outline-none placeholder:text-mute"})]}),(0,t.jsx)("div",{className:"flex shrink-0 gap-2",children:l})]})});e.s(["RequestBar",0,L],44794);var D=e.i(95486),P=e.i(99522);let z=(0,P.default)("chevron-up",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]);var A=e.i(89932),U=e.i(75117),O=e.i(88293);let F=(0,P.default)("wrap-text",[["path",{d:"m16 16-2 2 2 2",key:"kkc6pm"}],["path",{d:"M3 12h15a3 3 0 1 1 0 6h-4",key:"1cl7v7"}],["path",{d:"M3 18h7",key:"sq21v6"}],["path",{d:"M3 6h18",key:"d0wm0j"}]]);var I=e.i(13318),V=e.i(56396),W=e.i(15060),_=e.i(19656);let H={200:"OK",201:"Created",202:"Accepted",204:"No Content",301:"Moved Permanently",302:"Found",304:"Not Modified",307:"Temporary Redirect",308:"Permanent Redirect",400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",408:"Request Timeout",409:"Conflict",415:"Unsupported Media Type",422:"Unprocessable Content",429:"Too Many Requests",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout"};function B({label:e,value:s}){return(0,t.jsxs)("span",{className:"text-xs text-mute",children:[e," ",(0,t.jsx)("span",{className:"font-mono text-sm text-ink",children:s})]})}function K({message:e}){let s,{title:a,tip:n}=(s=e.toLowerCase()).includes("econnrefused")?{title:"Connection refused",tip:"Nothing is listening on that host and port. Is the server running, and is the port right?"}:s.includes("enotfound")||s.includes("eai_again")?{title:"Host not found",tip:"DNS could not resolve the host name. Check the spelling, or connect to the VPN for internal hosts."}:s.includes("timeout")||s.includes("etimedout")||s.includes("und_err_headers_timeout")?{title:"Timed out",tip:"The server did not answer in time. Raise Timeout under Settings, or check that the host is reachable."}:s.includes("certificate")||s.includes("self-signed")||s.includes("unable to verify")||s.includes("cert_")?{title:"TLS certificate rejected",tip:"The certificate is not trusted. For a lab certificate, turn on 'Skip TLS certificate check' under Settings."}:s.includes("econnreset")||s.includes("socket hang up")?{title:"Connection reset",tip:"The server closed the connection mid-request. Check the server logs, or a proxy or firewall in between."}:s.includes("engine")?{title:"Engine problem",tip:"The local engine did not answer. Make sure pnpm dev is running."}:{title:"Request failed",tip:"See the details below."};return(0,t.jsxs)("div",{role:"alert",className:"mt-3 rounded-md border border-bad/40 bg-bad/10 px-3 py-2.5",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-bad",children:a}),(0,t.jsx)("p",{className:"mt-1 text-sm text-ink",children:n}),(0,t.jsx)("p",{className:"mt-2 font-mono text-xs break-all text-mute",children:e})]})}function J({headers:e}){let s=(0,V.useToast)(),a=Object.entries(e).sort(([e],[t])=>e.localeCompare(t));return 0===a.length?(0,t.jsx)("p",{className:"text-sm text-mute",children:"No headers."}):(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{className:"flex justify-end",children:(0,t.jsxs)("button",{type:"button",className:"inline-flex items-center gap-1 text-xs text-mute hover:text-ink",onClick:()=>{navigator.clipboard.writeText(a.map(([e,t])=>`${e}: ${t}`).join("\n")),s("Headers copied","success")},children:[(0,t.jsx)(A.Copy,{size:12})," Copy all"]})}),(0,t.jsx)("div",{className:"overflow-auto rounded-md border border-line",children:(0,t.jsx)("table",{className:"w-full text-left text-[13px]",children:(0,t.jsx)("tbody",{children:a.map(([e,s])=>(0,t.jsxs)("tr",{className:"border-t border-line first:border-t-0",children:[(0,t.jsx)("th",{scope:"row",className:"w-2/5 bg-panel-2 px-3 py-1.5 align-top font-mono font-normal text-mute",children:e}),(0,t.jsx)("td",{className:`px-3 py-1.5 font-mono break-all ${"[redacted]"===s?"text-mute italic":"text-ink"}`,children:s})]},e))})})}),(0,t.jsx)("p",{className:"text-xs text-mute",children:"Cookie and authorization headers are redacted by the engine."})]})}function X({body:e,contentType:s,truncated:a,url:n}){let l=(0,V.useToast)(),i=function(e,t){let s=t.toLowerCase();if(s.includes("json"))return"json";if(s.includes("html"))return"html";if(s.includes("xml"))return"xml";let a=e.trim();if(a.startsWith("{")||a.startsWith("["))try{return JSON.parse(a),"json"}catch{}return/^<!doctype html|^<html/i.test(a)?"html":a.startsWith("<")?"xml":"text"}(e,s),d=a||e.length>=16384,[c,u]=(0,r.useState)("pretty"),[m,h]=(0,r.useState)(!0),[x,p]=(0,r.useState)(""),[f,b]=(0,r.useState)(0),[v,g]=(0,r.useState)(!1),j=(0,r.useRef)(null),y=(0,r.useRef)(null);(0,r.useEffect)(()=>{u("pretty"),p(""),b(0)},[e]);let k=(0,r.useMemo)(()=>e?"raw"===c?e:function(e,t){if("json"!==t)return e;try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}(e,i):"",[e,c,i]),N=(0,r.useMemo)(()=>(function(e,t){if(!t)return 0;let s=e.toLowerCase(),a=t.toLowerCase(),n=0;for(let e=s.indexOf(a);e>=0&&n<1e4;e=s.indexOf(a,e+a.length))n++;return n})(k,x),[k,x]);function w(e){0!==N&&b(t=>(t+e+N)%N)}(0,r.useEffect)(()=>{let e=y.current?.querySelector("mark.current");e?.scrollIntoView({block:"center"})},[f,x,c]);let C=[{value:"pretty",label:"Pretty"},{value:"raw",label:"Raw"},..."html"===i?[{value:"preview",label:"Preview"}]:[]];return e?(0,t.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border border-line bg-panel-2",onKeyDown:e=>{(e.ctrlKey||e.metaKey)&&"f"===e.key.toLowerCase()&&(e.preventDefault(),g(!0),window.setTimeout(()=>j.current?.focus(),0))},children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2 border-b border-line px-2 py-1.5",children:[(0,t.jsx)(o.Segmented,{label:"Body view",value:c,onChange:u,options:C}),(0,t.jsx)("span",{className:"rounded border border-line px-1.5 py-0.5 font-mono text-xs text-mute uppercase",children:i}),a?(0,t.jsx)("span",{className:"text-xs text-warn",children:"First 64 KB shown"}):null,(0,t.jsxs)("div",{className:"ml-auto flex items-center gap-1",children:[v?(0,t.jsxs)("div",{className:"flex items-center gap-1 rounded-md border border-line bg-panel px-1.5",children:[(0,t.jsx)(O.Search,{size:12,className:"text-mute"}),(0,t.jsx)("input",{ref:j,value:x,"aria-label":"Find in body",placeholder:"Find",onChange:e=>{p(e.target.value),b(0)},onKeyDown:e=>{"Enter"===e.key&&w(e.shiftKey?-1:1),"Escape"===e.key&&(p(""),g(!1))},className:"w-28 bg-transparent py-1 text-xs text-ink outline-none"}),(0,t.jsx)("span",{className:"font-mono text-xs text-mute tabular",children:x?`${N?f+1:0}/${N}`:""}),(0,t.jsx)(G,{label:"Previous match",onClick:()=>w(-1),children:(0,t.jsx)(z,{size:12})}),(0,t.jsx)(G,{label:"Next match",onClick:()=>w(1),children:(0,t.jsx)(D.ChevronDown,{size:12})})]}):(0,t.jsx)(G,{label:"Find in body (Ctrl+F)",onClick:()=>{g(!0),window.setTimeout(()=>j.current?.focus(),0)},children:(0,t.jsx)(O.Search,{size:14})}),(0,t.jsx)(G,{label:m?"Turn off line wrap":"Wrap long lines",pressed:m,onClick:()=>h(e=>!e),children:(0,t.jsx)(F,{size:14})}),(0,t.jsx)(G,{label:"Copy body",onClick:()=>{navigator.clipboard.writeText(k),l("Body copied","success")},children:(0,t.jsx)(A.Copy,{size:14})}),(0,t.jsx)(G,{label:"Download body",onClick:()=>{var e;return(0,W.downloadText)(function(e,t){let s="response";try{s=new URL(e).pathname.split("/").filter(Boolean).pop()||"response"}catch{}return`${s.replace(/[^\w.-]+/g,"_")}.${"json"===t?"json":"html"===t?"html":"xml"===t?"xml":"txt"}`}(n,i),k,"json"===(e=i)?"application/json":"html"===e?"text/html":"xml"===e?"application/xml":"text/plain")},children:(0,t.jsx)(U.Download,{size:14})})]})]}),"preview"===c?(0,t.jsx)("iframe",{title:"HTML preview",sandbox:"",srcDoc:e,className:"min-h-[24rem] w-full flex-1 bg-white"}):(0,t.jsx)("pre",{ref:y,tabIndex:0,"aria-label":"Response body",className:`min-h-[12rem] flex-1 overflow-auto p-3 font-mono text-[13px] leading-5 text-ink ${m?"break-words whitespace-pre-wrap":"whitespace-pre"}`,children:x?function(e,s,a){let n=[],r=e.toLowerCase(),l=s.toLowerCase(),i=0,o=0;for(let s=r.indexOf(l);s>=0&&o<1e4;s=r.indexOf(l,s+l.length))n.push(e.slice(i,s)),n.push((0,t.jsx)("mark",{className:`find-hit${o===a?" current":""}`,children:e.slice(s,s+l.length)},s)),i=s+l.length,o++;return n.push(e.slice(i)),n}(k,x,f):"pretty"!==c||"json"!==i||d?k:function(e){let s=[],a=0;for(let n of e.matchAll(Z)){let r=n.index??0;s.push(e.slice(a,r)),n[1]?(s.push((0,t.jsx)("span",{className:n[2]?"tok-key":"tok-str",children:n[1]},r)),n[2]&&s.push(n[2])):n[3]?s.push((0,t.jsx)("span",{className:"tok-lit",children:n[3]},r)):s.push((0,t.jsx)("span",{className:"tok-num",children:n[4]},r)),a=r+n[0].length}return s.push(e.slice(a)),s}(k)})]}):(0,t.jsx)("p",{className:"text-sm text-mute",children:"Empty body."})}function G({label:e,onClick:s,children:a,pressed:n}){return(0,t.jsx)("button",{type:"button","aria-label":e,title:e,"aria-pressed":n,onClick:s,className:`rounded p-1 hover:bg-panel hover:text-ink ${n?"text-accent":"text-mute"}`,children:a})}let Z=/("(?:\\u[a-fA-F0-9]{4}|\\[^u]|[^\\"])*")(\s*:)?|\b(true|false|null)\b|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g;e.s(["ResponseViewer",0,function({result:e}){var s,a;let n,[l,i]=(0,r.useState)("body"),o=e.checks??[],d=o.filter(e=>e.ok).length,c=Object.keys(e.headers).length,u=(n=Object.keys(s=e.headers).find(e=>"content-type"===e.toLowerCase()))?s[n]??"":"",m=(0,r.useMemo)(()=>new TextEncoder().encode(e.body).length,[e.body]),h=!e.status;return(0,t.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[(0,t.jsx)("span",{className:`rounded-md border px-2 py-0.5 font-mono text-sm font-medium ${(a=e.status)>=200&&a<300?"text-ok border-ok/40 bg-ok/10":a>=300&&a<400?"text-accent border-accent/40 bg-accent/10":a>=400&&a<500?"text-warn border-warn/40 bg-warn/10":"text-bad border-bad/40 bg-bad/10"}`,children:h?"Error":`${e.status} ${H[e.status]??""}`.trim()}),(0,t.jsx)(B,{label:"Time",value:`${e.durationMs} ms`}),h?null:(0,t.jsx)(B,{label:"Size",value:`${(0,_.formatBytes)(m)}${e.truncated?"+":""}`}),u?(0,t.jsx)(B,{label:"Type",value:u.split(";")[0]??u}):null,o.length?(0,t.jsxs)("button",{type:"button",onClick:()=>i("checks"),className:`rounded-md border px-2 py-0.5 text-xs ${d===o.length?"border-ok/40 text-ok":"border-bad/40 text-bad"}`,children:[d===o.length?"✓":"✕"," ",d,"/",o.length," checks"]}):null]}),(0,t.jsx)("p",{className:"mt-2 font-mono text-xs break-all text-mute",children:e.url}),e.setup||e.dataRow?(0,t.jsxs)("p",{className:"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-mute",children:[e.setup?(0,t.jsxs)("span",{className:e.setup.ok?"":"text-bad",children:["Ran first: ",(0,t.jsx)("span",{className:"text-ink",children:e.setup.label}),e.setup.status?` \xb7 ${e.setup.status} \xb7 ${e.setup.durationMs} ms`:"",e.setup.values.map(e=>(0,t.jsxs)("span",{className:`ml-2 font-mono ${e.found?"text-ok":"text-bad"}`,title:e.found?`From ${e.from}: ${e.preview}`:`Not found: ${e.from}`,children:[e.found?"✓":"✕"," ",`{{${e.name}}}`]},e.name))]}):null,e.dataRow?(0,t.jsxs)("span",{children:["Test data: row ",e.dataRow.row," of ",e.dataRow.of.toLocaleString()]}):null]}):null,e.error?(0,t.jsx)(K,{message:e.error}):null,h?null:(0,t.jsxs)("div",{className:"mt-3 flex min-h-0 flex-1 flex-col",children:[(0,t.jsx)(I.Tabs,{id:"response",label:"Response",value:l,onChange:i,items:[{id:"body",label:"Body"},{id:"headers",label:"Headers",badge:c||void 0},...o.length?[{id:"checks",label:"Checks",badge:(0,t.jsxs)("span",{className:d===o.length?"text-ok":"text-bad",children:[d,"/",o.length]})}]:[]]}),(0,t.jsx)("div",{...(0,I.tabPanelProps)("response",l),className:"flex min-h-0 flex-1 flex-col pt-3",children:"body"===l?(0,t.jsx)(X,{body:e.body,contentType:u,truncated:e.truncated,url:e.url}):"checks"===l?(0,t.jsx)("ul",{className:"space-y-1.5",children:o.map((e,s)=>(0,t.jsxs)("li",{className:`flex items-center gap-2 rounded-md border px-3 py-2 text-sm ${e.ok?"border-ok/30 bg-ok/5":"border-bad/40 bg-bad/10"}`,children:[(0,t.jsx)("span",{className:e.ok?"text-ok":"text-bad","aria-hidden":!0,children:e.ok?"✓":"✕"}),(0,t.jsx)("span",{className:"font-mono text-[13px] text-ink",children:e.name}),(0,t.jsx)("span",{className:`ml-auto text-xs ${e.ok?"text-ok":"text-bad"}`,children:e.ok?"pass":"fail"})]},s))}):(0,t.jsx)(J,{headers:e.headers})})]})]})}],60566)},68228,65638,e=>{"use strict";var t=e.i(61666);e.i(24856);var s=e.i(78451),a=e.i(89932),n=e.i(99522);let r=(0,n.default)("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]),l=(0,n.default)("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]),i=(0,n.default)("lock",[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]]);var o=e.i(71189),d=e.i(43514),c=e.i(96659),u=e.i(87283),m=e.i(83067),h=e.i(39170),x=e.i(80707),p=e.i(56396);e.i(42674);var f=e.i(5305),b=e.i(65238),v=e.i(6278);let g=()=>globalThis.crypto?.randomUUID?.()??`env-${Date.now().toString(36)}`;function j({onClose:e}){let s=(0,p.useToast)(),n=(0,h.useConfirm)(),{environments:r,activeEnv:l,setActiveEnv:d,saveEnvironments:x,index:f}=(0,v.useWorkspace)(),[b,k]=(0,m.useState)(()=>structuredClone(r)),[N,w]=(0,m.useState)(l?.id??r[0]?.id??null),[C,$]=(0,m.useState)(!1),S=(0,m.useRef)(null),E=b.find(e=>e.id===N)??null,q=JSON.stringify(b)!==JSON.stringify(r);(0,m.useEffect)(()=>{let e=document.activeElement;return S.current?.querySelector("input,button")?.focus(),()=>e?.focus()},[]);let R=(e,t)=>k(s=>s.map(s=>s.id===e?{...s,...t}:s));function T(e){let t=e?{id:g(),name:`${e.name} copy`,variables:structuredClone(e.variables)}:{id:g(),name:b.length?`Environment ${b.length+1}`:"DEV",variables:[{key:"baseUrl",value:"",secret:!1}]};k(e=>[...e,t]),w(t.id)}async function M(){(!q||await n({title:"Discard changes to environments?",confirmLabel:"Discard",tone:"danger"}))&&e()}async function L(){$(!0);try{await x(b),l&&!b.some(e=>e.id===l.id)&&d(null),s("Environments saved","success"),e()}catch(e){s(e instanceof Error?e.message:"Could not save environments","error")}finally{$(!1)}}return(0,t.jsx)("div",{className:"fixed inset-0 z-50 grid place-items-center bg-black/50 p-4 backdrop-blur-sm",onMouseDown:e=>e.target===e.currentTarget&&void M(),children:(0,t.jsxs)("div",{ref:S,role:"dialog","aria-modal":"true","aria-label":"Environments",onKeyDown:e=>"Escape"===e.key&&void M(),className:"flex max-h-[85vh] w-full max-w-4xl flex-col overflow-hidden rounded-xl border border-line bg-panel shadow-2xl",children:[(0,t.jsxs)("header",{className:"flex items-center justify-between border-b border-line px-5 py-3",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h2",{className:"text-base font-medium text-ink",children:"Environments"}),(0,t.jsxs)("p",{className:"text-xs text-mute",children:["Use ",(0,t.jsx)("code",{className:"font-mono text-ink",children:"{{name}}"})," in the URL, params, headers, body, or auth. Saved to environments.json in your app-data folder."]})]}),(0,t.jsx)("button",{type:"button","aria-label":"Close",className:"rounded p-1 text-mute hover:text-ink",onClick:()=>void M(),children:(0,t.jsx)(u.X,{size:16})})]}),(0,t.jsxs)("div",{className:"grid min-h-0 flex-1 md:grid-cols-[14rem_minmax(0,1fr)]",children:[(0,t.jsxs)("nav",{"aria-label":"Environment list",className:"space-y-1 overflow-auto border-line p-3 md:border-r",children:[b.map(e=>(0,t.jsxs)("button",{type:"button",onClick:()=>w(e.id),"aria-current":e.id===N?"true":void 0,className:`block w-full truncate rounded-md px-2 py-1.5 text-left text-sm ${e.id===N?"bg-accent-dim text-ink":"text-mute hover:bg-panel-2 hover:text-ink"}`,children:[e.name,(0,t.jsx)("span",{className:"ml-1 text-xs text-mute",children:e.variables.length})]},e.id)),(0,t.jsxs)("button",{type:"button",onClick:()=>T(),className:"mt-2 inline-flex items-center gap-1 text-xs text-accent hover:underline",children:[(0,t.jsx)(o.Plus,{size:12,"aria-hidden":!0})," New environment"]})]}),(0,t.jsx)("section",{className:"min-h-0 overflow-auto p-4",children:E?(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,t.jsxs)("label",{className:"min-w-0 flex-1",children:[(0,t.jsx)("span",{className:"sr-only",children:"Environment name"}),(0,t.jsx)("input",{value:E.name,onChange:e=>R(E.id,{name:e.target.value}),className:"input text-base font-medium"})]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-secondary py-1.5 text-xs",onClick:()=>T(E),children:[(0,t.jsx)(a.Copy,{size:13})," Duplicate"]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-danger py-1.5 text-xs",onClick:()=>{k(e=>e.filter(e=>e.id!==E.id)),w(b.find(e=>e.id!==E.id)?.id??null)},children:[(0,t.jsx)(c.Trash2,{size:13})," Delete"]})]}),(0,t.jsx)(y,{vars:E.variables,onPatch:(e,t)=>E&&R(E.id,{variables:E.variables.map((s,a)=>a===e?{...s,...t}:s)}),onChange:e=>R(E.id,{variables:e})}),(0,t.jsxs)("p",{className:"flex items-start gap-1.5 text-xs text-mute",children:[(0,t.jsx)(i,{size:12,className:"mt-0.5 shrink-0","aria-hidden":!0}),f?.secretsPersistent?"Secret values are encrypted on this computer and never written to environments.json.":"Secret values are never written to disk. In this browser setup they are kept by the engine until it restarts; the desktop app encrypts them."]})]}):(0,t.jsxs)("div",{className:"py-12 text-center text-sm text-mute",children:["No environments yet. Create one for each place you test — DEV, UAT, PROD.",(0,t.jsx)("div",{className:"mt-4",children:(0,t.jsxs)("button",{type:"button",className:"btn btn-primary text-sm",onClick:()=>T(),children:[(0,t.jsx)(o.Plus,{size:14})," New environment"]})})]})})]}),(0,t.jsxs)("footer",{className:"flex justify-end gap-2 border-t border-line px-5 py-3",children:[(0,t.jsx)("button",{type:"button",className:"btn btn-secondary text-sm",onClick:()=>void M(),children:"Cancel"}),(0,t.jsx)("button",{type:"button",className:"btn btn-primary text-sm",disabled:!q||C,onClick:()=>void L(),children:"Save environments"})]})]})})}function y({vars:e,onPatch:s,onChange:a}){let[n,i]=(0,m.useState)(new Set),d=new Set(e.map(e=>e.key.trim()).filter((e,t,s)=>e&&s.indexOf(e)!==t));return(0,t.jsxs)("div",{className:"overflow-hidden rounded-md border border-line",children:[(0,t.jsxs)("div",{className:"grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_5.5rem_2rem] bg-panel-2 text-xs text-mute",children:[(0,t.jsx)("span",{className:"px-2.5 py-1.5",children:"Variable"}),(0,t.jsx)("span",{className:"border-l border-line px-2.5 py-1.5",children:"Value"}),(0,t.jsx)("span",{className:"border-l border-line px-2.5 py-1.5",children:"Secret"}),(0,t.jsx)("span",{})]}),e.map((o,c)=>{let m=o.key&&!/^[A-Za-z_][\w.-]*$/.test(o.key)||d.has(o.key.trim());return(0,t.jsxs)("div",{className:"grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_5.5rem_2rem] border-t border-line",children:[(0,t.jsx)("input",{"aria-label":`Variable ${c+1} name`,"aria-invalid":m||void 0,title:m?"Letters, digits, _ . - ; must start with a letter or _ ; must be unique":void 0,value:o.key,onChange:e=>s(c,{key:e.target.value}),placeholder:"baseUrl",className:`min-w-0 bg-transparent px-2.5 py-1.5 font-mono text-[13px] outline-none focus:bg-panel-2 ${m?"text-bad":"text-ink"}`}),(0,t.jsxs)("span",{className:"relative flex min-w-0 border-l border-line",children:[(0,t.jsx)("input",{"aria-label":`Variable ${c+1} value`,type:o.secret&&!n.has(c)?"password":"text",autoComplete:"off",value:o.value,onChange:e=>s(c,{value:e.target.value}),className:"min-w-0 flex-1 bg-transparent px-2.5 py-1.5 font-mono text-[13px] text-ink outline-none focus:bg-panel-2"}),o.secret?(0,t.jsx)("button",{type:"button","aria-label":n.has(c)?"Hide value":"Show value",onClick:()=>i(e=>{let t=new Set(e);return t.has(c)?t.delete(c):t.add(c),t}),className:"px-2 text-mute hover:text-ink",children:n.has(c)?(0,t.jsx)(l,{size:13}):(0,t.jsx)(r,{size:13})}):null]}),(0,t.jsxs)("label",{className:"flex items-center gap-1.5 border-l border-line px-2.5 text-xs text-mute",children:[(0,t.jsx)("input",{type:"checkbox",checked:o.secret,onChange:e=>s(c,{secret:e.target.checked}),className:"accent-[var(--accent)]"}),"secret"]}),(0,t.jsx)("button",{type:"button","aria-label":`Remove ${o.key||`variable ${c+1}`}`,onClick:()=>a(e.filter((e,t)=>t!==c)),className:"grid place-items-center text-mute hover:text-bad",children:(0,t.jsx)(u.X,{size:13})})]},c)}),(0,t.jsxs)("button",{type:"button",onClick:()=>a([...e,{key:"",value:"",secret:!1}]),className:"flex w-full items-center gap-1 border-t border-line px-2.5 py-1.5 text-xs text-accent hover:bg-panel-2",children:[(0,t.jsx)(o.Plus,{size:12,"aria-hidden":!0})," Add variable"]})]})}e.s(["EnvironmentBar",0,function({drafts:e,collections:a=[]}){let{environments:n,activeEnv:r,setActiveEnv:l,vars:i,savedValues:o,clearSavedValues:c}=(0,v.useWorkspace)(),u=Object.keys(o),[h,p]=(0,m.useState)(!1),g=(0,m.useMemo)(()=>{let t=new Set;for(let a of e){let e=new Set((0,f.draftRuntimeNames)(a)),n=[a.url,a.bodyText,a.token,a.username,a.password,a.apiValue,...a.params.map(e=>e.value),...a.headers.map(e=>e.value)].join(" ");(0,s.findVariables)(n).forEach(s=>!e.has(s)&&t.add(s))}return[...t]},[e]),y=(0,b.useFolderVarNames)(a),k=g.filter(e=>!(e in i)&&!y.has(e));return(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2 text-xs",children:[(0,t.jsxs)("span",{className:"flex items-center gap-1.5 text-mute",children:["Environment",(0,t.jsx)(x.Select,{label:"Environment",value:r?.id??"",onChange:e=>l(e||null),minWidth:200,options:[{value:"",label:"None",hint:"Only built-in variables"},...n.map(e=>({value:e.id,label:e.name,hint:`${e.variables.length} variable${1===e.variables.length?"":"s"}`}))],className:"rounded-md border border-line bg-panel-2 px-2 py-1 text-xs text-ink hover:border-mute focus-visible:border-accent focus-visible:outline-none"})]}),(0,t.jsxs)("button",{type:"button",onClick:()=>p(!0),className:"inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-mute hover:text-ink",children:[(0,t.jsx)(d.Settings2,{size:12,"aria-hidden":!0})," Manage"]}),g.length>0?k.length?(0,t.jsxs)("span",{className:"text-warn",role:"status",children:[k.map(e=>`{{${e}}}`).join(", ")," not defined",r?` in ${r.name}`:" — pick an environment"]}):(0,t.jsxs)("span",{className:"text-mute",children:["Uses ",g.map(e=>`{{${e}}}`).join(", ")]}):null,u.length?(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-mute",title:u.map(e=>`{{${e}}} — saved from “${o[e].from}”`).join("\n"),children:["Saved from answers: ",(0,t.jsx)("span",{className:"font-mono text-accent",children:u.map(e=>`{{${e}}}`).join(", ")}),(0,t.jsx)("button",{type:"button",onClick:c,className:"text-mute underline-offset-2 hover:text-ink hover:underline",children:"Clear"})]}):null,h?(0,t.jsx)(j,{onClose:()=>p(!1)}):null]})},"VariableTable",0,y],68228);var k=e.i(95486),N=e.i(60961);let w=(0,n.default)("file-plus-2",[["path",{d:"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4",key:"1pf5j1"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M3 15h6",key:"4e2qda"}],["path",{d:"M6 12v6",key:"1u72j0"}]]),C=(0,n.default)("folder",[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]]),$=(0,n.default)("folder-plus",[["path",{d:"M12 10v6",key:"1bos4e"}],["path",{d:"M9 13h6",key:"1uhe8q"}],["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]]),S=(0,n.default)("import",[["path",{d:"M12 3v12",key:"1x0j5s"}],["path",{d:"m8 11 4 4 4-4",key:"1dohi6"}],["path",{d:"M8 5H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-4",key:"1ywtjm"}]]);var E=e.i(19286),q=e.i(81538),R=e.i(3792),T=e.i(88293),M=e.i(50804),L=e.i(67217),D=e.i(41997),P=e.i(37837),z=e.i(27813),A=e.i(36e3),U=e.i(13318);function O({path:e,onClose:a}){let n=(0,p.useToast)(),{refresh:r}=(0,v.useWorkspace)(),[l,i]=(0,m.useState)(null),[o,d]=(0,m.useState)([]),[c,h]=(0,m.useState)([]),[x,f]=(0,m.useState)("auth"),[g,j]=(0,m.useState)(!1);async function k(){if(l&&!g){j(!0);try{await b.folderApi.save(e,{...l,headers:l.headers.filter(e=>e.key.trim()),variables:l.variables.filter(e=>e.key.trim())}),await r(),n(`Saved the settings of ${e}`,"success"),a()}catch(e){n(e instanceof Error?e.message:"Could not save","error")}finally{j(!1)}}}(0,m.useEffect)(()=>{let t=!0;return Promise.all([b.folderApi.get(e),b.folderApi.chain((0,s.parentFolder)(e))]).then(([e,s])=>{t&&(i(e.settings),d(e.secretsMissing??[]),h(s))}).catch(e=>{t&&(n(e instanceof Error?e.message:"Could not open the folder","error"),i((0,s.emptyFolderSettings)()))}),()=>{t=!1}},[e,n]);let N=[...c].reverse().find(e=>"inherit"!==e.settings.auth.authMode),w=l?{headers:l.headers.filter(e=>e.key.trim()).length,variables:l.variables.length}:{headers:0,variables:0};return(0,t.jsx)("div",{className:"fixed inset-0 z-50 grid place-items-center bg-black/50 p-4 backdrop-blur-sm",onMouseDown:e=>e.target===e.currentTarget&&a(),children:(0,t.jsxs)("div",{role:"dialog","aria-modal":"true","aria-labelledby":"folder-settings-title",onKeyDown:e=>"Escape"===e.key&&a(),className:"flex max-h-[85vh] w-full max-w-2xl flex-col overflow-hidden rounded-xl border border-line bg-panel shadow-2xl",children:[(0,t.jsxs)("header",{className:"flex items-start justify-between gap-3 border-b border-line px-5 py-3",children:[(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsxs)("h2",{id:"folder-settings-title",className:"truncate text-base font-medium text-ink",children:["Folder settings · ",e]}),(0,t.jsx)("p",{className:"text-xs text-mute",children:"Every request inside — and inside its subfolders — uses these. A request's own value wins."})]}),(0,t.jsx)("button",{type:"button","aria-label":"Close",className:"rounded p-1 text-mute hover:text-ink",onClick:a,children:(0,t.jsx)(u.X,{size:16})})]}),l?(0,t.jsxs)("div",{className:"min-h-0 flex-1 overflow-auto px-5 py-4",children:[(0,t.jsx)(U.Tabs,{id:"folder-settings",label:"Folder settings",value:x,onChange:f,items:[{id:"auth",label:"Auth"},{id:"headers",label:"Headers",badge:w.headers||void 0},{id:"variables",label:"Variables",badge:w.variables||void 0}]}),(0,t.jsxs)("div",{...(0,U.tabPanelProps)("folder-settings",x),className:"pt-4",children:["auth"===x?(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("p",{className:"text-xs text-mute",children:["Requests set to ",(0,t.jsx)("span",{className:"text-ink",children:"Auth → From folder"})," (the default for new requests) use this — sign in once here instead of in every request."]}),(0,t.jsx)(D.AuthFields,{value:l.auth,onChange:e=>i({...l,auth:{...l.auth,...e}}),inheritLabel:"From parent",defaults:Object.fromEntries([...c.flatMap(e=>e.settings.variables),...l.variables].map(e=>[e.key,e.value])),inheritNote:N&&"none"!==N.settings.auth.authMode?(0,t.jsxs)(t.Fragment,{children:["Passes on the ",(0,t.jsx)("span",{className:"text-ink",children:(0,D.authModeLabel)(N.settings.auth.authMode)})," of"," ",(0,t.jsx)("span",{className:"text-ink",children:N.path}),"."]}):(0,t.jsx)(t.Fragment,{children:"No folder above sets auth, so this folder passes none down."}),secretNote:"Use {{token}} to take it from the environment, or type it — it's kept encrypted on this computer, never in the folder's file."}),o.some(e=>!e.startsWith("var:"))?(0,t.jsxs)("p",{className:"text-xs text-warn",children:["The saved ",o.filter(e=>!e.startsWith("var:")).join(", ")," isn't available on this computer — enter it again."]}):null]}):null,"headers"===x?(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)(A.KeyValueEditor,{rows:l.headers,onChange:e=>i({...l,headers:e}),keyPlaceholder:"Header",valuePlaceholder:"Value",noun:"header"}),(0,t.jsx)("p",{className:"text-xs text-mute",children:"Sent with every request inside. An inner folder's or a request's header with the same name replaces it."})]}):null,"variables"===x?(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)(y,{vars:l.variables,onPatch:(e,t)=>i({...l,variables:l.variables.map((s,a)=>a===e?{...s,...t}:s)}),onChange:e=>i({...l,variables:e})}),(0,t.jsxs)("p",{className:"text-xs text-mute",children:["Defaults for ",(0,t.jsx)("code",{className:"font-mono text-ink",children:"{{name}}"})," in the requests inside. The chosen environment wins when it has the same name — so a folder can say"," ",(0,t.jsx)("code",{className:"font-mono text-ink",children:"basePath = /v2"})," and the environment picks the server."]}),o.some(e=>e.startsWith("var:"))?(0,t.jsxs)("p",{className:"text-xs text-warn",children:["Secret values not available on this computer: ",o.filter(e=>e.startsWith("var:")).map(e=>e.slice(4)).join(", ")," — enter them again."]}):null]}):null]})]}):(0,t.jsx)("div",{className:"grid place-items-center p-10 text-mute",children:(0,t.jsx)(z.Loader2,{className:"animate-spin",size:18,"aria-label":"Loading"})}),(0,t.jsxs)("footer",{className:"flex justify-end gap-2 border-t border-line px-5 py-3",children:[(0,t.jsx)("button",{type:"button",className:"btn btn-secondary",onClick:a,disabled:g,children:"Cancel"}),(0,t.jsxs)("button",{type:"button",className:"btn btn-primary",onClick:()=>void k(),disabled:!l||g,children:[g?(0,t.jsx)(z.Loader2,{size:14,className:"animate-spin"}):null,"Save folder settings"]})]})]})})}var F=e.i(14168);let I={GET:"text-ok",POST:"text-warn",PUT:"text-accent",PATCH:"text-accent",DELETE:"text-bad"};function V({activeId:e,onOpen:a,allowDelete:n=!0,newFolder:r,onNewFolderDone:l}){let i=(0,p.useToast)(),o=(0,h.useConfirm)(),{index:d,refresh:u}=(0,v.useWorkspace)(),[x,f]=(0,m.useState)(""),[g,j]=(0,m.useState)(new Set),[y,w]=(0,m.useState)(null),[$,S]=(0,m.useState)(null),q=d?.requests??[],P=d?.folders??[],z=x.trim().toLowerCase(),A=(0,m.useMemo)(()=>z?q.filter(e=>`${e.name} ${e.collection} ${e.url} ${e.method}`.toLowerCase().includes(z)):q,[q,z]),U=(0,m.useMemo)(()=>(function(e,t,a){let n={path:"",name:"",folders:[],requests:[],summary:null},r=new Map([["",n]]),l=e=>{let t=r.get(e);if(t)return t;let a={path:e,name:(0,s.folderName)(e),folders:[],requests:[],summary:null};return r.set(e,a),l((0,s.parentFolder)(e)).folders.push(a),a};if(a)for(let e of t)l(e.path);for(let t of e)l(t.collection).requests.push(t);for(let e of t){let t=r.get(e.path);t&&(t.summary=e)}let i=e=>{e.folders.sort((e,t)=>e.name.localeCompare(t.name)),e.folders.forEach(i)};return i(n),n})(A,P,!z),[A,P,z]);async function H(e){try{let t=await v.workspaceApi.get(e);a(t),t.secretsMissing?.length&&i(`Re-enter the ${t.secretsMissing.join(", ")} — secrets are kept only until the engine restarts in this setup`,"info")}catch(e){i(e instanceof Error?e.message:"Could not open the request","error")}}async function B(e){await o({title:`Delete “${e.name}”?`,body:"The saved request file is removed. Load test history is not affected.",confirmLabel:"Delete",tone:"danger"})&&(await v.workspaceApi.remove(e.id).catch(()=>void 0),await u())}async function K(e){if(w(null),l?.(),!y)return;let t=e.trim();if(t)try{if("new"===y.kind){let e=(0,s.folderPath)(y.parent?`${y.parent}/${t}`:t);await b.folderApi.save(e,(0,s.emptyFolderSettings)()),j(e=>{let t=new Set(e);return t.delete(y.parent),t})}else{let e=(0,s.folderPath)(t.includes("/")?t:(0,s.parentFolder)(y.path)?`${(0,s.parentFolder)(y.path)}/${t}`:t);e!==y.path&&await b.folderApi.move(y.path,e)}await u()}catch(e){i(e instanceof Error?e.message:"Could not do that","error")}}async function J(e){if(await o({title:`Delete the folder “${e}”?`,body:"Its settings and empty subfolders are removed. A folder that still has requests can't be deleted — move or delete them first.",confirmLabel:"Delete folder",tone:"danger"}))try{await b.folderApi.remove(e),await u()}catch(e){i(e instanceof Error?e.message:"Could not delete the folder","error")}}(0,m.useEffect)(()=>{r&&w({kind:"new",parent:""})},[r]);let X=s=>(0,t.jsx)("ul",{children:s.map(s=>(0,t.jsxs)("li",{className:`group flex items-center rounded ${s.id===e?"bg-accent-dim":"hover:bg-panel-2"}`,children:[(0,t.jsxs)("button",{type:"button",onClick:()=>void H(s.id),"aria-current":s.id===e?"true":void 0,title:s.url,className:"flex min-w-0 flex-1 items-center gap-2 px-1.5 py-1 text-left",children:[(0,t.jsx)("span",{className:`w-12 shrink-0 font-mono text-[11px] font-medium ${I[s.method]??"text-mute"}`,children:s.method}),(0,t.jsx)("span",{className:"min-w-0 truncate text-xs text-ink",children:s.name})]}),n?(0,t.jsx)("button",{type:"button","aria-label":`Delete ${s.name}`,onClick:()=>void B(s),className:"mr-1 rounded p-1 text-mute opacity-0 group-hover:opacity-100 hover:text-bad focus:opacity-100",children:(0,t.jsx)(c.Trash2,{size:12})}):null]},s.id))}),G=e=>{var s;let a=g.has(e.path)&&!z,r=(s=e.summary)?[s.auth?(0,D.authModeLabel)(s.auth):"",s.headers?`${s.headers} header${1===s.headers?"":"s"}`:"",s.variables?`${s.variables} variable${1===s.variables?"":"s"}`:""].filter(Boolean).join(" · "):"";return(0,t.jsxs)("div",{className:"mb-0.5",children:[y?.kind==="rename"&&y.path===e.path?(0,t.jsx)(W,{initial:e.path,label:`New name for ${e.path}`,onDone:e=>void K(e),hint:"Use / to move it into another folder"}):(0,t.jsxs)("div",{className:"group/folder flex items-center",children:[(0,t.jsxs)("button",{type:"button","aria-expanded":!a,onClick:()=>{let t;return t=e.path,j(e=>{let s=new Set(e);return s.has(t)?s.delete(t):s.add(t),s})},title:r?`Passes down: ${r}`:e.path,className:"flex min-w-0 flex-1 items-center gap-1 rounded px-1 py-1 text-left text-xs font-medium text-mute hover:text-ink",children:[a?(0,t.jsx)(N.ChevronRight,{size:12,"aria-hidden":!0,className:"shrink-0"}):(0,t.jsx)(k.ChevronDown,{size:12,"aria-hidden":!0,className:"shrink-0"}),(0,t.jsx)(C,{size:12,"aria-hidden":!0,className:"shrink-0"}),(0,t.jsx)("span",{className:"truncate",children:e.name}),e.summary?.auth?(0,t.jsx)(E.KeyRound,{size:11,className:"shrink-0 text-accent","aria-label":`signs in with ${(0,D.authModeLabel)(e.summary.auth)}`}):null,(0,t.jsx)("span",{className:"ml-auto pl-1 font-normal",children:function e(t){return t.requests.length+t.folders.reduce((t,s)=>t+e(s),0)}(e)})]}),n?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(M.default,{href:(0,F.suiteHref)(e.path),title:`Run all requests in ${e.path}`,"aria-label":`Run all requests in ${e.path}`,className:"ml-0.5 rounded p-1 text-mute opacity-0 group-hover/folder:opacity-100 hover:text-accent focus:opacity-100",children:(0,t.jsx)(R.Play,{size:12})}),(0,t.jsx)(_,{path:e.path,onSettings:()=>S(e.path),onNewInside:()=>w({kind:"new",parent:e.path}),onRename:()=>w({kind:"rename",path:e.path}),onDelete:()=>void J(e.path)})]}):null]}),a?null:(0,t.jsxs)("div",{className:"ml-3 border-l border-line/60 pl-1",children:[y?.kind==="new"&&y.parent===e.path?(0,t.jsx)(W,{initial:"",label:`New folder in ${e.path}`,onDone:e=>void K(e)}):null,e.folders.map(G),X(e.requests)]})]},e.path)};return(0,t.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col",children:[(0,t.jsxs)("label",{className:"relative mb-2 block",children:[(0,t.jsx)("span",{className:"sr-only",children:"Search saved requests"}),(0,t.jsx)(T.Search,{size:13,className:"pointer-events-none absolute top-1/2 left-2 -translate-y-1/2 text-mute","aria-hidden":!0}),(0,t.jsx)("input",{value:x,onChange:e=>f(e.target.value),placeholder:"Search requests",className:"input py-1 pl-7 text-xs"})]}),(0,t.jsxs)("div",{className:"min-h-0 flex-1 overflow-auto",children:[y?.kind==="new"&&""===y.parent?(0,t.jsx)(W,{initial:"",label:"New folder",onDone:e=>void K(e),hint:"Use / for a folder inside another: Orders/Admin"}):null,0===q.length&&0===P.length?(0,t.jsxs)("div",{className:"space-y-2 px-1 py-4 text-xs text-mute",children:[(0,t.jsx)("p",{children:"No saved requests yet. Press Save (Ctrl+S) to keep the current one."}),(0,t.jsxs)("p",{children:["Coming from Postman or Swagger?"," ",(0,t.jsx)("button",{type:"button",onClick:L.openImport,className:"text-accent hover:underline",children:"Import your requests"})]})]}):z&&0===A.length?(0,t.jsx)("p",{className:"px-1 py-4 text-xs text-mute",children:"Nothing matches."}):(0,t.jsxs)(t.Fragment,{children:[U.folders.map(G),X(U.requests)]})]}),$?(0,t.jsx)(O,{path:$,onClose:()=>S(null)}):null]})}function W({initial:e,label:s,onDone:a,hint:n}){let[r,l]=(0,m.useState)(e),i=(0,m.useRef)(null),o=(0,m.useRef)(!1);(0,m.useEffect)(()=>i.current?.select(),[]);let d=e=>{o.current||(o.current=!0,a(e))};return(0,t.jsxs)("div",{className:"px-1 py-1",children:[(0,t.jsx)("input",{ref:i,value:r,"aria-label":s,placeholder:"Folder name",onChange:e=>l(e.target.value),onKeyDown:e=>{"Enter"===e.key&&d(r),"Escape"===e.key&&d("")},onBlur:()=>d(r),className:"input py-1 text-xs"}),n?(0,t.jsx)("p",{className:"mt-0.5 text-[11px] text-mute",children:n}):null]})}function _({path:e,onSettings:s,onNewInside:a,onRename:n,onDelete:r}){let[l,i]=(0,m.useState)(!1),o=(0,m.useRef)(null),d=(e,s,a=!1)=>(0,t.jsx)("button",{type:"button",role:"menuitem",onClick:()=>{i(!1),s()},className:`block w-full rounded px-2.5 py-1.5 text-left text-sm hover:bg-panel-2 ${a?"text-bad":"text-ink"}`,children:e});return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{ref:o,type:"button","aria-label":`Actions for ${e}`,"aria-haspopup":"menu","aria-expanded":l,onClick:()=>i(e=>!e),className:`rounded p-1 text-mute hover:text-ink focus:opacity-100 ${l?"opacity-100":"opacity-0 group-hover/folder:opacity-100"}`,children:(0,t.jsx)(q.MoreHorizontal,{size:13})}),(0,t.jsx)(P.Popover,{anchor:o,open:l,onClose:()=>i(!1),label:`Actions for ${e}`,width:220,role:"menu",children:(0,t.jsxs)("div",{className:"p-1",children:[d("Folder settings — auth, headers, variables",s),d("New folder inside",a),d("Rename or move",n),d("Delete folder",r,!0)]})})]})}e.s(["RequestPicker",0,function({onOpen:e}){let[s,a]=(0,m.useState)(!1),n=(0,m.useRef)(null);return(0,m.useEffect)(()=>{if(!s)return;let e=e=>!n.current?.contains(e.target)&&a(!1),t=e=>"Escape"===e.key&&a(!1);return document.addEventListener("pointerdown",e),document.addEventListener("keydown",t),()=>{document.removeEventListener("pointerdown",e),document.removeEventListener("keydown",t)}},[s]),(0,t.jsxs)("div",{ref:n,className:"relative",children:[(0,t.jsxs)("button",{type:"button","aria-expanded":s,onClick:()=>a(e=>!e),className:"inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-xs text-mute hover:text-ink",children:[(0,t.jsx)(C,{size:12,"aria-hidden":!0})," Load saved request"]}),s?(0,t.jsx)("div",{className:"absolute left-0 z-40 mt-1 flex h-80 w-80 flex-col rounded-md border border-line bg-panel p-2 shadow-xl",children:(0,t.jsx)(V,{allowDelete:!1,onOpen:t=>{e(t),a(!1)}})}):null]})},"RequestsPanel",0,function({activeId:e,onOpen:s,onNew:a,onClose:n}){let[r,l]=(0,m.useState)(!1);return(0,t.jsxs)("aside",{"aria-label":"Saved requests",className:"flex min-h-0 flex-col border-line px-3 py-4 lg:border-r",children:[(0,t.jsxs)("div",{className:"mb-2 flex items-center justify-between",children:[(0,t.jsx)("h2",{className:"text-xs font-medium tracking-wide text-mute uppercase",children:"Saved requests"}),(0,t.jsxs)("span",{className:"flex items-center gap-1",children:[(0,t.jsx)("button",{type:"button",onClick:a,title:"New request","aria-label":"New request",className:"rounded p-1 text-mute hover:bg-panel-2 hover:text-ink",children:(0,t.jsx)(w,{size:14})}),(0,t.jsx)("button",{type:"button",onClick:()=>l(!0),title:"New folder","aria-label":"New folder",className:"rounded p-1 text-mute hover:bg-panel-2 hover:text-ink",children:(0,t.jsx)($,{size:14})}),(0,t.jsx)("button",{type:"button",onClick:L.openImport,title:"Import from Postman or OpenAPI","aria-label":"Import from Postman or OpenAPI",className:"rounded p-1 text-mute hover:bg-panel-2 hover:text-ink",children:(0,t.jsx)(S,{size:14})}),(0,t.jsx)("button",{type:"button",onClick:n,title:"Hide saved requests","aria-label":"Hide saved requests",className:"rounded p-1 text-mute hover:bg-panel-2 hover:text-ink",children:(0,t.jsx)(u.X,{size:14})})]})]}),(0,t.jsx)(V,{activeId:e,onOpen:s,newFolder:r,onNewFolderDone:()=>l(!1)})]})},"SaveRequestForm",0,function({initial:e,onSave:s,onCancel:a}){let{index:n}=(0,v.useWorkspace)(),[r,l]=(0,m.useState)(e.name),[i,o]=(0,m.useState)(e.collection),d=(0,m.useRef)(null),c=[...new Set([...(n?.folders??[]).map(e=>e.path),...(n?.requests??[]).map(e=>e.collection)].filter(Boolean))].sort();return(0,m.useEffect)(()=>d.current?.select(),[]),(0,t.jsxs)("form",{onSubmit:e=>{e.preventDefault(),r.trim()&&s(r.trim(),i.trim())},onKeyDown:e=>"Escape"===e.key&&a(),className:"flex flex-wrap items-center gap-2",children:[(0,t.jsxs)("label",{className:"flex items-center gap-1.5 text-xs text-mute",children:["Name",(0,t.jsx)("input",{ref:d,value:r,onChange:e=>l(e.target.value),className:"input w-52 py-1 text-xs","aria-label":"Request name"})]}),(0,t.jsxs)("label",{className:"flex items-center gap-1.5 text-xs text-mute",children:["Collection",(0,t.jsx)("input",{value:i,onChange:e=>o(e.target.value),list:"atc-collections",placeholder:"none — or Orders/Admin",title:"A folder; use / for a folder inside another",className:"input w-48 py-1 text-xs","aria-label":"Collection"}),(0,t.jsx)("datalist",{id:"atc-collections",children:c.map(e=>(0,t.jsx)("option",{value:e},e))})]}),(0,t.jsx)("button",{type:"submit",className:"btn btn-primary py-1 text-xs",children:"Save request"}),(0,t.jsx)("button",{type:"button",className:"rounded p-1 text-mute hover:text-ink","aria-label":"Cancel",onClick:a,children:(0,t.jsx)(u.X,{size:14})})]})}],65638)},46679,e=>{"use strict";var t=e.i(65238),s=e.i(6278);e.i(42674);var a=e.i(5305);async function n(e,n,r,l){let i,o,d=n.before;if(!d)return e;try{i=await s.workspaceApi.get(d.requestId)}catch{throw Error(`Run first: “${d.requestName}” is no longer saved — pick another request on the Run first tab`)}if(i.secretsMissing?.length)throw Error(`Run first: the saved ${i.secretsMissing.join(", ")} of “${i.name}” is not available — open it and enter it again`);try{let e=await (0,t.withFolders)({...(0,a.requestFromUnknown)(i.request),before:null,testData:null},i.collection,r);o=(0,a.resolveDraft)(e.draft,e.vars,l)}catch(e){throw Error(`Run first “${i.name}”: ${e instanceof Error?e.message:"invalid request"}`)}try{return{...e,setup:(0,a.buildSetup)({...d,requestName:i.name},o)}}catch(e){throw Error(e instanceof Error&&e.message.startsWith("Run first")?e.message:`Run first “${i.name}”: ${e instanceof Error?e.message:"invalid request"}`)}}e.s(["withRunFirst",0,n])},21206,e=>{"use strict";e.i(24856);var t=e.i(59100);function s(e,t,a=0){return{ok:!1,status:a,statusText:"",headers:{},body:"",truncated:!1,durationMs:0,url:e,error:t}}async function a(e){let t=await e.text();try{return{json:JSON.parse(t),text:t}}catch{return{json:null,text:t}}}function n(e){return e.slice(0,180).replace(/\s+/g," ").trim()}async function r(e){let t=e.request.url;try{let r=await fetch("/engine/probe",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({request:e.request,auth:e.auth,options:e.options,setup:e.setup,data:e.data,save:e.save})}),{json:l,text:i}=await a(r);if(!l){let e=n(i);return s(t,e?`Engine error (${r.status}): ${e}`:`Engine error (${r.status}). Is it running?`,r.status)}if(!r.ok)return s(t,"string"==typeof l.error?l.error:"Request failed",r.status);return l}catch(e){return s(t,e instanceof Error?e.message:"Engine unreachable")}}async function l(e){let t=await fetch("/engine/runs",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)}),{json:s,text:r}=await a(t);if(!s)throw Error(n(r)||"Failed to start load");if(!t.ok)throw Error("string"==typeof s.error?s.error:"Failed to start load");return s}async function i(e){try{let t=await fetch(`/engine/runs/${e}`,{cache:"no-store"});if(!t.ok)return null;return await t.json()}catch{return null}}async function o(e){try{let t=await fetch(`/engine/runs/${e}/stop`,{method:"POST"});if(!t.ok)return null;return await t.json()}catch{return null}}let d=new Set(["completed","failed","cancelled","interrupted"]);e.s(["fetchRun",0,i,"hostOf",0,function(e){try{return new URL(e).host}catch{return e}},"isSuccess",0,function(e){return!!(e&&e.ok&&e.status>=200&&e.status<300)},"isTerminalStatus",0,function(e){return d.has(e)},"needsLoadConfirm",0,function(e,s,a){if(function(e){try{let t=new URL(e).hostname.toLowerCase();return"localhost"===t||"127.0.0.1"===t||"[::1]"===t||"::1"===t||t.endsWith(".localhost")}catch{return!1}}(a))return!1;if("stress"===e||"spike"===e||"soak"===e)return!0;let n=(0,t.isArrivalRate)(s.executor)?s.rate??Math.max(0,...s.stages.map(e=>e.target)):null;return null!=n?n>=50:((0,t.isArrivalRate)(s.executor)?s.maxVUs??s.vus:s.stages.length>0?Math.max(s.vus,...s.stages.map(e=>e.target)):s.vus)>=25},"sendRequest",0,r,"startLoadRun",0,l,"stopLoadRun",0,o])}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,53356,e=>{"use strict";var t=e.i(61666);e.i(24856);var s=e.i(2385),a=e.i(53012),n=e.i(93250),r=e.i(84355),l=e.i(20621),i=e.i(67951),o=e.i(91694),c=e.i(27813),d=e.i(88293),m=e.i(96659),x=e.i(87283),u=e.i(50804),p=e.i(46443),h=e.i(83067),f=e.i(67754),b=e.i(6980),j=e.i(29724),y=e.i(39170),g=e.i(28867),N=e.i(56396),v=e.i(19656),w=e.i(59180),k=e.i(88231),C=e.i(88153);function S(e){return"run"===e.kind?e.startedAt:e.savedAt}function D(e){return new Date(e).toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}function T({run:e,slo:a}){let r=(0,s.buildVerdictFromInputs)(e.verdict,{slo:a}).overall;return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsxs)("span",{className:"min-w-0 flex-1 truncate text-sm text-ink",children:[e.baseline?(0,t.jsx)(n.Diamond,{size:11,className:"mr-1 inline fill-current align-[-1px] text-accent","aria-label":"Reference run"}):null,e.name]}),"failed"===e.status||"cancelled"===e.status?(0,t.jsx)("span",{className:"shrink-0 text-xs text-mute capitalize",children:e.status}):(0,t.jsx)(b.VerdictTag,{level:r})]}),(0,t.jsx)("div",{className:"mt-0.5 truncate font-mono text-xs text-mute",children:e.endpoint}),(0,t.jsxs)("div",{className:"mt-0.5 flex flex-wrap gap-x-3 font-mono text-xs text-mute",children:[(0,t.jsxs)("span",{children:["p95 ",(0,v.formatMs)(e.p95)]}),(0,t.jsxs)("span",{children:[(0,v.formatPercent)(e.errorRate)," err"]}),(0,t.jsx)("span",{children:D(e.startedAt)})]}),e.note?(0,t.jsx)("p",{className:"mt-1 line-clamp-1 text-xs text-ink",children:e.note}):null]})}function A({compare:e}){return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(i.GitCompareArrows,{size:13,className:"shrink-0 text-accent","aria-label":"Compare"}),(0,t.jsx)("span",{className:"min-w-0 flex-1 truncate text-sm text-ink",children:e.name})]}),(0,t.jsxs)("div",{className:"mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-mute",children:[e.titles.map((e,s)=>(0,t.jsxs)("span",{className:"inline-flex items-center gap-1",children:[(0,t.jsx)("span",{className:"h-1.5 w-1.5 rounded-full",style:{background:(0,k.seriesColor)(s)},"aria-hidden":!0}),e]},s)),(0,t.jsx)("span",{className:"font-mono",children:D(e.savedAt)})]})]})}function z({name:e,note:s,onSave:a}){let[n,r]=(0,h.useState)(e),[l,i]=(0,h.useState)(s??"");return(0,h.useEffect)(()=>r(e),[e]),(0,h.useEffect)(()=>i(s??""),[s]),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"sr-only",children:"Name"}),(0,t.jsx)("input",{value:n,onChange:e=>r(e.target.value),onBlur:()=>n.trim()!==e&&void a({name:n}),onKeyDown:e=>"Enter"===e.key&&e.target.blur(),className:"w-full rounded-md border border-transparent bg-transparent px-1 py-0.5 text-xl font-medium text-ink hover:border-line focus:border-accent focus:outline-none",title:"Click to rename"})]}),(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"sr-only",children:"Note"}),(0,t.jsx)("textarea",{value:l,rows:l?2:1,onChange:e=>i(e.target.value),onBlur:()=>l.trim()!==(s??"")&&void a({note:l}),placeholder:"Add a note — what changed, which build, why you ran it…",className:"input resize-y text-sm"})]})]})}function $({summary:e,related:s,onSelect:a,onDelete:n,onReveal:r}){let i=(0,N.useToast)(),{refresh:o}=(0,w.useHistory)(),[d,x]=(0,h.useState)(null),[u,p]=(0,h.useState)(null);if((0,h.useEffect)(()=>{if(!e)return;let t=!1;return w.historyApi.run(e.id).then(e=>!t&&x(e)).catch(e=>!t&&p(e instanceof Error?e.message:"Could not read the file")),()=>{t=!0}},[e?.id,e?.bytes]),!e)return null;let b=s.filter(t=>t.endpoint===e.endpoint);async function y(t){try{await w.historyApi.updateRun(e.id,t),await o()}catch(e){i(e instanceof Error?e.message:"Could not save","error")}}return(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-start gap-3",children:[(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)(z,{name:e.name,note:e.note,onSave:y}),(0,t.jsx)("p",{className:"mt-1 px-1 font-mono text-xs break-all text-mute",children:e.file})]}),(0,t.jsxs)("div",{className:"flex shrink-0 gap-2",children:[(0,t.jsxs)("button",{type:"button",className:"btn btn-secondary py-1.5 text-xs",onClick:()=>r(e.id),children:[(0,t.jsx)(l.FolderOpen,{size:13}),"Show file"]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-danger py-1.5 text-xs",onClick:()=>n(e.id),children:[(0,t.jsx)(m.Trash2,{size:13}),"Delete"]})]})]}),e.error?(0,t.jsx)("p",{role:"alert",className:"rounded-md border border-bad/40 bg-bad/10 px-3 py-2 font-mono text-xs text-bad",children:e.error}):null,b.length>=2?(0,t.jsx)(f.TrendPanel,{runs:b,selectedId:e.id,onSelect:a}):null,u?(0,t.jsx)("p",{className:"text-sm text-bad",children:u}):d&&d.report.id===e.id?(0,t.jsx)(j.ReportView,{report:d.report,source:"session",showTitle:!1}):(0,t.jsxs)("p",{className:"flex items-center gap-2 text-sm text-mute",children:[(0,t.jsx)(c.Loader2,{size:14,className:"animate-spin"})," Opening…"]})]})}function L({summary:e,onDelete:a,onReveal:n}){let r=(0,N.useToast)(),{slo:o}=(0,C.useSlo)(),{refresh:d}=(0,w.useHistory)(),[x,p]=(0,h.useState)(null);if((0,h.useEffect)(()=>{if(!e)return;let t=!1;return w.historyApi.compare(e.id).then(e=>!t&&p(e)).catch(()=>void 0),()=>{t=!0}},[e?.id,e?.bytes]),!e)return null;async function f(t){try{await w.historyApi.updateCompare(e.id,t),await d()}catch(e){r(e instanceof Error?e.message:"Could not save","error")}}return(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-start gap-3",children:[(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsxs)("p",{className:"px-1 text-xs tracking-wide text-accent uppercase",children:["Compare · ","parallel"===e.mode?"all at once":"one after another"]}),(0,t.jsx)(z,{name:e.name,note:e.note,onSave:f}),(0,t.jsx)("p",{className:"mt-1 px-1 font-mono text-xs break-all text-mute",children:e.file})]}),(0,t.jsxs)("div",{className:"flex shrink-0 flex-wrap gap-2",children:[(0,t.jsxs)(u.default,{href:`/compare?compare=${e.id}`,className:"btn btn-primary py-1.5 text-xs",children:[(0,t.jsx)(i.GitCompareArrows,{size:13}),"Open overlay"]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-secondary py-1.5 text-xs",onClick:()=>n(e.id),children:[(0,t.jsx)(l.FolderOpen,{size:13}),"Show file"]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-danger py-1.5 text-xs",onClick:()=>a(e.id),children:[(0,t.jsx)(m.Trash2,{size:13}),"Delete"]})]})]}),x?(0,t.jsx)("ul",{className:"grid gap-2 @2xl:grid-cols-2",children:x.apis.map((e,a)=>(0,t.jsxs)("li",{className:"rounded-lg border border-line bg-panel p-3",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsxs)("span",{className:"inline-flex min-w-0 items-center gap-1.5 text-sm text-ink",children:[(0,t.jsx)("span",{className:"h-2 w-2 shrink-0 rounded-full",style:{background:(0,k.seriesColor)(a)},"aria-hidden":!0}),(0,t.jsx)("span",{className:"truncate",children:e.title})]}),(0,t.jsx)(b.VerdictTag,{level:(0,s.buildVerdict)(e.report,{slo:o}).overall})]}),(0,t.jsxs)("p",{className:"mt-1 truncate font-mono text-xs text-mute",children:[e.report.definition.method," ",e.report.definition.url]}),(0,t.jsxs)("div",{className:"mt-2 flex flex-wrap gap-x-4 font-mono text-xs text-ink",children:[(0,t.jsxs)("span",{children:["p95 ",(0,v.formatMs)(e.report.summary.latencyMs.p95)]}),(0,t.jsxs)("span",{children:[(0,v.formatPercent)(e.report.summary.http.failed.rate)," err"]}),(0,t.jsxs)("span",{children:[e.report.summary.http.requests.toLocaleString()," req"]})]})]},e.id))}):(0,t.jsxs)("p",{className:"flex items-center gap-2 text-sm text-mute",children:[(0,t.jsx)(c.Loader2,{size:14,className:"animate-spin"})," Opening…"]})]})}function R({index:e,onChanged:s,onReveal:n}){let r=(0,y.useConfirm)(),l=(0,N.useToast)();return(0,t.jsxs)("details",{className:"mx-1 mb-3 rounded-md border border-warn/40 bg-warn/10 px-3 py-2 text-sm",children:[(0,t.jsxs)("summary",{className:"cursor-pointer text-ink",children:[(0,t.jsx)(a.AlertTriangle,{size:13,className:"mr-1 inline align-[-2px] text-warn","aria-hidden":!0}),e.invalid.length," ",1===e.invalid.length?"file":"files"," in your history folder couldn't be read"]}),(0,t.jsx)("ul",{className:"mt-2 space-y-1",children:e.invalid.map(e=>(0,t.jsxs)("li",{className:"text-xs",children:[(0,t.jsxs)("span",{className:"font-mono text-ink",children:[e.folder,"/",e.file]}),(0,t.jsx)("span",{className:"block text-mute",children:e.reason})]},`${e.folder}/${e.file}`))}),(0,t.jsxs)("div",{className:"mt-2 flex gap-2",children:[(0,t.jsx)("button",{type:"button",className:"btn btn-secondary py-1 text-xs",onClick:n,children:"Show folder"}),(0,t.jsx)("button",{type:"button",className:"btn btn-danger py-1 text-xs",onClick:async()=>{await r({title:"Delete the unreadable files?",body:"They are not valid APITestCenter records. If you edited one by hand, fix it instead and it will reappear.",confirmLabel:"Delete files",tone:"danger"})&&(await w.historyApi.remove({invalid:e.invalid.map(({folder:e,file:t})=>({folder:e,file:t}))}),await s(),l("Unreadable files deleted","success"))},children:"Delete them"})]})]})}function E({filtered:e,hasAny:s}){return(0,t.jsx)("p",{className:"px-3 py-6 text-sm text-mute",children:e&&s?"Nothing matches. Clear the search or filter.":"No saved records yet."})}function O(){return(0,t.jsxs)("div",{className:"flex h-full flex-col items-center justify-center px-6 py-16 text-center",children:[(0,t.jsx)("div",{className:"grid h-12 w-12 place-items-center rounded-full bg-accent-dim text-accent",children:(0,t.jsx)(o.History,{size:22,strokeWidth:1.75,"aria-hidden":!0})}),(0,t.jsx)("h2",{className:"mt-4 text-base font-medium text-ink",children:"Your history is empty"}),(0,t.jsx)("p",{className:"mt-2 max-w-sm text-sm text-mute",children:"Every load test and compare is saved here automatically, as a JSON file on this computer. Nothing leaves your machine."}),(0,t.jsxs)("div",{className:"mt-6 flex flex-wrap justify-center gap-2",children:[(0,t.jsxs)(u.default,{href:"/",className:"btn btn-primary text-sm",children:[(0,t.jsx)(r.FlaskConical,{size:14}),"Test an API"]}),(0,t.jsxs)(u.default,{href:"/compare",className:"btn btn-secondary text-sm",children:[(0,t.jsx)(i.GitCompareArrows,{size:14}),"Compare APIs"]})]})]})}e.s(["default",0,function(){let e=(0,p.useRouter)(),s=(0,N.useToast)(),a=(0,y.useConfirm)(),{slo:n}=(0,C.useSlo)(),{index:r,loading:o,error:u,refresh:f}=(0,w.useHistory)(),[b,j]=(0,h.useState)(""),[k,D]=(0,h.useState)("all"),[z,F]=(0,h.useState)(null),[P,H]=(0,h.useState)(new Set),[B,I]=(0,h.useState)(!1),M=r?.runs??[],V=r?.compares??[],G=(0,h.useMemo)(()=>{let e=b.trim().toLowerCase();return[..."compares"===k?[]:M.filter(e=>"baselines"!==k||e.baseline),..."runs"===k||"baselines"===k?[]:V].filter(t=>!e||t.name.toLowerCase().includes(e)||(t.note??"").toLowerCase().includes(e)||("run"===t.kind?t.endpoint.toLowerCase().includes(e):t.titles.join(" ").toLowerCase().includes(e))).sort((e,t)=>Date.parse(S(t))-Date.parse(S(e)))},[M,V,b,k]);(0,h.useEffect)(()=>{if(r&&!(z&&("run"===z.kind?M.some(e=>e.id===z.id):V.some(e=>e.id===z.id)))){let e=G[0];F(e?{kind:e.kind,id:e.id}:null)}},[r]);let U=[...P].filter(e=>e.startsWith("run:")).map(e=>e.slice(4)),Y=[...P].filter(e=>e.startsWith("compare:")).map(e=>e.slice(8));async function K(e,t){let n=e.length+t.length;if(await a({title:`Delete ${n} ${1===n?"record":"records"}?`,body:"The JSON files are removed from your history folder. This cannot be undone — export first if you want a copy.",confirmLabel:"Delete",tone:"danger"})){I(!0);try{let{removed:a}=await w.historyApi.remove({runs:e,compares:t});H(new Set),await f(),s(`Deleted ${a} ${1===a?"record":"records"}`,"success")}catch(e){s(e instanceof Error?e.message:"Delete failed","error")}finally{I(!1)}}}async function W(e){try{await w.historyApi.reveal(e)}catch(e){s(e instanceof Error?e.message:"Could not open the folder","error")}}let q=function(e){let t=new Map,s=new Date,a=new Date(s.getTime()-864e5),n=(e,t)=>e.toDateString()===t.toDateString();for(let r of e){let e=new Date(S(r)),l=n(e,s)?"Today":n(e,a)?"Yesterday":e.toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric",year:e.getFullYear()===s.getFullYear()?void 0:"numeric"}),i=t.get(l)??[];i.push(r),t.set(l,i)}return[...t]}(G);return(0,t.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col",children:[(0,t.jsxs)("header",{className:"flex flex-wrap items-center gap-x-4 gap-y-2 border-b border-line bg-panel px-4 py-3 lg:px-6",children:[(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("h1",{className:"text-lg font-medium text-ink",children:"History"}),(0,t.jsx)("p",{className:"truncate text-xs text-mute",title:r?.dataDir,children:r?`${M.length} load ${1===M.length?"test":"tests"} \xb7 ${V.length} ${1===V.length?"compare":"compares"} \xb7 ${(0,v.formatBytes)(r.totalBytes)} on this computer`:o?"Loading…":"History is unavailable"})]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-secondary py-1.5 text-sm",onClick:()=>void W(),disabled:!r,children:[(0,t.jsx)(l.FolderOpen,{size:15}),"Show folder"]})]}),u&&!r?(0,t.jsxs)("div",{role:"alert",className:"m-6 rounded-md border border-bad/40 bg-bad/10 px-4 py-3 text-sm text-ink",children:[(0,t.jsx)("p",{className:"font-medium text-bad",children:"Can't reach the engine"}),(0,t.jsxs)("p",{className:"mt-1",children:["History is stored by the local engine. Start it with pnpm dev, then come back. (",u,")"]})]}):null,(0,t.jsxs)("div",{className:"grid min-h-0 flex-1 overflow-y-auto lg:grid-cols-[minmax(20rem,26rem)_minmax(0,1fr)] lg:overflow-hidden",children:[(0,t.jsxs)("section",{"aria-label":"Saved records",className:"flex min-h-0 flex-col border-line lg:border-r",children:[(0,t.jsxs)("div",{className:"space-y-2 border-b border-line px-4 py-3",children:[(0,t.jsxs)("label",{className:"relative block",children:[(0,t.jsx)("span",{className:"sr-only",children:"Search history"}),(0,t.jsx)(d.Search,{size:14,className:"pointer-events-none absolute top-1/2 left-2.5 -translate-y-1/2 text-mute","aria-hidden":!0}),(0,t.jsx)("input",{value:b,onChange:e=>j(e.target.value),placeholder:"Search name, URL, or note",className:"input pl-8"})]}),(0,t.jsx)(g.Segmented,{label:"Show",value:k,onChange:D,options:[{value:"all",label:"All"},{value:"runs",label:"Load tests"},{value:"compares",label:"Compares"},{value:"baselines",label:"Reference runs"}]})]}),P.size>0?(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2 border-b border-line bg-accent-dim px-4 py-2 text-sm",children:[(0,t.jsxs)("span",{className:"text-ink",children:[P.size," selected"]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-secondary ml-auto py-1 text-xs",disabled:U.length<2||U.length>6||Y.length>0,title:U.length<2?"Tick 2–6 load tests to overlay them":"Overlay these runs on Compare",onClick:()=>e.push(`/compare?ids=${U.join(",")}`),children:[(0,t.jsx)(i.GitCompareArrows,{size:13}),"Overlay"]}),(0,t.jsxs)("button",{type:"button",className:"btn btn-danger py-1 text-xs",disabled:B,onClick:()=>void K(U,Y),children:[(0,t.jsx)(m.Trash2,{size:13}),"Delete"]}),(0,t.jsx)("button",{type:"button","aria-label":"Clear selection",className:"rounded p-1 text-mute hover:text-ink",onClick:()=>H(new Set),children:(0,t.jsx)(x.X,{size:14})})]}):null,(0,t.jsxs)("div",{className:"min-h-0 flex-1 overflow-y-auto px-2 py-2",children:[r?.invalid.length?(0,t.jsx)(R,{index:r,onChanged:f,onReveal:()=>void W()}):null,o&&!r?(0,t.jsxs)("p",{className:"flex items-center gap-2 px-3 py-6 text-sm text-mute",children:[(0,t.jsx)(c.Loader2,{size:14,className:"animate-spin"})," Reading your history folder…"]}):0===G.length?(0,t.jsx)(E,{filtered:!!b||"all"!==k,hasAny:M.length+V.length>0}):q.map(([e,s])=>(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("h2",{className:"px-2 py-1 text-xs font-medium text-mute",children:e}),(0,t.jsx)("ul",{className:"space-y-0.5",children:s.map(e=>{let s=`${e.kind}:${e.id}`,a=z?.kind===e.kind&&z.id===e.id;return(0,t.jsxs)("li",{className:`flex items-start gap-2 rounded-md px-2 py-2 ${a?"bg-accent-dim":"hover:bg-panel-2"}`,children:[(0,t.jsx)("input",{type:"checkbox",checked:P.has(s),onChange:()=>{let t;return t=`${e.kind}:${e.id}`,void H(e=>{let s=new Set(e);return s.has(t)?s.delete(t):s.add(t),s})},"aria-label":`Select ${e.name}`,className:"mt-1 accent-[var(--accent)]"}),(0,t.jsx)("button",{type:"button",onClick:()=>F({kind:e.kind,id:e.id}),"aria-current":a?"true":void 0,className:"min-w-0 flex-1 text-left",children:"run"===e.kind?(0,t.jsx)(T,{run:e,slo:n}):(0,t.jsx)(A,{compare:e})})]},s)})})]},e))]})]}),(0,t.jsx)("section",{"aria-label":"Details",className:"@container min-h-0 min-w-0 overflow-y-auto px-4 py-4 lg:px-6",children:z?.kind==="run"?(0,t.jsx)($,{summary:M.find(e=>e.id===z.id),related:M,onSelect:e=>F({kind:"run",id:e}),onDelete:e=>void K([e],[]),onReveal:e=>void W({folder:"runs",id:e})},z.id):z?.kind==="compare"?(0,t.jsx)(L,{summary:V.find(e=>e.id===z.id),onDelete:e=>void K([],[e]),onReveal:e=>void W({folder:"compares",id:e})},z.id):r?(0,t.jsx)(O,{}):null})]})]})}])}]);
|