apitestcenter 0.6.0 → 0.8.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/dist/THIRD-PARTY-NOTICES-UI.txt +1 -1
- package/dist/THIRD-PARTY-NOTICES.txt +336 -1
- package/dist/cli.mjs +21631 -1811
- package/dist/ui/404/index.html +1 -1
- package/dist/ui/404.html +1 -1
- package/dist/ui/__next.__PAGE__.txt +10 -10
- package/dist/ui/__next._full.txt +11 -11
- package/dist/ui/__next._tree.txt +2 -2
- 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/0e1nwxi9i1ag7.js +1 -0
- package/dist/ui/_next/static/chunks/0vkcbl8nakdh1.js +2 -0
- package/dist/ui/_next/static/chunks/{12eajgls1n2zi.js → 11nxnz4doxir5.js} +71 -71
- package/dist/ui/_next/static/chunks/13nvl7bxr0ra-.js +1 -0
- package/dist/ui/_next/static/chunks/{065oy54s0-cwr.js → 2idsynwg5lkk7.js} +2 -2
- package/dist/ui/_next/static/chunks/{0mlyz754peers.js → 2lw9bsrnh8k4u.js} +1 -1
- package/dist/ui/_next/static/chunks/2nxnxp6p-40kg.js +1 -0
- package/dist/ui/_next/static/chunks/2xls_z5abvl-5.js +1 -0
- package/dist/ui/_next/static/chunks/3ad2zh-p8_xhv.js +59 -0
- package/dist/ui/_not-found/__next._full.txt +10 -10
- package/dist/ui/_not-found/__next._not-found.__PAGE__.txt +9 -9
- package/dist/ui/_not-found/__next._tree.txt +2 -2
- package/dist/ui/_not-found/index.html +1 -1
- package/dist/ui/_not-found/index.txt +10 -10
- package/dist/ui/compare/__next._full.txt +11 -11
- package/dist/ui/compare/__next._tree.txt +2 -2
- package/dist/ui/compare/__next.compare.__PAGE__.txt +10 -10
- package/dist/ui/compare/index.html +1 -1
- package/dist/ui/compare/index.txt +11 -11
- package/dist/ui/history/__next._full.txt +12 -12
- package/dist/ui/history/__next._tree.txt +2 -2
- package/dist/ui/history/__next.history.__PAGE__.txt +11 -11
- package/dist/ui/history/index.html +1 -1
- package/dist/ui/history/index.txt +12 -12
- package/dist/ui/index.html +1 -1
- package/dist/ui/index.txt +11 -11
- package/dist/ui/preview/__next._full.txt +12 -12
- package/dist/ui/preview/__next._tree.txt +2 -2
- package/dist/ui/preview/__next.preview.__PAGE__.txt +11 -11
- package/dist/ui/preview/index.html +1 -1
- package/dist/ui/preview/index.txt +12 -12
- package/dist/ui/suite/__next._full.txt +11 -11
- package/dist/ui/suite/__next._tree.txt +2 -2
- package/dist/ui/suite/__next.suite.__PAGE__.txt +10 -10
- package/dist/ui/suite/index.html +1 -1
- package/dist/ui/suite/index.txt +11 -11
- package/dist/ui/tests/__next._full.txt +10 -10
- package/dist/ui/tests/__next._tree.txt +2 -2
- package/dist/ui/tests/__next.tests.__PAGE__.txt +9 -9
- package/dist/ui/tests/index.html +1 -1
- package/dist/ui/tests/index.txt +10 -10
- package/package.json +1 -1
- package/dist/ui/_next/static/chunks/03vwb47zropf0.js +0 -1
- package/dist/ui/_next/static/chunks/0dscs2dqej_33.css +0 -3
- package/dist/ui/_next/static/chunks/0kfnlqyz56lid.js +0 -2
- package/dist/ui/_next/static/chunks/117zwf3ps9-d0.js +0 -1
- package/dist/ui/_next/static/chunks/13hazp8hyksry.js +0 -59
- package/dist/ui/_next/static/chunks/1s74dc_u9f8bv.js +0 -1
- package/dist/ui/_next/static/chunks/1tpf12evb0w6s.js +0 -1
- package/dist/ui/_next/static/chunks/202n35227m-qn.js +0 -119
- /package/dist/ui/_next/static/{nzVJlcyPooozLLxcLfxub → BJz1RrA7HqZwUV22DBTCg}/_buildManifest.js +0 -0
- /package/dist/ui/_next/static/{nzVJlcyPooozLLxcLfxub → BJz1RrA7HqZwUV22DBTCg}/_clientMiddlewareManifest.js +0 -0
- /package/dist/ui/_next/static/{nzVJlcyPooozLLxcLfxub → BJz1RrA7HqZwUV22DBTCg}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,6980,e=>{"use strict";var t=e.i(61666);e.i(24856);var s=e.i(2385),n=e.i(95486),a=e.i(20621),r=e.i(27813),l=e.i(99522);let i=(0,l.default)("maximize-2",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"m21 3-7 7",key:"1l2asr"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M9 21H3v-6",key:"wtvkvv"}]]),o=(0,l.default)("minimize-2",[["path",{d:"m14 10 7-7",key:"oa77jy"}],["path",{d:"M20 10h-6V4",key:"mjg0md"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M4 14h6v6",key:"rmj7iw"}]]);var c=e.i(3792);let d=(0,l.default)("save",[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]]);var u=e.i(50962),m=e.i(66478),p=e.i(83067),h=e.i(63343),x=e.i(44794),f=e.i(31753),b=e.i(29724),g=e.i(60566),y=e.i(39170),v=e.i(13318),j=e.i(68228),w=e.i(59100);let k=(0,l.default)("link-2",[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]]);var N=e.i(87283),S=e.i(80707),E=e.i(56396);e.i(42674);var R=e.i(5305),q=e.i(6278);let C="\0new";function U(e,t){if(!t.has("baseUrl"))return"baseUrl";let s="api";try{s=new URL(e).hostname.split(".")[0].replace(/[^A-Za-z0-9]/g,"")||"api"}catch{}let n=`${s}Url`;for(let e=2;t.has(n);e++)n=`${s}Url${e}`;return n}function $({draft:e,sent:s,onChange:n}){let{environments:a,activeEnv:r,vars:l}=(0,q.useWorkspace)(),[i,o]=(0,p.useState)(!1),c=function(e){try{let t=new URL(e);if(!/^https?:$/.test(t.protocol)||["localhost","127.0.0.1"].includes(t.hostname))return[];let s=t.origin,n=t.pathname.split("/").filter(Boolean);return n.length>=2?[s,`${s}/${n[0]}`]:[s]}catch{return[]}}(e.url),d=new Set(Object.values(l).map(e=>e.trim().replace(/\/+$/,"")));return!s||!c.length||c.some(e=>d.has(e))?null:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("button",{type:"button",onClick:()=>o(!0),className:"inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-accent hover:underline",title:"Keep this server address in an environment",children:[(0,t.jsx)(k,{size:13,"aria-hidden":!0})," Save ",c[0].replace(/^https?:\/\//,"")," as a base URL"]}),i?(0,t.jsx)(L,{draft:e,addresses:c,environments:a,activeEnvId:r?.id??null,onChange:n,onClose:()=>o(!1)}):null]})}function L({draft:e,addresses:s,environments:n,activeEnvId:a,onChange:r,onClose:l}){let i=(0,E.useToast)(),{index:o,saveEnvironments:c,setActiveEnv:d,refresh:u}=(0,q.useWorkspace)(),[m,h]=(0,p.useState)(s[0]),[x,f]=(0,p.useState)(a??n[0]?.id??C),[b,g]=(0,p.useState)(()=>{try{return new URL(s[0]).hostname.split(".").slice(0,2).join(" ")}catch{return"My API"}}),y=n.find(e=>e.id===x)??null,v=(0,p.useMemo)(()=>new Set((y?.variables??[]).map(e=>e.key)),[y]),[j,k]=(0,p.useState)(()=>U(s[0],v)),[$,P]=(0,p.useState)(!0),[T,A]=(0,p.useState)(!1),O=(0,p.useRef)(null);(0,p.useEffect)(()=>O.current?.focus(),[]),(0,p.useEffect)(()=>k(U(m,v)),[m,v]);let F=(o?.requests??[]).filter(t=>t.url.startsWith(m)&&t.url!==e.url),M=y?.variables.find(e=>e.key===j),I=w.VARIABLE_NAME.test(j)&&(x!==C||b.trim());async function z(){if(I&&!T){A(!0);try{let t=x===C?globalThis.crypto?.randomUUID?.()??`env-${Date.now().toString(36)}`:x,s=structuredClone(n),a=s.find(e=>e.id===t);a||(a={id:t,name:b.trim(),variables:[]},s.push(a)),a.variables=[...a.variables.filter(e=>e.key!==j),{key:j,value:m,secret:!1}],await c(s),d(t),r((0,R.withUrl)(e,`{{${j}}}${e.url.slice(m.length)}`));let o=0,p=0;if($){for(let e of F){let t=await q.workspaceApi.get(e.id).catch(()=>null);if(!t||t.secretsMissing?.length){p++;continue}let s=(0,R.requestFromUnknown)(t.request);s.url.startsWith(m)&&(await q.workspaceApi.update(e.id,{name:t.name,collection:t.collection,request:(0,R.withUrl)(s,`{{${j}}}${s.url.slice(m.length)}`)}),o++)}await u()}i(`Saved {{${j}}} in ${a.name}.${o?` ${o} other saved request${1===o?"":"s"} now use it.`:""}${p?` ${p} left as they were (a saved secret isn't available).`:""} Save this request to keep the change.`,"success"),l()}catch(e){i(e instanceof Error?e.message:"Could not save the base URL","error")}finally{A(!1)}}}return(0,t.jsx)("div",{className:"fixed inset-0 z-[75] flex items-start justify-center overflow-y-auto bg-black/50 p-4 sm:p-16",role:"presentation",onMouseDown:e=>e.target===e.currentTarget&&!T&&l(),children:(0,t.jsxs)("form",{role:"dialog","aria-modal":"true","aria-labelledby":"save-base-title",onSubmit:e=>{e.preventDefault(),z()},onKeyDown:e=>"Escape"===e.key&&!T&&l(),className:"w-full max-w-lg space-y-4 rounded-xl border border-line bg-panel p-5 shadow-2xl",children:[(0,t.jsxs)("header",{className:"flex items-center gap-2",children:[(0,t.jsx)("h2",{id:"save-base-title",className:"text-base font-medium text-ink",children:"Save as a base URL"}),(0,t.jsx)("button",{type:"button",onClick:l,"aria-label":"Close",className:"ml-auto rounded p-1 text-mute hover:text-ink",children:(0,t.jsx)(N.X,{size:16})})]}),(0,t.jsx)("p",{className:"text-sm text-mute",children:"Keep the server address in an environment, so you type only the path — and switch servers (UAT, Prod) by switching environments."}),(0,t.jsxs)("fieldset",{className:"space-y-1.5",children:[(0,t.jsx)("legend",{className:"mb-1 text-xs text-mute",children:"Address"}),s.map(e=>(0,t.jsxs)("label",{className:"flex items-center gap-2 text-sm text-ink",children:[(0,t.jsx)("input",{type:"radio",name:"address",checked:m===e,onChange:()=>h(e)}),(0,t.jsx)("span",{className:"font-mono text-xs break-all",children:e})]},e))]}),(0,t.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2",children:[(0,t.jsxs)("label",{className:"flex flex-col gap-1 text-xs text-mute",children:["Environment",(0,t.jsx)(S.Select,{label:"Environment",value:x,onChange:f,options:[...n.map(e=>({value:e.id,label:e.name,hint:`${e.variables.length} variables`})),{value:C,label:"New environment…"}],className:"rounded-md border border-line bg-panel-2 px-2 py-1.5 text-sm text-ink"})]}),(0,t.jsxs)("label",{className:"flex flex-col gap-1 text-xs text-mute",children:["Variable name",(0,t.jsx)("input",{ref:O,value:j,onChange:e=>k(e.target.value.replace(/[^\w.-]/g,"")),className:"input py-1.5 font-mono text-sm"})]}),x===C?(0,t.jsxs)("label",{className:"flex flex-col gap-1 text-xs text-mute sm:col-span-2",children:["New environment name",(0,t.jsx)("input",{value:b,onChange:e=>g(e.target.value),className:"input py-1.5 text-sm"})]}):null]}),M&&M.value!==m?(0,t.jsxs)("p",{className:"text-xs text-warn",children:[`{{${j}}}`," already exists in this environment (",M.value,") — it will be replaced."]}):null,(0,t.jsxs)("p",{className:"rounded-md bg-panel-2 px-3 py-2 font-mono text-xs text-ink break-all",children:[`{{${j}}}`,(0,t.jsx)("span",{className:"text-mute",children:e.url.slice(m.length)||"/"})]}),F.length?(0,t.jsxs)("label",{className:"flex items-start gap-2 text-sm text-ink",children:[(0,t.jsx)("input",{type:"checkbox",checked:$,onChange:e=>P(e.target.checked),className:"mt-1"}),(0,t.jsxs)("span",{children:["Also switch ",F.length," other saved request",1===F.length?"":"s"," that use this address",(0,t.jsxs)("span",{className:"block text-xs text-mute",children:[F.slice(0,3).map(e=>e.name).join(", "),F.length>3?` and ${F.length-3} more`:""]})]})]}):null,(0,t.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,t.jsx)("button",{type:"button",className:"btn btn-secondary",onClick:l,disabled:T,children:"Cancel"}),(0,t.jsx)("button",{type:"submit",className:"btn btn-primary",disabled:!I||T,children:"Save base URL"})]})]})})}var P=e.i(65638),T=e.i(21206),A=e.i(20054);let O="apitestcenter-lab-draft";var F=e.i(59180),M=e.i(88153),I=e.i(2603),z=e.i(46679),D=e.i(65238),_=e.i(727),V=e.i(45672),B=e.i(69578);let H="apitestcenter-lab-saved",W="apitestcenter-requests-panel",J="apitestcenter-last-run";function K(e){try{sessionStorage.setItem(J,e)}catch{}}function Q(){return(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5",children:[(0,t.jsxs)("span",{className:"relative flex h-2 w-2",children:[(0,t.jsx)("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bg-accent opacity-60"}),(0,t.jsx)("span",{className:"relative inline-flex h-2 w-2 rounded-full bg-accent"})]}),"Load running"]})}function G({title:e,lines:s,action:n}){return(0,t.jsxs)("div",{className:"flex flex-1 flex-col items-center justify-center rounded-lg border border-dashed border-line px-6 py-14 text-center",children:[(0,t.jsx)("h2",{className:"text-base font-medium text-ink",children:e}),(0,t.jsx)("div",{className:"mt-2 max-w-md space-y-1.5 text-sm text-mute",children:s.map((e,s)=>(0,t.jsx)("p",{children:e},s))}),n?(0,t.jsx)("div",{className:"mt-5",children:n}):null]})}function Y({runs:e,current:a,disabled:r,onPick:l}){let{slo:i}=(0,M.useSlo)(),[o,c]=(0,p.useState)(!1),d=(0,p.useRef)(null),u=(0,p.useMemo)(()=>e.slice(0,30),[e]);return(0,p.useEffect)(()=>{if(!o)return;let e=e=>{d.current?.contains(e.target)||c(!1)},t=e=>"Escape"===e.key&&c(!1);return document.addEventListener("pointerdown",e),document.addEventListener("keydown",t),()=>{document.removeEventListener("pointerdown",e),document.removeEventListener("keydown",t)}},[o]),(0,t.jsxs)("div",{ref:d,className:"relative",children:[(0,t.jsxs)("button",{type:"button",disabled:r,"aria-haspopup":"listbox","aria-expanded":o,onClick:()=>c(e=>!e),className:"inline-flex items-center gap-1 rounded-md border border-line px-2 py-1 text-xs text-mute hover:text-ink disabled:opacity-40",children:["Recent runs",(0,t.jsx)(n.ChevronDown,{size:12})]}),o?(0,t.jsx)("ul",{role:"listbox","aria-label":"Recent runs",className:"absolute right-0 z-30 mt-1 max-h-80 w-80 overflow-auto rounded-md border border-line bg-panel p-1 shadow-xl",children:u.map(e=>{let n=(0,s.buildVerdictFromInputs)(e.verdict,{slo:i}).overall,r=a?.id===e.id;return(0,t.jsx)("li",{role:"option","aria-selected":r,children:(0,t.jsxs)("button",{type:"button",onClick:()=>{l(e),c(!1)},className:`flex w-full items-center justify-between gap-2 rounded px-2 py-1.5 text-left text-xs ${r?"bg-accent-dim text-ink":"text-ink hover:bg-panel-2"}`,children:[(0,t.jsxs)("span",{className:"min-w-0 truncate",children:[e.baseline?(0,t.jsx)("span",{className:"mr-1 text-accent",title:"Baseline",children:"◆"}):null,e.name]}),(0,t.jsx)(X,{level:n})]})},e.id)})}):null]})}function X({level:e}){let s="pass"===e?"text-ok":"fail"===e?"text-bad":"text-warn";return(0,t.jsxs)("span",{className:`shrink-0 font-mono text-xs uppercase ${s}`,children:[(0,t.jsxs)("span",{"aria-hidden":!0,children:["pass"===e?"✓":"fail"===e?"✕":"!"," "]}),e]})}function Z(){let{slo:e,setSlo:s,ready:n}=(0,M.useSlo)(),[a,r]=(0,p.useState)(!1),[l,i]=(0,p.useState)(500),[o,c]=(0,p.useState)(0),[d,u]=(0,p.useState)(1),[m,h]=(0,p.useState)(99),[x,f]=(0,p.useState)(!1),b=(0,p.useRef)(!1);function g(e){let t={on:a,p95:l,p99:o,errPct:d,checksPct:m,abort:x,...e};if(r(t.on),i(t.p95),c(t.p99),u(t.errPct),h(t.checksPct),f(t.abort),!t.on||!(t.p95>0)||t.errPct<0)return s(null);s({p95Ms:t.p95,errorRate:t.errPct/100,p99Ms:t.p99>0?t.p99:void 0,checksRate:Math.min(100,Math.max(0,t.checksPct))/100,abortOnFail:t.abort})}(0,p.useEffect)(()=>{n&&!b.current&&(b.current=!0,e&&(r(!0),i(e.p95Ms),c(e.p99Ms??0),u(Number((100*e.errorRate).toFixed(4))),h(null!=e.checksRate?Number((100*e.checksRate).toFixed(2)):99),f(!0===e.abortOnFail)))},[n,e]);let y=(e,s,n,a)=>(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"mb-1 block text-xs text-mute",children:e}),(0,t.jsx)("input",{type:"number",min:a.min,max:a.max,step:a.step,value:s,onChange:e=>g({[n]:Number(e.target.value)}),className:"input font-mono"}),a.hint?(0,t.jsx)("span",{className:"mt-1 block text-xs text-mute",children:a.hint}):null]});return(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("p",{className:"text-sm text-mute",children:"Targets decide whether a load test passes. They are sent to k6 as thresholds, drive the verdict and the report colours, and are remembered on this computer."}),(0,t.jsxs)("label",{className:"flex items-center gap-2 text-sm text-ink",children:[(0,t.jsx)("input",{type:"checkbox",checked:a,onChange:e=>g({on:e.target.checked}),className:"accent-[var(--accent)]"}),"Use my own performance targets"]}),a?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-3",children:[y("p95 must stay under (ms)",l,"p95",{min:1}),y("p99 must stay under (ms)",o,"p99",{min:0,hint:"0 = no p99 target"}),y("Error rate must stay under (%)",d,"errPct",{min:0,max:100,step:.1}),y("Checks must pass at least (%)",m,"checksPct",{min:0,max:100,step:.1,hint:"Only used when the request has checks"})]}),(0,t.jsxs)("label",{className:"flex items-start gap-2 rounded-md border border-line px-3 py-2.5 text-sm text-ink",children:[(0,t.jsx)("input",{type:"checkbox",checked:x,onChange:e=>g({abort:e.target.checked}),className:"mt-0.5 accent-[var(--accent)]"}),(0,t.jsxs)("span",{children:["Stop the test early if a target is clearly missed",(0,t.jsx)("span",{className:"block text-xs text-mute",children:"After a 10-second warm-up, k6 ends the run as soon as a target fails — saves time and stops hammering a struggling API."})]})]})]}):(0,t.jsx)("p",{className:"rounded-md bg-panel-2 px-3 py-2 text-sm text-mute",children:"Using built-in defaults: warn at p95 ≥ 500 ms or errors ≥ 1%, fail at p95 ≥ 2 s or errors ≥ 5%. No thresholds are sent to k6."})]})}e.s(["LabPage",0,function(){let e=(0,E.useToast)(),n=(0,y.useConfirm)(),l=(0,A.useEngineHealth)(),w=(0,I.useModKey)(),{slo:k}=(0,M.useSlo)(),{vars:N,activeEnv:S,refresh:C,rememberValues:U}=(0,q.useWorkspace)(),[L,X]=(0,p.useState)(null),[ee,et]=(0,p.useState)(!1),[es,en]=(0,p.useState)(!0),ea=(0,p.useRef)(null),[er,el]=(0,p.useState)(R.defaultRequestDraft),[ei,eo]=(0,p.useState)(R.DEFAULT_LOAD),[ec,ed]=(0,p.useState)(!1),[eu,em]=(0,p.useState)(null),[ep,eh]=(0,p.useState)(!1),[ex,ef]=(0,p.useState)(!1),[eb,eg]=(0,p.useState)(!1),[ey,ev]=(0,p.useState)(null),[ej,ew]=(0,p.useState)(null),{index:ek,refresh:eN}=(0,F.useHistory)(),eS=ek?.runs??[],[eE,eR]=(0,p.useState)("response"),[eq,eC]=(0,p.useState)(!1),eU=ej?.status==="running"||ej?.status==="queued",e$=(0,R.isReady)(er),eL=(0,R.loadProblem)(ei),eP=ep||ex;(0,p.useEffect)(()=>{let e=null;try{e=sessionStorage.getItem(J)}catch{}e&&(0,T.fetchRun)(e).then(async t=>{if(t)return ew(t);let s=await F.historyApi.run(e).catch(()=>null);s&&ew({id:s.report.id,status:s.report.status,report:s.report})});let t=function(){try{let e=sessionStorage.getItem(O);if(!e)return null;let t=JSON.parse(e);if(2===t.v)return{request:(0,R.requestFromUnknown)(t.request),load:(0,R.loadFromUnknown)(t.load)};return{request:(0,R.requestFromUnknown)(t),load:(0,R.loadFromUnknown)(t)}}catch{return null}}();t&&(el(t.request),eo(t.load));try{let e=sessionStorage.getItem(H);e&&X(JSON.parse(e)),en("closed"!==localStorage.getItem(W))}catch{}ed(!0)},[]),(0,p.useEffect)(()=>{if(!ec)return;let e=window.setTimeout(()=>(function(e){try{sessionStorage.setItem(O,JSON.stringify({v:2,...e}))}catch{}})({request:er,load:ei}),250);return()=>window.clearTimeout(e)},[er,ei,ec]),(0,p.useEffect)(()=>{if(!ej||!eU)return;let t=!1,n=window.setInterval(async()=>{let n=await (0,T.fetchRun)(ej.id);if(n&&!t&&(ew(n),(0,T.isTerminalStatus)(n.status))){eN();let t="completed"===n.status?"finished":n.status;e(`Load test ${t}`,"failed"===n.status?"error":"success");let a=(0,s.buildVerdict)(n.report,{slo:k});(0,_.notifyFinished)({title:`Load test ${t}`,body:`${n.report.testName}
|
|
2
|
+
${"completed"===n.status?a.headline:n.error??"See the report for details."}`,ok:"completed"===n.status&&"fail"!==a.overall})}},500);return()=>{t=!0,window.clearInterval(n)}},[ej?.id,eU]);let eT=!!L&&JSON.stringify(er)!==L.snapshot;function eA(e){X(e);try{e?sessionStorage.setItem(H,JSON.stringify(e)):sessionStorage.removeItem(H)}catch{}}function eO(e){en(e);try{localStorage.setItem(W,e?"open":"closed")}catch{}}async function eF(t){try{let s={name:t?.name??L.name,collection:t?.collection??L.collection,request:er},n=L&&!t?await q.workspaceApi.update(L.id,s):await q.workspaceApi.create(s);eA({id:n.id,name:n.name,collection:n.collection,snapshot:JSON.stringify(er)}),et(!1),await C(),e(`Saved “${n.name}”${n.collection?` in ${n.collection}`:""}`,"success")}catch(t){e(t instanceof Error?t.message:"Could not save the request","error")}}async function eM(){return!eT||n({title:`Discard changes to “${L.name}”?`,body:"They have not been saved.",confirmLabel:"Discard",tone:"danger"})}let[eI,ez]=(0,p.useState)(!1);async function eD(){await eM()&&(el({...(0,R.withUrl)((0,R.defaultRequestDraft)(),"{{practiceApi}}/products"),checks:[{type:"status",expect:"2xx"},{type:"json",path:"items[0].name",op:"exists",value:""}]}),eA(null),em(null),eg(!1),ev(null),eR("response"),e("Practice request ready — press Send","success"))}async function e_(){try{let t=await q.workspaceApi.index(),s=e=>t.requests.find(t=>"Practice"===t.collection&&t.name===e),n=s("Sign in")?.id??(await q.workspaceApi.create({name:"Sign in",collection:"Practice",request:{...(0,R.withUrl)({...(0,R.defaultRequestDraft)(),method:"POST"},"{{practiceApi}}/login"),bodyMode:"json",bodyText:'{\n "username": "you",\n "password": "demo"\n}',checks:[{type:"status",expect:"200"}]}})).id,a=s("My orders"),r=a?await q.workspaceApi.get(a.id):await q.workspaceApi.create({name:"My orders",collection:"Practice",request:{...(0,R.withUrl)((0,R.defaultRequestDraft)(),"{{practiceApi}}/orders"),authMode:"bearer",token:"{{token}}",checks:[{type:"status",expect:"200"}],before:{requestId:n,requestName:"Sign in",extract:[{name:"token",from:"json",path:"data.token"}]}}});await C(),eO(!0),await eV(r),e("Added Practice → Sign in and My orders. Press Send: it signs in first, then uses the token.","success")}catch(t){e(t instanceof Error?t.message:"Could not add the practice requests","error")}}async function eV(e){if(!await eM())return;let t=(0,R.requestFromUnknown)(e.request);el(t),eA({id:e.id,name:e.name,collection:e.collection,snapshot:JSON.stringify(t)}),em(null),eg(!1),ev(null),eR("response")}async function eB(){await eM()&&(el((0,R.defaultRequestDraft)()),eA(null),em(null),ev(null),window.setTimeout(()=>ea.current?.focus(),0))}async function eH(){try{ev(null);let e=await (0,D.withFolders)(er,L?.collection,N),t=(0,R.resolveDraft)(e.draft,e.vars,S?.name),s=(0,R.buildPayload)(t,(0,R.toLoadConfig)(ei),(0,R.autoRunName)(t,L?.name),(0,R.targetsFromSlo)(k));return await (0,z.withRunFirst)(s,t,N,S?.name)}catch(e){return ev(e instanceof Error?e.message:"Request is not valid"),null}}async function eW(){if(eP||!e$)return;let e=await eH();if(e){eh(!0),eg(!1),eR("response");try{let t=await (0,T.sendRequest)(e);em(t);let s=(t.saved??[]).flatMap(e=>e.found&&void 0!==e.value?[{name:e.name,value:e.value}]:[]);U(s,L?.name??"the last Send")}finally{eh(!1)}}}async function eJ(s=!1){if(eP||eU||!e$||!l.k6Ready)return;if(eL)return void ev(eL);let a=await eH();if(a){if(eg(!1),!s){ef(!0);try{let e=await (0,T.sendRequest)(a);if(em(e),!(0,T.isSuccess)(e)){eg(!0),eR("response");return}}finally{ef(!1)}}if((0,T.needsLoadConfirm)(ei.preset,a.load,a.request.url)&&!await n({title:`Start a ${(0,h.profileSummary)(ei)} load test against ${(0,T.hostOf)(a.request.url)}?`,body:(0,t.jsxs)(t.Fragment,{children:["This is a ",(0,t.jsx)("span",{className:"text-ink",children:ei.preset})," profile against a non-local host (",(0,h.profileSummary)(ei),"). Only load-test systems you own or are allowed to test.",(0,t.jsxs)("span",{className:"mt-2 block",children:["Each simulated user sends its next request as soon as the last one returns, so a few dozen users can mean thousands of requests per second. Public sites and APIs behind a CDN or firewall usually answer that with ",(0,t.jsx)("span",{className:"text-ink",children:"429"})," or"," ",(0,t.jsx)("span",{className:"text-ink",children:"403"})," and may block this computer for a while — test a staging server, or use Requests per second mode with a modest rate."]})]}),confirmLabel:"Start load test",tone:"danger"}))return;try{let e=await (0,T.startLoadRun)(a);K(e.id),ew(e),eR("report")}catch(t){e(t instanceof Error?t.message:"Failed to start load","error")}}}async function eK(){if(!ej)return;let t=await (0,T.stopLoadRun)(ej.id);t?ew(t):e("Could not reach the engine to stop the run","error")}(0,p.useEffect)(()=>{let e=()=>ez(!(0,V.welcomeHidden)());return e(),window.addEventListener(V.WELCOME_EVENT,e),()=>window.removeEventListener(V.WELCOME_EVENT,e)},[]),(0,p.useEffect)(()=>{let t=()=>{let t=null;try{t=sessionStorage.getItem(B.OPEN_REQUEST_KEY),sessionStorage.removeItem(B.OPEN_REQUEST_KEY)}catch{}t&&q.workspaceApi.get(t).then(e=>void eV(e)).catch(()=>e("That saved request is gone","error"))};return ec&&t(),window.addEventListener(B.OPEN_REQUEST_EVENT,t),()=>window.removeEventListener(B.OPEN_REQUEST_EVENT,t)},[ec]),(0,I.useShortcuts)({send:()=>void eW(),run:()=>void eJ(),focusUrl:()=>ea.current?.focus(),save:()=>L?void eF():et(!0)});let eQ=l.k6Ready?e$?eL??void 0:"Enter a URL first":l.k6Label,eG=(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("button",{type:"button","data-tour":"send",onClick:()=>void eW(),disabled:eP||!e$,title:`Send one request (${w}+Enter)`,className:"btn btn-primary",children:[ep?(0,t.jsx)(r.Loader2,{size:16,className:"animate-spin"}):(0,t.jsx)(u.Send,{size:16}),"Send"]}),eU?(0,t.jsxs)("button",{type:"button",onClick:()=>void eK(),disabled:ej?.stopping,className:"btn btn-danger",children:[ej?.stopping?(0,t.jsx)(r.Loader2,{size:16,className:"animate-spin"}):(0,t.jsx)(m.Square,{size:16}),ej?.stopping?"Stopping…":"Stop"]}):(0,t.jsxs)("button",{type:"button","data-tour":"run",onClick:()=>void eJ(),disabled:eP||!!eQ,title:eQ??`Check the request, then run the load profile (${w}+Shift+Enter)`,className:"btn btn-secondary",children:[ex?(0,t.jsx)(r.Loader2,{size:16,className:"animate-spin"}):(0,t.jsx)(c.Play,{size:16}),ex?"Checking…":"Run load test"]})]});return(0,t.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col",children:[(0,t.jsxs)("header",{className:"border-b border-line bg-panel px-4 py-3 lg:px-6",children:[(0,t.jsx)("h1",{className:"sr-only",children:"Test an API"}),(0,t.jsx)(x.RequestBar,{ref:ea,draft:er,onChange:e=>{el(e),ev(null)},onImported:t=>e(t,"success"),actions:eG}),(0,t.jsxs)("div",{className:"mt-2 flex flex-wrap items-center gap-x-4 gap-y-2 text-xs text-mute",children:[es?null:(0,t.jsxs)("button",{type:"button",onClick:()=>eO(!0),className:"inline-flex items-center gap-1 rounded-md px-1.5 py-1 hover:text-ink",children:[(0,t.jsx)(a.FolderOpen,{size:13,"aria-hidden":!0})," Saved requests"]}),(0,t.jsx)(j.EnvironmentBar,{drafts:[er],collections:[L?.collection]}),(0,t.jsx)($,{draft:er,sent:!!(eu&&eu.status>0),onChange:el}),ee?(0,t.jsx)(P.SaveRequestForm,{initial:{name:L?.name??(0,R.autoRunName)(er).replace(/ · \d.*$/,""),collection:L?.collection??""},onSave:(e,t)=>void eF({name:e,collection:t}),onCancel:()=>et(!1)}):(0,t.jsxs)("span",{className:"inline-flex items-center gap-2",children:[L?(0,t.jsxs)("span",{className:"text-ink",title:L.collection?`${L.collection} / ${L.name}`:L.name,children:[L.collection?(0,t.jsxs)("span",{className:"text-mute",children:[L.collection," / "]}):null,L.name,eT?(0,t.jsx)("span",{className:"ml-1 text-warn","aria-label":"unsaved changes",children:"● unsaved"}):null]}):null,(0,t.jsxs)("button",{type:"button",onClick:()=>L?void eF():et(!0),disabled:!!L&&!eT,title:`Save request (${w}+S)`,className:"inline-flex items-center gap-1 rounded-md border border-line px-2 py-0.5 text-ink hover:border-accent disabled:opacity-40",children:[(0,t.jsx)(d,{size:12,"aria-hidden":!0})," ",L?"Save":"Save request"]}),L?(0,t.jsx)("button",{type:"button",onClick:()=>et(!0),className:"rounded-md px-1.5 py-0.5 hover:text-ink",children:"Save as…"}):null]}),ey?(0,t.jsx)("span",{className:"text-bad",role:"alert",children:ey}):null,(0,t.jsxs)("span",{className:"ml-auto hidden items-center gap-1.5 sm:inline-flex",children:[(0,t.jsx)("span",{className:"kbd",children:w}),"+",(0,t.jsx)("span",{className:"kbd",children:"Enter"})," send",(0,t.jsx)("span",{className:"kbd ml-2",children:w}),"+",(0,t.jsx)("span",{className:"kbd",children:"Shift"}),"+",(0,t.jsx)("span",{className:"kbd",children:"Enter"})," load",(0,t.jsx)("span",{className:"kbd ml-2",children:"/"})," URL"]})]})]}),(0,t.jsxs)("div",{className:`grid min-h-0 flex-1 overflow-y-auto lg:overflow-hidden ${eq?"":es?"lg:grid-cols-[15rem_minmax(0,1fr)_minmax(0,1fr)] 2xl:grid-cols-[16rem_minmax(0,5fr)_minmax(0,7fr)]":"lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] 2xl:grid-cols-[minmax(0,5fr)_minmax(0,7fr)]"}`,children:[!eq&&es?(0,t.jsx)(P.RequestsPanel,{activeId:L?.id??null,onOpen:e=>void eV(e),onNew:()=>void eB(),onClose:()=>eO(!1)}):null,eq?null:(0,t.jsx)("section",{"aria-label":"Request",className:"min-w-0 px-4 py-4 lg:overflow-y-auto lg:px-6",children:(0,t.jsx)(f.RequestEditor,{id:"lab-request",draft:er,onChange:el,checkResults:eu?.checks,setupResult:eu?.setup,savedResults:eu?.saved,currentId:L?.id,collection:L?.collection,extraTabs:[{id:"load",label:"Load",badge:ei.stages?.length?"stages":"rate"===ei.mode?`${ei.rps}/s`:`${ei.vus} users \xb7 ${ei.duration}`,content:(0,t.jsx)(h.LoadEditor,{load:ei,onChange:eo})},{id:"targets",label:"Goals",content:(0,t.jsx)(Z,{})}]})}),(0,t.jsxs)("section",{"aria-label":"Results",className:"@container flex min-h-[32rem] min-w-0 flex-col border-line bg-panel/40 px-4 py-4 lg:min-h-0 lg:overflow-y-auto lg:border-l lg:px-6",children:[(0,t.jsx)(v.Tabs,{id:"lab-results",label:"Results",value:eE,onChange:eR,items:[{id:"response",label:"Response",badge:eu?eu.status||"ERR":void 0},{id:"report",label:eU?(0,t.jsx)(Q,{}):"Load report",badge:eS.length||void 0}],trailing:(0,t.jsxs)(t.Fragment,{children:["report"===eE&&eS.length>0?(0,t.jsx)(Y,{runs:eS,current:ej,disabled:eU,onPick:async t=>{try{let e=await F.historyApi.run(t.id);K(t.id),ew({id:e.report.id,status:e.report.status,report:e.report})}catch(t){e(t instanceof Error?t.message:"Could not open that run","error")}}}):null,(0,t.jsx)("button",{type:"button",onClick:()=>eC(e=>!e),"aria-label":eq?"Show the request editor":"Expand results to full width",title:eq?"Show the request editor":"Expand results",className:"hidden rounded p-1.5 text-mute hover:bg-panel-2 hover:text-ink lg:block",children:eq?(0,t.jsx)(o,{size:14}):(0,t.jsx)(i,{size:14})})]})}),(0,t.jsx)("div",{...(0,v.tabPanelProps)("lab-results",eE),className:"flex min-h-0 flex-1 flex-col pt-4",children:"response"===eE?(0,t.jsxs)(t.Fragment,{children:[eb&&eu?(0,t.jsxs)("div",{role:"alert",className:"mb-4 flex flex-wrap items-center gap-3 rounded-md border border-warn/40 bg-warn/10 px-3 py-2.5",children:[(0,t.jsxs)("p",{className:"min-w-0 flex-1 text-sm text-ink",children:[(0,t.jsx)("span",{className:"font-medium text-warn",children:"Load test not started."})," The check returned"," ",eu.status||"an error",", not 2xx. Fix the request, or run anyway if this status is expected."]}),(0,t.jsx)("button",{type:"button",className:"btn btn-secondary py-1.5 text-xs",onClick:()=>void eJ(!0),children:"Run anyway"})]}):null,eu?(0,t.jsx)(g.ResponseViewer,{result:eu}):eI?(0,t.jsx)(V.WelcomeCard,{practiceReady:!!l.demoApi,onSimple:()=>void eD(),onSignIn:()=>void e_(),onHide:()=>(0,V.setWelcomeHidden)(!0)}):(0,t.jsx)(G,{title:"Send a request to see the response",lines:[(0,t.jsx)(t.Fragment,{children:"Paste a URL — or a whole curl command from your browser's DevTools — into the bar above."}),(0,t.jsxs)(t.Fragment,{children:["Press ",(0,t.jsx)("span",{className:"kbd",children:w}),"+",(0,t.jsx)("span",{className:"kbd",children:"Enter"})," to send it."]})]})]}):ej?(0,t.jsxs)(t.Fragment,{children:[ej.error?(0,t.jsx)("p",{role:"alert",className:"mb-3 rounded-md border border-bad/40 bg-bad/10 px-3 py-2 text-sm text-bad",children:ej.error}):null,(0,t.jsx)(b.ReportView,{report:ej.report,source:"session",live:eU,probe:eu})]}):(0,t.jsx)(G,{title:"No load test yet",lines:[(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"text-ink",children:"Run load test"})," sends one check request first, then runs"," ",(0,t.jsx)("span",{className:"font-mono text-ink",children:(0,h.profileSummary)(ei)})," with k6."]}),(0,t.jsx)(t.Fragment,{children:"Change users, duration, and ramps in the Load tab. Set pass/fail goals in Goals."})],action:(0,t.jsxs)("button",{type:"button",className:"btn btn-primary",disabled:eP||!!eQ,title:eQ,onClick:()=>void eJ(),children:[(0,t.jsx)(c.Play,{size:16}),"Run load test"]})})})]})]})]})},"VerdictTag",0,X],6980)},17219,15060,e=>{"use strict";let t=new Uint32Array(256).map((e,t)=>{let s=t;for(let e=0;e<8;e++)s=1&s?0xedb88320^s>>>1:s>>>1;return s>>>0});function s(e){let t=new Uint8Array(2);return new DataView(t.buffer).setUint16(0,e,!0),t}function n(e){let t=new Uint8Array(4);return new DataView(t.buffer).setUint32(0,e,!0),t}function a(e){let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),s=0;for(let n of e)t.set(n,s),s+=n.length;return t}function r(e,t){let s=URL.createObjectURL(t),n=document.createElement("a");n.href=s,n.download=e,document.body.appendChild(n),n.click(),n.remove(),URL.revokeObjectURL(s)}e.s(["zipStore",0,function(e){let r=new TextEncoder,l=[],i=[],o=0;for(let[c,d]of Object.entries(e)){let e=r.encode(c),u="string"==typeof d?r.encode(d):d,m=function(e){let s=0xffffffff;for(let n of e)s=t[(s^n)&255]^s>>>8;return(0xffffffff^s)>>>0}(u),p=a([n(0x4034b50),s(20),s(0),s(0),s(0),s(0),n(m),n(u.length),n(u.length),s(e.length),s(0),e,u]),h=a([n(0x2014b50),s(20),s(20),s(0),s(0),s(0),s(0),n(m),n(u.length),n(u.length),s(e.length),s(0),s(0),s(0),s(0),n(0),n(o),e]);l.push(p),i.push(h),o+=p.length}let c=a(i),d=a([n(0x6054b50),s(0),s(0),s(Object.keys(e).length),s(Object.keys(e).length),n(c.length),n(o),s(0)]),u=a([...l,c,d]);return new Blob([u.buffer.slice(u.byteOffset,u.byteOffset+u.byteLength)],{type:"application/zip"})}],17219),e.s(["downloadBlob",0,r,"downloadText",0,function(e,t,s){r(e,new Blob([t],{type:s}))}],15060)},3792,66478,14168,e=>{"use strict";var t=e.i(99522);let s=(0,t.default)("play",[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]]);e.s(["Play",0,s],3792);let n=(0,t.default)("square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);async function a(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error??`Engine error (${e.status})`);return t}e.s(["Square",0,n],66478);let r=(e,t,s)=>fetch(t,{method:e,headers:void 0===s?void 0:{"content-type":"application/json"},body:void 0===s?void 0:JSON.stringify(s)});e.s(["suiteApi",0,{plan:e=>fetch(`/engine/suites/plan?collection=${encodeURIComponent(e)}`,{cache:"no-store"}).then(e=>a(e)),savePlan:(e,t)=>r("PUT","/engine/suites/plan",{collection:e,...t}).then(e=>a(e)),start:e=>r("POST","/engine/suites/runs",e).then(e=>a(e)),get:e=>fetch(`/engine/suites/runs/${encodeURIComponent(e)}`,{cache:"no-store"}).then(e=>a(e)),stop:e=>r("POST",`/engine/suites/runs/${encodeURIComponent(e)}/stop`).then(e=>a(e))},"suiteHref",0,function(e){return`/suite?c=${encodeURIComponent(e)}`}],14168)}]);
|