@stacksjs/ts-cloud 0.16.5 → 0.16.7

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.
Files changed (107) hide show
  1. package/dist/aws/index.js +1 -1
  2. package/dist/bin/{chunk-k9pb99tr.js → chunk-2tdt4xsv.js} +1 -1
  3. package/dist/bin/{chunk-ryhfvrsd.js → chunk-4v6y0dzc.js} +4 -4
  4. package/dist/bin/{chunk-x9ab1xz8.js → chunk-71ah0fk2.js} +1 -1
  5. package/dist/bin/chunk-czzczndx.js +2 -0
  6. package/dist/bin/{chunk-b48j6k55.js → chunk-deb7ws59.js} +1 -1
  7. package/dist/bin/{chunk-e1cxh9rj.js → chunk-gky64tr9.js} +2 -2
  8. package/dist/bin/{chunk-tkzz82s5.js → chunk-ph1n2es7.js} +7 -7
  9. package/dist/bin/{chunk-p197a99s.js → chunk-rs2d8nj2.js} +2 -2
  10. package/dist/bin/{chunk-xvn07b0e.js → chunk-v6mysz8x.js} +1 -1
  11. package/dist/bin/chunk-v8y0g7r7.js +1 -0
  12. package/dist/bin/{chunk-x4gsw45d.js → chunk-vfmad47g.js} +4 -4
  13. package/dist/bin/chunk-xe48f17b.js +1 -0
  14. package/dist/bin/{chunk-8dzsrbs1.js → chunk-zzwrhtmp.js} +13 -13
  15. package/dist/bin/cli.js +251 -251
  16. package/dist/bin/dashboard-server.js +1 -1
  17. package/dist/{chunk-sxtgx8fj.js → chunk-30504159.js} +15 -15
  18. package/dist/{chunk-srh0ctd4.js → chunk-3nccgrzf.js} +2 -2
  19. package/dist/{chunk-yqfkq6q7.js → chunk-7rygewtr.js} +1 -1
  20. package/dist/{chunk-6w827jkt.js → chunk-910yrha7.js} +143 -143
  21. package/dist/{chunk-q4bk0htq.js → chunk-9rkyxwex.js} +3 -3
  22. package/dist/{chunk-c3pvfcme.js → chunk-dbzveymg.js} +65 -65
  23. package/dist/{chunk-trsaqsgv.js → chunk-f5mqecfk.js} +2 -2
  24. package/dist/{chunk-nnfdz28e.js → chunk-fjqx22m1.js} +1 -1
  25. package/dist/chunk-my2adp07.js +2 -0
  26. package/dist/{chunk-t054j0zn.js → chunk-ndm0r1vb.js} +2 -2
  27. package/dist/{chunk-phr1cqgf.js → chunk-pnjajqyw.js} +1 -1
  28. package/dist/{chunk-bqtyqcj4.js → chunk-r7x7y3ha.js} +35 -35
  29. package/dist/{chunk-f0t7y458.js → chunk-rr1hqfyy.js} +4 -4
  30. package/dist/chunk-smmss8qy.js +1 -0
  31. package/dist/{chunk-f27a8et2.js → chunk-v99q99bs.js} +1 -1
  32. package/dist/{chunk-bvspqd2m.js → chunk-w41zkaey.js} +1 -1
  33. package/dist/{chunk-fgww8ya2.js → chunk-wkbk6pdg.js} +18 -18
  34. package/dist/{chunk-hhy358y8.js → chunk-wp6pg5sx.js} +3 -3
  35. package/dist/chunk-y2s8wcdg.js +1 -0
  36. package/dist/deploy/index.js +1 -1
  37. package/dist/dns/delegation.d.ts +17 -1
  38. package/dist/dns/index.js +1 -1
  39. package/dist/dns/route53-adapter.d.ts +14 -0
  40. package/dist/drivers/index.js +1 -1
  41. package/dist/index.js +32 -23
  42. package/dist/operations/index.js +1 -1
  43. package/dist/protection/index.js +1 -1
  44. package/dist/spend/index.js +1 -1
  45. package/dist/ssl/dns01-challenge.test.d.ts +1 -0
  46. package/dist/ssl/letsencrypt.d.ts +17 -1
  47. package/dist/ui/404.html +1 -1
  48. package/dist/ui/accept-invitation.html +1 -1
  49. package/dist/ui/access-denied.html +1 -1
  50. package/dist/ui/account/automation.html +6 -6
  51. package/dist/ui/account/security.html +2 -2
  52. package/dist/ui/applications/compose.html +6 -6
  53. package/dist/ui/applications/new.html +2 -2
  54. package/dist/ui/data/backups.html +6 -6
  55. package/dist/ui/data/services.html +6 -6
  56. package/dist/ui/data/volumes.html +6 -6
  57. package/dist/ui/index.html +5 -5
  58. package/dist/ui/infrastructure/topology.html +5 -5
  59. package/dist/ui/integrations.html +1 -1
  60. package/dist/ui/operations/alerts.html +6 -6
  61. package/dist/ui/operations/configuration.html +6 -6
  62. package/dist/ui/operations/jobs.html +6 -6
  63. package/dist/ui/operations/maintenance.html +6 -6
  64. package/dist/ui/operations/observability.html +6 -6
  65. package/dist/ui/operations/previews.html +6 -6
  66. package/dist/ui/operations/queue.html +6 -6
  67. package/dist/ui/operations/regions.html +6 -6
  68. package/dist/ui/operations/releases.html +6 -6
  69. package/dist/ui/operations/spend.html +6 -6
  70. package/dist/ui/operations/workloads.html +6 -6
  71. package/dist/ui/security.html +2 -2
  72. package/dist/ui/server/actions.html +6 -6
  73. package/dist/ui/server/activity.html +2 -2
  74. package/dist/ui/server/capacity.html +6 -6
  75. package/dist/ui/server/database.html +6 -6
  76. package/dist/ui/server/deployments.html +5 -5
  77. package/dist/ui/server/diagnostics.html +2 -2
  78. package/dist/ui/server/firewall.html +6 -6
  79. package/dist/ui/server/fleet.html +6 -6
  80. package/dist/ui/server/logs.html +6 -6
  81. package/dist/ui/server/metrics.html +5 -5
  82. package/dist/ui/server/security.html +2 -2
  83. package/dist/ui/server/services.html +2 -2
  84. package/dist/ui/server/sites.html +6 -6
  85. package/dist/ui/server/ssh-keys.html +6 -6
  86. package/dist/ui/server/team.html +6 -6
  87. package/dist/ui/server/terminal.html +2 -2
  88. package/dist/ui/serverless/alarms.html +6 -6
  89. package/dist/ui/serverless/assets.html +1 -1
  90. package/dist/ui/serverless/cost.html +2 -2
  91. package/dist/ui/serverless/data.html +6 -6
  92. package/dist/ui/serverless/deployments.html +2 -2
  93. package/dist/ui/serverless/firewall.html +1 -1
  94. package/dist/ui/serverless/functions.html +5 -5
  95. package/dist/ui/serverless/logs.html +6 -6
  96. package/dist/ui/serverless/metrics.html +2 -2
  97. package/dist/ui/serverless/queues.html +5 -5
  98. package/dist/ui/serverless/secrets.html +6 -6
  99. package/dist/ui/serverless/traces.html +6 -6
  100. package/dist/ui/serverless.html +6 -6
  101. package/package.json +3 -3
  102. package/dist/bin/chunk-2synp9gh.js +0 -1
  103. package/dist/bin/chunk-8dt5ehyk.js +0 -1
  104. package/dist/bin/chunk-p9em7chg.js +0 -2
  105. package/dist/chunk-11s59686.js +0 -2
  106. package/dist/chunk-gk5ehe62.js +0 -1
  107. package/dist/chunk-scy8mzqk.js +0 -1
@@ -1,4 +1,4 @@
1
- import{ks,Qe,A,V,C,U,Pe,Vt}from"./chunk-gxwsq3k0.js";import{ie,Zr,Z,en,h,Tr,Cs}from"./chunk-8bbw6qc2.js";import{_e,b,$o,tr,Vn,zn,st,Lr,la,Nt,Mr,Be,$e,Fe,da,ct,rr,Oe,je,qn,Hn,Ai,Ii,Ve,Ur,or,lt,p,$i,Ko,Jo}from"./chunk-dk38j1qr.js";import{u}from"./chunk-pdw0qjq1.js";import{le}from"./chunk-t7seq21w.js";import{f}from"./chunk-k3er0h4j.js";import{hr,St,yr,Sr,br,vr,Yr}from"./chunk-m5sjzxm3.js";import{We,cr,Ji,x,Gr,_a,$a,Ot,ei,ti}from"./chunk-tkzz82s5.js";import{v}from"./chunk-pd8v6bpd.js";import{ne,X,Qn}from"./chunk-xs62dg7t.js";import{w}from"./chunk-pthfzst7.js";import{F}from"./chunk-mcqkjhgp.js";import{R}from"./chunk-y1r1evt0.js";import{W,P,M,gr,co,fr,Kr}from"./chunk-x4gsw45d.js";import{no}from"./chunk-fbycbnvj.js";import{H,Zo,es,zi,$t,j,ts}from"./chunk-rzt92fwv.js";import{Xo,Qo}from"./chunk-e1cxh9rj.js";import{_o}from"./chunk-94cfdvrn.js";import{Qr}from"./chunk-a929za72.js";import{createHash as xT}from"node:crypto";import{existsSync as lo,mkdtempSync as ip,readdirSync as eb,rmSync as Ss,statSync as lb}from"node:fs";import{readFile as Fi,writeFile as ys}from"node:fs/promises";import{tmpdir as Cd}from"node:os";import{dirname as DT,extname as za,join as Et,normalize as OT,relative as _T,resolve as NT,sep as $T}from"node:path";import{fileURLToPath as MT}from"node:url";class Od extends Error{status;code;requestId;constructor(e,t,r,n){super(r);this.status=e;this.code=t;this.requestId=n}}class Ci{options;baseUrl;fetchFn;constructor(e){this.options=e;this.baseUrl=e.baseUrl.replace(/\/$/,""),this.fetchFn=e.fetch??fetch}async request(e,t={}){let r=await this.fetchFn(`${this.baseUrl}${e}`,{...t,headers:{accept:"application/json",authorization:`Bearer ${this.options.token}`,...t.headers}}),n=await r.json().catch(()=>({}));if(!r.ok)throw new Od(r.status,n.error?.code??"api_error",n.error?.message??"API request failed.",n.error?.requestId??r.headers.get("x-request-id")??void 0);return n}listProjects(e={}){return this.request(`/api/v1/projects?${new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).map(([t,r])=>[t,String(r)])))}`)}listEnvironments(e,t={}){return this.request(`/api/v1/projects/${encodeURIComponent(e)}/environments?${new URLSearchParams(Object.fromEntries(Object.entries(t).filter(([,r])=>r!==void 0).map(([r,n])=>[r,String(n)])))}`)}listServices(e,t){return this.request(`/api/v1/services?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}listOperations(e){return this.request(`/api/v1/operations${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listComposeTemplates(){return this.request("/api/v1/compose-templates")}listComposeApplications(e,t){return this.request(`/api/v1/compose-applications?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}previewCompose(e){return this.request("/api/v1/compose-applications/preview",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createComposeApplication(e){return this.request("/api/v1/compose-applications",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}composeServices(e){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/services`)}composeAction(e,t,r={}){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}releaseCapabilities(e,t={}){return this.request(`/api/v1/releases/capabilities?${new URLSearchParams({kind:e,health:String(!!t.health),replicas:String(t.replicas??1)})}`)}listReleases(e,t={}){return this.request(`/api/v1/releases?${new URLSearchParams({projectId:e,...t})}`)}createReleaseArtifact(e){return this.request("/api/v1/release-artifacts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createRelease(e){return this.request("/api/v1/releases",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}releaseAction(e,t,r={}){return this.request(`/api/v1/releases/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}createDeployment(e,t){return this.request("/api/v1/deployments",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}detectApplication(e){return this.request("/api/v1/application-detections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}planApplication(e){return this.request("/api/v1/application-plans",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}listApplicationDrafts(e){return this.request(`/api/v1/application-drafts?projectId=${encodeURIComponent(e)}`)}createApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createApplication(e,t){return this.request("/api/v1/applications",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}uploadApplicationArtifact(e,t,r){return this.request("/api/v1/application-artifacts",{method:"POST",headers:{"content-type":"application/octet-stream","x-project-id":e,"x-artifact-filename":t},body:r})}listRegistryConnections(){return this.request("/api/v1/registry-connections")}createRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}disconnectRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({id:e})})}listQueue(e={}){let t=new URLSearchParams(Object.entries(e).filter(([,r])=>r!==void 0).map(([r,n])=>[r,String(n)]));return this.request(`/api/v1/queue?${t}`)}operationLogs(e,t={}){let r=new URLSearchParams(Object.entries(t).filter(([,n])=>n!==void 0).map(([n,i])=>[n,String(i)]));return this.request(`/api/v1/operations/${encodeURIComponent(e)}/logs?${r}`)}streamOperationLogs(e,t=0){return this.fetchFn(`${this.baseUrl}/api/v1/operations/${encodeURIComponent(e)}/logs/stream`,{headers:{accept:"text/event-stream",authorization:`Bearer ${this.options.token}`,"last-event-id":String(t)}})}cancelOperation(e){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/cancel`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}retryOperation(e,t,r=0){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/retry`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({errorClass:t,delayMs:r})})}queueSettings(){return this.request("/api/v1/queue/settings")}updateQueueSettings(e){return this.request("/api/v1/queue/settings",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:"update queue limits",concurrency:e})})}listPreviews(e){return this.request(`/api/v1/previews${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listPreviewDefinitions(e){return this.request(`/api/v1/preview-definitions?projectId=${encodeURIComponent(e)}`)}createPreviewDefinition(e){return this.request("/api/v1/preview-definitions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createPreview(e){return this.request("/api/v1/previews",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}destroyPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/destroy`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:t})})}extendPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/extend`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hours:t})})}rebuildPreview(e){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/rebuild`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}usage(e={}){let t=new URLSearchParams;for(let[r,n]of Object.entries(e))if(n)t.set(r,String(n));return this.request(`/api/v1/usage${t.size>0?`?${t}`:""}`)}usageRollups(e){let t=new URLSearchParams({from:e.from,to:e.to});if(e.projectId)t.set("projectId",e.projectId);if(e.environmentId)t.set("environmentId",e.environmentId);if(e.limit)t.set("limit",String(e.limit));for(let r of e.meters??[])t.append("meter",r);return this.request(`/api/v1/usage/rollups?${t}`)}allowance(e="deploy",t={}){let r=new URLSearchParams({operation:e});if(t.projectId)r.set("projectId",t.projectId);if(t.environmentId)r.set("environmentId",t.environmentId);return this.request(`/api/v1/spend/allowance?${r}`)}budgets(e={}){let t=new URLSearchParams;for(let[r,n]of Object.entries(e))if(n)t.set(r,String(n));return this.request(`/api/v1/spend/budgets${t.size>0?`?${t}`:""}`)}anomalies(e={}){let t=new URLSearchParams;if(e.projectId)t.set("projectId",e.projectId);if(e.since)t.set("since",e.since);if(e.unacknowledged)t.set("unacknowledged","true");return this.request(`/api/v1/spend/anomalies${t.size>0?`?${t}`:""}`)}}import{createHash as yS}from"node:crypto";import{lstatSync as Ab,readdirSync as kb,readFileSync as Rb}from"node:fs";import{relative as Pb,resolve as Ap,sep as xb}from"node:path";function Db(e){return new Map(e.map((t)=>[t.path.replace(/^\.\//,"").replace(/\\/g,"/"),t]))}function Vo(e,t,r){return{path:e,reason:t,weight:r}}function kp(e){try{return e?.content?JSON.parse(e.content):{}}catch{return{}}}function As(e,t,r,n,i,o){return{framework:e,strategy:t,confidence:r,evidence:n,defaults:{build:i,runtime:{target:t==="static"?"serverless":t==="serverless"?"serverless":t==="dockerfile"||t==="prebuilt_image"?"container":"server",architecture:"x86_64",port:t==="static"||t==="serverless"?void 0:3000,healthCheck:t==="static"?void 0:{protocol:"http",path:"/health"}}},description:o}}function At(e){let t=Db(e.slice(0,1e4)),r=[];if(t.has("Dockerfile"))r.push(As("dockerfile","dockerfile",0.99,[Vo("Dockerfile","A root Dockerfile defines an explicit reproducible build.",1)],{kind:"dockerfile",context:".",dockerfile:"Dockerfile"},"Build the repository with its Dockerfile and run the resulting OCI image."));let n=kp(t.get("composer.json"));if(t.has("artisan")&&n.require?.["laravel/framework"])r.push(As("laravel","server",0.98,[Vo("artisan","Laravel Artisan entrypoint is present.",0.45),Vo("composer.json","Requires laravel/framework.",0.55)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",buildCommand:"php artisan config:cache && php artisan route:cache && php artisan view:cache",startCommand:"php artisan serve --host=0.0.0.0 --port=$PORT"},"Install a production Composer tree, warm Laravel caches, and run the HTTP application."));else if(t.has("composer.json"))r.push(As("php","server",0.82,[Vo("composer.json","Composer metadata identifies a PHP application.",0.8)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",startCommand:"php -S 0.0.0.0:$PORT -t public"},"Install Composer dependencies and run the configured PHP document root."));let i=kp(t.get("package.json"));if(t.has("package.json")){let o=t.has("bun.lock")||t.has("bun.lockb")||i.engines?.bun,s=o?"bun":"node",c=o?"bun":"node",l=[Vo("package.json",`Defines ${i.scripts?.build?"build and ":""}${i.scripts?.start?"start ":""}scripts.`,0.55)];if(o)l.push(Vo(t.has("bun.lock")?"bun.lock":t.has("bun.lockb")?"bun.lockb":"package.json","Pins the Bun package manager/runtime.",0.35));let a=!!(i.dependencies?.vite||i.devDependencies?.vite||i.dependencies?.["@stacksjs/bunpress"]||i.devDependencies?.["@stacksjs/bunpress"])&&!i.scripts?.start,m=a?{kind:"static",installCommand:`${s} install --frozen-lockfile`,buildCommand:`${s} run build`,publishDirectory:"dist"}:{kind:"server",runtime:s,installCommand:`${s} install --frozen-lockfile`,buildCommand:i.scripts?.build?`${s} run build`:void 0,startCommand:i.scripts?.start?`${s} run start`:s==="bun"?"bun run index.ts":"node index.js"};r.push(As(c,m.kind,Math.min(0.94,l.reduce((E,D)=>E+D.weight,0)),l,m,a?"Install dependencies, build static assets, and publish the output directory.":`Install dependencies, build if configured, and start the ${s} server.`))}if(!r.length&&(t.has("index.html")||t.has("public/index.html")))r.push(As("static","static",0.78,[Vo(t.has("index.html")?"index.html":"public/index.html","A static HTML entrypoint is present.",0.78)],{kind:"static",publishDirectory:t.has("index.html")?".":"public"},"Publish the static directory without a runtime process."));if(!r.length)r.push(As("unknown","buildpack",0.2,[],{kind:"buildpack",runtime:"node"},"No supported framework signature was conclusive; choose commands and runtime manually."));return r.sort((o,s)=>s.confidence-o.confidence||o.framework.localeCompare(s.framework))}function Nn(e,t={}){let r=Ap(e),n=t.maxFiles??1e4,i=t.maxContentBytes??262144,o=[],s=new Set(["Dockerfile","package.json","composer.json","index.html","public/index.html","bun.lock","bun.lockb","artisan"]),c=new Set([".git",".ts-cloud",".cache",".next",".nuxt",".output",".turbo",".bun","node_modules","vendor","pantry","dist","build","coverage"]),l=(a)=>{for(let m of kb(a).sort()){if(c.has(m))continue;let E=Ap(a,m),D=Pb(r,E).split(xb).join("/");if(!D||D.startsWith("../"))throw Error("Detection path escaped the application root");let O=Ab(E);if(O.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${D}`);if(O.isDirectory())l(E);else if(O.isFile()){if(o.length>=n)throw Error("Application file-count limit exceeded");let q={path:D,size:O.size};if(s.has(D)&&O.size<=i)q.content=Rb(E,"utf8");o.push(q)}}};return l(r),o}function Nd(e){if(Array.isArray(e))return`[${e.map(Nd).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${Nd(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function ga(e){return!!e&&!e.startsWith("/")&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function Wn(e,t,r,n){return{path:e,code:t,message:r,alternatives:n}}function _d(e){return JSON.parse(JSON.stringify(e))}function Ob(e){let t=Object.fromEntries(Object.entries(e.environment??{}).map(([r,n])=>[r,typeof n==="string"?n:`\${${n.secretRef}}`]));if(e.build.kind==="prebuilt_image"||e.build.kind==="dockerfile")return _d({infrastructure:{containers:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,cpu:e.runtime.cpu,memory:e.runtime.memoryMb,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,environment:t}}}});if(e.runtime.target==="serverless"||e.build.kind==="serverless")return _d({serverless:{apps:{[e.slug]:{source:e.source,build:e.build,architecture:e.runtime.architecture,environment:t,domain:e.domain}}}});return _d({sites:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,env:t,domain:e.domain?.hostname}}})}function se(e,t=[]){let r=[],n=(q)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(q),i=Object.fromEntries(Object.entries(e.environment??{}).map(([q,G])=>{if(typeof G==="string"&&n(q))return r.push(Wn(`environment.${q}`,"write_only_secret_required",`${q} must be supplied through the write-only secrets boundary.`)),[q,{secretRef:q}];return[q,G]})),o=e.build;if(e.build.kind==="dockerfile"&&e.build.buildArgs){let q=Object.fromEntries(Object.entries(e.build.buildArgs).map(([G,Y])=>{if(n(G))return r.push(Wn(`build.buildArgs.${G}`,"write_only_build_secret_required",`${G} must be declared in secretNames instead of buildArgs.`)),[G,"[REDACTED]"];return[G,Y]}));o={...e.build,buildArgs:q}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.slug))r.push(Wn("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!ga((e.source.kind==="git"?e.source.monorepoRoot:e.source.kind==="local"?e.source.root:".")??"."))r.push(Wn("source","unsafe_source_root","Source root must stay inside the source tree."));if(e.source.kind==="git"&&e.source.sparsePaths?.some((q)=>!ga(q)))r.push(Wn("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(e.build.kind==="dockerfile"&&(!ga(e.build.context)||!ga(e.build.dockerfile)))r.push(Wn("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(e.build.kind==="static"&&!ga(e.build.publishDirectory))r.push(Wn("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(e.build.kind==="server"&&!e.build.startCommand.trim())r.push(Wn("build.startCommand","missing_start_command","A server start command is required.",["Use static output","Use a Dockerfile"]));if(e.source.kind==="image"&&e.build.kind!=="prebuilt_image")r.push(Wn("build.kind","image_requires_prebuilt","An OCI image source must use the prebuilt-image strategy.",["Select prebuilt image"]));if(e.build.kind==="prebuilt_image"&&e.runtime.target!=="container")r.push(Wn("runtime.target","image_requires_container","Prebuilt images require the container runtime target.",["Select container target"]));if(e.runtime.target==="serverless"&&e.build.kind==="dockerfile")r.push(Wn("runtime.target","unsupported_serverless_dockerfile","Dockerfile builds currently target the container service path.",["Select container target","Select serverless package"]));if(e.runtime.port!==void 0&&(!Number.isInteger(e.runtime.port)||e.runtime.port<1||e.runtime.port>65535))r.push(Wn("runtime.port","invalid_port","Port must be an integer from 1 to 65535."));let s=e.runtime.healthCheck;if(s&&s.protocol!=="tcp"&&(!s.path||!s.path.startsWith("/")||/[\r\n]/.test(s.path)))r.push(Wn("runtime.healthCheck.path","invalid_health_path","HTTP health checks require a path beginning with /."));if(e.domain?.hostname&&(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i.test(e.domain.hostname)||e.domain.hostname.includes("..")))r.push(Wn("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let c=Object.values(i).flatMap((q)=>typeof q==="object"?[q.secretRef]:[]),l=[...new Set([...e.requiredSecretNames??[],...e.build.kind==="dockerfile"?e.build.secretNames??[]:[],...c])].sort(),a=new Set(t),m=l.filter((q)=>!a.has(q)),E={apiVersion:"ts-cloud.dev/v1",kind:"Application",metadata:{name:e.name,slug:e.slug,projectId:e.projectId,environmentId:e.environmentId},spec:{source:e.source,build:o,runtime:e.runtime,environment:i,domain:e.domain}},D=[...new Set([e.source.kind==="git"?"git:read":e.source.kind==="image"?"registry:pull":e.source.kind==="artifact"?"artifact:inspect":"filesystem:read",e.runtime.target==="container"?"containers":e.runtime.target==="serverless"?"serverless":"servers",e.domain?"dns":""])].filter(Boolean).sort(),O=[...new Set([e.runtime.target,e.runtime.cpu?`${e.runtime.cpu} vCPU`:"",e.runtime.memoryMb?`${e.runtime.memoryMb} MB memory`:"",(e.runtime.minInstances??0)>0?`${e.runtime.minInstances} minimum instances`:"scales from zero where supported",e.domain?"managed DNS/TLS":""])].filter(Boolean);return{valid:r.length===0&&m.length===0,issues:r,missingSecrets:m,manifest:E,configPatch:Ob({...e,build:o,environment:i}),capabilityRequirements:D,costDrivers:O,serializedManifest:`${Nd(E)}
1
+ import{ks,Qe,A,V,C,U,Pe,Vt}from"./chunk-gxwsq3k0.js";import{ie,Zr,Z,en,h,Tr,Cs}from"./chunk-8bbw6qc2.js";import{_e,b,$o,tr,Vn,zn,st,Lr,la,Nt,Mr,Be,$e,Fe,da,ct,rr,Oe,je,qn,Hn,Ai,Ii,Ve,Ur,or,lt,p,$i,Ko,Jo}from"./chunk-dk38j1qr.js";import{u}from"./chunk-pdw0qjq1.js";import{le}from"./chunk-t7seq21w.js";import{f}from"./chunk-k3er0h4j.js";import{hr,St,yr,Sr,br,vr,Yr}from"./chunk-m5sjzxm3.js";import{We,cr,Ji,x,Gr,_a,$a,Ot,ei,ti}from"./chunk-ph1n2es7.js";import{v}from"./chunk-pd8v6bpd.js";import{ne,X,Qn}from"./chunk-xs62dg7t.js";import{w}from"./chunk-pthfzst7.js";import{F}from"./chunk-mcqkjhgp.js";import{R}from"./chunk-y1r1evt0.js";import{W,P,L,gr,co,fr,Kr}from"./chunk-vfmad47g.js";import{no}from"./chunk-fbycbnvj.js";import{H,Zo,es,zi,$t,j,ts}from"./chunk-rzt92fwv.js";import{Xo,Qo}from"./chunk-gky64tr9.js";import{_o}from"./chunk-94cfdvrn.js";import{Qr}from"./chunk-a929za72.js";import{createHash as xT}from"node:crypto";import{existsSync as lo,mkdtempSync as ip,readdirSync as eb,rmSync as Ss,statSync as lb}from"node:fs";import{readFile as Fi,writeFile as ys}from"node:fs/promises";import{tmpdir as Cd}from"node:os";import{dirname as DT,extname as za,join as Et,normalize as OT,relative as _T,resolve as NT,sep as $T}from"node:path";import{fileURLToPath as MT}from"node:url";class Od extends Error{status;code;requestId;constructor(e,t,r,n){super(r);this.status=e;this.code=t;this.requestId=n}}class Ci{options;baseUrl;fetchFn;constructor(e){this.options=e;this.baseUrl=e.baseUrl.replace(/\/$/,""),this.fetchFn=e.fetch??fetch}async request(e,t={}){let r=await this.fetchFn(`${this.baseUrl}${e}`,{...t,headers:{accept:"application/json",authorization:`Bearer ${this.options.token}`,...t.headers}}),n=await r.json().catch(()=>({}));if(!r.ok)throw new Od(r.status,n.error?.code??"api_error",n.error?.message??"API request failed.",n.error?.requestId??r.headers.get("x-request-id")??void 0);return n}listProjects(e={}){return this.request(`/api/v1/projects?${new URLSearchParams(Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).map(([t,r])=>[t,String(r)])))}`)}listEnvironments(e,t={}){return this.request(`/api/v1/projects/${encodeURIComponent(e)}/environments?${new URLSearchParams(Object.fromEntries(Object.entries(t).filter(([,r])=>r!==void 0).map(([r,n])=>[r,String(n)])))}`)}listServices(e,t){return this.request(`/api/v1/services?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}listOperations(e){return this.request(`/api/v1/operations${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listComposeTemplates(){return this.request("/api/v1/compose-templates")}listComposeApplications(e,t){return this.request(`/api/v1/compose-applications?${new URLSearchParams({projectId:e,...t?{environmentId:t}:{}})}`)}previewCompose(e){return this.request("/api/v1/compose-applications/preview",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createComposeApplication(e){return this.request("/api/v1/compose-applications",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}composeServices(e){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/services`)}composeAction(e,t,r={}){return this.request(`/api/v1/compose-applications/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}releaseCapabilities(e,t={}){return this.request(`/api/v1/releases/capabilities?${new URLSearchParams({kind:e,health:String(!!t.health),replicas:String(t.replicas??1)})}`)}listReleases(e,t={}){return this.request(`/api/v1/releases?${new URLSearchParams({projectId:e,...t})}`)}createReleaseArtifact(e){return this.request("/api/v1/release-artifacts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createRelease(e){return this.request("/api/v1/releases",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}releaseAction(e,t,r={}){return this.request(`/api/v1/releases/${encodeURIComponent(e)}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})}createDeployment(e,t){return this.request("/api/v1/deployments",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}detectApplication(e){return this.request("/api/v1/application-detections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}planApplication(e){return this.request("/api/v1/application-plans",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}listApplicationDrafts(e){return this.request(`/api/v1/application-drafts?projectId=${encodeURIComponent(e)}`)}createApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateApplicationDraft(e){return this.request("/api/v1/application-drafts",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createApplication(e,t){return this.request("/api/v1/applications",{method:"POST",headers:{"content-type":"application/json","idempotency-key":t},body:JSON.stringify(e)})}uploadApplicationArtifact(e,t,r){return this.request("/api/v1/application-artifacts",{method:"POST",headers:{"content-type":"application/octet-stream","x-project-id":e,"x-artifact-filename":t},body:r})}listRegistryConnections(){return this.request("/api/v1/registry-connections")}createRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}updateRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}disconnectRegistryConnection(e){return this.request("/api/v1/registry-connections",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({id:e})})}listQueue(e={}){let t=new URLSearchParams(Object.entries(e).filter(([,r])=>r!==void 0).map(([r,n])=>[r,String(n)]));return this.request(`/api/v1/queue?${t}`)}operationLogs(e,t={}){let r=new URLSearchParams(Object.entries(t).filter(([,n])=>n!==void 0).map(([n,i])=>[n,String(i)]));return this.request(`/api/v1/operations/${encodeURIComponent(e)}/logs?${r}`)}streamOperationLogs(e,t=0){return this.fetchFn(`${this.baseUrl}/api/v1/operations/${encodeURIComponent(e)}/logs/stream`,{headers:{accept:"text/event-stream",authorization:`Bearer ${this.options.token}`,"last-event-id":String(t)}})}cancelOperation(e){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/cancel`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}retryOperation(e,t,r=0){return this.request(`/api/v1/operations/${encodeURIComponent(e)}/retry`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({errorClass:t,delayMs:r})})}queueSettings(){return this.request("/api/v1/queue/settings")}updateQueueSettings(e){return this.request("/api/v1/queue/settings",{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:"update queue limits",concurrency:e})})}listPreviews(e){return this.request(`/api/v1/previews${e?`?projectId=${encodeURIComponent(e)}`:""}`)}listPreviewDefinitions(e){return this.request(`/api/v1/preview-definitions?projectId=${encodeURIComponent(e)}`)}createPreviewDefinition(e){return this.request("/api/v1/preview-definitions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}createPreview(e){return this.request("/api/v1/previews",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}destroyPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/destroy`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({confirm:t})})}extendPreview(e,t){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/extend`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({hours:t})})}rebuildPreview(e){return this.request(`/api/v1/previews/${encodeURIComponent(e)}/rebuild`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"})}usage(e={}){let t=new URLSearchParams;for(let[r,n]of Object.entries(e))if(n)t.set(r,String(n));return this.request(`/api/v1/usage${t.size>0?`?${t}`:""}`)}usageRollups(e){let t=new URLSearchParams({from:e.from,to:e.to});if(e.projectId)t.set("projectId",e.projectId);if(e.environmentId)t.set("environmentId",e.environmentId);if(e.limit)t.set("limit",String(e.limit));for(let r of e.meters??[])t.append("meter",r);return this.request(`/api/v1/usage/rollups?${t}`)}allowance(e="deploy",t={}){let r=new URLSearchParams({operation:e});if(t.projectId)r.set("projectId",t.projectId);if(t.environmentId)r.set("environmentId",t.environmentId);return this.request(`/api/v1/spend/allowance?${r}`)}budgets(e={}){let t=new URLSearchParams;for(let[r,n]of Object.entries(e))if(n)t.set(r,String(n));return this.request(`/api/v1/spend/budgets${t.size>0?`?${t}`:""}`)}anomalies(e={}){let t=new URLSearchParams;if(e.projectId)t.set("projectId",e.projectId);if(e.since)t.set("since",e.since);if(e.unacknowledged)t.set("unacknowledged","true");return this.request(`/api/v1/spend/anomalies${t.size>0?`?${t}`:""}`)}}import{createHash as yS}from"node:crypto";import{lstatSync as Ab,readdirSync as kb,readFileSync as Rb}from"node:fs";import{relative as Pb,resolve as Ap,sep as xb}from"node:path";function Db(e){return new Map(e.map((t)=>[t.path.replace(/^\.\//,"").replace(/\\/g,"/"),t]))}function Vo(e,t,r){return{path:e,reason:t,weight:r}}function kp(e){try{return e?.content?JSON.parse(e.content):{}}catch{return{}}}function As(e,t,r,n,i,o){return{framework:e,strategy:t,confidence:r,evidence:n,defaults:{build:i,runtime:{target:t==="static"?"serverless":t==="serverless"?"serverless":t==="dockerfile"||t==="prebuilt_image"?"container":"server",architecture:"x86_64",port:t==="static"||t==="serverless"?void 0:3000,healthCheck:t==="static"?void 0:{protocol:"http",path:"/health"}}},description:o}}function At(e){let t=Db(e.slice(0,1e4)),r=[];if(t.has("Dockerfile"))r.push(As("dockerfile","dockerfile",0.99,[Vo("Dockerfile","A root Dockerfile defines an explicit reproducible build.",1)],{kind:"dockerfile",context:".",dockerfile:"Dockerfile"},"Build the repository with its Dockerfile and run the resulting OCI image."));let n=kp(t.get("composer.json"));if(t.has("artisan")&&n.require?.["laravel/framework"])r.push(As("laravel","server",0.98,[Vo("artisan","Laravel Artisan entrypoint is present.",0.45),Vo("composer.json","Requires laravel/framework.",0.55)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",buildCommand:"php artisan config:cache && php artisan route:cache && php artisan view:cache",startCommand:"php artisan serve --host=0.0.0.0 --port=$PORT"},"Install a production Composer tree, warm Laravel caches, and run the HTTP application."));else if(t.has("composer.json"))r.push(As("php","server",0.82,[Vo("composer.json","Composer metadata identifies a PHP application.",0.8)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",startCommand:"php -S 0.0.0.0:$PORT -t public"},"Install Composer dependencies and run the configured PHP document root."));let i=kp(t.get("package.json"));if(t.has("package.json")){let o=t.has("bun.lock")||t.has("bun.lockb")||i.engines?.bun,s=o?"bun":"node",c=o?"bun":"node",l=[Vo("package.json",`Defines ${i.scripts?.build?"build and ":""}${i.scripts?.start?"start ":""}scripts.`,0.55)];if(o)l.push(Vo(t.has("bun.lock")?"bun.lock":t.has("bun.lockb")?"bun.lockb":"package.json","Pins the Bun package manager/runtime.",0.35));let a=!!(i.dependencies?.vite||i.devDependencies?.vite||i.dependencies?.["@stacksjs/bunpress"]||i.devDependencies?.["@stacksjs/bunpress"])&&!i.scripts?.start,m=a?{kind:"static",installCommand:`${s} install --frozen-lockfile`,buildCommand:`${s} run build`,publishDirectory:"dist"}:{kind:"server",runtime:s,installCommand:`${s} install --frozen-lockfile`,buildCommand:i.scripts?.build?`${s} run build`:void 0,startCommand:i.scripts?.start?`${s} run start`:s==="bun"?"bun run index.ts":"node index.js"};r.push(As(c,m.kind,Math.min(0.94,l.reduce((E,D)=>E+D.weight,0)),l,m,a?"Install dependencies, build static assets, and publish the output directory.":`Install dependencies, build if configured, and start the ${s} server.`))}if(!r.length&&(t.has("index.html")||t.has("public/index.html")))r.push(As("static","static",0.78,[Vo(t.has("index.html")?"index.html":"public/index.html","A static HTML entrypoint is present.",0.78)],{kind:"static",publishDirectory:t.has("index.html")?".":"public"},"Publish the static directory without a runtime process."));if(!r.length)r.push(As("unknown","buildpack",0.2,[],{kind:"buildpack",runtime:"node"},"No supported framework signature was conclusive; choose commands and runtime manually."));return r.sort((o,s)=>s.confidence-o.confidence||o.framework.localeCompare(s.framework))}function Nn(e,t={}){let r=Ap(e),n=t.maxFiles??1e4,i=t.maxContentBytes??262144,o=[],s=new Set(["Dockerfile","package.json","composer.json","index.html","public/index.html","bun.lock","bun.lockb","artisan"]),c=new Set([".git",".ts-cloud",".cache",".next",".nuxt",".output",".turbo",".bun","node_modules","vendor","pantry","dist","build","coverage"]),l=(a)=>{for(let m of kb(a).sort()){if(c.has(m))continue;let E=Ap(a,m),D=Pb(r,E).split(xb).join("/");if(!D||D.startsWith("../"))throw Error("Detection path escaped the application root");let O=Ab(E);if(O.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${D}`);if(O.isDirectory())l(E);else if(O.isFile()){if(o.length>=n)throw Error("Application file-count limit exceeded");let q={path:D,size:O.size};if(s.has(D)&&O.size<=i)q.content=Rb(E,"utf8");o.push(q)}}};return l(r),o}function Nd(e){if(Array.isArray(e))return`[${e.map(Nd).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${Nd(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function ga(e){return!!e&&!e.startsWith("/")&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function Wn(e,t,r,n){return{path:e,code:t,message:r,alternatives:n}}function _d(e){return JSON.parse(JSON.stringify(e))}function Ob(e){let t=Object.fromEntries(Object.entries(e.environment??{}).map(([r,n])=>[r,typeof n==="string"?n:`\${${n.secretRef}}`]));if(e.build.kind==="prebuilt_image"||e.build.kind==="dockerfile")return _d({infrastructure:{containers:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,cpu:e.runtime.cpu,memory:e.runtime.memoryMb,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,environment:t}}}});if(e.runtime.target==="serverless"||e.build.kind==="serverless")return _d({serverless:{apps:{[e.slug]:{source:e.source,build:e.build,architecture:e.runtime.architecture,environment:t,domain:e.domain}}}});return _d({sites:{[e.slug]:{source:e.source,build:e.build,port:e.runtime.port,architecture:e.runtime.architecture,healthCheck:e.runtime.healthCheck,env:t,domain:e.domain?.hostname}}})}function se(e,t=[]){let r=[],n=(q)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(q),i=Object.fromEntries(Object.entries(e.environment??{}).map(([q,G])=>{if(typeof G==="string"&&n(q))return r.push(Wn(`environment.${q}`,"write_only_secret_required",`${q} must be supplied through the write-only secrets boundary.`)),[q,{secretRef:q}];return[q,G]})),o=e.build;if(e.build.kind==="dockerfile"&&e.build.buildArgs){let q=Object.fromEntries(Object.entries(e.build.buildArgs).map(([G,Y])=>{if(n(G))return r.push(Wn(`build.buildArgs.${G}`,"write_only_build_secret_required",`${G} must be declared in secretNames instead of buildArgs.`)),[G,"[REDACTED]"];return[G,Y]}));o={...e.build,buildArgs:q}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.slug))r.push(Wn("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!ga((e.source.kind==="git"?e.source.monorepoRoot:e.source.kind==="local"?e.source.root:".")??"."))r.push(Wn("source","unsafe_source_root","Source root must stay inside the source tree."));if(e.source.kind==="git"&&e.source.sparsePaths?.some((q)=>!ga(q)))r.push(Wn("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(e.build.kind==="dockerfile"&&(!ga(e.build.context)||!ga(e.build.dockerfile)))r.push(Wn("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(e.build.kind==="static"&&!ga(e.build.publishDirectory))r.push(Wn("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(e.build.kind==="server"&&!e.build.startCommand.trim())r.push(Wn("build.startCommand","missing_start_command","A server start command is required.",["Use static output","Use a Dockerfile"]));if(e.source.kind==="image"&&e.build.kind!=="prebuilt_image")r.push(Wn("build.kind","image_requires_prebuilt","An OCI image source must use the prebuilt-image strategy.",["Select prebuilt image"]));if(e.build.kind==="prebuilt_image"&&e.runtime.target!=="container")r.push(Wn("runtime.target","image_requires_container","Prebuilt images require the container runtime target.",["Select container target"]));if(e.runtime.target==="serverless"&&e.build.kind==="dockerfile")r.push(Wn("runtime.target","unsupported_serverless_dockerfile","Dockerfile builds currently target the container service path.",["Select container target","Select serverless package"]));if(e.runtime.port!==void 0&&(!Number.isInteger(e.runtime.port)||e.runtime.port<1||e.runtime.port>65535))r.push(Wn("runtime.port","invalid_port","Port must be an integer from 1 to 65535."));let s=e.runtime.healthCheck;if(s&&s.protocol!=="tcp"&&(!s.path||!s.path.startsWith("/")||/[\r\n]/.test(s.path)))r.push(Wn("runtime.healthCheck.path","invalid_health_path","HTTP health checks require a path beginning with /."));if(e.domain?.hostname&&(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i.test(e.domain.hostname)||e.domain.hostname.includes("..")))r.push(Wn("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let c=Object.values(i).flatMap((q)=>typeof q==="object"?[q.secretRef]:[]),l=[...new Set([...e.requiredSecretNames??[],...e.build.kind==="dockerfile"?e.build.secretNames??[]:[],...c])].sort(),a=new Set(t),m=l.filter((q)=>!a.has(q)),E={apiVersion:"ts-cloud.dev/v1",kind:"Application",metadata:{name:e.name,slug:e.slug,projectId:e.projectId,environmentId:e.environmentId},spec:{source:e.source,build:o,runtime:e.runtime,environment:i,domain:e.domain}},D=[...new Set([e.source.kind==="git"?"git:read":e.source.kind==="image"?"registry:pull":e.source.kind==="artifact"?"artifact:inspect":"filesystem:read",e.runtime.target==="container"?"containers":e.runtime.target==="serverless"?"serverless":"servers",e.domain?"dns":""])].filter(Boolean).sort(),O=[...new Set([e.runtime.target,e.runtime.cpu?`${e.runtime.cpu} vCPU`:"",e.runtime.memoryMb?`${e.runtime.memoryMb} MB memory`:"",(e.runtime.minInstances??0)>0?`${e.runtime.minInstances} minimum instances`:"scales from zero where supported",e.domain?"managed DNS/TLS":""])].filter(Boolean);return{valid:r.length===0&&m.length===0,issues:r,missingSecrets:m,manifest:E,configPatch:Ob({...e,build:o,environment:i}),capabilityRequirements:D,costDrivers:O,serializedManifest:`${Nd(E)}
2
2
  `}}function Rp(e){let t=e.replace(/\\/g,"/");return!!t&&!t.startsWith("/")&&!/^[A-Za-z]:\//.test(t)&&!t.split("/").includes("..")&&!/[\0\r\n]/.test(t)}function Pp(e,t,r={}){let n=r.maxBytes??104857600,i=r.maxEntries??1e4,o=r.maxExpandedBytes??524288000;if(e.byteLength>n)throw Error("Archive exceeds the compressed size limit");let s=new DataView(e.buffer,e.byteOffset,e.byteLength),c=[],l=0;if(t.toLowerCase().endsWith(".zip")||e[0]===80&&e[1]===75){let m=0;while(m+30<=e.length){let E=s.getUint32(m,!0);if(E===33639248||E===101010256)break;if(E!==67324752)throw Error("Malformed ZIP local header");let D=s.getUint16(m+6,!0),O=s.getUint32(m+18,!0),q=s.getUint32(m+22,!0),G=s.getUint16(m+26,!0),Y=s.getUint16(m+28,!0);if(D&8)throw Error("ZIP data descriptors are not accepted for uploaded artifacts");let re=new TextDecoder().decode(e.subarray(m+30,m+30+G));if(!Rp(re))throw Error(`Unsafe archive path: ${re}`);if(c.push(re),l+=q,c.length>i||l>o)throw Error("Archive expansion limit exceeded");m+=30+G+Y+O}return{format:"zip",entries:c.length,expandedBytes:l,paths:c}}if(!t.toLowerCase().match(/\.(?:tar|tar\.gz|tgz)$/))throw Error("Only ZIP and uncompressed TAR artifacts are supported");let a=0;while(a+512<=e.length){let m=e.subarray(a,a+512);if(m.every((G)=>G===0))break;let E=(G,Y)=>new TextDecoder().decode(m.subarray(G,G+Y)).replace(/\0.*$/,""),D=`${E(345,155)}${E(345,155)?"/":""}${E(0,100)}`,O=Number.parseInt(E(124,12).trim()||"0",8),q=String.fromCharCode(m[156]??0);if(!Rp(D))throw Error(`Unsafe archive path: ${D}`);if(q==="1"||q==="2")throw Error(`Archive links are not accepted: ${D}`);if(!Number.isFinite(O)||O<0)throw Error("Malformed TAR entry size");if(c.push(D),l+=O,c.length>i||l>o)throw Error("Archive expansion limit exceeded");a+=512+Math.ceil(O/512)*512}return{format:"tar",entries:c.length,expandedBytes:l,paths:c}}var xp=new Set(["source","build","runtime","environment","domain","review"]);function Dp(e,t){try{return typeof e==="string"?JSON.parse(e):t}catch{return t}}function Op(e){return/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(e)}function _p(e){for(let[r,n]of Object.entries(e.environment??{}))if(typeof n==="string"&&Op(r)&&n)throw Error(`${r} must be stored through the write-only secrets boundary`);if(e.build.kind==="dockerfile"){for(let[r,n]of Object.entries(e.build.buildArgs??{}))if(Op(r)&&n)throw Error(`${r} must be declared as a build secret name`)}let t=JSON.stringify(e);if(/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(t))throw Error("Drafts cannot contain credential-bearing URLs")}function Np(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),schemaVersion:Number(e.schema_version),name:String(e.name),step:String(e.step),input:Dp(e.input,{}),suppliedSecretNames:Dp(e.supplied_secret_names,[]),status:String(e.status),version:Number(e.version),createdByActorId:e.created_by_actor_id?String(e.created_by_actor_id):void 0,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class Dn{controlPlane;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}create(e){if(_p(e.draft),e.draft.projectId!==e.projectId)throw Error("Draft project does not match its storage scope");let t=this.controlPlane.getProject(e.projectId);if(!t||t.organizationId!==e.organizationId)throw Error("Draft project was not found");let r=this.idFn(),n=this.now(),i=e.step??"source";if(!xp.has(i))throw Error("Invalid draft step");let o=[...new Set(e.suppliedSecretNames??[])].sort(),s=se(e.draft,o).valid?"ready":"draft";return this.controlPlane.database.run("INSERT INTO application_drafts (id, organization_id, project_id, schema_version, name, step, input, supplied_secret_names, status, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.organizationId,e.projectId,e.name.trim().slice(0,100),i,JSON.stringify(e.draft),JSON.stringify(o),s,e.actorId??null,n,n]),this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,actorId:e.actorId,type:"application.draft.created",payload:{draftId:r,step:i,status:s,requiredSecretNames:e.draft.requiredSecretNames??[]}}),this.get(r)}get(e){let t=this.controlPlane.database.query("SELECT * FROM application_drafts WHERE id=?").get(e);return t?Np(t):void 0}list(e){return this.controlPlane.database.query("SELECT * FROM application_drafts WHERE project_id=? ORDER BY updated_at DESC").all(e).map(Np)}update(e,t,r){let n=this.get(e);if(!n||n.version!==t)throw Error(`Application draft ${e} changed since version ${t}`);if(!xp.has(r.step))throw Error("Invalid draft step");if(r.draft.projectId!==n.projectId)throw Error("Draft project cannot be changed");_p(r.draft);let i=[...new Set(r.suppliedSecretNames??n.suppliedSecretNames)].sort(),o=se(r.draft,i).valid?"ready":"draft",s=this.now();if(this.controlPlane.database.run("UPDATE application_drafts SET name=?, step=?, input=?, supplied_secret_names=?, status=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.draft.name.slice(0,100),r.step,JSON.stringify(r.draft),JSON.stringify(i),o,s,e,t]).changes!==1)throw Error(`Application draft ${e} changed since version ${t}`);return this.controlPlane.appendEvent({organizationId:n.organizationId,projectId:n.projectId,actorId:r.actorId,type:"application.draft.updated",payload:{draftId:e,fromVersion:t,toVersion:t+1,step:r.step,status:o}}),this.get(e)}markApplied(e,t,r){let n=this.get(e);if(!n||n.version!==t)throw Error(`Application draft ${e} changed since version ${t}`);let i=se(n.input,n.suppliedSecretNames);if(!i.valid)throw Error(`Draft is not deployable: ${[...i.issues.map((s)=>s.message),...i.missingSecrets.map((s)=>`Missing secret ${s}`)].join("; ")}`);let o=this.now();return this.controlPlane.database.run("UPDATE application_drafts SET status='applied', step='review', version=version+1, updated_at=? WHERE id=? AND version=?",[o,e,t]),this.controlPlane.appendEvent({organizationId:n.organizationId,projectId:n.projectId,actorId:r,type:"application.draft.applied",payload:h({draftId:e,manifest:i.manifest})}),this.get(e)}}import{createCipheriv as _b,createDecipheriv as Nb,createHash as Lp,randomBytes as $b}from"node:crypto";function ma(e){return typeof e==="string"&&e?e:void 0}function $d(e){return Lp("sha256").update(e).digest("hex").slice(0,16)}function $p(e){let t=new URL(e.includes("://")?e:`https://${e}`);if(t.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(t.hostname))throw Error("Registry host must use HTTPS");if(t.username||t.password||t.search||t.hash)throw Error("Registry host cannot contain credentials");return`${t.protocol}//${t.host}`}function Mb(e){return{id:String(e.id),organizationId:String(e.organization_id),provider:String(e.provider),name:String(e.name),host:String(e.host),credentialConfigured:!!e.credential_ciphertext,credentialFingerprint:ma(e.credential_fingerprint),credentialExpiresAt:ma(e.credential_expires_at),status:String(e.status),healthMessage:ma(e.health_message),lastTestedAt:ma(e.last_tested_at),version:Number(e.version),createdByActorId:ma(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class kn{controlPlane;key;nowFn;idFn;constructor(e,t){this.controlPlane=e;if(!t.encryptionKey)throw Error("Registry encryption key is required");this.key=Lp("sha256").update(`ts-cloud:registry:${t.encryptionKey}`).digest(),this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}encrypt(e){let t=$b(12),r=_b("aes-256-gcm",this.key,t),n=Buffer.concat([r.update(e,"utf8"),r.final()]);return`v1.${t.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${n.toString("base64url")}`}decrypt(e){let[t,r,n,i]=e.split(".");if(t!=="v1"||!r||!n||!i)throw Error("Registry credential envelope is invalid");let o=Nb("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return o.setAuthTag(Buffer.from(n,"base64url")),Buffer.concat([o.update(Buffer.from(i,"base64url")),o.final()]).toString("utf8")}current(e){let t=Mb(e);return t.status!=="disconnected"&&t.credentialExpiresAt&&new Date(t.credentialExpiresAt).getTime()<=this.nowFn().getTime()?{...t,status:"expired",healthMessage:"Registry credential expired; rotate it before pulling images."}:t}create(e){if(!["docker_hub","ghcr","ecr","gcr","generic"].includes(e.provider))throw Error("A supported registry provider is required");let t=e.credential?JSON.stringify(e.credential):void 0,r=this.idFn(),n=this.now();return this.controlPlane.database.run("INSERT INTO registry_connections (id, organization_id, provider, name, host, credential_ciphertext, credential_fingerprint, credential_expires_at, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.organizationId,e.provider,e.name.trim().slice(0,80),$p(e.host),t?this.encrypt(t):null,t?$d(t):null,e.credentialExpiresAt??null,e.actorId??null,n,n]),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.actorId,type:"registry.connection.created",payload:{connectionId:r,provider:e.provider,host:$p(e.host),credentialConfigured:!!t}}),this.get(r)}get(e){let t=this.controlPlane.database.query("SELECT * FROM registry_connections WHERE id=?").get(e);return t?this.current(t):void 0}list(e){return this.controlPlane.database.query("SELECT * FROM registry_connections WHERE organization_id=? ORDER BY name").all(e).map((t)=>this.current(t))}credential(e){let t=this.controlPlane.database.query("SELECT credential_ciphertext FROM registry_connections WHERE id=?").get(e);return t?.credential_ciphertext?JSON.parse(this.decrypt(String(t.credential_ciphertext))):void 0}rotate(e,t,r={}){let n=this.get(e);if(!n||n.status==="disconnected")throw Error("Registry connection was not found");let i=JSON.stringify(t);return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=?, credential_fingerprint=?, credential_expires_at=?, status='pending', health_message=NULL, version=version+1, updated_at=? WHERE id=?",[this.encrypt(i),$d(i),r.expiresAt??null,this.now(),e]),this.controlPlane.appendEvent({organizationId:n.organizationId,actorId:r.actorId,type:"registry.credential.rotated",payload:{connectionId:e,fingerprint:$d(i),expiresAt:r.expiresAt??null}}),this.get(e)}disconnect(e,t){let r=this.get(e);if(!r)throw Error("Registry connection was not found");return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=NULL, credential_fingerprint=NULL, status='disconnected', health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[this.now(),e]),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"registry.connection.disconnected",level:"warning",payload:{connectionId:e}}),this.get(e)}async test(e,t={}){let r=this.get(e);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active registry connection was not found");let n=this.credential(e),i=t.fetch??fetch,o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??15000),c=n?.token?`Bearer ${n.token}`:n?.username||n?.password?`Basic ${Buffer.from(`${n.username??""}:${n.password??""}`).toString("base64")}`:void 0;try{let l=await i(`${r.host}/v2/`,{method:"GET",redirect:"error",signal:o.signal,headers:c?{Authorization:c}:void 0}),a=l.headers.get("www-authenticate")??"";if(l.status===401&&a.startsWith("Bearer ")&&n){let D=Object.fromEntries([...a.slice(7).matchAll(/(\w+)="([^"]+)"/g)].map((re)=>[re[1],re[2]])),O=new URL(D.realm??"");if(O.protocol!=="https:")throw Error("Registry authentication realm must use HTTPS");if(D.service)O.searchParams.set("service",D.service);if(t.image)O.searchParams.set("scope",`repository:${Bp(t.image).repository}:pull`);let q=await i(O,{signal:o.signal,redirect:"error",headers:c?{Authorization:c}:void 0});if(!q.ok)throw Error(`Registry authentication failed (${q.status})`);let G=await q.json(),Y=G.token??G.access_token;if(!Y)throw Error("Registry did not return an access token");l=t.image?await Mp(i,r.host,t.image,Y,o.signal):await i(`${r.host}/v2/`,{signal:o.signal,redirect:"error",headers:{Authorization:`Bearer ${Y}`}})}else if(l.ok&&t.image)l=await Mp(i,r.host,t.image,n?.token,o.signal,c);let m=l.ok?"healthy":"degraded",E=l.ok?t.image?"Registry image is readable.":"Registry connection is healthy.":`Registry request failed (${l.status})`;return this.controlPlane.database.run("UPDATE registry_connections SET status=?, health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[m,E,this.now(),this.now(),e]),this.get(e)}catch(l){let a=o.signal.aborted?"Registry request timed out.":l instanceof Error?l.message:"Registry test failed";return this.controlPlane.database.run("UPDATE registry_connections SET status='degraded', health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[a.slice(0,1000),this.now(),this.now(),e]),this.get(e)}finally{clearTimeout(s)}}}function Bp(e){let t=e.replace(/^https?:\/\//,""),r=t.indexOf("/");if(r<1)throw Error("Image must include registry/repository");let n=t.slice(r+1),i=n.lastIndexOf("@"),o=n.lastIndexOf(":"),s=i>=0?i:o>n.lastIndexOf("/")?o:-1,c=s>=0?n.slice(0,s):n,l=s>=0?n.slice(s+1):"latest";if(!/^[A-Za-z0-9_.\/-]+$/.test(c)||!/^[A-Za-z0-9_.:+-]+$/.test(l))throw Error("Image reference is invalid");return{repository:c,reference:l}}async function Mp(e,t,r,n,i,o){let s=Bp(r);return e(`${t}/v2/${s.repository}/manifests/${encodeURIComponent(s.reference)}`,{method:"HEAD",redirect:"error",signal:i,headers:{Accept:"application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json",...n?{Authorization:`Bearer ${n}`}:o?{Authorization:o}:{}}})}import{createHash as Lb}from"node:crypto";import{chmodSync as jp,existsSync as Fp,mkdirSync as Bb,renameSync as jb,unlinkSync as Up,writeFileSync as Fb}from"node:fs";import{basename as Ub,join as zb}from"node:path";function Md(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),filename:String(e.filename),sha256:String(e.sha256),size:Number(e.size),format:String(e.format),entryCount:Number(e.entry_count),expandedBytes:Number(e.expanded_bytes),createdByActorId:e.created_by_actor_id?String(e.created_by_actor_id):void 0,createdAt:String(e.created_at)}}class xn{controlPlane;root;idFn;nowFn;constructor(e,t){this.controlPlane=e;this.root=A(t.cwd,"artifacts"),this.idFn=t.id??(()=>crypto.randomUUID()),this.nowFn=t.now??(()=>new Date)}create(e){let t=this.controlPlane.getProject(e.projectId);if(!t||t.organizationId!==e.organizationId)throw Error("Artifact project was not found");let r=Ub(e.filename).slice(0,200);if(!r||r!==e.filename)throw Error("Artifact filename must not contain a path");let n=Pp(e.bytes,r),i=Lb("sha256").update(e.bytes).digest("hex"),o=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? AND sha256=?").get(e.projectId,i);if(o)return Md(o);let s=this.idFn();Bb(this.root,{recursive:!0,mode:448}),jp(this.root,448);let c=zb(this.root,`${s}.archive`),l=`${c}.partial`;try{Fb(l,e.bytes,{mode:384,flag:"wx"}),jb(l,c),jp(c,384),this.controlPlane.database.run("INSERT INTO application_artifacts (id, organization_id, project_id, filename, storage_path, sha256, size, format, entry_count, expanded_bytes, created_by_actor_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[s,e.organizationId,e.projectId,r,c,i,e.bytes.byteLength,n.format,n.entries,n.expandedBytes,e.actorId??null,this.nowFn().toISOString()])}catch(a){if(Fp(l))Up(l);if(Fp(c))Up(c);throw a}return this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,actorId:e.actorId,type:"application.artifact.created",payload:{artifactId:s,filename:r,sha256:i,size:e.bytes.byteLength,entries:n.entries}}),this.get(s)}get(e){let t=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE id=?").get(e);return t?Md(t):void 0}list(e){return this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? ORDER BY created_at DESC").all(e).map(Md)}}function Nr(e){let t=e.drafts.get(e.draftId);if(!t||t.version!==e.expectedVersion)throw Error(`Application draft ${e.draftId} changed since version ${e.expectedVersion}`);if(t.status==="applied")throw Error("Application draft was already applied");let r=e.controlPlane.getProject(t.projectId),n=r?e.controlPlane.listEnvironments(r.id).find((a)=>a.id===t.input.environmentId):void 0;if(!r||!n||n.projectId!==r.id||r.organizationId!==t.organizationId)throw Error("Draft deployment scope was not found");if(e.confirmEnvironment!==n.slug)throw Error(`Type ${n.slug} to confirm this deployment target`);let i=se(t.input,t.suppliedSecretNames);if(!i.valid)throw Error(`Application plan is invalid: ${[...i.issues.map((a)=>a.message),...i.missingSecrets.map((a)=>`Missing secret ${a}`)].join("; ")}`);let o=e.controlPlane.listResources(r.id,n.id).find((a)=>a.kind==="application"&&a.slug===t.input.slug),s=JSON.parse(JSON.stringify({manifest:i.manifest,configPatch:i.configPatch})),c=o?e.controlPlane.updateResource(o.id,o.version,{name:t.input.name,desiredState:s}):e.controlPlane.createResource({projectId:r.id,environmentId:n.id,kind:"application",slug:t.input.slug,name:t.input.name,desiredState:s,metadata:{source:"application-onboarding",draftId:t.id}}),l=new b(e.controlPlane).enqueue({projectId:r.id,environmentId:n.id,resourceId:c.id,actorId:e.actorId,kind:"application.create",idempotencyKey:`application-draft:${t.id}:v${t.version}`,correlationId:`application-draft:${t.id}`,input:s,lockKey:`resource:${c.id}`,providerKey:c.provider??"default",buildSlot:t.input.build.kind!=="prebuilt_image",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return e.drafts.markApplied(t.id,t.version,e.actorId),e.controlPlane.appendEvent({organizationId:t.organizationId,projectId:r.id,resourceId:c.id,operationId:l.id,actorId:e.actorId,type:"application.create.queued",payload:{draftId:t.id,environment:n.slug,strategy:t.input.build.kind,costDrivers:i.costDrivers}}),{plan:i,resource:c,operation:l}}function Yt(e){let t=["static","compute","serverless_zip","serverless_image"].includes(e.kind),r=["container","compose"].includes(e.kind)&&(e.replicas??1)>1,n=e.kind==="container"||e.kind==="serverless_zip"||e.kind==="serverless_image",i=(o,s)=>s&&(o==="atomic"?e.kind==="static"||e.hasHealthGate:e.hasHealthGate);return[{strategy:"atomic",supported:i("atomic",t),explanation:t?e.hasHealthGate||e.kind==="static"?"Activate an immutable version with an atomic pointer/alias switch.":"Atomic activation needs a readiness gate for this runtime.":"This driver has no atomic pointer or alias primitive.",capacityMultiplier:1,costImpact:"none",rollback:"Switch the pointer/alias back to the previous immutable release."},{strategy:"rolling",supported:i("rolling",r),explanation:r?e.hasHealthGate?"Replace healthy replicas within the configured capacity envelope.":"Rolling activation requires a health/readiness gate.":"Rolling activation requires a capable container/Compose driver and at least two replicas.",capacityMultiplier:1.5,costImpact:"temporary",rollback:"Stop replacement and restore the prior task/service definition."},{strategy:"blue_green",supported:i("blue_green",n),explanation:n?e.hasHealthGate?"Provision a complete green target and switch traffic after health passes.":"Blue-green requires a health gate before traffic can switch.":"The provider does not expose two traffic-addressable revisions.",capacityMultiplier:2,costImpact:"temporary",rollback:"Return all traffic to the preserved blue target."},{strategy:"canary",supported:i("canary",n),explanation:n?e.hasHealthGate?"Shift bounded traffic steps while evaluating health.":"Canary requires a health gate and measurable traffic target.":"The provider does not expose weighted traffic primitives.",capacityMultiplier:1.25,costImpact:"temporary",rollback:"Set canary weight to zero and preserve its diagnostics."}]}function Qa(e,t){let r=Yt(e).find((n)=>n.strategy===t);if(!r.supported)throw Error(`${t} is unavailable: ${r.explanation}`);return r}import{createHash as Vb}from"node:crypto";var qb=/^sha256:[a-f0-9]{64}$/,Jb=/^[a-f0-9]{40,64}$/i;function _i(e){return typeof e==="string"&&e?e:void 0}function qo(e,t){try{return JSON.parse(String(e))}catch{return t}}function zp(e){return{id:String(e.id),organizationId:String(e.organization_id),digest:String(e.digest),kind:String(e.kind),uri:String(e.uri),size:Number(e.size),mediaType:String(e.media_type),provenance:qo(e.provenance,{}),attestation:qo(e.attestation,{}),verifiedAt:String(e.verified_at),createdAt:String(e.created_at)}}function Vp(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:String(e.environment_id),resourceId:String(e.resource_id),artifactId:String(e.artifact_id),kind:String(e.kind),sourceSha:_i(e.source_sha),configHash:String(e.config_hash),manifest:qo(e.manifest,{}),provenance:qo(e.provenance,{}),strategy:String(e.strategy),status:String(e.status),healthGate:e.health_gate==null?void 0:qo(e.health_gate,void 0),hooks:qo(e.hooks,{migrations:"none",preActivate:[],postActivate:[]}),drainSeconds:Number(e.drain_seconds),graceSeconds:Number(e.grace_seconds),automaticRollback:Number(e.automatic_rollback)===1,rollbackAttempts:Number(e.rollback_attempts),previousReleaseId:_i(e.previous_release_id),promotedFromReleaseId:_i(e.promoted_from_release_id),actorId:_i(e.actor_id),trigger:String(e.trigger),pinned:Number(e.pinned)===1,pinReason:_i(e.pin_reason),activatedAt:_i(e.activated_at),failedAt:_i(e.failed_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Wb(e){return{sequence:Number(e.sequence),id:String(e.id),releaseId:String(e.release_id),fromStatus:_i(e.from_status),toStatus:String(e.to_status),trafficPercent:e.traffic_percent==null?void 0:Number(e.traffic_percent),health:qo(e.health,{}),message:String(e.message),operationId:_i(e.operation_id),createdAt:String(e.created_at)}}function Hb(e,t){let r=[],n=(i,o,s)=>{if(JSON.stringify(o)===JSON.stringify(s))return;if(o&&s&&typeof o==="object"&&typeof s==="object"&&!Array.isArray(o)&&!Array.isArray(s)){for(let c of[...new Set([...Object.keys(o),...Object.keys(s)])].sort())n(i?`${i}.${c}`:c,o[c],s[c]);return}r.push({path:i,...o!==void 0?{before:o}:{},...s!==void 0?{after:s}:{}})};return n("",e,t),r}class Ld{controlPlane;now;id;constructor(e,t={}){this.controlPlane=e;this.now=t.now??(()=>new Date),this.id=t.id??(()=>crypto.randomUUID())}registerArtifact(e){if(!qb.test(e.digest)||!/^(?:s3|https|oci|file):/.test(e.uri)||!Number.isInteger(e.size)||e.size<0)throw Error("Artifact requires a SHA-256 digest, supported immutable URI, and non-negative byte size");let t=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE organization_id=? AND digest=?").get(e.organizationId,e.digest);if(t)return zp(t);let r=this.id(),n=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_artifacts (id, organization_id, digest, kind, uri, size, media_type, provenance, attestation, verified_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.organizationId,e.digest,e.kind,e.uri,e.size,e.mediaType??"application/octet-stream",JSON.stringify(h(e.provenance??{})),JSON.stringify(h(e.attestation??{})),n,n]),this.getArtifact(r)}getArtifact(e){let t=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE id=?").get(e);return t?zp(t):void 0}create(e){let t=this.getArtifact(e.artifactId),r=this.controlPlane.getResource(e.resourceId),n=this.controlPlane.listEnvironments(e.projectId).find((E)=>E.id===e.environmentId);if(!t||t.organizationId!==e.organizationId||t.kind!==e.kind)throw Error("Release artifact does not match the organization and deployable kind");if(!r||r.projectId!==e.projectId||r.environmentId!==e.environmentId||!n)throw Error("Release target scope does not match the resource");if(e.sourceSha&&!Jb.test(e.sourceSha))throw Error("Release source must be an immutable commit SHA");Qa({kind:e.kind,provider:r.provider,hasHealthGate:!!e.healthGate,replicas:e.replicas},e.strategy);let i=h(e.config),o=Vb("sha256").update(JSON.stringify(i)).digest("hex"),s=this.active(e.resourceId),c=this.id(),l=this.now().toISOString(),a=e.approvalRequired?"awaiting_approval":"built",m=e.hooks??{migrations:"none",preActivate:[],postActivate:[]};return this.controlPlane.database.run("INSERT INTO releases (id, organization_id, project_id, environment_id, resource_id, artifact_id, kind, source_sha, config_hash, manifest, provenance, strategy, status, health_gate, hooks, drain_seconds, grace_seconds, automatic_rollback, previous_release_id, promoted_from_release_id, actor_id, trigger, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[c,e.organizationId,e.projectId,e.environmentId,e.resourceId,e.artifactId,e.kind,e.sourceSha??null,o,JSON.stringify(h(e.manifest)),JSON.stringify(h(e.provenance??{})),e.strategy,a,e.healthGate?JSON.stringify(e.healthGate):null,JSON.stringify(m),Math.max(0,Math.min(3600,Math.floor(e.drainSeconds??30))),Math.max(0,Math.min(3600,Math.floor(e.graceSeconds??30))),e.automaticRollback===!1?0:1,s?.id??null,e.promotedFromReleaseId??null,e.actorId??null,e.trigger??"manual",l,l]),this.recordTransition(c,void 0,a,{message:e.promotedFromReleaseId?"Immutable artifact promoted without rebuild.":"Immutable release record created."}),this.get(c)}get(e){let t=this.controlPlane.database.query("SELECT * FROM releases WHERE id=?").get(e);return t?Vp(t):void 0}list(e={}){return this.controlPlane.database.query("SELECT * FROM releases ORDER BY created_at DESC, rowid DESC").all().map(Vp).filter((t)=>(!e.projectId||t.projectId===e.projectId)&&(!e.environmentId||t.environmentId===e.environmentId)&&(!e.resourceId||t.resourceId===e.resourceId)&&(!e.status||t.status===e.status))}active(e){return this.list({resourceId:e,status:"active"})[0]}transitions(e){return this.controlPlane.database.query("SELECT * FROM release_transitions WHERE release_id=? ORDER BY sequence").all(e).map(Wb)}recordTransition(e,t,r,n){this.controlPlane.database.run("INSERT INTO release_transitions (id, release_id, from_status, to_status, traffic_percent, health, message, operation_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",[this.id(),e,t??null,r,n.trafficPercent??null,JSON.stringify(h(n.health??{})),n.message.slice(0,1000),n.operationId??null,this.now().toISOString()])}progress(e,t){let r=this.get(e);if(!r)throw Error(`Release ${e} was not found`);return this.recordTransition(e,r.status,r.status,t),this.transitions(e).at(-1)}transition(e,t,r){let n=this.get(e);if(!n)throw Error(`Release ${e} was not found`);if(!{built:["awaiting_approval","activating","failed"],awaiting_approval:["built","failed"],activating:["active","failed","rolled_back"],active:["superseded","failed","rolled_back"],failed:["activating","rolled_back"],rolled_back:["activating"],superseded:["activating"]}[n.status].includes(t))throw Error(`Invalid release transition ${n.status} → ${t}`);let o=this.now().toISOString();if(t==="active"){let s=this.active(n.resourceId);if(s&&s.id!==e)this.controlPlane.database.run("UPDATE releases SET status='superseded', updated_at=? WHERE id=?",[o,s.id]),this.recordTransition(s.id,"active","superseded",{message:`Superseded by ${e}.`,operationId:r.operationId})}return this.controlPlane.database.run("UPDATE releases SET status=?, rollback_attempts=rollback_attempts+?, activated_at=CASE WHEN ?='active' THEN ? ELSE activated_at END, failed_at=CASE WHEN ?='failed' THEN ? ELSE failed_at END, updated_at=? WHERE id=?",[t,t==="rolled_back"?1:0,t,o,t,o,o,e]),this.recordTransition(e,n.status,t,r),this.get(e)}approve(e,t){let r=this.get(e);if(!r||r.status!=="awaiting_approval")throw Error("Release is not awaiting approval");let n=this.id(),i=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_approvals (id, release_id, environment_id, decision, actor_id, comment, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[n,e,r.environmentId,t.decision,t.actorId,t.comment?.slice(0,1000)??null,i]),this.transition(e,t.decision==="approved"?"built":"failed",{message:t.decision==="approved"?"Environment gate approved.":"Environment gate rejected."})}approvals(e){return this.controlPlane.database.query("SELECT * FROM release_approvals WHERE release_id=? ORDER BY created_at").all(e).map((t)=>({id:String(t.id),releaseId:String(t.release_id),environmentId:String(t.environment_id),decision:String(t.decision),actorId:String(t.actor_id),comment:_i(t.comment),createdAt:String(t.created_at)}))}promote(e,t){let r=this.get(e);if(!r||!["active","superseded"].includes(r.status))throw Error("Only a tested active/superseded release can be promoted");return this.create({organizationId:r.organizationId,projectId:r.projectId,environmentId:t.targetEnvironmentId,resourceId:t.targetResourceId,artifactId:r.artifactId,kind:r.kind,sourceSha:r.sourceSha,config:t.config,manifest:r.manifest,provenance:r.provenance,strategy:t.strategy??r.strategy,healthGate:t.healthGate??r.healthGate,hooks:r.hooks,drainSeconds:r.drainSeconds,graceSeconds:r.graceSeconds,automaticRollback:r.automaticRollback,promotedFromReleaseId:r.id,actorId:t.actorId,trigger:"promotion",approvalRequired:t.approvalRequired})}compare(e,t){let r=this.get(e),n=this.get(t);if(!r||!n)throw Error("Both releases are required for comparison");return{artifactChanged:r.artifactId!==n.artifactId,sourceChanged:r.sourceSha!==n.sourceSha,configChanged:r.configHash!==n.configHash,manifestChanges:Hb(r.manifest,n.manifest),dataCaveat:n.hooks.migrations==="none"?"No database migration is recorded.":`Database hooks are ${n.hooks.migrations}; release rollback does not roll back data.`}}pin(e,t,r){if(!this.get(e))throw Error("Release was not found");return this.controlPlane.database.run("UPDATE releases SET pinned=?, pin_reason=?, updated_at=? WHERE id=?",[t?1:0,t?r?.slice(0,500)??"operator":null,this.now().toISOString(),e]),this.get(e)}retentionCandidates(e){let t=Math.max(1,Math.min(100,Math.floor(e.keepPerResource??10))),r=new Map;for(let n of this.list()){let i=r.get(n.resourceId)??[];i.push(n),r.set(n.resourceId,i)}return[...r.values()].flatMap((n)=>n.slice(t)).filter((n)=>new Date(n.createdAt)<e.before&&!n.pinned&&!["active","activating","awaiting_approval"].includes(n.status)&&!this.list().some((i)=>i.previousReleaseId===n.id&&["active","activating"].includes(i.status)))}}class nt{controlPlane;releases;queue;constructor(e){this.controlPlane=e;this.releases=new Ld(e),this.queue=new b(e)}enqueueActivation(e,t={}){let r=this.releases.get(e.id);if(!r)throw Error("Release was not found");if(!["built","failed","rolled_back","superseded"].includes(r.status))throw Error(`Release ${r.status} cannot be activated`);let n=t.action??"activate",i=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:t.actorId,kind:`release.${n}`,idempotencyKey:`release:${r.id}:${n}:${r.rollbackAttempts}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:t.targetReleaseId??null},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:r.automaticRollback?2:1,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return this.releases.transition(r.id,"activating",{message:`${n} queued.`,operationId:i.id,trafficPercent:0}),i}completeHealthGate(e,t){let r=this.releases.get(e);if(!r||r.status!=="activating")throw Error("Release is not activating");if(t.healthy)return{release:this.releases.transition(r.id,"active",{message:t.message??"Health gate passed; activation completed.",operationId:t.operationId,trafficPercent:100,health:t.health})};let n=this.releases.transition(r.id,"failed",{message:t.message??"Health gate failed.",operationId:t.operationId,trafficPercent:0,health:t.health}),i=r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!r.automaticRollback||r.rollbackAttempts>=1||!i)return{release:n};let o=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,kind:"release.rollback",idempotencyKey:`release:${r.id}:automatic-rollback`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:i.id,automatic:!0},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return{release:n,rollbackOperation:o}}enqueueRollback(e,t={}){let r=this.releases.get(e.id);if(!r||r.status!=="active")throw Error("Only the active release can be rolled back");let n=t.targetReleaseId?this.releases.get(t.targetReleaseId):r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!n||n.resourceId!==r.resourceId||!["superseded","active"].includes(n.status))throw Error("Rollback requires a preserved prior release for the same resource");return this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:t.actorId,kind:"release.rollback",idempotencyKey:`release:${r.id}:manual-rollback:${n.id}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:n.id,automatic:!1},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation}}function Gb(e){if(e.strategy==="canary")return[5,25,50,100].map((t,r)=>({step:`canary-${t}`,trafficPercent:t,waitSeconds:r===3?e.drainSeconds:e.graceSeconds,requiresHealth:!0}));if(e.strategy==="blue_green")return[{step:"green-health",trafficPercent:0,waitSeconds:e.graceSeconds,requiresHealth:!0},{step:"traffic-switch",trafficPercent:100,waitSeconds:e.drainSeconds,requiresHealth:!0}];if(e.strategy==="rolling")return[{step:"rolling-replacement",trafficPercent:50,waitSeconds:e.graceSeconds,requiresHealth:!0},{step:"rolling-complete",trafficPercent:100,waitSeconds:e.drainSeconds,requiresHealth:!0}];return[{step:"immutable-switch",trafficPercent:100,waitSeconds:e.drainSeconds,requiresHealth:!!e.healthGate}]}async function qp(e,t){if(t.release.artifactId!==t.artifact.id)throw Error("Release activation artifact identity changed");Qa({kind:t.release.kind,hasHealthGate:!!t.release.healthGate,replicas:Number(t.release.manifest?.replicas)||void 0},t.release.strategy);let r=e.capability(t);if(!r.supported)throw Error(`${t.release.strategy} is unavailable in ${e.name}: ${r.explanation}`);return e.activate({...t,transitions:Gb(t.release)})}async function Jp(e,t){if(!t.previous)throw Error("Rollback requires the preserved previous release");return e.rollback({...t,transitions:[{step:"rollback",trafficPercent:0,waitSeconds:t.release.drainSeconds,requiresHealth:!0}]})}var Kb=["release.activate","release.rollback"];function Qb(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function Wp(e){let t=new nt(e.store),r=async(n)=>{let i=Qb(n.operation.input),o=typeof i.releaseId==="string"?i.releaseId:"",s=t.releases.get(o);if(!s)throw Error(`Queued release ${o||"(missing)"} was not found`);if(s.projectId!==n.operation.projectId||s.environmentId!==n.operation.environmentId||s.resourceId!==n.operation.resourceId)throw Error("Queued release does not match the operation scope");let c=t.releases.getArtifact(s.artifactId);if(!c||c.digest!==t.releases.getArtifact(s.artifactId)?.digest)throw Error("Immutable release artifact is unavailable");let l=typeof i.targetReleaseId==="string"&&i.targetReleaseId?i.targetReleaseId:s.previousReleaseId,a=l?t.releases.get(l):void 0;if(a&&(a.resourceId!==s.resourceId||a.artifactId===s.artifactId&&a.id===s.id))throw Error("Rollback target does not match the release resource");let m=await e.resolveDriver(s);n.checkpoint("verify",`Verifying ${c.digest} and ${s.configHash} for ${m.name}.`),n.log(`Artifact ${c.digest}; source ${s.sourceSha??"not recorded"}; config ${s.configHash}.`,{stream:"system"}),n.throwIfCancellationRequested();let E;try{E=n.operation.kind==="release.rollback"?await Jp(m,{release:s,artifact:c,previous:a}):await qp(m,{release:s,artifact:c,previous:a})}catch(D){if(n.operation.kind==="release.activate"&&t.releases.get(s.id)?.status==="activating")t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,message:D instanceof Error?D.message:String(D)});throw D}for(let D of E.transitions)t.releases.progress(s.id,{message:`${n.operation.kind==="release.rollback"?"Rollback":"Activation"} traffic at ${D.trafficPercent}%.`,trafficPercent:D.trafficPercent,health:D.observed,operationId:n.operation.id}),n.log(`Traffic ${D.trafficPercent}%: ${D.healthy?"healthy":"unhealthy"}.`,{stream:D.healthy?"step":"stderr",step:"health"});if(n.checkpoint("health","Evaluating the provider health result."),!E.activated||!E.healthy){if(n.operation.kind==="release.activate"&&t.releases.get(s.id)?.status==="activating")t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,health:{resourceVersions:E.resourceVersions},message:E.error??"Provider health gate failed."});throw Error(E.error??`${m.name} reported an unhealthy release`)}if(n.operation.kind==="release.activate"&&s.healthGate?.name){if(!e.resolveHealthGate)throw t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,message:`Named health gate ${s.healthGate.name} is not available to this worker.`}),Error(`Named health gate ${s.healthGate.name} is unavailable`);n.checkpoint("named-health-gate",`Waiting on ${s.healthGate.name}.`);let D=await e.resolveHealthGate(s.healthGate.name,s);if(n.log(`${s.healthGate.name}: ${D.healthy?"healthy":"unhealthy"}${D.message?` — ${D.message}`:""}.`,{stream:D.healthy?"step":"stderr",step:"health"}),!D.healthy)throw t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,health:D.evidence,message:D.message??`Named health gate ${s.healthGate.name} failed.`}),Error(D.message??`Named health gate ${s.healthGate.name} failed`)}if(n.operation.kind==="release.rollback"){let D=t.releases.get(s.id);if(D.status!=="rolled_back")t.releases.transition(D.id,"rolled_back",{message:`Traffic restored through ${m.name}.`,operationId:n.operation.id,trafficPercent:0,health:{resourceVersions:E.resourceVersions}});if(a&&a.status!=="active"){let O=a.status==="activating"?a:t.releases.transition(a.id,"activating",{message:"Rollback target restoring traffic.",operationId:n.operation.id,trafficPercent:0});t.releases.transition(O.id,"active",{message:"Previous immutable release restored.",operationId:n.operation.id,trafficPercent:100,health:{resourceVersions:E.resourceVersions}})}}else t.completeHealthGate(s.id,{healthy:!0,operationId:n.operation.id,health:{providerVersion:E.providerVersion??null,resourceVersions:E.resourceVersions},message:"Provider activation and health gates completed."});return n.checkpoint("finalize","Persisted the terminal release state."),{releaseId:s.id,artifactDigest:c.digest,provider:m.name,providerVersion:E.providerVersion??null,resourceVersions:E.resourceVersions,status:t.releases.get(s.id).status}};return Object.fromEntries(Kb.map((n)=>[n,r]))}import{createCipheriv as Yb,createDecipheriv as Xb,createHash as Yp,randomBytes as Bd}from"node:crypto";var Xp={github:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitlab:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},bitbucket:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitea:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!1,deployKeys:!0},generic_https:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!1},generic_ssh:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!0}};function Pt(e){return typeof e==="string"&&e?e:void 0}function Ho(e,t){try{return typeof e==="string"?JSON.parse(e):t}catch{return t}}function Ni(e){return JSON.stringify(h(e))}function Wo(e){return Yp("sha256").update(e).digest("hex")}function Hp(e){let t=e.trim().replace(/\/$/,""),r=new URL(t.includes("://")?t:`https://${t}`);if(r.username||r.password||r.search||r.hash)throw Error("Source host cannot contain credentials, a query, or a fragment");if(r.protocol!=="https:"&&!(r.protocol==="http:"&&["localhost","127.0.0.1","::1"].includes(r.hostname)))throw Error("Source host must use HTTPS");return`${r.protocol}//${r.host}${r.pathname.replace(/\/$/,"")}`}function Gp(e){let t=e.trim();if(t.length<2||t.length>80)throw Error("Connection name must contain 2-80 characters");return t}function jd(e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t))throw Error("Repository must use owner/name format");return t}function Kp(e){let t=e.trim()||".";if(t.startsWith("/")||t.split("/").includes("..")||/[\0\r\n]/.test(t))throw Error("Monorepo root must stay inside the repository");return t.replace(/^\.\//,"")||"."}function Ya(e){return[...new Set((e??[]).map((t)=>t.trim()).filter(Boolean))].slice(0,100)}function Zb(e){let t=e.trim();if(/\r|\n/.test(t)||/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(t))throw Error("Clone URL cannot contain credentials or control characters");if(!/^(?:https?:\/\/|ssh:\/\/|git@[A-Za-z0-9.-]+:)/.test(t))throw Error("Clone URL must use HTTPS or SSH");return t}function eS(e){return{id:String(e.id),organizationId:String(e.organization_id),provider:String(e.provider),name:String(e.name),host:String(e.host),owner:Pt(e.owner),authKind:String(e.auth_kind),credentialConfigured:!!e.credential_ciphertext,credentialFingerprint:Pt(e.credential_fingerprint),grantedScopes:Ho(e.granted_scopes,[]),capabilities:Ho(e.capabilities,Xp[String(e.provider)]),status:String(e.status),healthMessage:Pt(e.health_message),lastTestedAt:Pt(e.last_tested_at),lastSyncedAt:Pt(e.last_synced_at),credentialExpiresAt:Pt(e.credential_expires_at),version:Number(e.version),createdByActorId:Pt(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Fd(e){return{id:String(e.id),connectionId:String(e.connection_id),providerRepositoryId:String(e.provider_repository_id),fullName:String(e.full_name),cloneUrl:String(e.clone_url),defaultBranch:String(e.default_branch),visibility:String(e.visibility),archived:Number(e.archived)===1,metadata:Ho(e.metadata,{}),syncedAt:String(e.synced_at)}}function Qp(e){return{id:String(e.id),projectId:String(e.project_id),environmentId:Pt(e.environment_id),resourceId:Pt(e.resource_id),connectionId:String(e.connection_id),repositoryId:Pt(e.repository_id),repositoryFullName:String(e.repository_full_name),defaultBranch:String(e.default_branch),branchRule:Pt(e.branch_rule),tagRule:Pt(e.tag_rule),monorepoRoot:String(e.monorepo_root),includePaths:Ho(e.include_paths,[]),excludePaths:Ho(e.exclude_paths,[]),submodules:Number(e.submodules)===1,cloneDepth:e.clone_depth==null?void 0:Number(e.clone_depth),deployKeyId:Pt(e.deploy_key_id),autoDeploy:Number(e.auto_deploy)===1,pullRequestPreviews:Number(e.pull_request_previews)===1,status:String(e.status),disabledReason:Pt(e.disabled_reason),version:Number(e.version),createdByActorId:Pt(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Ud(e){return{id:String(e.id),connectionId:String(e.connection_id),name:String(e.name),publicKey:String(e.public_key),publicKeyFingerprint:String(e.public_key_fingerprint),host:String(e.host),hostKey:String(e.host_key),hostKeyFingerprint:String(e.host_key_fingerprint),createdByActorId:Pt(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function zd(e){return{id:String(e.id),connectionId:String(e.connection_id),repositoryId:Pt(e.repository_id),repositoryFullName:String(e.repository_full_name),providerWebhookId:Pt(e.provider_webhook_id),events:Ho(e.events,[]),status:String(e.status),healthMessage:Pt(e.health_message),lastDeliveryAt:Pt(e.last_delivery_at),lastReconciledAt:Pt(e.last_reconciled_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Vd(e){return{id:String(e.id),connectionId:String(e.connection_id),webhookId:String(e.webhook_id),providerDeliveryId:String(e.provider_delivery_id),event:String(e.event),action:Pt(e.action),commitSha:Pt(e.commit_sha),signatureStatus:String(e.signature_status),status:String(e.status),payloadSummary:Ho(e.payload_summary,{}),operationId:Pt(e.operation_id),error:Pt(e.error),receivedAt:String(e.received_at),processedAt:Pt(e.processed_at)}}class Kt{controlPlane;key;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.key=t.encryptionKey?Yp("sha256").update(t.encryptionKey).digest():void 0,this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}encrypt(e){if(!this.key)throw Error("Source credential encryption key is not configured");let t=Bd(12),r=Yb("aes-256-gcm",this.key,t),n=Buffer.concat([r.update(e,"utf8"),r.final()]);return`v1.${t.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${n.toString("base64url")}`}decrypt(e){if(!this.key)throw Error("Source credential encryption key is not configured");let[t,r,n,i]=e.split(".");if(t!=="v1"||!r||!n||!i)throw Error("Encrypted source credential is unavailable");let o=Xb("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return o.setAuthTag(Buffer.from(n,"base64url")),Buffer.concat([o.update(Buffer.from(i,"base64url")),o.final()]).toString("utf8")}createConnection(e){if(!this.controlPlane.getOrganization(e.organizationId))throw Error("Source connection organization was not found");let t=this.now(),r=this.idFn(),n=e.credential?JSON.stringify(e.credential):void 0;return this.run(`INSERT INTO source_connections (id, organization_id, provider, name, host, owner, auth_kind, credential_ciphertext, credential_fingerprint, granted_scopes, capabilities, status, credential_expires_at, created_by_actor_id, created_at, updated_at)
3
3
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?)`,[r,e.organizationId,e.provider,Gp(e.name),Hp(e.host),e.owner?.trim()||null,e.authKind??(n?"access_token":"none"),n?this.encrypt(n):null,n?Wo(n).slice(0,16):null,Ni([...new Set(e.grantedScopes??[])].sort()),Ni(Xp[e.provider]),e.credentialExpiresAt??null,e.createdByActorId??null,t,t]),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.createdByActorId,type:"source.connection.created",payload:{connectionId:r,provider:e.provider,host:Hp(e.host),owner:e.owner??null,scopes:e.grantedScopes??[]}}),this.getConnection(r)}getConnection(e){let t=this.controlPlane.database.query("SELECT * FROM source_connections WHERE id = ?").get(e);return t?this.currentConnection(t):void 0}listConnections(e){return this.controlPlane.database.query("SELECT * FROM source_connections WHERE organization_id = ? ORDER BY name").all(e).map((t)=>this.currentConnection(t))}currentConnection(e){let t=eS(e);if(t.status!=="disconnected"&&t.credentialExpiresAt&&new Date(t.credentialExpiresAt).getTime()<=this.nowFn().getTime())return{...t,status:"expired",healthMessage:"Source credential expired; rotate it before deploying."};return t}getCredential(e){let t=this.controlPlane.database.query("SELECT credential_ciphertext FROM source_connections WHERE id = ?").get(e);return t?.credential_ciphertext?JSON.parse(this.decrypt(String(t.credential_ciphertext))):void 0}rotateCredential(e,t,r={}){let n=this.getConnection(e);if(!n||n.status==="disconnected")throw Error("Active source connection was not found");let i=JSON.stringify(t);return this.run("UPDATE source_connections SET credential_ciphertext = ?, credential_fingerprint = ?, credential_expires_at = ?, status = 'pending', health_message = NULL, version = version + 1, updated_at = ? WHERE id = ?",[this.encrypt(i),Wo(i).slice(0,16),r.expiresAt??null,this.now(),e]),this.controlPlane.appendEvent({organizationId:n.organizationId,actorId:r.actorId,type:"source.credential.rotated",payload:{connectionId:e,fingerprint:Wo(i).slice(0,16),expiresAt:r.expiresAt??null}}),this.getConnection(e)}updateHealth(e,t){let r=this.getConnection(e);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active source connection was not found");let n=this.now(),i=t.grantedScopes?[...new Set(t.grantedScopes.map((o)=>o.trim()).filter(Boolean))].sort():void 0;if(this.run("UPDATE source_connections SET status = ?, health_message = ?, granted_scopes = COALESCE(?, granted_scopes), last_tested_at = COALESCE(?, last_tested_at), last_synced_at = COALESCE(?, last_synced_at), version = version + 1, updated_at = ? WHERE id = ?",[t.status,t.message?.slice(0,1000)??null,i?Ni(i):null,t.tested?n:null,t.synced?n:null,n,e]),i&&JSON.stringify(i)!==JSON.stringify([...r.grantedScopes].sort()))this.controlPlane.appendEvent({organizationId:r.organizationId,type:"source.connection.scopes_updated",payload:{connectionId:e,grantedScopes:i}});return this.getConnection(e)}upsertRepository(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status))throw Error("Active source connection was not found");let r=this.now(),n=this.controlPlane.database.query("SELECT id FROM source_repositories WHERE connection_id = ? AND provider_repository_id = ?").get(e.connectionId,e.providerRepositoryId),i=n?String(n.id):this.idFn();return this.run(`INSERT INTO source_repositories (id, connection_id, provider_repository_id, full_name, clone_url, default_branch, visibility, archived, metadata, synced_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
4
4
  ON CONFLICT(connection_id, provider_repository_id) DO UPDATE SET full_name=excluded.full_name, clone_url=excluded.clone_url, default_branch=excluded.default_branch, visibility=excluded.visibility, archived=excluded.archived, metadata=excluded.metadata, synced_at=excluded.synced_at`,[i,e.connectionId,e.providerRepositoryId,jd(e.fullName),Zb(e.cloneUrl),e.defaultBranch.trim()||"main",e.visibility,e.archived?1:0,Ni(e.metadata),r]),Fd(this.controlPlane.database.query("SELECT * FROM source_repositories WHERE id = ?").get(i))}listRepositories(e,t,r=100){let n=t?.trim().toLowerCase();return(n?this.controlPlane.database.query("SELECT * FROM source_repositories WHERE connection_id = ? AND lower(full_name) LIKE ? ORDER BY full_name LIMIT ?").all(e,`%${n}%`,Math.min(500,r)):this.controlPlane.database.query("SELECT * FROM source_repositories WHERE connection_id = ? ORDER BY full_name LIMIT ?").all(e,Math.min(500,r))).map(Fd)}getRepository(e){let t=this.controlPlane.database.query("SELECT * FROM source_repositories WHERE id = ?").get(e);return t?Fd(t):void 0}createDeployKey(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status)||!t.capabilities.deployKeys)throw Error("An active deploy-key capable source connection is required");if(!/^ssh-(?:ed25519|rsa)\s+[A-Za-z0-9+/=]+/.test(e.publicKey.trim()))throw Error("A valid SSH public key is required");if(!/BEGIN (?:OPENSSH|RSA) PRIVATE KEY/.test(e.privateKey))throw Error("A valid SSH private key is required");if(!/^(?:ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp\d+)\s+[A-Za-z0-9+/=]+/.test(e.hostKey.trim()))throw Error("A pinned SSH host key is required");let r=this.idFn(),n=this.now(),i=`sha256:${Wo(e.publicKey.trim())}`,o=`sha256:${Wo(e.hostKey.trim())}`;return this.run("INSERT INTO source_deploy_keys (id, connection_id, name, public_key, public_key_fingerprint, private_key_ciphertext, host, host_key, host_key_fingerprint, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.connectionId,Gp(e.name),e.publicKey.trim(),i,this.encrypt(e.privateKey),e.host.trim().toLowerCase(),e.hostKey.trim(),o,e.actorId??null,n,n]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:e.actorId,type:"source.deploy_key.created",payload:{connectionId:e.connectionId,deployKeyId:r,publicFingerprint:i,hostFingerprint:o}}),Ud(this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE id = ?").get(r))}getDeployKey(e){let t=this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE id = ?").get(e);return t?Ud(t):void 0}listDeployKeys(e){return this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE connection_id = ? ORDER BY name, created_at").all(e).map(Ud)}revokeDeployKey(e,t){let r=this.getDeployKey(e),n=r?this.getConnection(r.connectionId):void 0;if(!r||!n)throw Error("Deploy key was not found");let i=this.listBindings({connectionId:n.id}).filter((s)=>s.deployKeyId===e),o=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_bindings SET deploy_key_id=NULL, status='disabled', auto_deploy=0, disabled_reason='Source deploy key was revoked', version=version+1, updated_at=? WHERE deploy_key_id=?",[o,e]),this.run("DELETE FROM source_deploy_keys WHERE id=?",[e])})(),this.controlPlane.appendEvent({organizationId:n.organizationId,actorId:t,type:"source.deploy_key.revoked",level:"warning",payload:{connectionId:n.id,deployKeyId:e,affectedBindingIds:i.map((s)=>s.id)}}),{affectedBindings:i}}getDeployPrivateKey(e){let t=this.controlPlane.database.query("SELECT private_key_ciphertext FROM source_deploy_keys WHERE id = ?").get(e);if(!t)throw Error("Deploy key was not found");return this.decrypt(String(t.private_key_ciphertext))}createBinding(e){let t=this.getConnection(e.connectionId);if(!t||["disconnected","expired"].includes(t.status))throw Error("Active source connection was not found");if(e.repositoryId&&this.getRepository(e.repositoryId)?.connectionId!==t.id)throw Error("Repository does not belong to this connection");if(e.deployKeyId&&this.getDeployKey(e.deployKeyId)?.connectionId!==t.id)throw Error("Deploy key does not belong to this connection");let r=this.idFn(),n=this.now();return this.run(`INSERT INTO source_bindings (id, project_id, environment_id, resource_id, connection_id, repository_id, repository_full_name, default_branch, branch_rule, tag_rule, monorepo_root, include_paths, exclude_paths, submodules, clone_depth, deploy_key_id, auto_deploy, pull_request_previews, status, created_by_actor_id, created_at, updated_at)
@@ -30,7 +30,7 @@ data: ${JSON.stringify(et)}
30
30
  default_role = ?, enabled = ?, enforce_sso = ?, updated_at = ? WHERE id = ?`,[t,r,n,i,e.clientSecret?this.encrypt(e.clientSecret):null,JSON.stringify(o),JSON.stringify(s),e.defaultRole??c.defaultRole,e.enabled??c.enabled?1:0,e.enforceSso??c.enforceSso?1:0,l,c.id]),this.getOidcProvider(c.id)}if(!e.clientSecret)throw Error("OIDC client secret is required for a new provider");let a=e.id??this.idFn();return this.run(`INSERT INTO auth_oidc_providers (id, organization_id, slug, name, issuer, client_id,
31
31
  client_secret_ciphertext, scopes, allowed_domains, default_role, enabled, enforce_sso, created_at, updated_at)
32
32
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[a,e.organizationId,t,r,n,i,this.encrypt(e.clientSecret),JSON.stringify(o),JSON.stringify(s),e.defaultRole??"viewer",e.enabled===!1?0:1,e.enforceSso?1:0,l,l]),this.getOidcProvider(a)}getOidcProvider(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE id = ?").get(e);return t?rc(t):void 0}getOidcProviderBySlug(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE slug = ? COLLATE NOCASE").get(e.trim());return t?rc(t):void 0}listOidcProviders(e,t={}){return(e?this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE organization_id = ? ORDER BY name COLLATE NOCASE").all(e):this.controlPlane.database.query("SELECT * FROM auth_oidc_providers ORDER BY name COLLATE NOCASE").all()).map(rc).filter((n)=>t.includeDisabled||n.enabled)}setOidcProviderEnabled(e,t){let r=this.now();if(this.controlPlane.database.run("UPDATE auth_oidc_providers SET enabled = ?, enforce_sso = CASE WHEN ? = 0 THEN 0 ELSE enforce_sso END, updated_at = ? WHERE id = ?",[t?1:0,t?1:0,r,e]).changes!==1)throw Error("OIDC provider was not found");if(!t)this.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE provider_id = ? AND consumed_at IS NULL",[r,e]);return this.getOidcProvider(e)}getOidcProviderCredentials(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE id = ?").get(e);if(!t||typeof t.client_secret_ciphertext!=="string")throw Error("OIDC provider credentials are unavailable");return{provider:rc(t),clientSecret:this.decrypt(t.client_secret_ciphertext)}}beginOidcTransaction(e,t,r){if(!this.getOidcProvider(e)?.enabled)throw Error("OIDC provider is unavailable");let i=this.idFn(),o=Wi(32).toString("base64url"),s=Wi(32).toString("base64url"),c=Wi(64).toString("base64url"),l=this.now(),a=new Date(this.nowFn().getTime()+Ig).toISOString();return this.run(`INSERT INTO auth_oidc_transactions (id, provider_id, state_hash, nonce_ciphertext, verifier_ciphertext,
33
- redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[i,e,mi(o),this.encrypt(s),this.encrypt(c),t,r,a,l]),{transaction:this.getOidcTransaction(i),state:o,nonce:s,verifier:c}}getOidcTransaction(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE id = ?").get(e);return t?yg(t,this.now()):void 0}consumeOidcTransaction(e,t){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE provider_id = ? AND state_hash = ?").get(e,mi(t));if(!r)throw Error("OIDC transaction is invalid");let n=yg(r,this.now());if(n.state!=="pending")throw Error(`OIDC transaction is ${n.state}`);if(this.controlPlane.database.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),n.id,this.now()]).changes!==1)throw Error("OIDC transaction is no longer available");return{transaction:this.getOidcTransaction(n.id),nonce:this.decrypt(String(r.nonce_ciphertext)),verifier:this.decrypt(String(r.verifier_ciphertext))}})}getOidcSubject(e,t){let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_subjects WHERE provider_id = ? AND subject = ?").get(e,t);return r?PS(r):void 0}linkOidcSubject(e,t,r,n){let i=this.getOidcProvider(e),o=this.getIdentity(t);if(!i||!o)throw Error("OIDC provider or identity was not found");let s=Xd(n);if(!r.trim()||r.length>512)throw Error("OIDC subject is invalid");let c=this.getOidcSubject(e,r);if(c&&c.identityId!==t)throw Error("OIDC subject is already linked to another identity");let l=this.now();if(c)return this.run("UPDATE auth_oidc_subjects SET email = ?, last_login_at = ? WHERE id = ?",[s,l,c.id]),this.getOidcSubject(e,r);let a=this.idFn();return this.run("INSERT INTO auth_oidc_subjects (id, provider_id, identity_id, subject, email, linked_at, last_login_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[a,e,t,r,s,l,l]),this.getOidcSubject(e,r)}purgeExpired(){let e=this.now(),t=this.controlPlane.database.run("DELETE FROM auth_action_tokens WHERE expires_at < ? OR consumed_at IS NOT NULL",[e]).changes,r=this.controlPlane.database.run("DELETE FROM auth_sessions WHERE revoked_at IS NOT NULL OR idle_expires_at < ? OR absolute_expires_at < ?",[e,e]).changes;return this.controlPlane.database.run("DELETE FROM auth_mfa_challenges WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),this.controlPlane.database.run("DELETE FROM auth_oidc_transactions WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),{actionTokens:t,sessions:r}}}async function Sa(e,t){let r=e.notifications?.email?.from;if(!r)return!1;try{let{EmailClient:n}=await import("./chunk-xvn07b0e.js");return await new n({region:e.project.region,defaultFrom:r}).send(t),!0}catch{return!1}}import{randomBytes as xS}from"node:crypto";import{chmodSync as DS,existsSync as OS,mkdirSync as _S,readFileSync as NS,writeFileSync as $S}from"node:fs";import{dirname as MS}from"node:path";function k(e){let t=process.env.TS_CLOUD_AUTH_ENCRYPTION_KEY?.trim();if(t)return t;let r=A(e,"auth-encryption-key");try{if(OS(r)){let i=NS(r,"utf8").trim();if(i)return i}}catch{}let n=xS(32).toString("base64url");try{_S(MS(r),{recursive:!0,mode:448}),$S(r,`${n}
33
+ redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[i,e,mi(o),this.encrypt(s),this.encrypt(c),t,r,a,l]),{transaction:this.getOidcTransaction(i),state:o,nonce:s,verifier:c}}getOidcTransaction(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE id = ?").get(e);return t?yg(t,this.now()):void 0}consumeOidcTransaction(e,t){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE provider_id = ? AND state_hash = ?").get(e,mi(t));if(!r)throw Error("OIDC transaction is invalid");let n=yg(r,this.now());if(n.state!=="pending")throw Error(`OIDC transaction is ${n.state}`);if(this.controlPlane.database.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),n.id,this.now()]).changes!==1)throw Error("OIDC transaction is no longer available");return{transaction:this.getOidcTransaction(n.id),nonce:this.decrypt(String(r.nonce_ciphertext)),verifier:this.decrypt(String(r.verifier_ciphertext))}})}getOidcSubject(e,t){let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_subjects WHERE provider_id = ? AND subject = ?").get(e,t);return r?PS(r):void 0}linkOidcSubject(e,t,r,n){let i=this.getOidcProvider(e),o=this.getIdentity(t);if(!i||!o)throw Error("OIDC provider or identity was not found");let s=Xd(n);if(!r.trim()||r.length>512)throw Error("OIDC subject is invalid");let c=this.getOidcSubject(e,r);if(c&&c.identityId!==t)throw Error("OIDC subject is already linked to another identity");let l=this.now();if(c)return this.run("UPDATE auth_oidc_subjects SET email = ?, last_login_at = ? WHERE id = ?",[s,l,c.id]),this.getOidcSubject(e,r);let a=this.idFn();return this.run("INSERT INTO auth_oidc_subjects (id, provider_id, identity_id, subject, email, linked_at, last_login_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[a,e,t,r,s,l,l]),this.getOidcSubject(e,r)}purgeExpired(){let e=this.now(),t=this.controlPlane.database.run("DELETE FROM auth_action_tokens WHERE expires_at < ? OR consumed_at IS NOT NULL",[e]).changes,r=this.controlPlane.database.run("DELETE FROM auth_sessions WHERE revoked_at IS NOT NULL OR idle_expires_at < ? OR absolute_expires_at < ?",[e,e]).changes;return this.controlPlane.database.run("DELETE FROM auth_mfa_challenges WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),this.controlPlane.database.run("DELETE FROM auth_oidc_transactions WHERE consumed_at IS NOT NULL OR expires_at < ?",[e]),{actionTokens:t,sessions:r}}}async function Sa(e,t){let r=e.notifications?.email?.from;if(!r)return!1;try{let{EmailClient:n}=await import("./chunk-v6mysz8x.js");return await new n({region:e.project.region,defaultFrom:r}).send(t),!0}catch{return!1}}import{randomBytes as xS}from"node:crypto";import{chmodSync as DS,existsSync as OS,mkdirSync as _S,readFileSync as NS,writeFileSync as $S}from"node:fs";import{dirname as MS}from"node:path";function k(e){let t=process.env.TS_CLOUD_AUTH_ENCRYPTION_KEY?.trim();if(t)return t;let r=A(e,"auth-encryption-key");try{if(OS(r)){let i=NS(r,"utf8").trim();if(i)return i}}catch{}let n=xS(32).toString("base64url");try{_S(MS(r),{recursive:!0,mode:448}),$S(r,`${n}
34
34
  `,{mode:384}),DS(r,384)}catch{}return n}import{constants as LS,createHash as tu,createPublicKey as BS,createVerify as jS,timingSafeEqual as FS}from"node:crypto";var Tg=new Set(["RS256","PS256","ES256"]),Eg=60;function nc(e,t){let r=new URL(e),n=["127.0.0.1","::1","localhost"].includes(r.hostname);if(r.protocol!=="https:"&&!(r.protocol==="http:"&&n))throw Error(`${t} must use HTTPS`);if(r.username||r.password||r.hash)throw Error(`${t} contains unsupported URL components`);return r}function ru(e,t){if(!e||typeof e!=="object"||Array.isArray(e))throw Error(`${t} is invalid`);return e}async function nu(e,t){if(!e.ok)throw Error(`${t} failed with HTTP ${e.status}`);if(!(e.headers.get("content-type")??"").toLowerCase().includes("application/json"))throw Error(`${t} returned an unsupported content type`);if(Number(e.headers.get("content-length")??0)>1048576)throw Error(`${t} response is too large`);let i=await e.text();if(i.length>1048576)throw Error(`${t} response is too large`);try{return ru(JSON.parse(i),t)}catch(o){if(o instanceof Error&&o.message===`${t} is invalid`)throw o;throw Error(`${t} returned invalid JSON`)}}function US(e,t){let r=tu("sha256").update(e).digest(),n=tu("sha256").update(t).digest();return FS(r,n)}function Ag(e){if(!e)return"/";let t=e.trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("\\")||/[\r\n]/.test(t))return"/";try{let r=new URL(t,"https://local.invalid");return r.origin==="https://local.invalid"?`${r.pathname}${r.search}${r.hash}`:"/"}catch{return"/"}}async function ln(e,t=fetch){let r=nc(e.issuer,"OIDC issuer"),n=new URL(`${r.pathname.replace(/\/$/,"")}/.well-known/openid-configuration`,r.origin),i=await nu(await t(n,{headers:{accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC discovery");if(i.issuer!==e.issuer)throw Error("OIDC discovery issuer does not match the configured issuer");for(let s of["authorization_endpoint","token_endpoint","jwks_uri"]){if(typeof i[s]!=="string")throw Error(`OIDC discovery is missing ${s}`);nc(i[s],`OIDC ${s}`)}if(Array.isArray(i.response_types_supported)&&!i.response_types_supported.includes("code"))throw Error("OIDC provider does not support authorization code flow");if(Array.isArray(i.code_challenge_methods_supported)&&!i.code_challenge_methods_supported.includes("S256"))throw Error("OIDC provider does not support PKCE S256");let o=Array.isArray(i.id_token_signing_alg_values_supported)?i.id_token_signing_alg_values_supported.filter((s)=>typeof s==="string"):[];if(o.length>0&&!o.some((s)=>Tg.has(s)))throw Error("OIDC provider does not offer a supported ID-token signing algorithm");return i}async function iu(e,t,r,n,i=fetch){let o=e.getOidcProviderBySlug(t);if(!o?.enabled)throw Error("OIDC provider is unavailable");let s=nc(r,"Application origin").origin,c=await ln(o,i),l=`${s}/auth/oidc/${encodeURIComponent(o.slug)}/callback`,a=e.beginOidcTransaction(o.id,l,Ag(n)),m=new URL(c.authorization_endpoint);return m.searchParams.set("response_type","code"),m.searchParams.set("client_id",o.clientId),m.searchParams.set("redirect_uri",l),m.searchParams.set("scope",o.scopes.join(" ")),m.searchParams.set("state",a.state),m.searchParams.set("nonce",a.nonce),m.searchParams.set("code_challenge",tu("sha256").update(a.verifier).digest("base64url")),m.searchParams.set("code_challenge_method","S256"),{authorizationUrl:m.href,expiresAt:a.transaction.expiresAt}}function zS(e){if(e.length>32768)throw Error("OIDC ID token is too large");let t=e.split(".");if(t.length!==3||t.some((r)=>!r))throw Error("OIDC ID token is malformed");try{return{header:ru(JSON.parse(Buffer.from(t[0],"base64url").toString("utf8")),"OIDC ID-token header"),claims:ru(JSON.parse(Buffer.from(t[1],"base64url").toString("utf8")),"OIDC ID-token claims"),signingInput:`${t[0]}.${t[1]}`,signature:Buffer.from(t[2],"base64url")}}catch(r){if(r instanceof Error&&r.message.startsWith("OIDC"))throw r;throw Error("OIDC ID token is malformed")}}async function VS(e,t,r){let n=zS(e),i=typeof n.header.alg==="string"?n.header.alg:"",o=typeof n.header.kid==="string"?n.header.kid:"";if(!Tg.has(i)||!o)throw Error("OIDC ID token uses an unsupported signing key");if(t.id_token_signing_alg_values_supported&&!t.id_token_signing_alg_values_supported.includes(i))throw Error("OIDC ID-token algorithm was not advertised by the provider");let s=await nu(await r(t.jwks_uri,{headers:{accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC signing-key request");if(!Array.isArray(s.keys))throw Error("OIDC signing-key response is invalid");let c=s.keys.find((E)=>{if(!E||typeof E!=="object"||Array.isArray(E))return!1;let D=E;return D.kid===o&&(!D.alg||D.alg===i)&&(!D.use||D.use==="sig")});if(!c)throw Error("OIDC ID-token signing key was not found");let l=BS({key:c,format:"jwk"}),a=jS("SHA256").update(n.signingInput).end();if(!(i==="PS256"?a.verify({key:l,padding:LS.RSA_PKCS1_PSS_PADDING,saltLength:32},n.signature):i==="ES256"?a.verify({key:l,dsaEncoding:"ieee-p1363"},n.signature):a.verify(l,n.signature)))throw Error("OIDC ID-token signature is invalid");return n.claims}function qS(e,t,r,n){if(e.iss!==t.issuer)throw Error("OIDC ID-token issuer is invalid");let i=typeof e.aud==="string"?[e.aud]:Array.isArray(e.aud)?e.aud.filter((l)=>typeof l==="string"):[];if(!i.includes(t.clientId))throw Error("OIDC ID-token audience is invalid");if((i.length>1||e.azp!==void 0)&&e.azp!==t.clientId)throw Error("OIDC ID-token authorized party is invalid");let o=Math.floor(n.getTime()/1000);if(typeof e.exp!=="number"||e.exp<o-Eg)throw Error("OIDC ID token is expired");if(typeof e.iat!=="number"||e.iat>o+Eg)throw Error("OIDC ID-token issued-at time is invalid");if(typeof e.nonce!=="string"||!US(e.nonce,r))throw Error("OIDC ID-token nonce is invalid");if(typeof e.sub!=="string"||!e.sub||e.sub.length>512)throw Error("OIDC ID-token subject is invalid");if(e.email_verified!==!0||typeof e.email!=="string")throw Error("OIDC provider did not return a verified email address");let s=e.email.trim().toLowerCase();if(s.length>254||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s))throw Error("OIDC provider returned an invalid email address");let c=s.split("@")[1];if(!c||!t.allowedDomains.includes(c))throw Error("OIDC email domain is not allowed for this organization");return{provider:t,subject:e.sub,email:s,name:typeof e.name==="string"?e.name.slice(0,120):void 0,claims:e}}async function ou(e,t,r=fetch){let n=e.getOidcProviderBySlug(t.providerSlug);if(!n?.enabled)throw Error("OIDC provider is unavailable");if(!t.state||t.state.length>512||!t.code||t.code.length>4096)throw Error("OIDC callback is incomplete");let i=nc(t.origin,"Application origin").origin,o=e.consumeOidcTransaction(n.id,t.state),s=`${i}/auth/oidc/${encodeURIComponent(n.slug)}/callback`;if(o.transaction.redirectUri!==s)throw Error("OIDC callback redirect URI does not match the original request");let{clientSecret:c}=e.getOidcProviderCredentials(n.id),l=await ln(n,r),a=new URLSearchParams({grant_type:"authorization_code",code:t.code,redirect_uri:o.transaction.redirectUri,code_verifier:o.verifier}),m={accept:"application/json","content-type":"application/x-www-form-urlencoded"},E=l.token_endpoint_auth_methods_supported??["client_secret_basic"];if(E.includes("client_secret_basic")){let q=(Y)=>new URLSearchParams({value:Y}).toString().slice(6),G=`${q(n.clientId)}:${q(c)}`;m.authorization=`Basic ${Buffer.from(G).toString("base64")}`}else if(E.includes("client_secret_post"))a.set("client_id",n.clientId),a.set("client_secret",c);else throw Error("OIDC provider does not support a configured client authentication method");let D=await nu(await r(l.token_endpoint,{method:"POST",headers:m,body:a,redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC token exchange");if(typeof D.id_token!=="string")throw Error("OIDC token response did not include an ID token");let O=await VS(D.id_token,l,r);return{identity:qS(O,n,o.nonce,t.now??new Date),returnPath:o.transaction.returnPath}}import{createHash as JS,randomBytes as WS}from"node:crypto";var Rg=new Set(ie),Pg=7776000000,xg=31536000000,Dg=86400000;function Hi(e){return typeof e==="string"?e:void 0}function kg(e){return JS("sha256").update(e).digest("hex")}function HS(e){try{let t=JSON.parse(String(e));return Array.isArray(t)?t.filter((r)=>typeof r==="string"&&Rg.has(r)):[]}catch{return[]}}function GS(e){let t=String(e.scope_type);return t==="organization"?{type:t}:{type:t,id:String(e.scope_id)}}function su(e){let t=Hi(e.disabled_at);return{id:String(e.id),organizationId:String(e.organization_id),actorId:String(e.actor_id),slug:String(e.slug),name:String(e.name),description:Hi(e.description),createdByActorId:Hi(e.created_by_actor_id),disabledAt:t,createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:t?"disabled":"active"}}function au(e,t){let r=Hi(e.revoked_at),n=String(e.expires_at);return{id:String(e.id),serviceAccountId:String(e.service_account_id),name:String(e.name),prefix:String(e.token_prefix),capabilities:HS(e.capabilities),scope:GS(e),expiresAt:n,lastUsedAt:Hi(e.last_used_at),lastNetworkHint:Hi(e.last_network_hint),revokedAt:r,rotatedFromTokenId:Hi(e.rotated_from_token_id),createdByActorId:Hi(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:r?"revoked":n<=t?"expired":"active"}}function KS(e){let t={};try{t=JSON.parse(String(e.response_body))}catch{}return{id:String(e.id),tokenId:String(e.token_id),key:String(e.idempotency_key),requestHash:String(e.request_hash),operationId:Hi(e.operation_id),responseStatus:Number(e.response_status),responseBody:t,expiresAt:String(e.expires_at),createdAt:String(e.created_at)}}class Ue{controlPlane;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}createServiceAccount(e){if(!this.controlPlane.getOrganization(e.organizationId))throw Error("Service-account organization was not found");let t=e.slug.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(t))throw Error("Service-account slug must be 2-48 lowercase letters, numbers or dashes");let r=e.name.trim().slice(0,100);if(!r)throw Error("Service-account name is required");let n=this.controlPlane.createActor({kind:"service_account",externalId:`service-account:${e.organizationId}:${t}`,displayName:r,metadata:{source:"api",serviceAccountSlug:t}}),i=this.idFn(),o=this.now();this.run(`INSERT INTO service_accounts (id, organization_id, actor_id, slug, name, description, created_by_actor_id, created_at, updated_at)
35
35
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[i,e.organizationId,n.id,t,r,e.description?.trim().slice(0,500)||null,e.createdByActorId??null,o,o]);let s=this.controlPlane.createMembership({organizationId:e.organizationId,actorId:n.id,roleTemplate:e.roleTemplate,scope:e.scope,source:"manual",performedByActorId:e.createdByActorId}),c=e.scope??{type:"organization"};return this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.createdByActorId,type:"api.service_account.created",payload:{serviceAccountId:i,roleTemplate:e.roleTemplate,scope:{type:c.type,id:c.id??null}}}),{serviceAccount:this.getServiceAccount(i),membership:s}}getServiceAccount(e){let t=this.controlPlane.database.query("SELECT * FROM service_accounts WHERE id = ?").get(e);return t?su(t):void 0}getServiceAccountBySlug(e,t){let r=this.controlPlane.database.query("SELECT * FROM service_accounts WHERE organization_id = ? AND slug = ? COLLATE NOCASE").get(e,t.trim());return r?su(r):void 0}listServiceAccounts(e,t={}){return this.controlPlane.database.query("SELECT * FROM service_accounts WHERE organization_id = ? ORDER BY name COLLATE NOCASE").all(e).map(su).filter((r)=>t.includeDisabled||r.state==="active")}disableServiceAccount(e,t){let r=this.getServiceAccount(e);if(!r)throw Error("Service account was not found");let n=this.now();return this.controlPlane.transaction(()=>{this.run("UPDATE service_accounts SET disabled_at = ?, updated_at = ? WHERE id = ?",[n,n,e]),this.run("UPDATE api_tokens SET revoked_at = ?, updated_at = ? WHERE service_account_id = ? AND revoked_at IS NULL",[n,n,e]);let i=this.controlPlane.getMembershipForActor(r.organizationId,r.actorId);if(i?.status==="active")this.controlPlane.revokeMembership(i.id)}),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"api.service_account.disabled",payload:{serviceAccountId:e}}),this.getServiceAccount(e)}createToken(e){let t=this.getServiceAccount(e.serviceAccountId);if(!t||t.state!=="active")throw Error("Service account is unavailable");let r=this.controlPlane.getMembershipForActor(t.organizationId,t.actorId);if(!r||r.status!=="active")throw Error("Service-account membership is unavailable");let n=[...new Set(e.capabilities)];if(n.length===0||n.some((D)=>!Rg.has(D)))throw Error("API token requires valid explicit capabilities");let i=e.scope??r.scope,o=this.controlPlane.resolveAuthorizationTarget(t.organizationId,i);if(!o)throw Error("API token scope was not found in this organization");for(let D of n)if(!Z({membership:r,grants:this.controlPlane.listGrants(r.id),capability:D,target:o}).allowed)throw Error(`Service-account membership does not grant ${D} at the token scope`);let s=e.expiresAt?new Date(e.expiresAt):new Date(this.nowFn().getTime()+Pg);if(!Number.isFinite(s.getTime())||s.getTime()<=this.nowFn().getTime()+60000||s.getTime()>this.nowFn().getTime()+xg)throw Error("API token expiry must be between one minute and one year from now");let c=this.idFn(),l=WS(32).toString("base64url"),a=`tsc_v1.${c}.${l}`,m=`tsc_v1.${c.slice(0,8)}`,E=this.now();return this.run(`INSERT INTO api_tokens (id, service_account_id, name, token_hash, token_prefix, capabilities, scope_type, scope_id,
36
36
  expires_at, rotated_from_token_id, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[c,t.id,e.name.trim().slice(0,100)||"API token",kg(a),m,JSON.stringify(n.sort()),i.type,i.type==="organization"?null:i.id??null,s.toISOString(),e.rotatedFromTokenId??null,e.createdByActorId??null,E,E]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:e.createdByActorId,type:"api.token.created",payload:{serviceAccountId:t.id,tokenId:c,prefix:m,capabilities:n,scope:{type:i.type,id:i.id??null},expiresAt:s.toISOString(),rotatedFromTokenId:e.rotatedFromTokenId??null}}),{token:this.getToken(c),secret:a}}getToken(e){let t=this.controlPlane.database.query("SELECT * FROM api_tokens WHERE id = ?").get(e);return t?au(t,this.now()):void 0}listTokens(e,t={}){return this.controlPlane.database.query("SELECT * FROM api_tokens WHERE service_account_id = ? ORDER BY created_at DESC").all(e).map((r)=>au(r,this.now())).filter((r)=>t.includeInactive||r.state==="active")}verifyToken(e,t){let r=/^tsc_v1\.([^.]+)\.[A-Za-z0-9_-]{40,}$/.exec(e);if(!r)return;let n=this.controlPlane.database.query("SELECT * FROM api_tokens WHERE id = ? AND token_hash = ?").get(r[1],kg(e));if(!n)return;let i=au(n,this.now()),o=this.getServiceAccount(i.serviceAccountId);if(!o||o.state!=="active"||i.state!=="active")return;let s=this.controlPlane.getActor(o.actorId),c=this.controlPlane.getMembershipForActor(o.organizationId,o.actorId);if(!s||s.disabledAt||!c||c.status!=="active")return;let l=this.now(),a=!i.lastUsedAt||this.nowFn().getTime()-new Date(i.lastUsedAt).getTime()>=3600000;if(this.run("UPDATE api_tokens SET last_used_at = ?, last_network_hint = ?, updated_at = ? WHERE id = ?",[l,t?.slice(0,128)??null,l,i.id]),a)this.controlPlane.appendEvent({organizationId:o.organizationId,actorId:s.id,type:"api.token.used",payload:{serviceAccountId:o.id,tokenId:i.id,prefix:i.prefix}});return{serviceAccount:o,token:this.getToken(i.id),actor:s,membership:c}}rotateToken(e,t){let r=this.getToken(e);if(!r||r.state!=="active")throw Error("Active API token was not found");let n=this.createToken({serviceAccountId:r.serviceAccountId,name:`${r.name} (rotated)`,capabilities:r.capabilities,scope:r.scope,expiresAt:r.expiresAt,createdByActorId:t,rotatedFromTokenId:r.id}),i=this.getServiceAccount(r.serviceAccountId);return this.controlPlane.appendEvent({organizationId:i?.organizationId,actorId:t,type:"api.token.rotated",payload:{serviceAccountId:r.serviceAccountId,previousTokenId:r.id,tokenId:n.token.id}}),n}revokeToken(e,t){let r=this.getToken(e);if(!r)throw Error("API token was not found");if(r.state==="active"){let n=this.now();this.run("UPDATE api_tokens SET revoked_at = ?, updated_at = ? WHERE id = ?",[n,n,e]);let i=this.getServiceAccount(r.serviceAccountId);this.controlPlane.appendEvent({organizationId:i?.organizationId,actorId:t,type:"api.token.revoked",payload:{serviceAccountId:r.serviceAccountId,tokenId:e}})}return this.getToken(e)}getIdempotency(e,t){let r=this.controlPlane.database.query("SELECT * FROM api_idempotency_records WHERE token_id = ? AND idempotency_key = ? AND expires_at > ?").get(e,t,this.now());return r?KS(r):void 0}saveIdempotency(e){if(!/^[A-Za-z0-9._:-]{8,128}$/.test(e.key))throw Error("Idempotency-Key must contain 8-128 safe characters");let t=this.getIdempotency(e.tokenId,e.key);if(t){if(t.requestHash!==e.requestHash)throw Error("Idempotency-Key was already used for a different request");return t}let r=this.idFn(),n=this.now(),i=new Date(this.nowFn().getTime()+Dg).toISOString();return this.run(`INSERT INTO api_idempotency_records (id, token_id, idempotency_key, request_hash, operation_id, response_status, response_body, expires_at, created_at)
@@ -427,7 +427,7 @@ export type ConfigOf = Config
427
427
  </body>
428
428
  </html>`}var tT=["restart","reload","start","stop","enable","disable"],ay=65536;function ra(e){return e.length<=ay?e:`${e.slice(0,ay)}
429
429
 
430
- [output truncated]`}function rT(e){return/^[A-Za-z0-9_.@:-]+$/.test(e)}function Vl(e){return/^[A-Za-z0-9_-]+$/.test(e)}function nT(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Dr(e,t){let r=[],n=t.servicesDetail??t.services??[];for(let s of n){let c=String(s?.name??"");if(!c||!rT(c))continue;for(let l of tT)r.push({id:`${l}:${c}`,label:`${nT(l)} ${c}`,group:"service",target:c,mutates:!0,confirm:c,danger:l==="stop"||l==="disable"})}for(let[s,c]of Object.entries(e.sites??{})){if(!c||!Vl(s))continue;let l=P(c);if(l==="server-app"||l==="server-php")r.push({id:`rollback:${s}`,label:`Rollback ${s}`,group:"deploy",target:s,mutates:!0,confirm:s,danger:!0})}let i=new Set;for(let s of t.workers??[]){let c=String(s?.name??"").split(":")[0];if(c&&Vl(c))i.add(c)}for(let s of i)r.push({id:`worker:restart:${s}`,label:`Restart workers (${s})`,group:"worker",target:s,mutates:!0,confirm:s});for(let[s,c]of Object.entries(e.sites??{})){if(!c||!Vl(s))continue;if(c.scheduler||c.schedule){let l=Gr(c)==="laravel";r.push({id:`scheduler:run:${s}`,label:`${l?"Run":"Restart"} scheduler (${s})`,group:"scheduler",target:s,mutates:!0,confirm:s})}}if(e.infrastructure?.compute?.backups?.enabled){if(r.push({id:"backup:run",label:"Run backup now",group:"backup",target:"backup",mutates:!0,confirm:"backup"}),C(e))r.push({id:"backup:restore",label:"Restore latest DB backup",group:"backup",target:"database",mutates:!0,confirm:"restore",danger:!0})}return r}function _n(e,t,r){return Dr(t,r).find((n)=>n.id===e)}function iT(e,t){let r=e==="enable"||e==="disable"?`systemctl is-enabled ${t} 2>/dev/null || true`:`systemctl is-active ${t} 2>/dev/null || true`;return["set -o pipefail",`systemctl ${e} ${t}`,r]}function oT(){return`eval "$(cd ${M} && pantry env 2>/dev/null)"`}function dy(e,t,r){let n=`${W(e,t)}/current`;return["set -uo pipefail",`[ -d ${n} ] || { echo "site ${t} has no current release" >&2; exit 1; }`,`cd ${n} && ${oT()} && php artisan ${r}`]}function sT(e,t,r){if(e==="laravel")return dy(t,r,"queue:restart");let n=`${t}-${r}-queue-*.service`;return["set -uo pipefail",`units=$(systemctl list-units --type=service --all --no-legend '${n}' 2>/dev/null | awk '{print $1}')`,`[ -n "$units" ] || { echo "no queue-worker units found for ${r} (${n})" >&2; exit 1; }`,"systemctl restart $units",`systemctl --no-legend --type=service list-units '${n}' 2>/dev/null || true`]}function aT(e,t,r){if(e==="laravel")return dy(t,r,"schedule:run");let n=`${t}-${r}-scheduler.service`;return["set -uo pipefail",`systemctl restart ${n}`,`systemctl is-active ${n} 2>/dev/null || true`]}function cT(){return["set -uo pipefail",`[ -x ${Kr} ] || { echo "scheduled backups are not provisioned on this server" >&2; exit 1; }`,Kr]}function cy(e,t,r){return{operation:e,command:t,ok:r.success,stdout:ra(r.perInstance?.[0]?.output??""),stderr:ra(r.perInstance?.[0]?.error??r.error??"")}}async function kr(e,t,r,n={}){let i=e.project.slug,o;try{o=x({config:e})}catch(E){return{operation:r.id,ok:!1,error:`Could not initialize the cloud driver: ${E?.message??E}`}}let s={driver:o,slug:i,environment:t,role:"app"};if(r.group==="deploy"){let E=n.to&&/^[A-Za-z0-9._-]+$/.test(n.to)?n.to:void 0,D=await Xo(s,{siteName:r.target,to:E});return cy(r.id,`rollback ${r.target}${E?` → ${E}`:""}`,D)}if(r.id==="backup:restore"){let E=await Qo(s,{database:C(e)});return cy(r.id,"db restore",E)}let c=await o.findComputeTargets({slug:i,environment:t,role:"app"});if(!c.length)return{operation:r.id,ok:!1,error:"No app server target was found for this environment."};let l,a;if(r.group==="service"){let[E,...D]=r.id.split(":");l=iT(E,D.join(":")),a=`systemctl ${E} ${r.target}`}else if(r.group==="worker"){let E=Gr(e.sites?.[r.target]??{});l=sT(E,i,r.target),a=E==="laravel"?`queue:restart (${r.target})`:`restart queue units (${r.target})`}else if(r.group==="scheduler"){let E=Gr(e.sites?.[r.target]??{});l=aT(E,i,r.target),a=E==="laravel"?`schedule:run (${r.target})`:`restart scheduler (${r.target})`}else if(r.id==="backup:run")l=cT(),a="ts-cloud backup";else return{operation:r.id,ok:!1,error:"Unknown operation."};let m=await o.runRemoteDeploy({targets:[c[0]],commands:l,comment:`ts-cloud dashboard:${r.id}`,tags:{Project:i,Environment:t,Role:"app"}});return{operation:r.id,command:a,ok:m.success,stdout:ra(m.perInstance?.[0]?.output??""),stderr:ra(m.perInstance?.[0]?.error??m.error??"")}}async function Qt(e,t,r){let n=r.trim();if(!n)return{operation:"command",ok:!1,error:"A command is required."};let i;try{i=x({config:e})}catch(l){return{operation:"command",ok:!1,error:`Could not initialize the cloud driver: ${l?.message??l}`}}let o=e.project.slug,s=await i.findComputeTargets({slug:o,environment:t,role:"app"});if(!s.length)return{operation:"command",ok:!1,error:"No app server target was found for this environment."};let c=await i.runRemoteDeploy({targets:[s[0]],commands:["set -o pipefail",n],comment:"ts-cloud dashboard:command",tags:{Project:o,Environment:t,Role:"app"}});return{operation:"command",command:n,ok:c.success,stdout:ra(c.perInstance?.[0]?.output??""),stderr:ra(c.perInstance?.[0]?.error??c.error??"")}}var dT=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"spend.overview",path:"/operations/spend",label:"Spend & budgets",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"infrastructure.topology",path:"/infrastructure/topology",label:"Infrastructure map",group:"infrastructure",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/topology"]},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],uT=new Map(dT.flatMap((e)=>(e.legacyPaths??[]).map((t)=>[t,e.path])));function uy(e){return uT.get(e)}function lT(e,t){return[`${e}-${t}`,`${e}-${t}-queues`,`${e}-${t}-daemons`]}function ly(e,t,r){return r.some((n)=>lT(t,n).includes(e))}function ql(e,t){let{user:r,slug:n}=t;if(r.role==="admin")return e;let i=(e.sites??[]).map((q)=>q.name).filter(Boolean),o=_l(r,i),s=new Set(o),c=(e.sites??[]).filter((q)=>s.has(q.name)),l=(e.sitesDetail??[]).filter((q)=>s.has(q.name)),a=new Set(l.map((q)=>q.domain).filter(Boolean)),m=(e.serverDeploymentsDetail??e.serverDeployments??[]).filter((q)=>s.has(q.site)),E=(e.serverLogs??[]).filter((q)=>ly(q.source,n,o)),D=(e.security?.tlsCertificates??[]).filter((q)=>a.has(q.domain)),O=(e.activity??[]).filter((q)=>{if(q.type==="deploy")return o.some((G)=>String(q.title??"").startsWith(`${G} `));if(q.type==="log")return ly(String(q.title??"").split(" ")[0],n,o);return!1});return{mode:e.mode,environment:e.environment,environments:e.environments,scoped:!0,server:{name:""},sites:c,sitesDetail:l,workers:(e.workers??[]).filter((q)=>s.has(q.site)),serverDeployments:m.slice(0,5),serverDeploymentsDetail:m.slice(0,50),deploymentsEmptyReason:m.length?void 0:"No deployments have been recorded for your sites yet.",serverLogs:E,serverLogsEmptyReason:E.length?void 0:"No recent log entries for your sites.",security:{tlsCertificates:D,ports:[],firewall:null,authEvents:[]},diagnostics:(e.diagnostics??[]).filter((q)=>["Route conflicts","TLS certificates"].includes(q.name)),activity:O}}function py(e,t){if(t.role==="admin")return e;let r=new Set(_l(t,Object.keys(e.sites??{})));return{project:{name:e.project?.name},environment:e.environment,environments:e.environments,sites:Object.fromEntries(Object.entries(e.sites??{}).filter(([n])=>r.has(n)))}}var pT=new Set(["name","ssl","env","redirects","aliases","domain","path"]),gy={build:"build runs as a shell command on the server",start:"start runs as a shell command on the server",root:"root is a filesystem path on the shared server",port:"ports are allocated by the server owner",type:"the deploy type is set by the server owner",php:"the PHP runtime is set by the server owner"};function fy(e){let t=Object.keys(e).filter((i)=>e[i]!==void 0),r=t.filter((i)=>(i in gy));if(r.length)return{ok:!1,error:`Only the server owner can change ${r.map((o)=>`${o} (${gy[o]})`).join(", ")}.`};let n=t.filter((i)=>!pT.has(i));if(n.length)return{ok:!1,error:`Only the server owner can change ${n.join(", ")}.`};return{ok:!0}}function bd(e){return String(e??"").trim().toLowerCase().replace(/\.$/,"")}function my(e){let t=String(e??"/").trim();if(!t||t==="/")return"/";return(t.startsWith("/")?t:`/${t}`).replace(/\/+$/,"")||"/"}function gT(e){let t=[bd(e?.domain)];if(Array.isArray(e?.aliases))t.push(...e.aliases.map(bd));return t.filter(Boolean)}function hy({siteName:e,body:t,sites:r,ownSites:n}){let i=r[e]??{},o=new Set(n),s=new Set;if(t.domain!==void 0)s.add(bd(t.domain));if(Array.isArray(t.aliases))for(let l of t.aliases)s.add(bd(l));if(s.delete(""),s.size===0)return{ok:!0};let c=my(t.path!==void 0?t.path:i.path);for(let[l,a]of Object.entries(r)){if(l===e||o.has(l))continue;let m=my(a?.path);for(let E of gT(a)){if(!s.has(E))continue;if(m===c)return{ok:!1,error:`${E}${c==="/"?"":c} is already served by another site on this server.`}}}return{ok:!0}}class Ba{maxAttempts;lockoutMs;windowMs;attempts=new Map;constructor(e=8,t=900000,r=900000){this.maxAttempts=e;this.lockoutMs=t;this.windowMs=r}key(e,t){return`${e.trim().toLowerCase()}\x00${t}`}check(e,t,r=Date.now()){let n=this.attempts.get(this.key(e,t));if(!n?.until)return{allowed:!0};if(r>=n.until)return this.attempts.delete(this.key(e,t)),{allowed:!0};return{allowed:!1,retryAfterSeconds:Math.ceil((n.until-r)/1000)}}recordFailure(e,t,r=Date.now()){let n=this.key(e,t),i=this.attempts.get(n),s=!i||r-i.last>this.windowMs?1:i.count+1,c={count:s,last:r};if(s>=this.maxAttempts)c.until=r+this.lockoutMs;this.attempts.set(n,c)}recordSuccess(e,t){this.attempts.delete(this.key(e,t))}prune(e=Date.now()){for(let[t,r]of this.attempts)if(r.until?e>=r.until:e-r.last>this.windowMs)this.attempts.delete(t)}get size(){return this.attempts.size}}var by=new Set([22,80,443]);function ja(e){return Number.isInteger(e)&&e>=1&&e<=65535}function hs(e){return[...new Set(e.filter((t)=>ja(t)&&!by.has(t)))].sort((t,r)=>t-r)}function Sy(e,t,r=[]){if(!ja(t))throw Error("Port must be an integer between 1 and 65535.");if(by.has(t))throw Error(`Port ${t} (SSH/HTTP/HTTPS) is always open and is not managed here.`);return wy({configText:e,ports:hs([...r,t])})}function vy(e,t,r=[]){return wy({configText:e,ports:hs(r.filter((n)=>n!==t))})}function yy(e,t,r,n,i){let o=e.slice(t,r),s=new RegExp(`\\b${n}\\s*:\\s*\\${i}`).exec(o);if(!s)return null;let c=t+s.index,l=e.indexOf(i,c);return{propStart:c,open:l,close:ei(e,l,i,i==="{"?"}":"]")}}function Jl(e){return`allowedPorts: [${e.join(", ")}]`}function wy(e){let{configText:t}=e,r=hs(e.ports),n=/\bcompute\s*:\s*{/.exec(t);if(!n)throw Error("Could not find infrastructure.compute in the cloud config.");let i=t.indexOf("{",n.index),o=ei(t,i,"{","}"),s=yy(t,i+1,o,"firewall","{");if(s){let m=yy(t,s.open+1,s.close,"allowedPorts","[");if(m){let q=m.propStart;while(q>0&&t[q-1]!==`
430
+ [output truncated]`}function rT(e){return/^[A-Za-z0-9_.@:-]+$/.test(e)}function Vl(e){return/^[A-Za-z0-9_-]+$/.test(e)}function nT(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Dr(e,t){let r=[],n=t.servicesDetail??t.services??[];for(let s of n){let c=String(s?.name??"");if(!c||!rT(c))continue;for(let l of tT)r.push({id:`${l}:${c}`,label:`${nT(l)} ${c}`,group:"service",target:c,mutates:!0,confirm:c,danger:l==="stop"||l==="disable"})}for(let[s,c]of Object.entries(e.sites??{})){if(!c||!Vl(s))continue;let l=P(c);if(l==="server-app"||l==="server-php")r.push({id:`rollback:${s}`,label:`Rollback ${s}`,group:"deploy",target:s,mutates:!0,confirm:s,danger:!0})}let i=new Set;for(let s of t.workers??[]){let c=String(s?.name??"").split(":")[0];if(c&&Vl(c))i.add(c)}for(let s of i)r.push({id:`worker:restart:${s}`,label:`Restart workers (${s})`,group:"worker",target:s,mutates:!0,confirm:s});for(let[s,c]of Object.entries(e.sites??{})){if(!c||!Vl(s))continue;if(c.scheduler||c.schedule){let l=Gr(c)==="laravel";r.push({id:`scheduler:run:${s}`,label:`${l?"Run":"Restart"} scheduler (${s})`,group:"scheduler",target:s,mutates:!0,confirm:s})}}if(e.infrastructure?.compute?.backups?.enabled){if(r.push({id:"backup:run",label:"Run backup now",group:"backup",target:"backup",mutates:!0,confirm:"backup"}),C(e))r.push({id:"backup:restore",label:"Restore latest DB backup",group:"backup",target:"database",mutates:!0,confirm:"restore",danger:!0})}return r}function _n(e,t,r){return Dr(t,r).find((n)=>n.id===e)}function iT(e,t){let r=e==="enable"||e==="disable"?`systemctl is-enabled ${t} 2>/dev/null || true`:`systemctl is-active ${t} 2>/dev/null || true`;return["set -o pipefail",`systemctl ${e} ${t}`,r]}function oT(){return`eval "$(cd ${L} && pantry env 2>/dev/null)"`}function dy(e,t,r){let n=`${W(e,t)}/current`;return["set -uo pipefail",`[ -d ${n} ] || { echo "site ${t} has no current release" >&2; exit 1; }`,`cd ${n} && ${oT()} && php artisan ${r}`]}function sT(e,t,r){if(e==="laravel")return dy(t,r,"queue:restart");let n=`${t}-${r}-queue-*.service`;return["set -uo pipefail",`units=$(systemctl list-units --type=service --all --no-legend '${n}' 2>/dev/null | awk '{print $1}')`,`[ -n "$units" ] || { echo "no queue-worker units found for ${r} (${n})" >&2; exit 1; }`,"systemctl restart $units",`systemctl --no-legend --type=service list-units '${n}' 2>/dev/null || true`]}function aT(e,t,r){if(e==="laravel")return dy(t,r,"schedule:run");let n=`${t}-${r}-scheduler.service`;return["set -uo pipefail",`systemctl restart ${n}`,`systemctl is-active ${n} 2>/dev/null || true`]}function cT(){return["set -uo pipefail",`[ -x ${Kr} ] || { echo "scheduled backups are not provisioned on this server" >&2; exit 1; }`,Kr]}function cy(e,t,r){return{operation:e,command:t,ok:r.success,stdout:ra(r.perInstance?.[0]?.output??""),stderr:ra(r.perInstance?.[0]?.error??r.error??"")}}async function kr(e,t,r,n={}){let i=e.project.slug,o;try{o=x({config:e})}catch(E){return{operation:r.id,ok:!1,error:`Could not initialize the cloud driver: ${E?.message??E}`}}let s={driver:o,slug:i,environment:t,role:"app"};if(r.group==="deploy"){let E=n.to&&/^[A-Za-z0-9._-]+$/.test(n.to)?n.to:void 0,D=await Xo(s,{siteName:r.target,to:E});return cy(r.id,`rollback ${r.target}${E?` → ${E}`:""}`,D)}if(r.id==="backup:restore"){let E=await Qo(s,{database:C(e)});return cy(r.id,"db restore",E)}let c=await o.findComputeTargets({slug:i,environment:t,role:"app"});if(!c.length)return{operation:r.id,ok:!1,error:"No app server target was found for this environment."};let l,a;if(r.group==="service"){let[E,...D]=r.id.split(":");l=iT(E,D.join(":")),a=`systemctl ${E} ${r.target}`}else if(r.group==="worker"){let E=Gr(e.sites?.[r.target]??{});l=sT(E,i,r.target),a=E==="laravel"?`queue:restart (${r.target})`:`restart queue units (${r.target})`}else if(r.group==="scheduler"){let E=Gr(e.sites?.[r.target]??{});l=aT(E,i,r.target),a=E==="laravel"?`schedule:run (${r.target})`:`restart scheduler (${r.target})`}else if(r.id==="backup:run")l=cT(),a="ts-cloud backup";else return{operation:r.id,ok:!1,error:"Unknown operation."};let m=await o.runRemoteDeploy({targets:[c[0]],commands:l,comment:`ts-cloud dashboard:${r.id}`,tags:{Project:i,Environment:t,Role:"app"}});return{operation:r.id,command:a,ok:m.success,stdout:ra(m.perInstance?.[0]?.output??""),stderr:ra(m.perInstance?.[0]?.error??m.error??"")}}async function Qt(e,t,r){let n=r.trim();if(!n)return{operation:"command",ok:!1,error:"A command is required."};let i;try{i=x({config:e})}catch(l){return{operation:"command",ok:!1,error:`Could not initialize the cloud driver: ${l?.message??l}`}}let o=e.project.slug,s=await i.findComputeTargets({slug:o,environment:t,role:"app"});if(!s.length)return{operation:"command",ok:!1,error:"No app server target was found for this environment."};let c=await i.runRemoteDeploy({targets:[s[0]],commands:["set -o pipefail",n],comment:"ts-cloud dashboard:command",tags:{Project:o,Environment:t,Role:"app"}});return{operation:"command",command:n,ok:c.success,stdout:ra(c.perInstance?.[0]?.output??""),stderr:ra(c.perInstance?.[0]?.error??c.error??"")}}var dT=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"spend.overview",path:"/operations/spend",label:"Spend & budgets",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"infrastructure.topology",path:"/infrastructure/topology",label:"Infrastructure map",group:"infrastructure",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/topology"]},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],uT=new Map(dT.flatMap((e)=>(e.legacyPaths??[]).map((t)=>[t,e.path])));function uy(e){return uT.get(e)}function lT(e,t){return[`${e}-${t}`,`${e}-${t}-queues`,`${e}-${t}-daemons`]}function ly(e,t,r){return r.some((n)=>lT(t,n).includes(e))}function ql(e,t){let{user:r,slug:n}=t;if(r.role==="admin")return e;let i=(e.sites??[]).map((q)=>q.name).filter(Boolean),o=_l(r,i),s=new Set(o),c=(e.sites??[]).filter((q)=>s.has(q.name)),l=(e.sitesDetail??[]).filter((q)=>s.has(q.name)),a=new Set(l.map((q)=>q.domain).filter(Boolean)),m=(e.serverDeploymentsDetail??e.serverDeployments??[]).filter((q)=>s.has(q.site)),E=(e.serverLogs??[]).filter((q)=>ly(q.source,n,o)),D=(e.security?.tlsCertificates??[]).filter((q)=>a.has(q.domain)),O=(e.activity??[]).filter((q)=>{if(q.type==="deploy")return o.some((G)=>String(q.title??"").startsWith(`${G} `));if(q.type==="log")return ly(String(q.title??"").split(" ")[0],n,o);return!1});return{mode:e.mode,environment:e.environment,environments:e.environments,scoped:!0,server:{name:""},sites:c,sitesDetail:l,workers:(e.workers??[]).filter((q)=>s.has(q.site)),serverDeployments:m.slice(0,5),serverDeploymentsDetail:m.slice(0,50),deploymentsEmptyReason:m.length?void 0:"No deployments have been recorded for your sites yet.",serverLogs:E,serverLogsEmptyReason:E.length?void 0:"No recent log entries for your sites.",security:{tlsCertificates:D,ports:[],firewall:null,authEvents:[]},diagnostics:(e.diagnostics??[]).filter((q)=>["Route conflicts","TLS certificates"].includes(q.name)),activity:O}}function py(e,t){if(t.role==="admin")return e;let r=new Set(_l(t,Object.keys(e.sites??{})));return{project:{name:e.project?.name},environment:e.environment,environments:e.environments,sites:Object.fromEntries(Object.entries(e.sites??{}).filter(([n])=>r.has(n)))}}var pT=new Set(["name","ssl","env","redirects","aliases","domain","path"]),gy={build:"build runs as a shell command on the server",start:"start runs as a shell command on the server",root:"root is a filesystem path on the shared server",port:"ports are allocated by the server owner",type:"the deploy type is set by the server owner",php:"the PHP runtime is set by the server owner"};function fy(e){let t=Object.keys(e).filter((i)=>e[i]!==void 0),r=t.filter((i)=>(i in gy));if(r.length)return{ok:!1,error:`Only the server owner can change ${r.map((o)=>`${o} (${gy[o]})`).join(", ")}.`};let n=t.filter((i)=>!pT.has(i));if(n.length)return{ok:!1,error:`Only the server owner can change ${n.join(", ")}.`};return{ok:!0}}function bd(e){return String(e??"").trim().toLowerCase().replace(/\.$/,"")}function my(e){let t=String(e??"/").trim();if(!t||t==="/")return"/";return(t.startsWith("/")?t:`/${t}`).replace(/\/+$/,"")||"/"}function gT(e){let t=[bd(e?.domain)];if(Array.isArray(e?.aliases))t.push(...e.aliases.map(bd));return t.filter(Boolean)}function hy({siteName:e,body:t,sites:r,ownSites:n}){let i=r[e]??{},o=new Set(n),s=new Set;if(t.domain!==void 0)s.add(bd(t.domain));if(Array.isArray(t.aliases))for(let l of t.aliases)s.add(bd(l));if(s.delete(""),s.size===0)return{ok:!0};let c=my(t.path!==void 0?t.path:i.path);for(let[l,a]of Object.entries(r)){if(l===e||o.has(l))continue;let m=my(a?.path);for(let E of gT(a)){if(!s.has(E))continue;if(m===c)return{ok:!1,error:`${E}${c==="/"?"":c} is already served by another site on this server.`}}}return{ok:!0}}class Ba{maxAttempts;lockoutMs;windowMs;attempts=new Map;constructor(e=8,t=900000,r=900000){this.maxAttempts=e;this.lockoutMs=t;this.windowMs=r}key(e,t){return`${e.trim().toLowerCase()}\x00${t}`}check(e,t,r=Date.now()){let n=this.attempts.get(this.key(e,t));if(!n?.until)return{allowed:!0};if(r>=n.until)return this.attempts.delete(this.key(e,t)),{allowed:!0};return{allowed:!1,retryAfterSeconds:Math.ceil((n.until-r)/1000)}}recordFailure(e,t,r=Date.now()){let n=this.key(e,t),i=this.attempts.get(n),s=!i||r-i.last>this.windowMs?1:i.count+1,c={count:s,last:r};if(s>=this.maxAttempts)c.until=r+this.lockoutMs;this.attempts.set(n,c)}recordSuccess(e,t){this.attempts.delete(this.key(e,t))}prune(e=Date.now()){for(let[t,r]of this.attempts)if(r.until?e>=r.until:e-r.last>this.windowMs)this.attempts.delete(t)}get size(){return this.attempts.size}}var by=new Set([22,80,443]);function ja(e){return Number.isInteger(e)&&e>=1&&e<=65535}function hs(e){return[...new Set(e.filter((t)=>ja(t)&&!by.has(t)))].sort((t,r)=>t-r)}function Sy(e,t,r=[]){if(!ja(t))throw Error("Port must be an integer between 1 and 65535.");if(by.has(t))throw Error(`Port ${t} (SSH/HTTP/HTTPS) is always open and is not managed here.`);return wy({configText:e,ports:hs([...r,t])})}function vy(e,t,r=[]){return wy({configText:e,ports:hs(r.filter((n)=>n!==t))})}function yy(e,t,r,n,i){let o=e.slice(t,r),s=new RegExp(`\\b${n}\\s*:\\s*\\${i}`).exec(o);if(!s)return null;let c=t+s.index,l=e.indexOf(i,c);return{propStart:c,open:l,close:ei(e,l,i,i==="{"?"}":"]")}}function Jl(e){return`allowedPorts: [${e.join(", ")}]`}function wy(e){let{configText:t}=e,r=hs(e.ports),n=/\bcompute\s*:\s*{/.exec(t);if(!n)throw Error("Could not find infrastructure.compute in the cloud config.");let i=t.indexOf("{",n.index),o=ei(t,i,"{","}"),s=yy(t,i+1,o,"firewall","{");if(s){let m=yy(t,s.open+1,s.close,"allowedPorts","[");if(m){let q=m.propStart;while(q>0&&t[q-1]!==`
431
431
  `&&/\s/.test(t[q-1]))q--;let G=t.slice(q,m.propStart);return`${t.slice(0,q)}${G}${Jl(r)}${t.slice(m.close+1)}`}let E=t.slice(0,s.close).trimEnd(),D=t.slice(s.close),O=E.endsWith(",")||E.endsWith("{")?"":",";return`${E}${O}
432
432
  ${Jl(r)},
433
433
  ${D}`}let c=t.slice(0,o).trimEnd(),l=t.slice(o),a=c.endsWith(",")||c.endsWith("{")?"":",";return`${c}${a}
@@ -474,29 +474,29 @@ data: ${JSON.stringify({cursor:o,at:new Date().toISOString()})}
474
474
  ${c}
475
475
  ${l}`);return null}return n}catch(i){if(n)Ss(n,{recursive:!0,force:!0});if(process.env.TSCLOUD_DASHBOARD_VERBOSE)console.warn(`ts-cloud dashboard: live UI build errored; serving the pre-built UI. ${i.message}`);return null}}function oA(e){let t=e.infrastructure?.compute?.managedServices?JSON.parse(JSON.stringify(e.infrastructure.compute.managedServices)):void 0;if(t?.vitess?.password)t.vitess.password="";return{project:{name:e.project?.name,slug:e.project?.slug,region:e.project?.region},provider:e.provider,environments:Object.keys(e.environments??{}),compute:e.infrastructure?.compute?{provider:e.infrastructure.compute.provider,runtime:e.infrastructure.compute.runtime,webServer:e.infrastructure.compute.webServer,proxy:e.infrastructure.compute.proxy?{engine:e.infrastructure.compute.proxy.engine,onDemandTls:e.infrastructure.compute.proxy.onDemandTls,cdn:!!e.infrastructure.compute.proxy.cdn}:void 0,managedServices:t,sshKeys:Ot(ca(e)).map((r)=>({name:r.name,type:r.type,fingerprint:r.fingerprint,added:r.added}))}:void 0,sites:Object.fromEntries(Object.entries(e.sites??{}).map(([r,n])=>[r,{domain:n.domain,path:n.path,type:n.type,deploy:n.deploy,root:n.root,port:n.port,ssl:n.ssl}]))}}function gb(e){return[{id:"status",label:"Refresh Cloud Status",description:"Runs the local ts-cloud status checks against configured providers.",command:["status","--env",e],mutates:!1},{id:"doctor",label:"Run Doctor",description:"Checks local tooling, credentials, and provider access.",command:["doctor"],mutates:!1},{id:"security-scan",label:"Security Scan",description:"Runs the pre-deploy scanner from this checkout.",command:["deploy:security-scan","--source",".","--fail-on","critical"],mutates:!1},{id:"deploy",label:"Deploy Environment",description:"Deploys the selected environment from the local checkout.",command:["deploy","--env",e,"--yes"],mutates:!0,confirm:"deploy"}]}function sA(e,t){return gb(t).find((r)=>r.id===e)}function ob(e){if(e.length<=tb)return e;return`${e.slice(0,tb)}
476
476
 
477
- [output truncated]`}async function sb(e,t,r){let n=e.getReader(),i=new TextDecoder,o="";while(!0){let{done:c,value:l}=await n.read();if(c)break;let a=i.decode(l,{stream:!0});if(o+=a,a)r?.(t,a)}let s=i.decode();if(s)o+=s,r?.(t,s);return o}async function np(e,t){let r=Bun.spawn([process.execPath,t.cliEntry,...e.command],{cwd:t.cwd,stdout:"pipe",stderr:"pipe",env:{...process.env,...t.env}}),n=()=>{try{r.kill()}catch{}};if(t.signal?.aborted)n();else t.signal?.addEventListener("abort",n,{once:!0});try{let[i,o,s]=await Promise.all([sb(r.stdout,"stdout",t.onOutput),sb(r.stderr,"stderr",t.onOutput),r.exited]);return{action:e.id,command:["cloud",...e.command].join(" "),exitCode:s,ok:s===0,stdout:ob(i),stderr:ob(o)}}finally{t.signal?.removeEventListener("abort",n)}}function aA(){return Object.entries(process.env).filter(([e,t])=>!!t&&t.length>=8&&/(?:secret|token|password|passwd|private|credential|api.?key|access.?key)/i.test(e)).map(([,e])=>e)}var cA=new Set(["/server/sites","/server/deployments","/server/logs","/integrations","/applications/new","/applications/compose","/operations/queue","/operations/previews","/operations/releases","/operations/workloads","/operations/observability","/operations/alerts","/operations/jobs","/data/backups","/account/security","/security","/access-denied"]);function dA(e){let t=za(e);if(t&&t!==".html")return!1;let r=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(r==="/")return!1;return!cA.has(r)}var uA={"/":"runtime:read","/server/activity":"audit:read","/server/sites":"project:read","/server/deployments":"deployments:read","/server/logs":"runtime:logs","/server/metrics":"runtime:read","/server/services":"runtime:read","/data/backups":"backups:read","/data/volumes":"data:read","/server/fleet":"fleet:read","/server/capacity":"fleet:read","/server/actions":"runtime:restart","/server/database":"data:read","/server/firewall":"fleet:read","/infrastructure/topology":"fleet:read","/server/security":"security:read","/security":"security:read","/integrations":"sources:read","/applications/new":"applications:read","/applications/compose":"applications:read","/operations/queue":"deployments:read","/operations/previews":"deployments:read","/operations/releases":"deployments:read","/operations/regions":"deployments:read","/operations/maintenance":"deployments:read","/operations/workloads":"runtime:read","/operations/observability":"runtime:logs","/operations/alerts":"runtime:read","/operations/jobs":"automation:read","/operations/configuration":"config:read","/server/ssh-keys":"fleet:read","/server/terminal":"runtime:terminal","/server/team":"users:read","/account/security":"project:read","/account/automation":"users:read","/serverless":"project:read","/serverless/deployments":"deployments:read","/serverless/logs":"runtime:logs","/serverless/metrics":"runtime:read","/serverless/traces":"runtime:read","/serverless/functions":"config:read","/serverless/queues":"data:read","/serverless/data":"data:read","/serverless/assets":"project:read","/serverless/secrets":"secrets:read","/serverless/firewall":"fleet:read","/serverless/alarms":"runtime:read","/serverless/cost":"project:read"};function ab(e,t){if(t.role==="admin")return!0;let r=za(e);if(r&&r!==".html")return!0;if(t.organizationSource==="legacy")return!dA(e);let n=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(n==="/access-denied")return!0;let i=uA[n];return!!i&&!!t.capabilities?.includes(i)}function lA(e,t){let r=decodeURIComponent(t).replace(/^\/+/,""),i=OT(r===""?"index.html":r);if(i.startsWith("..")||i.includes("/../"))return null;let o=Et(e,i);if(lo(o)&&!lb(o).isDirectory())return o;if(!za(o)&&lo(`${o}.html`))return`${o}.html`;if(!za(o)&&lo(Et(o,"index.html")))return Et(o,"index.html");return null}async function cb(e,t){let r=lA(e,t);if(!r){let o=Et(e,"404.html");if(lo(o))return new Response(await Fi(o),{status:404,headers:{"content-type":"text/html; charset=utf-8"}});return Ed("Not found",404)}if(lb(r).isDirectory())return Ed("Not found",404);let n=await Fi(r),i=UT[za(r)]??"application/octet-stream";return new Response(n,{headers:{"content-type":i}})}var Id=["observe","backup","restore","restart","resize","version","rotate","expose","delete","logs","slow_queries","users","databases"],db=new WeakMap;async function ub(e){let t=db.get(e);if(t)return t;let r=await import("./chunk-bdgkeqv6.js"),n=new r.SpendStore(e),i={store:n,service:new r.SpendService(n),gate:new r.SpendGate(e)};return db.set(e,i),i}async function er(e={}){FT();let t=e.cwd??process.cwd(),r=e.host??LT,n=e.port??BT,i=e.cliEntry??process.argv[1];if(e.box)process.env.TS_CLOUD_DASHBOARD_BOX="1";await KT(t);let o=e.config??await Ei(),s=process.env.TS_CLOUD_DASHBOARD_DB_PASSWORD,c=C(o);if(s&&c&&!c.password)c.password=s;let l=o.infrastructure?.compute?.managedServices?.vitess;if(s&&l&&typeof l==="object"&&!l.password)l.password=s;let a=y(t,o);if(a.reconciliation.failed>0)console.warn(` ts-cloud dashboard: marked ${a.reconciliation.failed} orphaned operation(s) as failed after restart.`);let m=Object.keys(o.environments??{}),E=HT(o,e.environment),D=QT(t),O=await bs(o,E),q=new Map([[E,O]]),G=new Map([[E,Date.now()]]),Y=new Map([[E,Date.now()]]),re=new Map,he=Math.min(300000,Math.max(5000,Number(process.env.TS_CLOUD_DASHBOARD_REFRESH_MS)||30000)),ee=Math.min(1800000,Math.max(60000,Number(process.env.TS_CLOUD_DASHBOARD_SITE_REFRESH_MS)||300000)),De=V(o)!=="serverless",Ze=(I)=>{let Ee=q.get(I);if(Ee&&!rb(G.get(I),Date.now(),he))return Promise.resolve(Ee);let Ne=re.get(I);if(Ne)return Ne;let we=!De||rb(Y.get(I),Date.now(),ee),Je=bs(o,I,{includeSiteHealth:we}).then((mt)=>{let N=q.get(I),Wr=we?mt:rA(N,mt);if(q.set(I,Wr),G.set(I,Date.now()),we)Y.set(I,Date.now());if(N?._serverReachable!==Wr._serverReachable||N?._metricsStatus!==Wr._metricsStatus||(N?.sitesDetail?.length??0)!==(Wr.sitesDetail?.length??0))gi();return Wr}).finally(()=>re.delete(I));return re.set(I,Je),Je},ze=no(t),zt=process.env.TS_CLOUD_DASHBOARD_TELEMETRY?.trim();if(e.box&&zt!=="0"&&(zt==="1"||!o.cloud?.attachTo)){let I=!1,Ee=Date.now()+300000,Ne=async()=>{if(I)return;I=!0;try{let Je=Date.now(),mt=Je>=Ee;if(mt)Ee=Je+300000;let N=a.environments.get(E);await Bn({controlPlane:a.store,projectId:a.project.id,environmentId:N?.id,config:o,environment:E,force:!0,lightweight:!0,includeSiteHealth:mt})}catch(Je){if(e.verbose)console.warn(` ts-cloud dashboard: background telemetry collection failed: ${Je instanceof Error?Je.message:String(Je)}`)}finally{I=!1}};Ne(),setInterval(()=>void Ne(),60000).unref?.()}let Ae=new Map,Ke=new Map,Tt=new Set,ki=0;function po(I,Ee){if(I.role==="admin"&&!a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`))return I;let Ne=a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`),we=Ne?a.store.getMembershipForActor(a.organization.id,Ne.id):void 0;if(!we||we.status!=="active")return{...I,role:"member",sites:{},capabilities:[]};let Je=a.store.listGrants(we.id),mt=a.store.resolveAuthorizationTarget(a.organization.id,we.scope)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),N=en({membership:we,grants:Je,target:mt});if(we.roleTemplate==="owner"||we.roleTemplate==="admin")return{...I,role:"admin",sites:{},organizationRole:we.roleTemplate,organizationSource:we.source,capabilities:N};let Wr=a.environments.get(Ee),ir={};for(let Ye of a.store.listResources(a.project.id,Wr?.id).filter((at)=>at.kind==="application")){let at=a.store.resolveAuthorizationTarget(a.organization.id,{type:"resource",id:Ye.id});if(!at||!Z({membership:we,grants:Je,capability:"project:read",target:at}).allowed)continue;ir[Ye.slug]=Z({membership:we,grants:Je,capability:"config:write",target:at}).allowed?"owner":"collaborator"}return{...I,role:"member",sites:ir,organizationRole:we.roleTemplate,organizationSource:we.source,capabilities:N}}function gi(){ki+=1,Ae.clear();for(let I of Tt)Ss(I,{recursive:!0,force:!0});Tt.clear()}let Ri=(I,Ee)=>`${Ee}:${I.role==="admin"?"admin":`member:${Object.entries(I.sites).sort(([Ne],[we])=>Ne.localeCompare(we)).map(([Ne,we])=>`${Ne}=${we}`).join(",")}`}:${[...I.capabilities??[]].sort().join(",")}`;async function Pi(I,Ee){let Ne=po(I,Ee),we=Ri(Ne,Ee),Je=Ae.get(we);if(Je)return Je;let mt=Ke.get(we);if(mt)return mt;let N=ki,Wr=(async()=>{let ir=q.get(Ee)??await bs(o,Ee);q.set(Ee,ir);let Ye={...ql(ir,{user:Ne,slug:o.project.slug}),viewer:{role:Ne.role,organizationRole:Ne.organizationRole,organizationSource:Ne.organizationSource,capabilities:Ne.capabilities??[]}},at=await iA(t,Ye);if(at&&N!==ki)return Ss(at,{recursive:!0,force:!0}),ze?.uiRoot;if(at)Tt.add(at);let Br=at??ze?.uiRoot;if(Br)Ae.set(we,Br);return Br})();Ke.set(we,Wr);try{return await Wr}finally{Ke.delete(we)}}let xi=await Pi({username:"",passwordHash:"",role:"admin",sites:{}},E);if(!xi)throw Error("ts-cloud dashboard UI not found. Run `bun run build` in ts-cloud or reinstall the package.");let J=new WeakMap,pe=process.env.TS_CLOUD_DASHBOARD_TERMINAL!=="0",Ce=process.env.TS_CLOUD_DASHBOARD_AUTH==="0";if(Ce&&e.box)throw Error("TS_CLOUD_DASHBOARD_AUTH=0 is refused in box mode: the dashboard is internet-facing there, and disabling auth would expose a root shell.");let Re=!Ce,Dt=Kh(t),qt=Re?Zh(t,process.env.TS_CLOUD_UI_USERNAME?.trim()||"admin"):void 0,ve=new ke(a.store,{encryptionKey:k(t)}),pt=new Ue(a.store),et=new Rt(a.store),qe=new Kt(a.store,{encryptionKey:k(t)}),Jr=new Dn(a.store),vs=new xn(a.store,{cwd:t}),Di=new kn(a.store,{encryptionKey:k(t)}),kt=new b(a.store,{workerId:`dashboard:${process.pid}`}),_t=new Wt(a.store),Ui=new Gt(a.store,k(t)),go=new hr(a.store),Va=new Rr(_t,kt,Ui),mo=o.project?.region??"us-east-1",op=k(t),Jn=new vr(go,{encryptionKey:op,backends:[new St(a.store,op),new yr(new H(mo),mo),new Sr(new We(mo),mo),new br]});await Yr(Jn,a,o);let Td=new le(mo),mb={aws_rds:new Tn(new In(Td)),aws_aurora:new En(new Rn(Td)),aws_elasticache:new wn(new Pn(new te(mo))),server:new Cn(new rt),container:new An(new rt)},sp=(I)=>mb[I.provider],sr=new Mn(a.store),jo=new Or(sr,kt),ap=new Un(Ui),fb={managed_database:new gu(_t,Td),logical_database:new bu(_t,Ui),volume:new vu,files:new yu(t),control_plane:new Iu(a.store,t),infrastructure:new Eu(new va(mo))},hb=(I)=>fb[I.resourceKind],yb=(I)=>I.provider==="aws_backup"?void 0:ap,Ad=new st(a.store),kd=[new Nt,new Mr(A(t,"volumes"))],Vi=new Lr(Ad,kd,kt),ua=new Ie(a.store),Oi=new pn(ua,[new tt("aws"),new tt("hetzner"),new tt("ssh")],kt),fo=new mn(a.store),cp=new gn(fo,ua),Fo=new fn(a.store),dp=new hn(Fo,kt),qi=new yn(a.store),Rd=new Sn(qi,kt),up=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((I)=>new bn(I,a.store,a.project.id,a.organization.id)),Er=new _r(a.store),lp=new Ln(Er,{queue:kt}),nr=new Fe(a.store),ho=new Be(a.store),ii=new nt(a.store),Ge=new ct(a.store,{encryptionKey:k(t)}),bb=()=>ub(a.store);for(let I of a.environments.values())$r(Er,o,{organization:a.organization,project:a.project,environment:I,resources:a.store.listResources(a.project.id,I.id)});let oi=new rr(Ge,{emailImpl:async(I)=>{let{email:Ee}=await import("./chunk-xvn07b0e.js");return Ee.send(I)}}),pp=async(I)=>{let Ee=Ur(Ge,a.project.id,I),Ne=[];for(let we of Ee.filter((Je)=>Je.notify&&Je.alert))Ne.push(...await oi.deliverAll(oi.enqueue(a.organization.id,we.alert,we.transition)));return Ne.push(...await oi.deliverAll(oi.enqueueRemindersAndEscalations(a.organization.id,Ge.listAlerts(a.project.id,{environmentId:I,states:["firing"]})))),Ne.push(...await oi.retryDue()),{evaluations:Ee,deliveries:Ne}},Pd=!1,Sb=async()=>{if(Pd)return;Pd=!0;try{for(let I of a.environments.values())for(let Ee of Ge.listHealthChecks(a.project.id,I.id).filter((Ne)=>Ne.enabled)){let Ne=Ge.listHealthResults(Ee.id,1)[0];if(Ne&&Date.now()-new Date(Ne.checkedAt).getTime()<Ee.intervalSeconds*1000)continue;let we=await new Oe(Ge).runAndEvaluate(Ee);for(let Je of we.evaluations.filter((mt)=>mt.notify&&mt.alert))await oi.deliverAll(oi.enqueue(a.organization.id,Je.alert,Je.transition))}}finally{Pd=!1}},gp=setInterval(()=>{for(let I of a.environments.values())pp(I.id).catch((Ee)=>console.error("ts-cloud alert evaluation failed:",Ee))},60000);gp.unref?.();let mp=setInterval(()=>{Sb().catch((I)=>console.error("ts-cloud health check evaluation failed:",I))},30000);mp.unref?.();let fp=setInterval(()=>{try{lp.tick()}catch(I){console.error("ts-cloud scheduled job evaluation failed:",I)}},30000);fp.unref?.();let hp=setInterval(()=>{try{jo.enqueueDue(),jo.enqueueRetention()}catch(I){console.error("ts-cloud backup policy evaluation failed:",I)}},30000);hp.unref?.(),nr.cleanup();let yp=setInterval(()=>{try{nr.cleanup()}catch(I){console.error("ts-cloud preview cleanup failed:",I)}},3600000);yp.unref?.();let vb=e.queueWorker??!0,wb=aA(),Ib=async(I,Ee)=>{let we=(I.environmentId?a.store.listEnvironments(I.projectId).find((Je)=>Je.id===I.environmentId):void 0)?.slug??String(E);if(Ee.kind==="dashboard_operation"&&Ee.operationId){let Je=q.get(we)??O,mt=_n(Ee.operationId,o,Je);if(!mt||mt.danger||!["scheduler","backup","worker"].includes(mt.group))return{ok:!1,stderr:"The allowlisted dashboard operation is no longer available."};let N=await kr(o,we,mt);return{ok:N.ok,stdout:N.stdout,stderr:N.stderr??N.error,retryable:/temporar|unavailable|timeout|network/i.test(N.stderr??N.error??""),output:{command:N.command??null,operation:N.operation}}}if(Ee.kind==="serverless_scheduler"){let Je=await Xl(o,we,"run");return{ok:Je.ok,stdout:Je.stdout,stderr:Je.error,retryable:/temporar|unavailable|timeout|network/i.test(Je.error??""),output:{command:Je.command??null,operation:"serverless_scheduler"}}}return{ok:!1,stderr:`No safe executor is configured for ${Ee.kind}.`}},qa=vb?new $o(kt,{...da({store:a.store,execute:async(I,Ee)=>{let Ne=Ee.operation.input&&typeof Ee.operation.input==="object"&&!Array.isArray(Ee.operation.input)?Ee.operation.input:{},we=Ne.source&&typeof Ne.source==="object"?Ne.source:void 0,Je=t,mt,N,Wr;try{if(we?.bindingId&&we?.connectionId&&we?.commitSha){let Ye=qe.getBinding(String(we.bindingId)),at=qe.getConnection(String(we.connectionId));if(!Ye||!at||Ye.connectionId!==at.id)throw Error("Queued source binding is no longer available");let wr=(Ye.repositoryId?qe.getRepository(Ye.repositoryId):qe.listRepositories(at.id).find((Es)=>Es.fullName.toLowerCase()===Ye.repositoryFullName.toLowerCase()))?.cloneUrl;if(!wr&&at.provider==="generic_ssh")wr=`git@${new URL(at.host).hostname}:${Ye.repositoryFullName}.git`;if(!wr)wr=new URL(`/${Ye.repositoryFullName}.git`,at.host.endsWith("/")?at.host:`${at.host}/`).href;let ye=Ye.deployKeyId?qe.getDeployKey(Ye.deployKeyId):void 0,Mt=ye&&Ye.deployKeyId?{...ye,privateKey:qe.getDeployPrivateKey(Ye.deployKeyId)}:void 0;if(["github","gitlab","bitbucket","gitea"].includes(at.provider)&&I.target.previewId){let Es=wo(at,qe.getCredential(at.id)),de=nr.previews.getInstance(I.target.previewId);Wr=async(si,Ka)=>{try{await Es.setCommitStatus(Ye.repositoryFullName,String(we.commitSha),{state:si,url:de?.url,description:Ka})}catch(Ts){Ee.log(`Could not publish source status: ${Ts instanceof Error?Ts.message:String(Ts)}`,{stream:"stderr"})}},await Wr("pending",`Preview deployment started for ${String(we.commitSha).slice(0,12)}`)}mt=ip(Et(Cd(),"ts-cloud-queued-source-")),Ee.log(`Checking out immutable source commit ${we.commitSha}.`,{stream:"system"}),Je=(await Wd({remote:wr,binding:Ye,destination:Et(mt,"checkout"),ref:String(we.branch??Ye.defaultBranch),commitSha:String(we.commitSha)},{credential:qe.getCredential(at.id),deployKey:Mt})).directory}if(Ee.operation.kind!=="preview.destroy"){let Ye=I.target.previewId?nr.previews.getInstance(I.target.previewId):void 0,at=Ye?nr.previews.getDefinition(Ye.definitionId):void 0,Br=Ee.operation.resourceId?a.store.getResource(Ee.operation.resourceId):void 0;if(N=await Jn.resolve({projectId:a.project.id,environmentId:Ee.operation.environmentId,resourceId:Ee.operation.resourceId,functionId:Br?.kind==="function"?Br.id:void 0,previewId:Ye?.id,trustedPreview:!!Ye&&!Ye.fork,allowedPreviewSecrets:at?.inheritedSecrets}),N.warnings.some((wr)=>wr.code==="missing_required"))throw Error(`Required deployment configuration is unavailable: ${N.warnings.filter((wr)=>wr.code==="missing_required").map((wr)=>wr.key).join(", ")}`);if(Ee.operation.resourceId)for(let wr of Object.values(N.entries))go.setDependency({entryId:wr.id,resourceId:Ee.operation.resourceId,injectionTarget:"environment",required:wr.required,requiresRedeploy:!0});Ee.log(`Resolved configuration ${N.configurationHash.slice(0,18)} for ${Object.keys(N.values).length} keys.`,{stream:"system"})}let ir=await np(I,{cwd:Je,cliEntry:i,signal:Ee.signal,env:N?.values,onOutput:(Ye,at)=>Ee.log(at,{stream:Ye,step:"execute",secrets:[...wb,...Object.entries(N?.entries??{}).filter(([,Br])=>Br.kind==="secret").map(([Br])=>N.values[Br]).filter(Boolean)]})});if(ir.ok&&Ee.operation.resourceId&&N)for(let Ye of Object.values(N.entries))go.setDependency({entryId:Ye.id,resourceId:Ee.operation.resourceId,injectionTarget:"environment",required:Ye.required,requiresRedeploy:!1,lastDeployedVersion:Ye.version});return await Wr?.(ir.ok?"success":"failure",ir.ok?`Preview is ready at ${String(we?.commitSha).slice(0,12)}`:`Preview deployment failed at ${String(we?.commitSha).slice(0,12)}`),ir}catch(ir){throw await Wr?.("error",`Preview deployment could not complete at ${String(we?.commitSha).slice(0,12)}`),ir}finally{if(mt)Ss(mt,{recursive:!0,force:!0})}}}),...Mg({store:Er,executor:Ib}),...Hg({store:_t,secrets:Ui,resolveAdapter:sp}),...Nf(ua,Oi.drivers),...th(Fo,[new Sl("aws","AWS regional execution requires an injected AwsRegionalTransport; topology and plans were preserved without provider mutation.")]),...Hf({store:qi,cleanup:up}),...la(Ad,kd),...qg({store:sr,queue:kt,resolveSource:hb,resolveDestination:yb,validateHealth:async(I,Ee)=>{if(!I.healthCheckId)return{healthy:!0,mode:"adapter"};let Ne=Ge.getHealthCheck(I.healthCheckId);if(!Ne||Ne.projectId!==I.projectId)return{healthy:!1,error:"Configured restore health check was not found."};let we=await new Oe(Ge).runAndEvaluate(Ne);return{healthy:we.result.status==="healthy",healthCheckId:Ne.id,healthResultId:we.result.id,target:Ee}}}),...Wp({store:a.store,resolveDriver:e.releaseDriver??((I)=>({name:`${a.store.getResource(I.resourceId)?.provider??"provider"} release driver`,capability:()=>({strategy:I.strategy,supported:!1,explanation:"This dashboard process has no immutable activation driver configured for the target provider.",capacityMultiplier:1,costImpact:"none",rollback:"The previous release remains preserved; configure a release driver before retrying."}),activate:async()=>{throw Error("Immutable activation driver is not configured")},rollback:async()=>{throw Error("Immutable rollback driver is not configured")}})),resolveHealthGate:async(I,Ee)=>{let Ne=Ge.listHealthChecks(Ee.projectId,Ee.environmentId).find((Je)=>Je.enabled&&Je.name===I&&(!Je.resourceId||Je.resourceId===Ee.resourceId));if(!Ne)return{healthy:!1,message:`Named health gate ${I} was not found for this release.`};let we=await new Oe(Ge).runAndEvaluate(Ne);return{healthy:we.result.status==="healthy",evidence:{healthCheckId:Ne.id,healthResultId:we.result.id,status:we.result.status,timings:we.result.timings},message:we.result.message}}})},{parallelism:e.queueParallelism??(Number(process.env.TS_CLOUD_QUEUE_PARALLELISM)||8),onError:(I)=>console.error("ts-cloud deployment queue worker failed:",I)}):void 0;if($n(a),od(et,ae(a,String(E)),O),qt)sd(a,qt.users),ry(ve,a,qt.users);let Bt=ey({cwd:t,enabled:Re,secret:Dt,authentication:ve,authorization:{store:a.store,organizationId:a.organization.id,projectId:a.project.id,defaultEnvironment:String(E)}}),ar=new Il,bp=setInterval(()=>ar.sweep(),60000);bp.unref?.();let Ja=new Ba,xd=new Ba(3,900000,900000),Wa=new Ba(8,900000,900000),Sp=setInterval(()=>Ja.prune(),300000),vp=setInterval(()=>xd.prune(),300000),wp=setInterval(()=>Wa.prune(),300000);if(Sp.unref?.(),vp.unref?.(),wp.unref?.(),Re){if(qt?.generated)console.warn(`
477
+ [output truncated]`}async function sb(e,t,r){let n=e.getReader(),i=new TextDecoder,o="";while(!0){let{done:c,value:l}=await n.read();if(c)break;let a=i.decode(l,{stream:!0});if(o+=a,a)r?.(t,a)}let s=i.decode();if(s)o+=s,r?.(t,s);return o}async function np(e,t){let r=Bun.spawn([process.execPath,t.cliEntry,...e.command],{cwd:t.cwd,stdout:"pipe",stderr:"pipe",env:{...process.env,...t.env}}),n=()=>{try{r.kill()}catch{}};if(t.signal?.aborted)n();else t.signal?.addEventListener("abort",n,{once:!0});try{let[i,o,s]=await Promise.all([sb(r.stdout,"stdout",t.onOutput),sb(r.stderr,"stderr",t.onOutput),r.exited]);return{action:e.id,command:["cloud",...e.command].join(" "),exitCode:s,ok:s===0,stdout:ob(i),stderr:ob(o)}}finally{t.signal?.removeEventListener("abort",n)}}function aA(){return Object.entries(process.env).filter(([e,t])=>!!t&&t.length>=8&&/(?:secret|token|password|passwd|private|credential|api.?key|access.?key)/i.test(e)).map(([,e])=>e)}var cA=new Set(["/server/sites","/server/deployments","/server/logs","/integrations","/applications/new","/applications/compose","/operations/queue","/operations/previews","/operations/releases","/operations/workloads","/operations/observability","/operations/alerts","/operations/jobs","/data/backups","/account/security","/security","/access-denied"]);function dA(e){let t=za(e);if(t&&t!==".html")return!1;let r=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(r==="/")return!1;return!cA.has(r)}var uA={"/":"runtime:read","/server/activity":"audit:read","/server/sites":"project:read","/server/deployments":"deployments:read","/server/logs":"runtime:logs","/server/metrics":"runtime:read","/server/services":"runtime:read","/data/backups":"backups:read","/data/volumes":"data:read","/server/fleet":"fleet:read","/server/capacity":"fleet:read","/server/actions":"runtime:restart","/server/database":"data:read","/server/firewall":"fleet:read","/infrastructure/topology":"fleet:read","/server/security":"security:read","/security":"security:read","/integrations":"sources:read","/applications/new":"applications:read","/applications/compose":"applications:read","/operations/queue":"deployments:read","/operations/previews":"deployments:read","/operations/releases":"deployments:read","/operations/regions":"deployments:read","/operations/maintenance":"deployments:read","/operations/workloads":"runtime:read","/operations/observability":"runtime:logs","/operations/alerts":"runtime:read","/operations/jobs":"automation:read","/operations/configuration":"config:read","/server/ssh-keys":"fleet:read","/server/terminal":"runtime:terminal","/server/team":"users:read","/account/security":"project:read","/account/automation":"users:read","/serverless":"project:read","/serverless/deployments":"deployments:read","/serverless/logs":"runtime:logs","/serverless/metrics":"runtime:read","/serverless/traces":"runtime:read","/serverless/functions":"config:read","/serverless/queues":"data:read","/serverless/data":"data:read","/serverless/assets":"project:read","/serverless/secrets":"secrets:read","/serverless/firewall":"fleet:read","/serverless/alarms":"runtime:read","/serverless/cost":"project:read"};function ab(e,t){if(t.role==="admin")return!0;let r=za(e);if(r&&r!==".html")return!0;if(t.organizationSource==="legacy")return!dA(e);let n=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(n==="/access-denied")return!0;let i=uA[n];return!!i&&!!t.capabilities?.includes(i)}function lA(e,t){let r=decodeURIComponent(t).replace(/^\/+/,""),i=OT(r===""?"index.html":r);if(i.startsWith("..")||i.includes("/../"))return null;let o=Et(e,i);if(lo(o)&&!lb(o).isDirectory())return o;if(!za(o)&&lo(`${o}.html`))return`${o}.html`;if(!za(o)&&lo(Et(o,"index.html")))return Et(o,"index.html");return null}async function cb(e,t){let r=lA(e,t);if(!r){let o=Et(e,"404.html");if(lo(o))return new Response(await Fi(o),{status:404,headers:{"content-type":"text/html; charset=utf-8"}});return Ed("Not found",404)}if(lb(r).isDirectory())return Ed("Not found",404);let n=await Fi(r),i=UT[za(r)]??"application/octet-stream";return new Response(n,{headers:{"content-type":i}})}var Id=["observe","backup","restore","restart","resize","version","rotate","expose","delete","logs","slow_queries","users","databases"],db=new WeakMap;async function ub(e){let t=db.get(e);if(t)return t;let r=await import("./chunk-bdgkeqv6.js"),n=new r.SpendStore(e),i={store:n,service:new r.SpendService(n),gate:new r.SpendGate(e)};return db.set(e,i),i}async function er(e={}){FT();let t=e.cwd??process.cwd(),r=e.host??LT,n=e.port??BT,i=e.cliEntry??process.argv[1];if(e.box)process.env.TS_CLOUD_DASHBOARD_BOX="1";await KT(t);let o=e.config??await Ei(),s=process.env.TS_CLOUD_DASHBOARD_DB_PASSWORD,c=C(o);if(s&&c&&!c.password)c.password=s;let l=o.infrastructure?.compute?.managedServices?.vitess;if(s&&l&&typeof l==="object"&&!l.password)l.password=s;let a=y(t,o);if(a.reconciliation.failed>0)console.warn(` ts-cloud dashboard: marked ${a.reconciliation.failed} orphaned operation(s) as failed after restart.`);let m=Object.keys(o.environments??{}),E=HT(o,e.environment),D=QT(t),O=await bs(o,E),q=new Map([[E,O]]),G=new Map([[E,Date.now()]]),Y=new Map([[E,Date.now()]]),re=new Map,he=Math.min(300000,Math.max(5000,Number(process.env.TS_CLOUD_DASHBOARD_REFRESH_MS)||30000)),ee=Math.min(1800000,Math.max(60000,Number(process.env.TS_CLOUD_DASHBOARD_SITE_REFRESH_MS)||300000)),De=V(o)!=="serverless",Ze=(I)=>{let Ee=q.get(I);if(Ee&&!rb(G.get(I),Date.now(),he))return Promise.resolve(Ee);let Ne=re.get(I);if(Ne)return Ne;let we=!De||rb(Y.get(I),Date.now(),ee),Je=bs(o,I,{includeSiteHealth:we}).then((mt)=>{let N=q.get(I),Wr=we?mt:rA(N,mt);if(q.set(I,Wr),G.set(I,Date.now()),we)Y.set(I,Date.now());if(N?._serverReachable!==Wr._serverReachable||N?._metricsStatus!==Wr._metricsStatus||(N?.sitesDetail?.length??0)!==(Wr.sitesDetail?.length??0))gi();return Wr}).finally(()=>re.delete(I));return re.set(I,Je),Je},ze=no(t),zt=process.env.TS_CLOUD_DASHBOARD_TELEMETRY?.trim();if(e.box&&zt!=="0"&&(zt==="1"||!o.cloud?.attachTo)){let I=!1,Ee=Date.now()+300000,Ne=async()=>{if(I)return;I=!0;try{let Je=Date.now(),mt=Je>=Ee;if(mt)Ee=Je+300000;let N=a.environments.get(E);await Bn({controlPlane:a.store,projectId:a.project.id,environmentId:N?.id,config:o,environment:E,force:!0,lightweight:!0,includeSiteHealth:mt})}catch(Je){if(e.verbose)console.warn(` ts-cloud dashboard: background telemetry collection failed: ${Je instanceof Error?Je.message:String(Je)}`)}finally{I=!1}};Ne(),setInterval(()=>void Ne(),60000).unref?.()}let Ae=new Map,Ke=new Map,Tt=new Set,ki=0;function po(I,Ee){if(I.role==="admin"&&!a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`))return I;let Ne=a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`),we=Ne?a.store.getMembershipForActor(a.organization.id,Ne.id):void 0;if(!we||we.status!=="active")return{...I,role:"member",sites:{},capabilities:[]};let Je=a.store.listGrants(we.id),mt=a.store.resolveAuthorizationTarget(a.organization.id,we.scope)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),N=en({membership:we,grants:Je,target:mt});if(we.roleTemplate==="owner"||we.roleTemplate==="admin")return{...I,role:"admin",sites:{},organizationRole:we.roleTemplate,organizationSource:we.source,capabilities:N};let Wr=a.environments.get(Ee),ir={};for(let Ye of a.store.listResources(a.project.id,Wr?.id).filter((at)=>at.kind==="application")){let at=a.store.resolveAuthorizationTarget(a.organization.id,{type:"resource",id:Ye.id});if(!at||!Z({membership:we,grants:Je,capability:"project:read",target:at}).allowed)continue;ir[Ye.slug]=Z({membership:we,grants:Je,capability:"config:write",target:at}).allowed?"owner":"collaborator"}return{...I,role:"member",sites:ir,organizationRole:we.roleTemplate,organizationSource:we.source,capabilities:N}}function gi(){ki+=1,Ae.clear();for(let I of Tt)Ss(I,{recursive:!0,force:!0});Tt.clear()}let Ri=(I,Ee)=>`${Ee}:${I.role==="admin"?"admin":`member:${Object.entries(I.sites).sort(([Ne],[we])=>Ne.localeCompare(we)).map(([Ne,we])=>`${Ne}=${we}`).join(",")}`}:${[...I.capabilities??[]].sort().join(",")}`;async function Pi(I,Ee){let Ne=po(I,Ee),we=Ri(Ne,Ee),Je=Ae.get(we);if(Je)return Je;let mt=Ke.get(we);if(mt)return mt;let N=ki,Wr=(async()=>{let ir=q.get(Ee)??await bs(o,Ee);q.set(Ee,ir);let Ye={...ql(ir,{user:Ne,slug:o.project.slug}),viewer:{role:Ne.role,organizationRole:Ne.organizationRole,organizationSource:Ne.organizationSource,capabilities:Ne.capabilities??[]}},at=await iA(t,Ye);if(at&&N!==ki)return Ss(at,{recursive:!0,force:!0}),ze?.uiRoot;if(at)Tt.add(at);let Br=at??ze?.uiRoot;if(Br)Ae.set(we,Br);return Br})();Ke.set(we,Wr);try{return await Wr}finally{Ke.delete(we)}}let xi=await Pi({username:"",passwordHash:"",role:"admin",sites:{}},E);if(!xi)throw Error("ts-cloud dashboard UI not found. Run `bun run build` in ts-cloud or reinstall the package.");let J=new WeakMap,pe=process.env.TS_CLOUD_DASHBOARD_TERMINAL!=="0",Ce=process.env.TS_CLOUD_DASHBOARD_AUTH==="0";if(Ce&&e.box)throw Error("TS_CLOUD_DASHBOARD_AUTH=0 is refused in box mode: the dashboard is internet-facing there, and disabling auth would expose a root shell.");let Re=!Ce,Dt=Kh(t),qt=Re?Zh(t,process.env.TS_CLOUD_UI_USERNAME?.trim()||"admin"):void 0,ve=new ke(a.store,{encryptionKey:k(t)}),pt=new Ue(a.store),et=new Rt(a.store),qe=new Kt(a.store,{encryptionKey:k(t)}),Jr=new Dn(a.store),vs=new xn(a.store,{cwd:t}),Di=new kn(a.store,{encryptionKey:k(t)}),kt=new b(a.store,{workerId:`dashboard:${process.pid}`}),_t=new Wt(a.store),Ui=new Gt(a.store,k(t)),go=new hr(a.store),Va=new Rr(_t,kt,Ui),mo=o.project?.region??"us-east-1",op=k(t),Jn=new vr(go,{encryptionKey:op,backends:[new St(a.store,op),new yr(new H(mo),mo),new Sr(new We(mo),mo),new br]});await Yr(Jn,a,o);let Td=new le(mo),mb={aws_rds:new Tn(new In(Td)),aws_aurora:new En(new Rn(Td)),aws_elasticache:new wn(new Pn(new te(mo))),server:new Cn(new rt),container:new An(new rt)},sp=(I)=>mb[I.provider],sr=new Mn(a.store),jo=new Or(sr,kt),ap=new Un(Ui),fb={managed_database:new gu(_t,Td),logical_database:new bu(_t,Ui),volume:new vu,files:new yu(t),control_plane:new Iu(a.store,t),infrastructure:new Eu(new va(mo))},hb=(I)=>fb[I.resourceKind],yb=(I)=>I.provider==="aws_backup"?void 0:ap,Ad=new st(a.store),kd=[new Nt,new Mr(A(t,"volumes"))],Vi=new Lr(Ad,kd,kt),ua=new Ie(a.store),Oi=new pn(ua,[new tt("aws"),new tt("hetzner"),new tt("ssh")],kt),fo=new mn(a.store),cp=new gn(fo,ua),Fo=new fn(a.store),dp=new hn(Fo,kt),qi=new yn(a.store),Rd=new Sn(qi,kt),up=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((I)=>new bn(I,a.store,a.project.id,a.organization.id)),Er=new _r(a.store),lp=new Ln(Er,{queue:kt}),nr=new Fe(a.store),ho=new Be(a.store),ii=new nt(a.store),Ge=new ct(a.store,{encryptionKey:k(t)}),bb=()=>ub(a.store);for(let I of a.environments.values())$r(Er,o,{organization:a.organization,project:a.project,environment:I,resources:a.store.listResources(a.project.id,I.id)});let oi=new rr(Ge,{emailImpl:async(I)=>{let{email:Ee}=await import("./chunk-v6mysz8x.js");return Ee.send(I)}}),pp=async(I)=>{let Ee=Ur(Ge,a.project.id,I),Ne=[];for(let we of Ee.filter((Je)=>Je.notify&&Je.alert))Ne.push(...await oi.deliverAll(oi.enqueue(a.organization.id,we.alert,we.transition)));return Ne.push(...await oi.deliverAll(oi.enqueueRemindersAndEscalations(a.organization.id,Ge.listAlerts(a.project.id,{environmentId:I,states:["firing"]})))),Ne.push(...await oi.retryDue()),{evaluations:Ee,deliveries:Ne}},Pd=!1,Sb=async()=>{if(Pd)return;Pd=!0;try{for(let I of a.environments.values())for(let Ee of Ge.listHealthChecks(a.project.id,I.id).filter((Ne)=>Ne.enabled)){let Ne=Ge.listHealthResults(Ee.id,1)[0];if(Ne&&Date.now()-new Date(Ne.checkedAt).getTime()<Ee.intervalSeconds*1000)continue;let we=await new Oe(Ge).runAndEvaluate(Ee);for(let Je of we.evaluations.filter((mt)=>mt.notify&&mt.alert))await oi.deliverAll(oi.enqueue(a.organization.id,Je.alert,Je.transition))}}finally{Pd=!1}},gp=setInterval(()=>{for(let I of a.environments.values())pp(I.id).catch((Ee)=>console.error("ts-cloud alert evaluation failed:",Ee))},60000);gp.unref?.();let mp=setInterval(()=>{Sb().catch((I)=>console.error("ts-cloud health check evaluation failed:",I))},30000);mp.unref?.();let fp=setInterval(()=>{try{lp.tick()}catch(I){console.error("ts-cloud scheduled job evaluation failed:",I)}},30000);fp.unref?.();let hp=setInterval(()=>{try{jo.enqueueDue(),jo.enqueueRetention()}catch(I){console.error("ts-cloud backup policy evaluation failed:",I)}},30000);hp.unref?.(),nr.cleanup();let yp=setInterval(()=>{try{nr.cleanup()}catch(I){console.error("ts-cloud preview cleanup failed:",I)}},3600000);yp.unref?.();let vb=e.queueWorker??!0,wb=aA(),Ib=async(I,Ee)=>{let we=(I.environmentId?a.store.listEnvironments(I.projectId).find((Je)=>Je.id===I.environmentId):void 0)?.slug??String(E);if(Ee.kind==="dashboard_operation"&&Ee.operationId){let Je=q.get(we)??O,mt=_n(Ee.operationId,o,Je);if(!mt||mt.danger||!["scheduler","backup","worker"].includes(mt.group))return{ok:!1,stderr:"The allowlisted dashboard operation is no longer available."};let N=await kr(o,we,mt);return{ok:N.ok,stdout:N.stdout,stderr:N.stderr??N.error,retryable:/temporar|unavailable|timeout|network/i.test(N.stderr??N.error??""),output:{command:N.command??null,operation:N.operation}}}if(Ee.kind==="serverless_scheduler"){let Je=await Xl(o,we,"run");return{ok:Je.ok,stdout:Je.stdout,stderr:Je.error,retryable:/temporar|unavailable|timeout|network/i.test(Je.error??""),output:{command:Je.command??null,operation:"serverless_scheduler"}}}return{ok:!1,stderr:`No safe executor is configured for ${Ee.kind}.`}},qa=vb?new $o(kt,{...da({store:a.store,execute:async(I,Ee)=>{let Ne=Ee.operation.input&&typeof Ee.operation.input==="object"&&!Array.isArray(Ee.operation.input)?Ee.operation.input:{},we=Ne.source&&typeof Ne.source==="object"?Ne.source:void 0,Je=t,mt,N,Wr;try{if(we?.bindingId&&we?.connectionId&&we?.commitSha){let Ye=qe.getBinding(String(we.bindingId)),at=qe.getConnection(String(we.connectionId));if(!Ye||!at||Ye.connectionId!==at.id)throw Error("Queued source binding is no longer available");let wr=(Ye.repositoryId?qe.getRepository(Ye.repositoryId):qe.listRepositories(at.id).find((Es)=>Es.fullName.toLowerCase()===Ye.repositoryFullName.toLowerCase()))?.cloneUrl;if(!wr&&at.provider==="generic_ssh")wr=`git@${new URL(at.host).hostname}:${Ye.repositoryFullName}.git`;if(!wr)wr=new URL(`/${Ye.repositoryFullName}.git`,at.host.endsWith("/")?at.host:`${at.host}/`).href;let ye=Ye.deployKeyId?qe.getDeployKey(Ye.deployKeyId):void 0,Mt=ye&&Ye.deployKeyId?{...ye,privateKey:qe.getDeployPrivateKey(Ye.deployKeyId)}:void 0;if(["github","gitlab","bitbucket","gitea"].includes(at.provider)&&I.target.previewId){let Es=wo(at,qe.getCredential(at.id)),de=nr.previews.getInstance(I.target.previewId);Wr=async(si,Ka)=>{try{await Es.setCommitStatus(Ye.repositoryFullName,String(we.commitSha),{state:si,url:de?.url,description:Ka})}catch(Ts){Ee.log(`Could not publish source status: ${Ts instanceof Error?Ts.message:String(Ts)}`,{stream:"stderr"})}},await Wr("pending",`Preview deployment started for ${String(we.commitSha).slice(0,12)}`)}mt=ip(Et(Cd(),"ts-cloud-queued-source-")),Ee.log(`Checking out immutable source commit ${we.commitSha}.`,{stream:"system"}),Je=(await Wd({remote:wr,binding:Ye,destination:Et(mt,"checkout"),ref:String(we.branch??Ye.defaultBranch),commitSha:String(we.commitSha)},{credential:qe.getCredential(at.id),deployKey:Mt})).directory}if(Ee.operation.kind!=="preview.destroy"){let Ye=I.target.previewId?nr.previews.getInstance(I.target.previewId):void 0,at=Ye?nr.previews.getDefinition(Ye.definitionId):void 0,Br=Ee.operation.resourceId?a.store.getResource(Ee.operation.resourceId):void 0;if(N=await Jn.resolve({projectId:a.project.id,environmentId:Ee.operation.environmentId,resourceId:Ee.operation.resourceId,functionId:Br?.kind==="function"?Br.id:void 0,previewId:Ye?.id,trustedPreview:!!Ye&&!Ye.fork,allowedPreviewSecrets:at?.inheritedSecrets}),N.warnings.some((wr)=>wr.code==="missing_required"))throw Error(`Required deployment configuration is unavailable: ${N.warnings.filter((wr)=>wr.code==="missing_required").map((wr)=>wr.key).join(", ")}`);if(Ee.operation.resourceId)for(let wr of Object.values(N.entries))go.setDependency({entryId:wr.id,resourceId:Ee.operation.resourceId,injectionTarget:"environment",required:wr.required,requiresRedeploy:!0});Ee.log(`Resolved configuration ${N.configurationHash.slice(0,18)} for ${Object.keys(N.values).length} keys.`,{stream:"system"})}let ir=await np(I,{cwd:Je,cliEntry:i,signal:Ee.signal,env:N?.values,onOutput:(Ye,at)=>Ee.log(at,{stream:Ye,step:"execute",secrets:[...wb,...Object.entries(N?.entries??{}).filter(([,Br])=>Br.kind==="secret").map(([Br])=>N.values[Br]).filter(Boolean)]})});if(ir.ok&&Ee.operation.resourceId&&N)for(let Ye of Object.values(N.entries))go.setDependency({entryId:Ye.id,resourceId:Ee.operation.resourceId,injectionTarget:"environment",required:Ye.required,requiresRedeploy:!1,lastDeployedVersion:Ye.version});return await Wr?.(ir.ok?"success":"failure",ir.ok?`Preview is ready at ${String(we?.commitSha).slice(0,12)}`:`Preview deployment failed at ${String(we?.commitSha).slice(0,12)}`),ir}catch(ir){throw await Wr?.("error",`Preview deployment could not complete at ${String(we?.commitSha).slice(0,12)}`),ir}finally{if(mt)Ss(mt,{recursive:!0,force:!0})}}}),...Mg({store:Er,executor:Ib}),...Hg({store:_t,secrets:Ui,resolveAdapter:sp}),...Nf(ua,Oi.drivers),...th(Fo,[new Sl("aws","AWS regional execution requires an injected AwsRegionalTransport; topology and plans were preserved without provider mutation.")]),...Hf({store:qi,cleanup:up}),...la(Ad,kd),...qg({store:sr,queue:kt,resolveSource:hb,resolveDestination:yb,validateHealth:async(I,Ee)=>{if(!I.healthCheckId)return{healthy:!0,mode:"adapter"};let Ne=Ge.getHealthCheck(I.healthCheckId);if(!Ne||Ne.projectId!==I.projectId)return{healthy:!1,error:"Configured restore health check was not found."};let we=await new Oe(Ge).runAndEvaluate(Ne);return{healthy:we.result.status==="healthy",healthCheckId:Ne.id,healthResultId:we.result.id,target:Ee}}}),...Wp({store:a.store,resolveDriver:e.releaseDriver??((I)=>({name:`${a.store.getResource(I.resourceId)?.provider??"provider"} release driver`,capability:()=>({strategy:I.strategy,supported:!1,explanation:"This dashboard process has no immutable activation driver configured for the target provider.",capacityMultiplier:1,costImpact:"none",rollback:"The previous release remains preserved; configure a release driver before retrying."}),activate:async()=>{throw Error("Immutable activation driver is not configured")},rollback:async()=>{throw Error("Immutable rollback driver is not configured")}})),resolveHealthGate:async(I,Ee)=>{let Ne=Ge.listHealthChecks(Ee.projectId,Ee.environmentId).find((Je)=>Je.enabled&&Je.name===I&&(!Je.resourceId||Je.resourceId===Ee.resourceId));if(!Ne)return{healthy:!1,message:`Named health gate ${I} was not found for this release.`};let we=await new Oe(Ge).runAndEvaluate(Ne);return{healthy:we.result.status==="healthy",evidence:{healthCheckId:Ne.id,healthResultId:we.result.id,status:we.result.status,timings:we.result.timings},message:we.result.message}}})},{parallelism:e.queueParallelism??(Number(process.env.TS_CLOUD_QUEUE_PARALLELISM)||8),onError:(I)=>console.error("ts-cloud deployment queue worker failed:",I)}):void 0;if($n(a),od(et,ae(a,String(E)),O),qt)sd(a,qt.users),ry(ve,a,qt.users);let Bt=ey({cwd:t,enabled:Re,secret:Dt,authentication:ve,authorization:{store:a.store,organizationId:a.organization.id,projectId:a.project.id,defaultEnvironment:String(E)}}),ar=new Il,bp=setInterval(()=>ar.sweep(),60000);bp.unref?.();let Ja=new Ba,xd=new Ba(3,900000,900000),Wa=new Ba(8,900000,900000),Sp=setInterval(()=>Ja.prune(),300000),vp=setInterval(()=>xd.prune(),300000),wp=setInterval(()=>Wa.prune(),300000);if(Sp.unref?.(),vp.unref?.(),wp.unref?.(),Re){if(qt?.generated)console.warn(`
478
478
  ts-cloud dashboard: created the first admin.
479
479
  username: ${qt.generated.username}
480
480
  password: ${qt.generated.password}
481
481
  Saved (hashed) to ${Yh()}. This password is shown once.
482
482
  `)}else console.warn(" ts-cloud dashboard: authentication is DISABLED (TS_CLOUD_DASHBOARD_AUTH=0). Every request runs as an admin.");let yo=r!=="127.0.0.1"&&r!=="localhost",Dd=(I)=>xT("sha256").update(`${Dt}:${I}`).digest("hex").slice(0,16),Cb=Kd({controlPlane:a.store,identities:pt,sources:qe,applications:{drafts:Jr,artifacts:vs,registries:Di}}),Ip=(I)=>I.headers.get("user-agent")?.trim().slice(0,256)||void 0,Ha=(I,Ee,Ne,we="local")=>ve.createSession({identityId:I,authMethod:we,userAgent:Ip(Ee),networkHint:Dd(Ne)}),Me=(I)=>{let Ee=a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`),Ne=Ee?a.store.getMembershipForActor(a.organization.id,Ee.id):void 0;return{actor:Ee,membership:Ne,grants:Ne?a.store.listGrants(Ne.id):[]}},ws=(I,Ee,Ne)=>{if(I.role==="admin")return!0;let we=a.store.getOperation(Ee),Je=Me(I);if(!we||!Je.membership)return!1;let mt=we.resourceId?{type:"resource",id:we.resourceId}:we.environmentId?{type:"environment",id:we.environmentId}:we.projectId?{type:"project",id:we.projectId}:{type:"organization"},N=a.store.resolveAuthorizationTarget(a.organization.id,mt);return!!N&&Z({membership:Je.membership,grants:Je.grants,capability:Ne,target:N}).allowed},Ar=(I,Ee,Ne)=>{if(I.role==="admin")return!0;let we=Me(I);if(!we.membership)return!1;let Je=a.store.resolveAuthorizationTarget(a.organization.id,{type:"resource",id:Ee});return!!Je&&Z({membership:we.membership,grants:we.grants,capability:Ne,target:Je}).allowed},pa=(I,Ee,Ne)=>{if(I.role==="admin")return!0;let we=Me(I);if(!we.membership)return!1;let Je=a.store.resolveAuthorizationTarget(a.organization.id,{type:"environment",id:Ee});return!!Je&&Z({membership:we.membership,grants:we.grants,capability:Ne,target:Je}).allowed},Ga=(I,Ee)=>{if(I.role==="admin")return!0;let Ne=Me(I);if(!Ne.membership)return!1;let we=a.store.resolveAuthorizationTarget(a.organization.id,{type:"organization"});return!!we&&Z({membership:Ne.membership,grants:Ne.grants,capability:Ee,target:we}).allowed},Is=Bun.serve({hostname:r,port:n,idleTimeout:30,websocket:{open(I){if(!pe){I.send(`The web terminal is disabled (TS_CLOUD_DASHBOARD_TERMINAL=0).\r
483
483
  `),I.close();return}let Ee=Zy((Ne)=>I.send(Ne),{cwd:t,onExit:()=>{try{I.close()}catch{}}});J.set(I,Ee),I.send(`Connected to ${r==="127.0.0.1"?"localhost":r} shell. This is a line-oriented shell (no full-screen apps).\r
484
- `)},message(I,Ee){J.get(I)?.write(typeof Ee==="string"?Ee:new TextDecoder().decode(Ee))},close(I){J.get(I)?.close(),J.delete(I)}},async fetch(I,Ee){let Ne=Date.now(),we=I.clone(),Je=I.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),mt=!["GET","HEAD","OPTIONS"].includes(I.method.toUpperCase()),N=new URL(I.url),ir=await(async()=>{let Ye=Ee??Is,at=WT(r,Ye.port??n),Br=await Cb(I,Dd(Ye.requestIP(I)?.address??"unknown"));if(Br)return Br;let wr=N.searchParams.get("env"),ye=GT(m,E,wr),Mt=q.get(ye);if(!Mt)Mt=await Ze(ye);try{if(!XT(I))return S({ok:!1,error:"Cross-site requests are not allowed."},403);let Uo=/^\/api\/source\/webhooks\/([A-Za-z0-9_-]{16,200})$/.exec(N.pathname);if(Uo&&I.method==="POST"){let d=await ag({sources:qe,controlPlane:a.store,endpointToken:Uo[1],headers:I.headers,rawBody:new Uint8Array(await I.arrayBuffer())});return S({accepted:d.accepted,duplicate:d.duplicate,status:d.status,operationIds:d.operations.map((g)=>g.id),message:d.message},d.accepted?202:404)}let Es=/^\/auth\/oidc\/([a-z0-9-]+)\/(start|callback)$/.exec(N.pathname);if(Es&&I.method==="GET"){let[,d,g]=Es;if(!at)return new Response(null,{status:302,headers:{location:"/login?sso_error=configuration"}});if(g==="start")try{let T=await iu(ve,d,at,N.searchParams.get("return")??void 0,e.oidcFetch);return new Response(null,{status:302,headers:{location:T.authorizationUrl,"cache-control":"no-store"}})}catch(T){return a.store.appendEvent({organizationId:a.organization.id,type:"auth.oidc.start_failed",level:"warning",payload:{provider:d,reason:T instanceof Error?T.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=start","cache-control":"no-store"}})}try{if(N.searchParams.has("error")){let K=ve.getOidcProviderBySlug(d),B=N.searchParams.get("state");if(K&&B)ve.consumeOidcTransaction(K.id,B);throw Error("OIDC provider returned an authorization error")}let T=await ou(ve,{providerSlug:d,state:N.searchParams.get("state")??"",code:N.searchParams.get("code")??"",origin:at},e.oidcFetch),_=ny(ve,a,t,T.identity);ve.recordLogin(_.identity.id);let L=Ha(_.identity.id,I,Ye.requestIP(I)?.address??"unknown","oidc");return gi(),a.store.appendEvent({organizationId:a.organization.id,actorId:_.identity.actorId,type:"auth.login.succeeded",payload:{method:"oidc",provider:d,provisioned:_.provisioned}}),new Response(null,{status:302,headers:{location:T.returnPath,"cache-control":"no-store","set-cookie":ea(L.token,{secure:yo,maxAgeMs:Co})}})}catch(T){return a.store.appendEvent({organizationId:a.organization.id,type:"auth.oidc.callback_failed",level:"warning",payload:{provider:d,reason:T instanceof Error?T.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=callback","cache-control":"no-store"}})}}if(N.pathname==="/api/invitations/accept"&&I.method==="POST"){let d=await oe(I),g=String(d.token??"").trim(),T=String(d.username??"").trim(),_=String(d.password??"");if(!g||!fd(T)||_.length<12)return S({ok:!1,error:"Invitation token, valid username, and a password of at least 12 characters are required."},422);let L=a.store.inspectInvitationToken(g);if(!L||L.state!=="pending")return S({ok:!1,error:L?`Invitation is ${L.state}`:"Invitation is invalid"},L?409:404);let K=pi(Fn(t),T),B=ve.getIdentityByUsername(T);if(K&&!Ti(_,B?.passwordHash??K.passwordHash))return S({ok:!1,error:"That username already exists; enter its current password to continue."},401);let Q=ve.getIdentityByEmail(L.email);if(Q&&Q.id!==B?.id)return S({ok:!1,error:"This invitation belongs to an existing account. Sign in with that account or ask an owner to resend it."},409);let fe=La(t,{username:T,password:K?void 0:_,name:typeof d.name==="string"?d.name:void 0,email:L.email,sites:K?.sites??{}}),ue=mr(a.store,fe.user);try{let He=a.store.acceptInvitation(g,ue.id),be=B?ve.setVerifiedEmail(B.id,He.invitation.email):ve.createIdentity({actorId:ue.id,username:fe.user.username,email:He.invitation.email,emailVerified:!0,passwordHash:fe.user.passwordHash}),Le=Ha(be.id,I,Ye.requestIP(I)?.address??"unknown");return gi(),S({ok:!0,user:ta(fe.user),organization:a.organization,membership:He.membership},200,{"set-cookie":ea(Le.token,{secure:yo,maxAgeMs:Co})})}catch(He){if(!K)zl(t,fe.user.username);let be=He instanceof Error?He.message:"Invitation could not be accepted.";return S({ok:!1,error:be},be.includes("expired")||be.includes("revoked")||be.includes("accepted")?409:404)}}if(N.pathname==="/api/auth/password-reset/request"&&I.method==="POST"){let d=await oe(I),g=String(d.identifier??"").trim().toLowerCase(),T=Ye.requestIP(I)?.address??"unknown",_=xd.check(g,T),L=g.includes("@")?ve.getIdentityByEmail(g):ve.getIdentityByUsername(g);if(_.allowed)xd.recordFailure(g,T);if(_.allowed&&L?.email&&L.emailVerifiedAt&&!L.disabledAt){ve.revokeActionTokens(L.id,"password_reset");let K=ve.createActionToken(L.id,"password_reset"),B=`${N.origin}/reset-password?token=${encodeURIComponent(K.token)}`,Q=await Sa(o,{to:L.email,subject:"Reset your ts-cloud password",text:`Reset your ts-cloud password: ${B}
484
+ `)},message(I,Ee){J.get(I)?.write(typeof Ee==="string"?Ee:new TextDecoder().decode(Ee))},close(I){J.get(I)?.close(),J.delete(I)}},async fetch(I,Ee){let Ne=Date.now(),we=I.clone(),Je=I.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),mt=!["GET","HEAD","OPTIONS"].includes(I.method.toUpperCase()),N=new URL(I.url),ir=await(async()=>{let Ye=Ee??Is,at=WT(r,Ye.port??n),Br=await Cb(I,Dd(Ye.requestIP(I)?.address??"unknown"));if(Br)return Br;let wr=N.searchParams.get("env"),ye=GT(m,E,wr),Mt=q.get(ye);if(!Mt)Mt=await Ze(ye);try{if(!XT(I))return S({ok:!1,error:"Cross-site requests are not allowed."},403);let Uo=/^\/api\/source\/webhooks\/([A-Za-z0-9_-]{16,200})$/.exec(N.pathname);if(Uo&&I.method==="POST"){let d=await ag({sources:qe,controlPlane:a.store,endpointToken:Uo[1],headers:I.headers,rawBody:new Uint8Array(await I.arrayBuffer())});return S({accepted:d.accepted,duplicate:d.duplicate,status:d.status,operationIds:d.operations.map((g)=>g.id),message:d.message},d.accepted?202:404)}let Es=/^\/auth\/oidc\/([a-z0-9-]+)\/(start|callback)$/.exec(N.pathname);if(Es&&I.method==="GET"){let[,d,g]=Es;if(!at)return new Response(null,{status:302,headers:{location:"/login?sso_error=configuration"}});if(g==="start")try{let T=await iu(ve,d,at,N.searchParams.get("return")??void 0,e.oidcFetch);return new Response(null,{status:302,headers:{location:T.authorizationUrl,"cache-control":"no-store"}})}catch(T){return a.store.appendEvent({organizationId:a.organization.id,type:"auth.oidc.start_failed",level:"warning",payload:{provider:d,reason:T instanceof Error?T.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=start","cache-control":"no-store"}})}try{if(N.searchParams.has("error")){let K=ve.getOidcProviderBySlug(d),B=N.searchParams.get("state");if(K&&B)ve.consumeOidcTransaction(K.id,B);throw Error("OIDC provider returned an authorization error")}let T=await ou(ve,{providerSlug:d,state:N.searchParams.get("state")??"",code:N.searchParams.get("code")??"",origin:at},e.oidcFetch),_=ny(ve,a,t,T.identity);ve.recordLogin(_.identity.id);let M=Ha(_.identity.id,I,Ye.requestIP(I)?.address??"unknown","oidc");return gi(),a.store.appendEvent({organizationId:a.organization.id,actorId:_.identity.actorId,type:"auth.login.succeeded",payload:{method:"oidc",provider:d,provisioned:_.provisioned}}),new Response(null,{status:302,headers:{location:T.returnPath,"cache-control":"no-store","set-cookie":ea(M.token,{secure:yo,maxAgeMs:Co})}})}catch(T){return a.store.appendEvent({organizationId:a.organization.id,type:"auth.oidc.callback_failed",level:"warning",payload:{provider:d,reason:T instanceof Error?T.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=callback","cache-control":"no-store"}})}}if(N.pathname==="/api/invitations/accept"&&I.method==="POST"){let d=await oe(I),g=String(d.token??"").trim(),T=String(d.username??"").trim(),_=String(d.password??"");if(!g||!fd(T)||_.length<12)return S({ok:!1,error:"Invitation token, valid username, and a password of at least 12 characters are required."},422);let M=a.store.inspectInvitationToken(g);if(!M||M.state!=="pending")return S({ok:!1,error:M?`Invitation is ${M.state}`:"Invitation is invalid"},M?409:404);let K=pi(Fn(t),T),B=ve.getIdentityByUsername(T);if(K&&!Ti(_,B?.passwordHash??K.passwordHash))return S({ok:!1,error:"That username already exists; enter its current password to continue."},401);let Q=ve.getIdentityByEmail(M.email);if(Q&&Q.id!==B?.id)return S({ok:!1,error:"This invitation belongs to an existing account. Sign in with that account or ask an owner to resend it."},409);let fe=La(t,{username:T,password:K?void 0:_,name:typeof d.name==="string"?d.name:void 0,email:M.email,sites:K?.sites??{}}),ue=mr(a.store,fe.user);try{let He=a.store.acceptInvitation(g,ue.id),be=B?ve.setVerifiedEmail(B.id,He.invitation.email):ve.createIdentity({actorId:ue.id,username:fe.user.username,email:He.invitation.email,emailVerified:!0,passwordHash:fe.user.passwordHash}),Le=Ha(be.id,I,Ye.requestIP(I)?.address??"unknown");return gi(),S({ok:!0,user:ta(fe.user),organization:a.organization,membership:He.membership},200,{"set-cookie":ea(Le.token,{secure:yo,maxAgeMs:Co})})}catch(He){if(!K)zl(t,fe.user.username);let be=He instanceof Error?He.message:"Invitation could not be accepted.";return S({ok:!1,error:be},be.includes("expired")||be.includes("revoked")||be.includes("accepted")?409:404)}}if(N.pathname==="/api/auth/password-reset/request"&&I.method==="POST"){let d=await oe(I),g=String(d.identifier??"").trim().toLowerCase(),T=Ye.requestIP(I)?.address??"unknown",_=xd.check(g,T),M=g.includes("@")?ve.getIdentityByEmail(g):ve.getIdentityByUsername(g);if(_.allowed)xd.recordFailure(g,T);if(_.allowed&&M?.email&&M.emailVerifiedAt&&!M.disabledAt){ve.revokeActionTokens(M.id,"password_reset");let K=ve.createActionToken(M.id,"password_reset"),B=`${N.origin}/reset-password?token=${encodeURIComponent(K.token)}`,Q=await Sa(o,{to:M.email,subject:"Reset your ts-cloud password",text:`Reset your ts-cloud password: ${B}
485
485
 
486
- This link expires in one hour and can be used once.`});a.store.appendEvent({organizationId:a.organization.id,actorId:L.actorId,type:"auth.password_reset.requested",payload:{delivered:Q}})}return S({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(N.pathname==="/api/auth/password-reset/complete"&&I.method==="POST"){let d=await oe(I),g=String(d.token??"").trim(),T=String(d.password??"");if(!g||T.length<12)return S({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let _=ve.consumeActionToken(g,"password_reset"),L=No(T),K=ve.updatePassword(_.identityId,L);return yd(t,K.username,L),a.store.appendEvent({organizationId:a.organization.id,actorId:K.actorId,type:"auth.password_reset.completed"}),S({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":md({secure:yo})})}catch(_){let L=_ instanceof Error?_.message:"Password reset failed.";return S({ok:!1,error:L.replace("Action token","Reset link")},L.includes("consumed")||L.includes("expired")?409:404)}}if(N.pathname==="/api/login"&&I.method==="POST"){let d=await oe(I),g=String(d.username??"").trim(),T=String(d.password??""),_=Ye.requestIP(I)?.address??"unknown",L=Ja.check(g,_);if(!L.allowed)return S({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((L.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(L.retryAfterSeconds??60)});let K=pi(Fn(t),g),B=ve.getIdentityByUsername(g),Q=B?.passwordHash??K?.passwordHash??JT;if(!(Ti(T,Q)&&!!K&&!!B&&!B.disabledAt))return Ja.recordFailure(g,_),S({ok:!1,error:"Incorrect username or password."},401);if(iy(ve,a,B))return S({ok:!1,error:"Single sign-on is required for this account."},403);Ja.recordSuccess(g,_);let ue=B,He=ue.requiresPasswordUpgrade||xh(ue.passwordHash);if(He){let Le=No(T);ue=ve.rehashPassword(ue.id,Le),yd(t,ue.username,Le)}if(ve.recordLogin(ue.id),ve.getMfaFactor(ue.id)?.state==="active"){let Le=ve.createMfaChallenge(ue.id,"login");return a.store.appendEvent({organizationId:a.organization.id,actorId:ue.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),S({ok:!0,mfaRequired:!0,challengeToken:Le.token,passwordUpgraded:He})}let be=Ha(ue.id,I,_);return a.store.appendEvent({organizationId:a.organization.id,actorId:ue.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),S({ok:!0,user:ta(K),passwordUpgraded:He},200,{"set-cookie":ea(be.token,{secure:yo,maxAgeMs:Co})})}if(N.pathname==="/api/auth/mfa/complete"&&I.method==="POST"){let d=await oe(I),g=String(d.challengeToken??"").trim(),T=String(d.code??"").trim(),_=Ye.requestIP(I)?.address??"unknown",K=ve.inspectMfaChallengeToken(g,"login")?.identityId??"unknown-mfa",B=Wa.check(K,_);if(!B.allowed)return S({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(B.retryAfterSeconds??60)});try{let Q=ve.completeMfaChallenge(g,T,"login");Wa.recordSuccess(K,_);let fe=new Date().toISOString(),ue=ve.createSession({identityId:Q.identity.id,userAgent:Ip(I),networkHint:Dd(_),mfaAt:fe,recentAuthAt:fe});return a.store.appendEvent({organizationId:a.organization.id,actorId:Q.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:Q.method}}),S({ok:!0},200,{"set-cookie":ea(ue.token,{secure:yo,maxAgeMs:Co})})}catch{return Wa.recordFailure(K,_),S({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(N.pathname==="/api/logout"&&I.method==="POST"){let d=Bt.resolveSession(I);if(d)ve.revokeSession(d.identityId,d.id);let g=md({secure:yo});if(I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":g}});return S({ok:!0},200,{"set-cookie":g})}if(N.pathname==="/login"){let d=ve.listOidcProviders(a.organization.id).map((g)=>({slug:g.slug,name:g.name}));return new Response(oy(O?.mode==="serverless",d),{headers:{"content-type":"text/html; charset=utf-8"}})}if(N.pathname==="/forgot-password"||N.pathname==="/reset-password")return new Response(sy(N.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(N.pathname==="/accept-invitation")return cb(xi,N.pathname);let de=Bt.resolveUser(I);if(!de){if(!N.pathname.startsWith("/api/")&&I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return S({ok:!1,error:"Sign in to continue."},401)}let si=po(de,ye);if(N.pathname==="/api/me"){let d=a.store.getActorByExternalId("user",`dashboard:${de.username.toLowerCase()}`),g=d?a.store.getMembershipForActor(a.organization.id,d.id):void 0,T=a.store.resolveAuthorizationTarget(a.organization.id,g?.scope??{type:"project",id:a.project.id})??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id});return S({ok:!0,user:ta(de),authEnabled:Re,organization:a.organization,membership:g,capabilities:en({membership:g,grants:g?a.store.listGrants(g.id):[],target:T})})}if(N.pathname.startsWith("/api/")){let d=await ty(I,N.pathname),g=Bt.check(I,N.pathname,de,d);if(!g.ok)return S({ok:!1,error:g.error},g.status??403);if(Re&&tA.has(`${I.method.toUpperCase()} ${N.pathname}`)){let T=Bt.resolveSession(I);if(!T||!ve.isRecentlyAuthenticated(T))return S({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(N.pathname==="/api/auth/security"&&I.method==="GET"){let d=Me(de),g=d.actor?ve.getIdentityByActor(d.actor.id):void 0,T=Bt.resolveSession(I);return S({identity:g?{username:g.username,email:g.email,emailVerifiedAt:g.emailVerifiedAt,requiresPasswordUpgrade:g.requiresPasswordUpgrade,lastLoginAt:g.lastLoginAt}:void 0,currentSessionId:T?.id,sessions:g?ve.listSessions(g.id,{includeInactive:!0}):[],mfa:g?{factor:ve.getMfaFactor(g.id),recoveryCodesRemaining:ve.remainingRecoveryCodes(g.id)}:void 0})}if(N.pathname==="/api/auth/oidc/providers"&&I.method==="GET")return S({providers:ve.listOidcProviders(a.organization.id,{includeDisabled:!0}),callbackOrigin:at,callbackPattern:at?`${at}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(N.pathname==="/api/auth/oidc/providers"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=g.actor?ve.getIdentityByActor(g.actor.id):void 0,_=d.enforceSso===!0;if(_&&(!T?.emailVerifiedAt||ve.remainingRecoveryCodes(T.id)<1))return S({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let L=wd(d.defaultRole),K=ve.upsertOidcProvider({id:typeof d.id==="string"?d.id:void 0,organizationId:a.organization.id,slug:String(d.slug??""),name:String(d.name??""),issuer:String(d.issuer??""),clientId:String(d.clientId??""),clientSecret:typeof d.clientSecret==="string"&&d.clientSecret?d.clientSecret:void 0,scopes:Array.isArray(d.scopes)?d.scopes.map(String):void 0,allowedDomains:Array.isArray(d.allowedDomains)?d.allowedDomains.map(String):[],defaultRole:L&&L!=="owner"?L:void 0,enabled:d.enabled!==!1,enforceSso:_});return a.store.appendEvent({organizationId:a.organization.id,actorId:g.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:K.id,issuer:K.issuer,enabled:K.enabled,enforceSso:K.enforceSso}}),S({ok:!0,provider:K})}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"OIDC provider could not be saved."},422)}}if(N.pathname==="/api/auth/oidc/providers"&&I.method==="PATCH"){let d=await oe(I),g=ve.getOidcProvider(String(d.id??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"OIDC provider was not found."},404);let T=Me(de),_=ve.setOidcProviderEnabled(g.id,d.enabled===!0);return a.store.appendEvent({organizationId:a.organization.id,actorId:T.actor?.id,type:_.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:g.id}}),S({ok:!0,provider:_})}if(N.pathname==="/api/automation"&&I.method==="GET"){let d=pt.listServiceAccounts(a.organization.id,{includeDisabled:!0}).map((g)=>{let T=a.store.getMembershipForActor(a.organization.id,g.actorId),_=g.createdByActorId?a.store.getActor(g.createdByActorId):void 0,L=pt.listTokens(g.id,{includeInactive:!0}).map((K)=>({...K,createdBy:K.createdByActorId?a.store.getActor(K.createdByActorId):void 0}));return{account:g,createdBy:_,membership:T,tokens:L}});return S({accounts:d,apiBaseUrl:`${N.origin}/api/v1`,openApiUrl:`${N.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(N.pathname==="/api/automation/service-accounts"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=wd(d.roleTemplate),_=Ua(d);if(!g.actor||!T||T==="owner"||!_)return S({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let L=pt.createServiceAccount({organizationId:a.organization.id,slug:String(d.slug??""),name:String(d.name??""),description:typeof d.description==="string"?d.description:void 0,roleTemplate:T,scope:_,createdByActorId:g.actor.id});return S({ok:!0,...L},201)}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"Service account could not be created."},422)}}if(N.pathname==="/api/automation/service-accounts"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=pt.getServiceAccount(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Service account was not found."},404);return S({ok:!0,account:pt.disableServiceAccount(T.id,g.actor?.id)})}if(N.pathname==="/api/automation/tokens"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=pt.getServiceAccount(String(d.serviceAccountId??"")),_=Ua(d);if(!g.actor||!T||T.organizationId!==a.organization.id||!_||!Array.isArray(d.capabilities))return S({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let L=pt.createToken({serviceAccountId:T.id,name:String(d.name??"API token"),capabilities:d.capabilities.map(String),scope:_,expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,createdByActorId:g.actor.id});return S({ok:!0,token:L.token,secret:L.secret,revealOnce:!0},201)}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"API token could not be created."},422)}}if(N.pathname==="/api/automation/tokens/rotate"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=pt.getToken(String(d.id??"")),_=T?pt.getServiceAccount(T.serviceAccountId):void 0;if(!g.actor||!T||_?.organizationId!==a.organization.id)return S({ok:!1,error:"API token was not found."},404);try{let L=pt.rotateToken(T.id,g.actor.id);return S({ok:!0,token:L.token,secret:L.secret,revealOnce:!0,overlap:!0},201)}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"API token could not be rotated."},409)}}if(N.pathname==="/api/automation/tokens"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=pt.getToken(String(d.id??"")),_=T?pt.getServiceAccount(T.serviceAccountId):void 0;if(!T||_?.organizationId!==a.organization.id)return S({ok:!1,error:"API token was not found."},404);return S({ok:!0,token:pt.revokeToken(T.id,g.actor?.id)})}if(N.pathname==="/api/onboarding"&&I.method==="GET"){let d=qe.listConnections(a.organization.id);return S({drafts:Jr.list(a.project.id),artifacts:vs.list(a.project.id),registries:Di.list(a.organization.id),sourceConnections:d,repositories:d.flatMap((g)=>qe.listRepositories(g.id)),project:{id:a.project.id,slug:a.project.slug,name:a.project.name},environments:[...a.environments.values()].map((g)=>({id:g.id,slug:g.slug,name:g.name,kind:g.kind,region:g.region})),resources:a.store.listResources(a.project.id).filter((g)=>g.kind==="application").map((g)=>({id:g.id,slug:g.slug,name:g.name,environmentId:g.environmentId}))})}if(N.pathname==="/api/onboarding/detect"&&I.method==="POST"){let d=await oe(I);try{if(d.source?.kind==="git"){let _=qe.getConnection(String(d.source.connectionId??"")),L=qe.getRepository(String(d.source.repositoryId??""));if(!_||_.organizationId!==a.organization.id||!L||L.connectionId!==_.id)throw Error("Authorized Git repository was not found");let K=typeof d.source.deployKeyId==="string"?qe.getDeployKey(d.source.deployKeyId):void 0;if(K&&K.connectionId!==_.id)throw Error("Deploy key does not belong to this connection");let B=ip(Et(Cd(),"ts-cloud-onboarding-git-"));try{let Q=await Wd({remote:L.cloneUrl,destination:Et(B,"checkout"),ref:String(d.source.ref??L.defaultBranch),sparsePaths:Array.isArray(d.source.sparsePaths)?d.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:a.project.id,connectionId:_.id,repositoryId:L.id,repositoryFullName:L.fullName,defaultBranch:L.defaultBranch,monorepoRoot:String(d.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:d.source.submodules===!0,cloneDepth:1,deployKeyId:K?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:qe.getCredential(_.id),deployKey:K?{...K,privateKey:qe.getDeployPrivateKey(K.id)}:void 0,timeoutMs:120000});return S({ok:!0,commitSha:Q.commitSha,candidates:At(Nn(Q.directory))})}finally{Ss(B,{recursive:!0,force:!0})}}if(Array.isArray(d.files)){if(d.files.length>1e4)throw Error("Detection file-count limit exceeded");let _=d.files.map((L)=>({path:String(L.path??""),size:Number(L.size??0),content:typeof L.content==="string"?L.content.slice(0,262144):void 0}));return S({ok:!0,candidates:At(_)})}let g=NT(t,String(d.root??".")),T=_T(t,g);if(T===".."||T.startsWith(`..${$T}`))throw Error("Detection root must stay inside the project");return S({ok:!0,candidates:At(Nn(g))})}catch(g){return S({ok:!1,error:g instanceof Error?g.message:"Application detection failed."},422)}}if(N.pathname==="/api/onboarding/plan"&&I.method==="POST"){let d=await oe(I);try{return S({ok:!0,plan:se(d.draft,Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):[])})}catch(g){return S({ok:!1,error:g instanceof Error?g.message:"Application plan could not be generated."},422)}}if(N.pathname==="/api/onboarding/drafts"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{return S({ok:!0,draft:Jr.create({organizationId:a.organization.id,projectId:a.project.id,name:String(d.name??d.draft?.name??"Application draft"),draft:{...d.draft,projectId:a.project.id},step:d.step,suppliedSecretNames:Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):[],actorId:g.actor?.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Application draft could not be saved."},422)}}if(N.pathname==="/api/onboarding/drafts"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=Jr.get(String(d.id??""));if(!T||T.projectId!==a.project.id)return S({ok:!1,error:"Application draft was not found."},404);try{return S({ok:!0,draft:Jr.update(T.id,Number(d.version),{draft:{...d.draft,projectId:a.project.id},step:d.step,suppliedSecretNames:Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):void 0,actorId:g.actor?.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Application draft could not be updated."},409)}}if(N.pathname==="/api/onboarding/artifacts"&&I.method==="POST"){let d=Me(de);if(Number(I.headers.get("content-length")??0)>104857600)return S({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let T=new Uint8Array(await I.arrayBuffer());return S({ok:!0,artifact:vs.create({organizationId:a.organization.id,projectId:a.project.id,filename:I.headers.get("x-artifact-filename")??"application.zip",bytes:T,actorId:d.actor?.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Artifact could not be inspected."},422)}}if(N.pathname==="/api/onboarding/registries"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{return S({ok:!0,registry:Di.create({organizationId:a.organization.id,provider:d.provider,name:String(d.name??"Container registry"),host:String(d.host??""),credential:d.token||d.password?{username:typeof d.username==="string"?d.username:void 0,password:typeof d.password==="string"?d.password:void 0,token:typeof d.token==="string"?d.token:void 0}:void 0,credentialExpiresAt:typeof d.credentialExpiresAt==="string"?d.credentialExpiresAt:void 0,actorId:g.actor?.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Registry connection could not be created."},422)}}if(N.pathname==="/api/onboarding/registries"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=Di.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Registry connection was not found."},404);try{if(d.action==="test")return S({ok:!0,registry:await Di.test(T.id,{image:typeof d.image==="string"?d.image:void 0})});if(d.action==="rotate")return S({ok:!0,registry:Di.rotate(T.id,{username:typeof d.username==="string"?d.username:void 0,password:typeof d.password==="string"?d.password:void 0,token:typeof d.token==="string"?d.token:void 0},{expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,actorId:g.actor?.id})});return S({ok:!1,error:"Registry action must be test or rotate."},422)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Registry connection could not be updated."},422)}}if(N.pathname==="/api/onboarding/registries"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=Di.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Registry connection was not found."},404);let _=Jr.list(a.project.id).filter((L)=>L.input.source.kind==="image"&&L.input.source.registryConnectionId===T.id||L.input.build.kind==="prebuilt_image"&&L.input.build.registryConnectionId===T.id);if(d.preview===!0)return S({ok:!0,preview:!0,affectedDrafts:_});return S({ok:!0,registry:Di.disconnect(T.id,g.actor?.id),affectedDrafts:_})}if(N.pathname==="/api/onboarding/apply"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{let T=Nr({controlPlane:a.store,drafts:Jr,draftId:String(d.id??""),expectedVersion:Number(d.version),confirmEnvironment:String(d.confirmEnvironment??""),actorId:g.actor?.id});return S({ok:!0,resource:T.resource,operation:T.operation,plan:T.plan},202)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Application plan could not be applied."},422)}}if(N.pathname==="/api/sources"&&I.method==="GET"){let d=qe.listConnections(a.organization.id);return S({connections:d,bindings:qe.listBindings({projectId:a.project.id}),repositories:d.flatMap((g)=>qe.listRepositories(g.id)),deployKeys:d.flatMap((g)=>qe.listDeployKeys(g.id)),webhooks:d.flatMap((g)=>qe.listWebhooks(g.id)).map((g)=>({...g,deliveries:qe.listDeliveries(g.id,20)})),project:{id:a.project.id,slug:a.project.slug},environment:ae(a,String(ye)),resources:a.store.listResources(a.project.id,ae(a,String(ye)).environmentId).filter((g)=>g.kind==="application").map((g)=>({id:g.id,slug:g.slug,name:g.name}))})}if(N.pathname==="/api/sources/connections"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=String(d.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(T))return S({ok:!1,error:"A supported Git provider is required."},422);try{let _=T==="github"&&(d.privateKey||d.appId)?{appId:typeof d.appId==="string"?d.appId:void 0,installationId:typeof d.installationId==="string"?d.installationId:void 0,privateKey:typeof d.privateKey==="string"?d.privateKey:void 0}:T!=="generic_ssh"&&d.token?{token:typeof d.token==="string"?d.token:void 0,username:typeof d.username==="string"?d.username:void 0}:void 0,L={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},K,B,Q;if(a.store.database.transaction(()=>{if(K=qe.createConnection({organizationId:a.organization.id,provider:T,name:String(d.name??T),host:String(d.host??L[T]??""),owner:typeof d.owner==="string"?d.owner:void 0,authKind:d.authKind,credential:_,grantedScopes:Array.isArray(d.grantedScopes)?d.grantedScopes.map(String):[],credentialExpiresAt:typeof d.credentialExpiresAt==="string"?d.credentialExpiresAt:void 0,createdByActorId:g.actor?.id}),typeof d.repositoryUrl==="string"&&typeof d.repositoryFullName==="string")B=qe.upsertRepository({connectionId:K.id,providerRepositoryId:`manual:${d.repositoryFullName}`,fullName:d.repositoryFullName,cloneUrl:d.repositoryUrl,defaultBranch:String(d.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"manual"}});if(T==="generic_ssh")Q=qe.createDeployKey({connectionId:K.id,name:String(d.deployKeyName??"Repository deploy key"),publicKey:String(d.publicKey??""),privateKey:String(d.deployPrivateKey??""),host:String(d.sshHost??""),hostKey:String(d.hostKey??""),actorId:g.actor?.id})})(),d.test===!0)K=await Hd(qe,K.id,B?.id);return S({ok:!0,connection:K,repository:B,deployKey:Q},201)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source connection could not be created."},422)}}if(N.pathname==="/api/sources/connections"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=qe.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{if(d.action==="test")return S({ok:!0,connection:await Hd(qe,T.id,typeof d.repositoryId==="string"?d.repositoryId:void 0)});if(d.action==="rotate")return S({ok:!0,connection:qe.rotateCredential(T.id,{token:typeof d.token==="string"?d.token:void 0,username:typeof d.username==="string"?d.username:void 0,appId:typeof d.appId==="string"?d.appId:void 0,installationId:typeof d.installationId==="string"?d.installationId:void 0,privateKey:typeof d.privateKey==="string"?d.privateKey:void 0},{expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,actorId:g.actor?.id})});return S({ok:!1,error:"Connection action must be test or rotate."},422)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source connection could not be updated."},422)}}if(N.pathname==="/api/sources/connections"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=qe.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);let _=qe.listBindings({connectionId:T.id,status:"active"});if(d.preview===!0)return S({ok:!0,preview:!0,affectedBindings:_});return S({ok:!0,...qe.disconnectConnection(T.id,g.actor?.id)})}if(N.pathname==="/api/sources/deploy-keys"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=qe.getConnection(String(d.connectionId??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S({ok:!0,deployKey:qe.createDeployKey({connectionId:T.id,name:String(d.name??"Repository deploy key"),publicKey:String(d.publicKey??""),privateKey:String(d.privateKey??""),host:String(d.host??""),hostKey:String(d.hostKey??""),actorId:g.actor?.id})},201)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Deploy key could not be stored."},422)}}if(N.pathname==="/api/sources/deploy-keys"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=qe.getDeployKey(String(d.id??"")),_=T?qe.getConnection(T.connectionId):void 0;if(!T||!_||_.organizationId!==a.organization.id)return S({ok:!1,error:"Deploy key was not found."},404);let L=qe.listBindings({connectionId:_.id}).filter((K)=>K.deployKeyId===T.id);if(d.preview===!0)return S({ok:!0,preview:!0,affectedBindings:L});return S({ok:!0,...qe.revokeDeployKey(T.id,g.actor?.id)})}if(N.pathname==="/api/sources/repositories/sync"&&I.method==="POST"){let d=await oe(I),g=qe.getConnection(String(d.connectionId??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S({ok:!0,repositories:await Pr(qe,String(d.connectionId??""),{search:typeof d.search==="string"?d.search:void 0})})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Repositories could not be synchronized."},422)}}if(N.pathname==="/api/sources/references"&&I.method==="GET"){let d=qe.getConnection(String(N.searchParams.get("connectionId")??""));if(!d||d.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S(await Jt(qe,{connectionId:String(N.searchParams.get("connectionId")??""),repository:String(N.searchParams.get("repository")??""),repositoryId:N.searchParams.get("repositoryId")??void 0,deployKeyId:N.searchParams.get("deployKeyId")??void 0,type:N.searchParams.get("type")==="tags"?"tags":"branches",cursor:N.searchParams.get("cursor")??void 0}))}catch(g){return S({ok:!1,error:g instanceof Error?g.message:"References could not be listed."},422)}}if(N.pathname==="/api/sources/bindings"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=ae(a,String(ye)),_=qe.getConnection(String(d.connectionId??""));if(!_||_.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S({ok:!0,binding:qe.createBinding({projectId:a.project.id,environmentId:T.environmentId,resourceId:typeof d.resourceId==="string"?d.resourceId:void 0,connectionId:String(d.connectionId??""),repositoryId:typeof d.repositoryId==="string"?d.repositoryId:void 0,repositoryFullName:String(d.repositoryFullName??""),defaultBranch:String(d.defaultBranch??"main"),branchRule:typeof d.branchRule==="string"?d.branchRule:void 0,tagRule:typeof d.tagRule==="string"?d.tagRule:void 0,monorepoRoot:String(d.monorepoRoot??"."),includePaths:Array.isArray(d.includePaths)?d.includePaths.map(String):[],excludePaths:Array.isArray(d.excludePaths)?d.excludePaths.map(String):[],submodules:d.submodules===!0,cloneDepth:d.cloneDepth?Number(d.cloneDepth):void 0,deployKeyId:typeof d.deployKeyId==="string"&&d.deployKeyId?d.deployKeyId:void 0,autoDeploy:d.autoDeploy!==!1,pullRequestPreviews:d.pullRequestPreviews!==!1,actorId:g.actor?.id})},201)}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"Source binding could not be created."},422)}}if(N.pathname==="/api/sources/bindings"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=qe.getBinding(String(d.id??""));if(!T||T.projectId!==a.project.id)return S({ok:!1,error:"Source binding was not found."},404);try{return S({ok:!0,binding:qe.updateBinding(T.id,Number(d.version),{defaultBranch:d.defaultBranch,branchRule:d.branchRule,tagRule:d.tagRule,monorepoRoot:d.monorepoRoot,includePaths:d.includePaths,excludePaths:d.excludePaths,submodules:d.submodules,cloneDepth:d.cloneDepth,deployKeyId:d.deployKeyId,autoDeploy:d.autoDeploy,pullRequestPreviews:d.pullRequestPreviews,status:d.status,disabledReason:d.disabledReason,actorId:g.actor?.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source binding could not be updated."},409)}}if(N.pathname==="/api/sources/webhooks"&&I.method==="POST"){let d=await oe(I),g=qe.getConnection(String(d.connectionId??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{let T=qe.createWebhook({connectionId:String(d.connectionId??""),repositoryId:typeof d.repositoryId==="string"?d.repositoryId:void 0,repositoryFullName:String(d.repositoryFullName??""),events:Array.isArray(d.events)?d.events.map(String):void 0,secret:typeof d.secret==="string"?d.secret:void 0}),_=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||at,L=_?Ct(_,T.webhook):void 0,K=d.reconcile!==!1&&_?await Xt(qe,T.webhook.id,_):T.webhook;return S({ok:!0,webhook:K,endpoint:L,endpointRevealOnce:!0},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Source webhook could not be created."},422)}}if(N.pathname==="/api/sources/webhooks"&&I.method==="PATCH"){let d=await oe(I),g=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||at,T=qe.getWebhook(String(d.id??"")),_=T?qe.getConnection(T.connectionId):void 0;if(!T||!_||_.organizationId!==a.organization.id)return S({ok:!1,error:"Source webhook was not found."},404);if(!g)return S({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return S({ok:!0,webhook:await Xt(qe,String(d.id??""),g)})}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"Source webhook could not be reconciled."},422)}}if(N.pathname==="/api/sources/webhooks"&&I.method==="DELETE"){let d=await oe(I),g=qe.getWebhook(String(d.id??"")),T=g?qe.getConnection(g.connectionId):void 0;if(!g||!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source webhook was not found."},404);try{return S({ok:!0,webhook:await wi(qe,String(d.id??""))})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source webhook could not be removed."},422)}}if(N.pathname==="/api/security/posture"&&I.method==="GET"){let d=ae(a,String(ye)),g=et.listFindings({...d,limit:500});return S({scope:d,summary:et.summary(d.organizationId,d.projectId,d.environmentId),findings:g,scans:et.listScanRuns({...d,limit:100}),policies:et.listPolicies(d.organizationId).filter((T)=>!T.environmentId||T.environmentId===d.environmentId),waivers:g.flatMap((T)=>et.listWaivers(T.id)),decisions:et.listDecisions(d.environmentId,50),actors:a.store.listMemberships(a.organization.id).map((T)=>a.store.getActor(T.actorId)).filter(Boolean)})}if(N.pathname==="/api/security/export"&&I.method==="GET")return S(et.exportPosture(a.organization.id));if(N.pathname==="/api/security/scan"&&I.method==="POST"){let d=ae(a,String(ye)),g=await new ps(et).run(new Oa,{...d,artifactRoot:t}),T=od(et,d,Mt??{});return S({ok:!0,source:g,host:T,summary:et.summary(d.organizationId,d.projectId,d.environmentId)})}if(N.pathname==="/api/security/review"&&I.method==="POST")try{let d=ae(a,String(ye));return S({ok:!0,...Zt(et,{scope:d,desiredConfigHash:a.project.desiredConfigHash})})}catch(d){return S({ok:!1,error:d instanceof Error?d.message:"Security change review failed."},409)}if(N.pathname==="/api/security/policies"&&I.method==="POST"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{let T=et.createPolicy({organizationId:a.organization.id,environmentId:d.environmentId===null?void 0:String(d.environmentId??ae(a,String(ye)).environmentId),name:String(d.name??""),scannerFailMode:d.scannerFailMode==="open"?"open":"closed",requiredScanners:Array.isArray(d.requiredScanners)?d.requiredScanners.map(String):[],rules:Array.isArray(d.rules)?d.rules.map((_)=>({minimumSeverity:String(_.minimumSeverity),action:String(_.action),scannerId:_.scannerId?String(_.scannerId):void 0})):[],actorId:g.actor.id});return S({ok:!0,policy:T},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Security policy could not be created."},422)}}if(N.pathname==="/api/security/policies"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=et.getPolicy(String(d.id??""));if(!g.actor||!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Security policy was not found."},404);try{return S({ok:!0,policy:et.updatePolicy(T.id,Number(d.version),{name:typeof d.name==="string"?d.name:void 0,scannerFailMode:d.scannerFailMode==="open"||d.scannerFailMode==="closed"?d.scannerFailMode:void 0,requiredScanners:Array.isArray(d.requiredScanners)?d.requiredScanners.map(String):void 0,rules:Array.isArray(d.rules)?d.rules.map((_)=>({minimumSeverity:String(_.minimumSeverity),action:String(_.action),scannerId:_.scannerId?String(_.scannerId):void 0})):void 0,enabled:typeof d.enabled==="boolean"?d.enabled:void 0,actorId:g.actor.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Security policy could not be updated."},409)}}if(N.pathname==="/api/security/waivers"&&I.method==="POST"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{return S({ok:!0,waiver:et.createWaiver({findingId:String(d.findingId??""),policyId:typeof d.policyId==="string"?d.policyId:void 0,reason:String(d.reason??""),referenceUrl:typeof d.referenceUrl==="string"?d.referenceUrl:void 0,expiresAt:String(d.expiresAt??""),actorId:g.actor.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be created."},422)}}if(N.pathname==="/api/security/waivers"&&I.method==="DELETE"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{return S({ok:!0,waiver:et.revokeWaiver(String(d.id??""),g.actor.id)})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be revoked."},404)}}if(N.pathname==="/api/security/findings"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=et.getFinding(String(d.id??""));if(!g.actor||!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Security finding was not found."},404);try{let _=d.action==="acknowledge"?et.acknowledgeFinding(T.id,g.actor.id):et.assignFinding(T.id,typeof d.ownerActorId==="string"&&d.ownerActorId?d.ownerActorId:void 0,g.actor.id);return S({ok:!0,finding:_})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Security finding could not be updated."},422)}}if(N.pathname==="/api/security/comments"&&I.method==="POST"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{return S({ok:!0,comment:et.addComment({findingId:String(d.findingId??""),actorId:g.actor.id,body:String(d.body??""),referenceUrl:typeof d.referenceUrl==="string"?d.referenceUrl:void 0})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Comment could not be saved."},422)}}if(N.pathname==="/api/auth/sessions"&&I.method==="GET"){let d=Bt.resolveSession(I);return S({currentSessionId:d?.id,sessions:d?ve.listSessions(d.identityId,{includeInactive:!0}):[]})}if(N.pathname==="/api/auth/sessions"&&I.method==="DELETE"){let d=await oe(I),g=Bt.resolveSession(I);if(!g)return S({ok:!1,error:"Sign in again to manage sessions."},401);let T=String(d.id??""),_=ve.revokeSession(g.identityId,T),L=T===g.id&&_?{"set-cookie":md({secure:yo})}:void 0;return S({ok:_,signedOut:T===g.id&&_},_?200:404,L)}if(N.pathname==="/api/auth/sessions/revoke-others"&&I.method==="POST"){let d=Bt.resolveSession(I);if(!d)return S({ok:!1,error:"Sign in again to manage sessions."},401);return S({ok:!0,revoked:ve.revokeOtherSessions(d.identityId,d.id)})}if(N.pathname==="/api/auth/password/change"&&I.method==="POST"){let d=await oe(I),g=String(d.currentPassword??""),T=String(d.password??""),_=Me(de),L=_.actor?ve.getIdentityByActor(_.actor.id):void 0;if(!L||!Ti(g,L.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);if(T.length<12)return S({ok:!1,error:"New password must be at least 12 characters."},422);if(Ti(T,L.passwordHash))return S({ok:!1,error:"Choose a different password."},409);let K=No(T),B=ve.updatePassword(L.id,K);yd(t,B.username,K);let Q=Ha(B.id,I,Ye.requestIP(I)?.address??"unknown");return a.store.appendEvent({organizationId:a.organization.id,actorId:B.actorId,type:"auth.password.changed"}),S({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":ea(Q.token,{secure:yo,maxAgeMs:Co})})}if(N.pathname==="/api/auth/mfa/enroll"&&I.method==="POST"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_)return S({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Ti(String(d.password??""),_.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);try{let L=ve.beginTotpEnrollment(_.id,{issuer:a.organization.name});return a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.mfa.enrollment.started"}),S({factor:L.factor,secret:L.secret,uri:L.uri})}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"MFA enrollment failed."},409)}}if(N.pathname==="/api/auth/mfa/verify"&&I.method==="POST"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_)return S({ok:!1,error:"Sign in again before enabling MFA."},401);try{let L=ve.verifyTotpEnrollment(_.id,String(d.code??""));return ve.markSessionStepUp(g.id,!0),a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:L.recoveryCodes.length}}),S(L)}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"MFA enrollment failed."},422)}}if(N.pathname==="/api/auth/mfa"&&I.method==="DELETE"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_||!Ti(String(d.password??""),_.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);let L=ve.verifyMfaCode(_.id,String(d.code??""));if(!L.valid||!L.method)return S({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return ve.disableMfa(_.id),ve.revokeOtherSessions(_.id,g.id),ve.markSessionStepUp(g.id),a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.mfa.disabled",payload:{method:L.method}}),S({ok:!0})}if(N.pathname==="/api/auth/step-up"&&I.method==="POST"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_||!Ti(String(d.password??""),_.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);let L=ve.getMfaFactor(_.id);if(L?.state==="active"){if(!ve.verifyMfaCode(_.id,String(d.code??"")).valid)return S({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let K=ve.markSessionStepUp(g.id,L?.state==="active");return a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.step_up.succeeded",payload:{mfa:L?.state==="active"}}),S({ok:!0,recentAuthAt:K.recentAuthAt})}if(N.pathname==="/api/terminal"){if(!pe)return S({ok:!1,error:"The web terminal is disabled."},403);if(Ye.upgrade(I))return;return Ed("WebSocket upgrade failed",400)}if(N.pathname==="/api/health"){let d=a.store.health();return S({ok:!0,cwd:t,environment:ye,environments:m,uiRoot:await Pi(de,ye),liveData:Ae.size>0,terminal:pe,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:d.schemaVersion,supportedSchemaVersion:d.supportedSchemaVersion,integrity:d.integrity,pendingRetryableOperations:d.pendingRetryableOperations}})}if(N.pathname==="/api/control-plane/operations"){let d=N.searchParams.get("state"),g=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0;return S({operations:a.store.listOperations({projectId:a.project.id,state:g,kind:N.searchParams.get("kind")??void 0,limit:Number(N.searchParams.get("limit"))||100})})}if(N.pathname==="/api/queue"&&I.method==="GET"){let d=N.searchParams.get("state"),g=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0,T=kt.list({projectId:a.project.id,state:g,limit:Number(N.searchParams.get("limit"))||250}).filter((_)=>ws(de,_.operation.id,"deployments:read")).map((_)=>{let L=_.operation.resourceId?a.store.getResource(_.operation.resourceId):void 0,K=_.operation.environmentId?a.store.listEnvironments(a.project.id).find((fe)=>fe.id===_.operation.environmentId):void 0,B=_.operation.actorId?a.store.getActor(_.operation.actorId):void 0,Q=_.operation.input;return{..._,target:L?{id:L.id,name:L.name,slug:L.slug,kind:L.kind}:K?{id:K.id,name:K.name,slug:K.slug,kind:"environment"}:{id:a.project.id,name:a.project.name,slug:a.project.slug,kind:"project"},actor:B?{id:B.id,name:B.displayName,kind:B.kind}:void 0,commit:Q.revision??Q.source?.commitSha??null}});return S({operations:T,concurrency:kt.limits})}if(N.pathname==="/api/queue/logs"&&I.method==="GET"){let d=String(N.searchParams.get("id")??"");if(!ws(de,d,"deployments:read"))return S({ok:!1,error:"Operation was not found in this scope."},404);let g=kt.logs(d,{after:Number(N.searchParams.get("after"))||0,limit:Number(N.searchParams.get("limit"))||500});return S({entries:g,cursor:g.at(-1)?.sequence??(Number(N.searchParams.get("after"))||0),operation:a.store.getOperation(d)})}if(N.pathname==="/api/queue/stream"&&I.method==="GET"){let d=String(N.searchParams.get("id")??"");if(!ws(de,d,"deployments:read"))return S({ok:!1,error:"Operation was not found in this scope."},404);let g=I.headers.get("last-event-id")?.trim(),T=Number(g||N.searchParams.get("after")||0),_=new TextEncoder,L,K=!1,B=new ReadableStream({start(Q){let fe=()=>{if(K)return;let ue=Bt.resolveUser(I);if(!ue||!ws(ue,d,"deployments:read")){if(K=!0,L)clearInterval(L);Q.close();return}let He=kt.logs(d,{after:T,limit:500});for(let Le of He)T=Le.sequence,Q.enqueue(_.encode(`id: ${Le.sequence}
486
+ This link expires in one hour and can be used once.`});a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.password_reset.requested",payload:{delivered:Q}})}return S({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(N.pathname==="/api/auth/password-reset/complete"&&I.method==="POST"){let d=await oe(I),g=String(d.token??"").trim(),T=String(d.password??"");if(!g||T.length<12)return S({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let _=ve.consumeActionToken(g,"password_reset"),M=No(T),K=ve.updatePassword(_.identityId,M);return yd(t,K.username,M),a.store.appendEvent({organizationId:a.organization.id,actorId:K.actorId,type:"auth.password_reset.completed"}),S({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":md({secure:yo})})}catch(_){let M=_ instanceof Error?_.message:"Password reset failed.";return S({ok:!1,error:M.replace("Action token","Reset link")},M.includes("consumed")||M.includes("expired")?409:404)}}if(N.pathname==="/api/login"&&I.method==="POST"){let d=await oe(I),g=String(d.username??"").trim(),T=String(d.password??""),_=Ye.requestIP(I)?.address??"unknown",M=Ja.check(g,_);if(!M.allowed)return S({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((M.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(M.retryAfterSeconds??60)});let K=pi(Fn(t),g),B=ve.getIdentityByUsername(g),Q=B?.passwordHash??K?.passwordHash??JT;if(!(Ti(T,Q)&&!!K&&!!B&&!B.disabledAt))return Ja.recordFailure(g,_),S({ok:!1,error:"Incorrect username or password."},401);if(iy(ve,a,B))return S({ok:!1,error:"Single sign-on is required for this account."},403);Ja.recordSuccess(g,_);let ue=B,He=ue.requiresPasswordUpgrade||xh(ue.passwordHash);if(He){let Le=No(T);ue=ve.rehashPassword(ue.id,Le),yd(t,ue.username,Le)}if(ve.recordLogin(ue.id),ve.getMfaFactor(ue.id)?.state==="active"){let Le=ve.createMfaChallenge(ue.id,"login");return a.store.appendEvent({organizationId:a.organization.id,actorId:ue.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),S({ok:!0,mfaRequired:!0,challengeToken:Le.token,passwordUpgraded:He})}let be=Ha(ue.id,I,_);return a.store.appendEvent({organizationId:a.organization.id,actorId:ue.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),S({ok:!0,user:ta(K),passwordUpgraded:He},200,{"set-cookie":ea(be.token,{secure:yo,maxAgeMs:Co})})}if(N.pathname==="/api/auth/mfa/complete"&&I.method==="POST"){let d=await oe(I),g=String(d.challengeToken??"").trim(),T=String(d.code??"").trim(),_=Ye.requestIP(I)?.address??"unknown",K=ve.inspectMfaChallengeToken(g,"login")?.identityId??"unknown-mfa",B=Wa.check(K,_);if(!B.allowed)return S({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(B.retryAfterSeconds??60)});try{let Q=ve.completeMfaChallenge(g,T,"login");Wa.recordSuccess(K,_);let fe=new Date().toISOString(),ue=ve.createSession({identityId:Q.identity.id,userAgent:Ip(I),networkHint:Dd(_),mfaAt:fe,recentAuthAt:fe});return a.store.appendEvent({organizationId:a.organization.id,actorId:Q.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:Q.method}}),S({ok:!0},200,{"set-cookie":ea(ue.token,{secure:yo,maxAgeMs:Co})})}catch{return Wa.recordFailure(K,_),S({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(N.pathname==="/api/logout"&&I.method==="POST"){let d=Bt.resolveSession(I);if(d)ve.revokeSession(d.identityId,d.id);let g=md({secure:yo});if(I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":g}});return S({ok:!0},200,{"set-cookie":g})}if(N.pathname==="/login"){let d=ve.listOidcProviders(a.organization.id).map((g)=>({slug:g.slug,name:g.name}));return new Response(oy(O?.mode==="serverless",d),{headers:{"content-type":"text/html; charset=utf-8"}})}if(N.pathname==="/forgot-password"||N.pathname==="/reset-password")return new Response(sy(N.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(N.pathname==="/accept-invitation")return cb(xi,N.pathname);let de=Bt.resolveUser(I);if(!de){if(!N.pathname.startsWith("/api/")&&I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return S({ok:!1,error:"Sign in to continue."},401)}let si=po(de,ye);if(N.pathname==="/api/me"){let d=a.store.getActorByExternalId("user",`dashboard:${de.username.toLowerCase()}`),g=d?a.store.getMembershipForActor(a.organization.id,d.id):void 0,T=a.store.resolveAuthorizationTarget(a.organization.id,g?.scope??{type:"project",id:a.project.id})??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id});return S({ok:!0,user:ta(de),authEnabled:Re,organization:a.organization,membership:g,capabilities:en({membership:g,grants:g?a.store.listGrants(g.id):[],target:T})})}if(N.pathname.startsWith("/api/")){let d=await ty(I,N.pathname),g=Bt.check(I,N.pathname,de,d);if(!g.ok)return S({ok:!1,error:g.error},g.status??403);if(Re&&tA.has(`${I.method.toUpperCase()} ${N.pathname}`)){let T=Bt.resolveSession(I);if(!T||!ve.isRecentlyAuthenticated(T))return S({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(N.pathname==="/api/auth/security"&&I.method==="GET"){let d=Me(de),g=d.actor?ve.getIdentityByActor(d.actor.id):void 0,T=Bt.resolveSession(I);return S({identity:g?{username:g.username,email:g.email,emailVerifiedAt:g.emailVerifiedAt,requiresPasswordUpgrade:g.requiresPasswordUpgrade,lastLoginAt:g.lastLoginAt}:void 0,currentSessionId:T?.id,sessions:g?ve.listSessions(g.id,{includeInactive:!0}):[],mfa:g?{factor:ve.getMfaFactor(g.id),recoveryCodesRemaining:ve.remainingRecoveryCodes(g.id)}:void 0})}if(N.pathname==="/api/auth/oidc/providers"&&I.method==="GET")return S({providers:ve.listOidcProviders(a.organization.id,{includeDisabled:!0}),callbackOrigin:at,callbackPattern:at?`${at}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(N.pathname==="/api/auth/oidc/providers"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=g.actor?ve.getIdentityByActor(g.actor.id):void 0,_=d.enforceSso===!0;if(_&&(!T?.emailVerifiedAt||ve.remainingRecoveryCodes(T.id)<1))return S({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let M=wd(d.defaultRole),K=ve.upsertOidcProvider({id:typeof d.id==="string"?d.id:void 0,organizationId:a.organization.id,slug:String(d.slug??""),name:String(d.name??""),issuer:String(d.issuer??""),clientId:String(d.clientId??""),clientSecret:typeof d.clientSecret==="string"&&d.clientSecret?d.clientSecret:void 0,scopes:Array.isArray(d.scopes)?d.scopes.map(String):void 0,allowedDomains:Array.isArray(d.allowedDomains)?d.allowedDomains.map(String):[],defaultRole:M&&M!=="owner"?M:void 0,enabled:d.enabled!==!1,enforceSso:_});return a.store.appendEvent({organizationId:a.organization.id,actorId:g.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:K.id,issuer:K.issuer,enabled:K.enabled,enforceSso:K.enforceSso}}),S({ok:!0,provider:K})}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"OIDC provider could not be saved."},422)}}if(N.pathname==="/api/auth/oidc/providers"&&I.method==="PATCH"){let d=await oe(I),g=ve.getOidcProvider(String(d.id??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"OIDC provider was not found."},404);let T=Me(de),_=ve.setOidcProviderEnabled(g.id,d.enabled===!0);return a.store.appendEvent({organizationId:a.organization.id,actorId:T.actor?.id,type:_.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:g.id}}),S({ok:!0,provider:_})}if(N.pathname==="/api/automation"&&I.method==="GET"){let d=pt.listServiceAccounts(a.organization.id,{includeDisabled:!0}).map((g)=>{let T=a.store.getMembershipForActor(a.organization.id,g.actorId),_=g.createdByActorId?a.store.getActor(g.createdByActorId):void 0,M=pt.listTokens(g.id,{includeInactive:!0}).map((K)=>({...K,createdBy:K.createdByActorId?a.store.getActor(K.createdByActorId):void 0}));return{account:g,createdBy:_,membership:T,tokens:M}});return S({accounts:d,apiBaseUrl:`${N.origin}/api/v1`,openApiUrl:`${N.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(N.pathname==="/api/automation/service-accounts"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=wd(d.roleTemplate),_=Ua(d);if(!g.actor||!T||T==="owner"||!_)return S({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let M=pt.createServiceAccount({organizationId:a.organization.id,slug:String(d.slug??""),name:String(d.name??""),description:typeof d.description==="string"?d.description:void 0,roleTemplate:T,scope:_,createdByActorId:g.actor.id});return S({ok:!0,...M},201)}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"Service account could not be created."},422)}}if(N.pathname==="/api/automation/service-accounts"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=pt.getServiceAccount(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Service account was not found."},404);return S({ok:!0,account:pt.disableServiceAccount(T.id,g.actor?.id)})}if(N.pathname==="/api/automation/tokens"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=pt.getServiceAccount(String(d.serviceAccountId??"")),_=Ua(d);if(!g.actor||!T||T.organizationId!==a.organization.id||!_||!Array.isArray(d.capabilities))return S({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let M=pt.createToken({serviceAccountId:T.id,name:String(d.name??"API token"),capabilities:d.capabilities.map(String),scope:_,expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,createdByActorId:g.actor.id});return S({ok:!0,token:M.token,secret:M.secret,revealOnce:!0},201)}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"API token could not be created."},422)}}if(N.pathname==="/api/automation/tokens/rotate"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=pt.getToken(String(d.id??"")),_=T?pt.getServiceAccount(T.serviceAccountId):void 0;if(!g.actor||!T||_?.organizationId!==a.organization.id)return S({ok:!1,error:"API token was not found."},404);try{let M=pt.rotateToken(T.id,g.actor.id);return S({ok:!0,token:M.token,secret:M.secret,revealOnce:!0,overlap:!0},201)}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"API token could not be rotated."},409)}}if(N.pathname==="/api/automation/tokens"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=pt.getToken(String(d.id??"")),_=T?pt.getServiceAccount(T.serviceAccountId):void 0;if(!T||_?.organizationId!==a.organization.id)return S({ok:!1,error:"API token was not found."},404);return S({ok:!0,token:pt.revokeToken(T.id,g.actor?.id)})}if(N.pathname==="/api/onboarding"&&I.method==="GET"){let d=qe.listConnections(a.organization.id);return S({drafts:Jr.list(a.project.id),artifacts:vs.list(a.project.id),registries:Di.list(a.organization.id),sourceConnections:d,repositories:d.flatMap((g)=>qe.listRepositories(g.id)),project:{id:a.project.id,slug:a.project.slug,name:a.project.name},environments:[...a.environments.values()].map((g)=>({id:g.id,slug:g.slug,name:g.name,kind:g.kind,region:g.region})),resources:a.store.listResources(a.project.id).filter((g)=>g.kind==="application").map((g)=>({id:g.id,slug:g.slug,name:g.name,environmentId:g.environmentId}))})}if(N.pathname==="/api/onboarding/detect"&&I.method==="POST"){let d=await oe(I);try{if(d.source?.kind==="git"){let _=qe.getConnection(String(d.source.connectionId??"")),M=qe.getRepository(String(d.source.repositoryId??""));if(!_||_.organizationId!==a.organization.id||!M||M.connectionId!==_.id)throw Error("Authorized Git repository was not found");let K=typeof d.source.deployKeyId==="string"?qe.getDeployKey(d.source.deployKeyId):void 0;if(K&&K.connectionId!==_.id)throw Error("Deploy key does not belong to this connection");let B=ip(Et(Cd(),"ts-cloud-onboarding-git-"));try{let Q=await Wd({remote:M.cloneUrl,destination:Et(B,"checkout"),ref:String(d.source.ref??M.defaultBranch),sparsePaths:Array.isArray(d.source.sparsePaths)?d.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:a.project.id,connectionId:_.id,repositoryId:M.id,repositoryFullName:M.fullName,defaultBranch:M.defaultBranch,monorepoRoot:String(d.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:d.source.submodules===!0,cloneDepth:1,deployKeyId:K?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:qe.getCredential(_.id),deployKey:K?{...K,privateKey:qe.getDeployPrivateKey(K.id)}:void 0,timeoutMs:120000});return S({ok:!0,commitSha:Q.commitSha,candidates:At(Nn(Q.directory))})}finally{Ss(B,{recursive:!0,force:!0})}}if(Array.isArray(d.files)){if(d.files.length>1e4)throw Error("Detection file-count limit exceeded");let _=d.files.map((M)=>({path:String(M.path??""),size:Number(M.size??0),content:typeof M.content==="string"?M.content.slice(0,262144):void 0}));return S({ok:!0,candidates:At(_)})}let g=NT(t,String(d.root??".")),T=_T(t,g);if(T===".."||T.startsWith(`..${$T}`))throw Error("Detection root must stay inside the project");return S({ok:!0,candidates:At(Nn(g))})}catch(g){return S({ok:!1,error:g instanceof Error?g.message:"Application detection failed."},422)}}if(N.pathname==="/api/onboarding/plan"&&I.method==="POST"){let d=await oe(I);try{return S({ok:!0,plan:se(d.draft,Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):[])})}catch(g){return S({ok:!1,error:g instanceof Error?g.message:"Application plan could not be generated."},422)}}if(N.pathname==="/api/onboarding/drafts"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{return S({ok:!0,draft:Jr.create({organizationId:a.organization.id,projectId:a.project.id,name:String(d.name??d.draft?.name??"Application draft"),draft:{...d.draft,projectId:a.project.id},step:d.step,suppliedSecretNames:Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):[],actorId:g.actor?.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Application draft could not be saved."},422)}}if(N.pathname==="/api/onboarding/drafts"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=Jr.get(String(d.id??""));if(!T||T.projectId!==a.project.id)return S({ok:!1,error:"Application draft was not found."},404);try{return S({ok:!0,draft:Jr.update(T.id,Number(d.version),{draft:{...d.draft,projectId:a.project.id},step:d.step,suppliedSecretNames:Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):void 0,actorId:g.actor?.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Application draft could not be updated."},409)}}if(N.pathname==="/api/onboarding/artifacts"&&I.method==="POST"){let d=Me(de);if(Number(I.headers.get("content-length")??0)>104857600)return S({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let T=new Uint8Array(await I.arrayBuffer());return S({ok:!0,artifact:vs.create({organizationId:a.organization.id,projectId:a.project.id,filename:I.headers.get("x-artifact-filename")??"application.zip",bytes:T,actorId:d.actor?.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Artifact could not be inspected."},422)}}if(N.pathname==="/api/onboarding/registries"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{return S({ok:!0,registry:Di.create({organizationId:a.organization.id,provider:d.provider,name:String(d.name??"Container registry"),host:String(d.host??""),credential:d.token||d.password?{username:typeof d.username==="string"?d.username:void 0,password:typeof d.password==="string"?d.password:void 0,token:typeof d.token==="string"?d.token:void 0}:void 0,credentialExpiresAt:typeof d.credentialExpiresAt==="string"?d.credentialExpiresAt:void 0,actorId:g.actor?.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Registry connection could not be created."},422)}}if(N.pathname==="/api/onboarding/registries"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=Di.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Registry connection was not found."},404);try{if(d.action==="test")return S({ok:!0,registry:await Di.test(T.id,{image:typeof d.image==="string"?d.image:void 0})});if(d.action==="rotate")return S({ok:!0,registry:Di.rotate(T.id,{username:typeof d.username==="string"?d.username:void 0,password:typeof d.password==="string"?d.password:void 0,token:typeof d.token==="string"?d.token:void 0},{expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,actorId:g.actor?.id})});return S({ok:!1,error:"Registry action must be test or rotate."},422)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Registry connection could not be updated."},422)}}if(N.pathname==="/api/onboarding/registries"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=Di.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Registry connection was not found."},404);let _=Jr.list(a.project.id).filter((M)=>M.input.source.kind==="image"&&M.input.source.registryConnectionId===T.id||M.input.build.kind==="prebuilt_image"&&M.input.build.registryConnectionId===T.id);if(d.preview===!0)return S({ok:!0,preview:!0,affectedDrafts:_});return S({ok:!0,registry:Di.disconnect(T.id,g.actor?.id),affectedDrafts:_})}if(N.pathname==="/api/onboarding/apply"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{let T=Nr({controlPlane:a.store,drafts:Jr,draftId:String(d.id??""),expectedVersion:Number(d.version),confirmEnvironment:String(d.confirmEnvironment??""),actorId:g.actor?.id});return S({ok:!0,resource:T.resource,operation:T.operation,plan:T.plan},202)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Application plan could not be applied."},422)}}if(N.pathname==="/api/sources"&&I.method==="GET"){let d=qe.listConnections(a.organization.id);return S({connections:d,bindings:qe.listBindings({projectId:a.project.id}),repositories:d.flatMap((g)=>qe.listRepositories(g.id)),deployKeys:d.flatMap((g)=>qe.listDeployKeys(g.id)),webhooks:d.flatMap((g)=>qe.listWebhooks(g.id)).map((g)=>({...g,deliveries:qe.listDeliveries(g.id,20)})),project:{id:a.project.id,slug:a.project.slug},environment:ae(a,String(ye)),resources:a.store.listResources(a.project.id,ae(a,String(ye)).environmentId).filter((g)=>g.kind==="application").map((g)=>({id:g.id,slug:g.slug,name:g.name}))})}if(N.pathname==="/api/sources/connections"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=String(d.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(T))return S({ok:!1,error:"A supported Git provider is required."},422);try{let _=T==="github"&&(d.privateKey||d.appId)?{appId:typeof d.appId==="string"?d.appId:void 0,installationId:typeof d.installationId==="string"?d.installationId:void 0,privateKey:typeof d.privateKey==="string"?d.privateKey:void 0}:T!=="generic_ssh"&&d.token?{token:typeof d.token==="string"?d.token:void 0,username:typeof d.username==="string"?d.username:void 0}:void 0,M={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},K,B,Q;if(a.store.database.transaction(()=>{if(K=qe.createConnection({organizationId:a.organization.id,provider:T,name:String(d.name??T),host:String(d.host??M[T]??""),owner:typeof d.owner==="string"?d.owner:void 0,authKind:d.authKind,credential:_,grantedScopes:Array.isArray(d.grantedScopes)?d.grantedScopes.map(String):[],credentialExpiresAt:typeof d.credentialExpiresAt==="string"?d.credentialExpiresAt:void 0,createdByActorId:g.actor?.id}),typeof d.repositoryUrl==="string"&&typeof d.repositoryFullName==="string")B=qe.upsertRepository({connectionId:K.id,providerRepositoryId:`manual:${d.repositoryFullName}`,fullName:d.repositoryFullName,cloneUrl:d.repositoryUrl,defaultBranch:String(d.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"manual"}});if(T==="generic_ssh")Q=qe.createDeployKey({connectionId:K.id,name:String(d.deployKeyName??"Repository deploy key"),publicKey:String(d.publicKey??""),privateKey:String(d.deployPrivateKey??""),host:String(d.sshHost??""),hostKey:String(d.hostKey??""),actorId:g.actor?.id})})(),d.test===!0)K=await Hd(qe,K.id,B?.id);return S({ok:!0,connection:K,repository:B,deployKey:Q},201)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source connection could not be created."},422)}}if(N.pathname==="/api/sources/connections"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=qe.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{if(d.action==="test")return S({ok:!0,connection:await Hd(qe,T.id,typeof d.repositoryId==="string"?d.repositoryId:void 0)});if(d.action==="rotate")return S({ok:!0,connection:qe.rotateCredential(T.id,{token:typeof d.token==="string"?d.token:void 0,username:typeof d.username==="string"?d.username:void 0,appId:typeof d.appId==="string"?d.appId:void 0,installationId:typeof d.installationId==="string"?d.installationId:void 0,privateKey:typeof d.privateKey==="string"?d.privateKey:void 0},{expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,actorId:g.actor?.id})});return S({ok:!1,error:"Connection action must be test or rotate."},422)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source connection could not be updated."},422)}}if(N.pathname==="/api/sources/connections"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=qe.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);let _=qe.listBindings({connectionId:T.id,status:"active"});if(d.preview===!0)return S({ok:!0,preview:!0,affectedBindings:_});return S({ok:!0,...qe.disconnectConnection(T.id,g.actor?.id)})}if(N.pathname==="/api/sources/deploy-keys"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=qe.getConnection(String(d.connectionId??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S({ok:!0,deployKey:qe.createDeployKey({connectionId:T.id,name:String(d.name??"Repository deploy key"),publicKey:String(d.publicKey??""),privateKey:String(d.privateKey??""),host:String(d.host??""),hostKey:String(d.hostKey??""),actorId:g.actor?.id})},201)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Deploy key could not be stored."},422)}}if(N.pathname==="/api/sources/deploy-keys"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=qe.getDeployKey(String(d.id??"")),_=T?qe.getConnection(T.connectionId):void 0;if(!T||!_||_.organizationId!==a.organization.id)return S({ok:!1,error:"Deploy key was not found."},404);let M=qe.listBindings({connectionId:_.id}).filter((K)=>K.deployKeyId===T.id);if(d.preview===!0)return S({ok:!0,preview:!0,affectedBindings:M});return S({ok:!0,...qe.revokeDeployKey(T.id,g.actor?.id)})}if(N.pathname==="/api/sources/repositories/sync"&&I.method==="POST"){let d=await oe(I),g=qe.getConnection(String(d.connectionId??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S({ok:!0,repositories:await Pr(qe,String(d.connectionId??""),{search:typeof d.search==="string"?d.search:void 0})})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Repositories could not be synchronized."},422)}}if(N.pathname==="/api/sources/references"&&I.method==="GET"){let d=qe.getConnection(String(N.searchParams.get("connectionId")??""));if(!d||d.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S(await Jt(qe,{connectionId:String(N.searchParams.get("connectionId")??""),repository:String(N.searchParams.get("repository")??""),repositoryId:N.searchParams.get("repositoryId")??void 0,deployKeyId:N.searchParams.get("deployKeyId")??void 0,type:N.searchParams.get("type")==="tags"?"tags":"branches",cursor:N.searchParams.get("cursor")??void 0}))}catch(g){return S({ok:!1,error:g instanceof Error?g.message:"References could not be listed."},422)}}if(N.pathname==="/api/sources/bindings"&&I.method==="POST"){let d=await oe(I),g=Me(de),T=ae(a,String(ye)),_=qe.getConnection(String(d.connectionId??""));if(!_||_.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{return S({ok:!0,binding:qe.createBinding({projectId:a.project.id,environmentId:T.environmentId,resourceId:typeof d.resourceId==="string"?d.resourceId:void 0,connectionId:String(d.connectionId??""),repositoryId:typeof d.repositoryId==="string"?d.repositoryId:void 0,repositoryFullName:String(d.repositoryFullName??""),defaultBranch:String(d.defaultBranch??"main"),branchRule:typeof d.branchRule==="string"?d.branchRule:void 0,tagRule:typeof d.tagRule==="string"?d.tagRule:void 0,monorepoRoot:String(d.monorepoRoot??"."),includePaths:Array.isArray(d.includePaths)?d.includePaths.map(String):[],excludePaths:Array.isArray(d.excludePaths)?d.excludePaths.map(String):[],submodules:d.submodules===!0,cloneDepth:d.cloneDepth?Number(d.cloneDepth):void 0,deployKeyId:typeof d.deployKeyId==="string"&&d.deployKeyId?d.deployKeyId:void 0,autoDeploy:d.autoDeploy!==!1,pullRequestPreviews:d.pullRequestPreviews!==!1,actorId:g.actor?.id})},201)}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"Source binding could not be created."},422)}}if(N.pathname==="/api/sources/bindings"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=qe.getBinding(String(d.id??""));if(!T||T.projectId!==a.project.id)return S({ok:!1,error:"Source binding was not found."},404);try{return S({ok:!0,binding:qe.updateBinding(T.id,Number(d.version),{defaultBranch:d.defaultBranch,branchRule:d.branchRule,tagRule:d.tagRule,monorepoRoot:d.monorepoRoot,includePaths:d.includePaths,excludePaths:d.excludePaths,submodules:d.submodules,cloneDepth:d.cloneDepth,deployKeyId:d.deployKeyId,autoDeploy:d.autoDeploy,pullRequestPreviews:d.pullRequestPreviews,status:d.status,disabledReason:d.disabledReason,actorId:g.actor?.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source binding could not be updated."},409)}}if(N.pathname==="/api/sources/webhooks"&&I.method==="POST"){let d=await oe(I),g=qe.getConnection(String(d.connectionId??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Source connection was not found."},404);try{let T=qe.createWebhook({connectionId:String(d.connectionId??""),repositoryId:typeof d.repositoryId==="string"?d.repositoryId:void 0,repositoryFullName:String(d.repositoryFullName??""),events:Array.isArray(d.events)?d.events.map(String):void 0,secret:typeof d.secret==="string"?d.secret:void 0}),_=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||at,M=_?Ct(_,T.webhook):void 0,K=d.reconcile!==!1&&_?await Xt(qe,T.webhook.id,_):T.webhook;return S({ok:!0,webhook:K,endpoint:M,endpointRevealOnce:!0},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Source webhook could not be created."},422)}}if(N.pathname==="/api/sources/webhooks"&&I.method==="PATCH"){let d=await oe(I),g=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||at,T=qe.getWebhook(String(d.id??"")),_=T?qe.getConnection(T.connectionId):void 0;if(!T||!_||_.organizationId!==a.organization.id)return S({ok:!1,error:"Source webhook was not found."},404);if(!g)return S({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return S({ok:!0,webhook:await Xt(qe,String(d.id??""),g)})}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"Source webhook could not be reconciled."},422)}}if(N.pathname==="/api/sources/webhooks"&&I.method==="DELETE"){let d=await oe(I),g=qe.getWebhook(String(d.id??"")),T=g?qe.getConnection(g.connectionId):void 0;if(!g||!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Source webhook was not found."},404);try{return S({ok:!0,webhook:await wi(qe,String(d.id??""))})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Source webhook could not be removed."},422)}}if(N.pathname==="/api/security/posture"&&I.method==="GET"){let d=ae(a,String(ye)),g=et.listFindings({...d,limit:500});return S({scope:d,summary:et.summary(d.organizationId,d.projectId,d.environmentId),findings:g,scans:et.listScanRuns({...d,limit:100}),policies:et.listPolicies(d.organizationId).filter((T)=>!T.environmentId||T.environmentId===d.environmentId),waivers:g.flatMap((T)=>et.listWaivers(T.id)),decisions:et.listDecisions(d.environmentId,50),actors:a.store.listMemberships(a.organization.id).map((T)=>a.store.getActor(T.actorId)).filter(Boolean)})}if(N.pathname==="/api/security/export"&&I.method==="GET")return S(et.exportPosture(a.organization.id));if(N.pathname==="/api/security/scan"&&I.method==="POST"){let d=ae(a,String(ye)),g=await new ps(et).run(new Oa,{...d,artifactRoot:t}),T=od(et,d,Mt??{});return S({ok:!0,source:g,host:T,summary:et.summary(d.organizationId,d.projectId,d.environmentId)})}if(N.pathname==="/api/security/review"&&I.method==="POST")try{let d=ae(a,String(ye));return S({ok:!0,...Zt(et,{scope:d,desiredConfigHash:a.project.desiredConfigHash})})}catch(d){return S({ok:!1,error:d instanceof Error?d.message:"Security change review failed."},409)}if(N.pathname==="/api/security/policies"&&I.method==="POST"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{let T=et.createPolicy({organizationId:a.organization.id,environmentId:d.environmentId===null?void 0:String(d.environmentId??ae(a,String(ye)).environmentId),name:String(d.name??""),scannerFailMode:d.scannerFailMode==="open"?"open":"closed",requiredScanners:Array.isArray(d.requiredScanners)?d.requiredScanners.map(String):[],rules:Array.isArray(d.rules)?d.rules.map((_)=>({minimumSeverity:String(_.minimumSeverity),action:String(_.action),scannerId:_.scannerId?String(_.scannerId):void 0})):[],actorId:g.actor.id});return S({ok:!0,policy:T},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Security policy could not be created."},422)}}if(N.pathname==="/api/security/policies"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=et.getPolicy(String(d.id??""));if(!g.actor||!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Security policy was not found."},404);try{return S({ok:!0,policy:et.updatePolicy(T.id,Number(d.version),{name:typeof d.name==="string"?d.name:void 0,scannerFailMode:d.scannerFailMode==="open"||d.scannerFailMode==="closed"?d.scannerFailMode:void 0,requiredScanners:Array.isArray(d.requiredScanners)?d.requiredScanners.map(String):void 0,rules:Array.isArray(d.rules)?d.rules.map((_)=>({minimumSeverity:String(_.minimumSeverity),action:String(_.action),scannerId:_.scannerId?String(_.scannerId):void 0})):void 0,enabled:typeof d.enabled==="boolean"?d.enabled:void 0,actorId:g.actor.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Security policy could not be updated."},409)}}if(N.pathname==="/api/security/waivers"&&I.method==="POST"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{return S({ok:!0,waiver:et.createWaiver({findingId:String(d.findingId??""),policyId:typeof d.policyId==="string"?d.policyId:void 0,reason:String(d.reason??""),referenceUrl:typeof d.referenceUrl==="string"?d.referenceUrl:void 0,expiresAt:String(d.expiresAt??""),actorId:g.actor.id})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be created."},422)}}if(N.pathname==="/api/security/waivers"&&I.method==="DELETE"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{return S({ok:!0,waiver:et.revokeWaiver(String(d.id??""),g.actor.id)})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be revoked."},404)}}if(N.pathname==="/api/security/findings"&&I.method==="PATCH"){let d=await oe(I),g=Me(de),T=et.getFinding(String(d.id??""));if(!g.actor||!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Security finding was not found."},404);try{let _=d.action==="acknowledge"?et.acknowledgeFinding(T.id,g.actor.id):et.assignFinding(T.id,typeof d.ownerActorId==="string"&&d.ownerActorId?d.ownerActorId:void 0,g.actor.id);return S({ok:!0,finding:_})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Security finding could not be updated."},422)}}if(N.pathname==="/api/security/comments"&&I.method==="POST"){let d=await oe(I),g=Me(de);if(!g.actor)return S({ok:!1,error:"An organization actor is required."},403);try{return S({ok:!0,comment:et.addComment({findingId:String(d.findingId??""),actorId:g.actor.id,body:String(d.body??""),referenceUrl:typeof d.referenceUrl==="string"?d.referenceUrl:void 0})},201)}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Comment could not be saved."},422)}}if(N.pathname==="/api/auth/sessions"&&I.method==="GET"){let d=Bt.resolveSession(I);return S({currentSessionId:d?.id,sessions:d?ve.listSessions(d.identityId,{includeInactive:!0}):[]})}if(N.pathname==="/api/auth/sessions"&&I.method==="DELETE"){let d=await oe(I),g=Bt.resolveSession(I);if(!g)return S({ok:!1,error:"Sign in again to manage sessions."},401);let T=String(d.id??""),_=ve.revokeSession(g.identityId,T),M=T===g.id&&_?{"set-cookie":md({secure:yo})}:void 0;return S({ok:_,signedOut:T===g.id&&_},_?200:404,M)}if(N.pathname==="/api/auth/sessions/revoke-others"&&I.method==="POST"){let d=Bt.resolveSession(I);if(!d)return S({ok:!1,error:"Sign in again to manage sessions."},401);return S({ok:!0,revoked:ve.revokeOtherSessions(d.identityId,d.id)})}if(N.pathname==="/api/auth/password/change"&&I.method==="POST"){let d=await oe(I),g=String(d.currentPassword??""),T=String(d.password??""),_=Me(de),M=_.actor?ve.getIdentityByActor(_.actor.id):void 0;if(!M||!Ti(g,M.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);if(T.length<12)return S({ok:!1,error:"New password must be at least 12 characters."},422);if(Ti(T,M.passwordHash))return S({ok:!1,error:"Choose a different password."},409);let K=No(T),B=ve.updatePassword(M.id,K);yd(t,B.username,K);let Q=Ha(B.id,I,Ye.requestIP(I)?.address??"unknown");return a.store.appendEvent({organizationId:a.organization.id,actorId:B.actorId,type:"auth.password.changed"}),S({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":ea(Q.token,{secure:yo,maxAgeMs:Co})})}if(N.pathname==="/api/auth/mfa/enroll"&&I.method==="POST"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_)return S({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Ti(String(d.password??""),_.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);try{let M=ve.beginTotpEnrollment(_.id,{issuer:a.organization.name});return a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.mfa.enrollment.started"}),S({factor:M.factor,secret:M.secret,uri:M.uri})}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"MFA enrollment failed."},409)}}if(N.pathname==="/api/auth/mfa/verify"&&I.method==="POST"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_)return S({ok:!1,error:"Sign in again before enabling MFA."},401);try{let M=ve.verifyTotpEnrollment(_.id,String(d.code??""));return ve.markSessionStepUp(g.id,!0),a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:M.recoveryCodes.length}}),S(M)}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"MFA enrollment failed."},422)}}if(N.pathname==="/api/auth/mfa"&&I.method==="DELETE"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_||!Ti(String(d.password??""),_.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);let M=ve.verifyMfaCode(_.id,String(d.code??""));if(!M.valid||!M.method)return S({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return ve.disableMfa(_.id),ve.revokeOtherSessions(_.id,g.id),ve.markSessionStepUp(g.id),a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.mfa.disabled",payload:{method:M.method}}),S({ok:!0})}if(N.pathname==="/api/auth/step-up"&&I.method==="POST"){let d=await oe(I),g=Bt.resolveSession(I),T=Me(de),_=T.actor?ve.getIdentityByActor(T.actor.id):void 0;if(!g||!_||!Ti(String(d.password??""),_.passwordHash))return S({ok:!1,error:"Current password is incorrect."},401);let M=ve.getMfaFactor(_.id);if(M?.state==="active"){if(!ve.verifyMfaCode(_.id,String(d.code??"")).valid)return S({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let K=ve.markSessionStepUp(g.id,M?.state==="active");return a.store.appendEvent({organizationId:a.organization.id,actorId:_.actorId,type:"auth.step_up.succeeded",payload:{mfa:M?.state==="active"}}),S({ok:!0,recentAuthAt:K.recentAuthAt})}if(N.pathname==="/api/terminal"){if(!pe)return S({ok:!1,error:"The web terminal is disabled."},403);if(Ye.upgrade(I))return;return Ed("WebSocket upgrade failed",400)}if(N.pathname==="/api/health"){let d=a.store.health();return S({ok:!0,cwd:t,environment:ye,environments:m,uiRoot:await Pi(de,ye),liveData:Ae.size>0,terminal:pe,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:d.schemaVersion,supportedSchemaVersion:d.supportedSchemaVersion,integrity:d.integrity,pendingRetryableOperations:d.pendingRetryableOperations}})}if(N.pathname==="/api/control-plane/operations"){let d=N.searchParams.get("state"),g=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0;return S({operations:a.store.listOperations({projectId:a.project.id,state:g,kind:N.searchParams.get("kind")??void 0,limit:Number(N.searchParams.get("limit"))||100})})}if(N.pathname==="/api/queue"&&I.method==="GET"){let d=N.searchParams.get("state"),g=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0,T=kt.list({projectId:a.project.id,state:g,limit:Number(N.searchParams.get("limit"))||250}).filter((_)=>ws(de,_.operation.id,"deployments:read")).map((_)=>{let M=_.operation.resourceId?a.store.getResource(_.operation.resourceId):void 0,K=_.operation.environmentId?a.store.listEnvironments(a.project.id).find((fe)=>fe.id===_.operation.environmentId):void 0,B=_.operation.actorId?a.store.getActor(_.operation.actorId):void 0,Q=_.operation.input;return{..._,target:M?{id:M.id,name:M.name,slug:M.slug,kind:M.kind}:K?{id:K.id,name:K.name,slug:K.slug,kind:"environment"}:{id:a.project.id,name:a.project.name,slug:a.project.slug,kind:"project"},actor:B?{id:B.id,name:B.displayName,kind:B.kind}:void 0,commit:Q.revision??Q.source?.commitSha??null}});return S({operations:T,concurrency:kt.limits})}if(N.pathname==="/api/queue/logs"&&I.method==="GET"){let d=String(N.searchParams.get("id")??"");if(!ws(de,d,"deployments:read"))return S({ok:!1,error:"Operation was not found in this scope."},404);let g=kt.logs(d,{after:Number(N.searchParams.get("after"))||0,limit:Number(N.searchParams.get("limit"))||500});return S({entries:g,cursor:g.at(-1)?.sequence??(Number(N.searchParams.get("after"))||0),operation:a.store.getOperation(d)})}if(N.pathname==="/api/queue/stream"&&I.method==="GET"){let d=String(N.searchParams.get("id")??"");if(!ws(de,d,"deployments:read"))return S({ok:!1,error:"Operation was not found in this scope."},404);let g=I.headers.get("last-event-id")?.trim(),T=Number(g||N.searchParams.get("after")||0),_=new TextEncoder,M,K=!1,B=new ReadableStream({start(Q){let fe=()=>{if(K)return;let ue=Bt.resolveUser(I);if(!ue||!ws(ue,d,"deployments:read")){if(K=!0,M)clearInterval(M);Q.close();return}let He=kt.logs(d,{after:T,limit:500});for(let Le of He)T=Le.sequence,Q.enqueue(_.encode(`id: ${Le.sequence}
487
487
  event: log
488
488
  data: ${JSON.stringify(Le)}
489
489
 
490
- `));let be=a.store.getOperation(d);if(be&&["succeeded","failed","cancelled","timed_out"].includes(be.state)&&kt.logs(d,{after:T,limit:1}).length===0){if(K=!0,L)clearInterval(L);Q.enqueue(_.encode(`event: complete
490
+ `));let be=a.store.getOperation(d);if(be&&["succeeded","failed","cancelled","timed_out"].includes(be.state)&&kt.logs(d,{after:T,limit:1}).length===0){if(K=!0,M)clearInterval(M);Q.enqueue(_.encode(`event: complete
491
491
  data: ${JSON.stringify({state:be.state,cursor:T})}
492
492
 
493
- `)),Q.close()}};if(fe(),!K)L=setInterval(fe,500);I.signal.addEventListener("abort",()=>{if(K=!0,L)clearInterval(L);try{Q.close()}catch{}},{once:!0})},cancel(){if(K=!0,L)clearInterval(L)}});return new Response(B,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no"}})}if(N.pathname==="/api/queue/cancel"&&I.method==="POST"){let d=await oe(I),g=String(d.id??"");if(!ws(de,g,"deployments:cancel"))return S({ok:!1,error:"Operation was not found or cannot be cancelled in this scope."},404);let T=mr(a.store,de);try{return S({ok:!0,operation:kt.requestCancellation(g,T.id)})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Cancellation failed."},409)}}if(N.pathname==="/api/queue/retry"&&I.method==="POST"){let d=await oe(I),g=String(d.id??"");if(!ws(de,g,"deployments:create"))return S({ok:!1,error:"Operation was not found or cannot be retried in this scope."},404);let T=mr(a.store,de);try{return S({ok:!0,operation:kt.retry(g,String(d.errorClass??"manual"),{delayMs:Number(d.delayMs)||0,actorId:T.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Retry failed."},409)}}if(N.pathname==="/api/queue/settings"&&I.method==="GET")return S({concurrency:kt.limits});if(N.pathname==="/api/queue/settings"&&I.method==="PATCH"){let d=await oe(I);if(d.confirm!=="update queue limits")return S({ok:!1,error:'Type "update queue limits" to confirm production concurrency changes.'},409);let g=mr(a.store,de);return S({ok:!0,concurrency:kt.configureConcurrency(d.concurrency??{},{organizationId:a.organization.id,actorId:g.id})})}if(N.pathname==="/api/queue/history"&&I.method==="DELETE"){let d=await oe(I);if(d.confirm!=="clear completed")return S({ok:!1,error:'Type "clear completed" to confirm retained history cleanup.'},409);let g=mr(a.store,de);return S({ok:!0,deleted:kt.clearCompleted({projectId:a.project.id,before:typeof d.before==="string"?d.before:void 0,actorId:g.id})})}if(N.pathname==="/api/previews"&&I.method==="GET"){let d=nr.previews.listInstances({projectId:a.project.id}).filter((_)=>Ar(de,_.resourceId,"deployments:read")),g=nr.previews.listDefinitions(a.project.id).filter((_)=>Ar(de,_.resourceId,"project:read")),T=a.store.listResources(a.project.id).filter((_)=>_.kind==="application"&&Ar(de,_.id,"project:read")).map((_)=>({id:_.id,slug:_.slug,name:_.name,environmentId:_.environmentId}));return S({previews:d,definitions:g,resources:T,environments:[...a.environments.values()]})}if(N.pathname==="/api/releases"&&I.method==="GET"){let d=[...a.environments.values()],g=a.store.listResources(a.project.id).filter((L)=>Ar(de,L.id,"deployments:read")),T=new Set(g.map((L)=>L.id)),_=ii.releases.list({projectId:a.project.id}).filter((L)=>T.has(L.resourceId)).map((L)=>{let K=g.find((fe)=>fe.id===L.resourceId),B=d.find((fe)=>fe.id===L.environmentId),Q=L.previousReleaseId?ii.releases.get(L.previousReleaseId):void 0;return{...L,resource:K?{id:K.id,name:K.name,slug:K.slug,provider:K.provider}:void 0,environment:B?{id:B.id,name:B.name,slug:B.slug,kind:B.kind}:void 0,artifact:ii.releases.getArtifact(L.artifactId),transitions:ii.releases.transitions(L.id),approvals:ii.releases.approvals(L.id),previous:Q,comparison:Q?ii.releases.compare(Q.id,L.id):void 0,capabilities:Yt({kind:L.kind,provider:K?.provider,hasHealthGate:!!L.healthGate,replicas:Number(L.manifest?.replicas)||1})}});return S({releases:_,resources:g.map((L)=>({id:L.id,name:L.name,slug:L.slug,environmentId:L.environmentId,provider:L.provider})),environments:d})}if(N.pathname==="/api/releases/action"&&I.method==="POST"){let d=await oe(I),g=ii.releases.get(String(d.id??"")),T=String(d.action??"");if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Release was not found in this scope."},404);let _=mr(a.store,de);try{if(T==="activate")return S({ok:!0,operation:ii.enqueueActivation(g,{actorId:_.id})});if(T==="rollback"){let L=a.store.getResource(g.resourceId);if(d.confirm!==L?.slug)return S({ok:!1,error:`Type "${L?.slug??""}" to confirm rollback.`},409);return S({ok:!0,operation:ii.enqueueRollback(g,{actorId:_.id,targetReleaseId:typeof d.targetReleaseId==="string"?d.targetReleaseId:void 0})})}if(T==="approve"){let L=a.store.listEnvironments(g.projectId).find((K)=>K.id===g.environmentId);if(d.confirm!==L?.slug)return S({ok:!1,error:`Type "${L?.slug??""}" to confirm the environment gate.`},409);return S({ok:!0,release:ii.releases.approve(g.id,{actorId:_.id,decision:d.decision==="rejected"?"rejected":"approved",comment:typeof d.comment==="string"?d.comment:void 0})})}if(T==="pin")return S({ok:!0,release:ii.releases.pin(g.id,d.pinned!==!1,typeof d.reason==="string"?d.reason:void 0)});if(T==="promote"){let L=a.store.getResource(String(d.targetResourceId??"")),K=L?a.store.listEnvironments(g.projectId).find((B)=>B.id===L.environmentId):void 0;if(!L||!K||!Ar(de,L.id,"deployments:create"))return S({ok:!1,error:"Promotion target was not found in this scope."},404);if(d.confirm!==K.slug)return S({ok:!1,error:`Type "${K.slug}" to confirm promotion.`},409);return S({ok:!0,release:ii.releases.promote(g.id,{targetEnvironmentId:K.id,targetResourceId:L.id,config:d.config&&typeof d.config==="object"?d.config:{},strategy:typeof d.strategy==="string"?d.strategy:void 0,actorId:_.id,approvalRequired:d.approvalRequired===!0})})}return S({ok:!1,error:"Unsupported release action."},422)}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"Release action failed."},409)}}if(N.pathname==="/api/compose"&&I.method==="GET"){let d=ho.applications.list({projectId:a.project.id}).filter((g)=>Ar(de,g.resourceId,"applications:read")).map((g)=>({...g,services:ho.applications.services(g.id)}));return S({applications:d,templates:tr(),environments:[...a.environments.values()]})}if(N.pathname==="/api/compose/preview"&&I.method==="POST"){let d=await oe(I),g=String(d.environmentId??"");if(!pa(de,g,"applications:manage"))return S({ok:!1,error:"Environment was not found in this scope."},404);try{return S({ok:!0,result:ho.applications.preview(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:g})})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Compose could not be parsed."},422)}}if((N.pathname==="/api/compose/import"||N.pathname==="/api/compose/template")&&I.method==="POST"){let d=await oe(I),g=String(d.environmentId??"");if(!pa(de,g,"applications:manage"))return S({ok:!1,error:"Environment was not found in this scope."},404);let T=mr(a.store,de);try{let _=N.pathname.endsWith("/template")?ho.applications.fromTemplate(String(d.templateId??""),d.inputs&&typeof d.inputs==="object"?d.inputs:{},{name:String(d.name??""),projectId:a.project.id,environmentId:g,version:typeof d.templateVersion==="string"?d.templateVersion:void 0,createdByActorId:T.id}):ho.applications.import(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:g,createdByActorId:T.id});return S({ok:!0,application:_.application,diagnostics:_.parsed.diagnostics})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Compose application could not be saved."},422)}}if(N.pathname==="/api/compose/action"&&I.method==="POST"){let d=await oe(I),g=ho.applications.get(String(d.id??"")),T=String(d.action??""),_=T==="delete"||T==="stop"?"deployments:cancel":"deployments:create";if(!g||!Ar(de,g.resourceId,_))return S({ok:!1,error:"Compose application was not found in this scope."},404);try{let L=mr(a.store,de);return S({ok:!0,operation:ho.enqueue(g,T,{actorId:L.id,service:typeof d.service==="string"?d.service:void 0,replicas:Number.isFinite(Number(d.replicas))?Number(d.replicas):void 0,removeVolumes:d.removeVolumes===!0,confirmation:typeof d.confirm==="string"?d.confirm:void 0})})}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"Compose operation could not be queued."},409)}}if((N.pathname==="/api/compose/logs"||N.pathname==="/api/compose/shell")&&I.method==="POST"){let d=await oe(I),g=ho.applications.get(String(d.id??"")),T=N.pathname.endsWith("/shell"),_=T?"runtime:terminal":"runtime:logs";if(!g||!Ar(de,g.resourceId,_))return S({ok:!1,error:"Compose service was not found in this scope."},404);let L=String(d.service??"");if(!g.manifest.spec.services[L])return S({ok:!1,error:"Compose service was not found."},404);if(T&&d.confirm!==L)return S({ok:!1,error:`Type "${L}" to run a service command.`},409);let K=a.store.listEnvironments(g.projectId).find((Q)=>Q.id===g.environmentId)?.slug;if(!K)return S({ok:!1,error:"Compose environment was not found."},404);let B=T?zn(g.manifest,L,Array.isArray(d.command)?d.command.map(String):["sh"]):Vn(g.manifest,L,Number(d.lines)||200);return S(await Qt(o,K,B))}if(N.pathname==="/api/previews/definitions"&&I.method==="POST"){let d=await oe(I),g=String(d.resourceId??"");if(!Ar(de,g,"config:write"))return S({ok:!1,error:"Application was not found in this scope."},404);let T=mr(a.store,de);try{return S({ok:!0,definition:nr.previews.createDefinition({...d,projectId:a.project.id,resourceId:g,baseEnvironmentId:String(d.baseEnvironmentId??""),domainPattern:String(d.domainPattern??""),createdByActorId:T.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Preview policy could not be created."},409)}}if(N.pathname==="/api/previews/deploy"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getDefinition(String(d.definitionId??""));if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Preview policy was not found in this scope."},404);let T=mr(a.store,de);try{let _=nr.previews.upsert({definitionId:g.id,sourceProvider:"dashboard",repository:"dashboard",branch:String(d.branch??""),pullRequestNumber:Number(d.pullRequestNumber)||void 0,commitSha:String(d.commitSha??""),createdByActorId:T.id});return S({ok:!0,preview:_.preview,operation:nr.enqueueDeploy(_.preview,{created:_.created,actorId:T.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Preview could not be queued."},409)}}if(N.pathname==="/api/previews/destroy"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getInstance(String(d.id??""));if(!g||!Ar(de,g.resourceId,"deployments:cancel"))return S({ok:!1,error:"Preview was not found in this scope."},404);if(d.confirm!==g.name)return S({ok:!1,error:`Type "${g.name}" to confirm tagged teardown.`},409);let T=mr(a.store,de);return S({ok:!0,operation:nr.enqueueDestroy(g,"dashboard",T.id)})}if(N.pathname==="/api/previews/extend"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getInstance(String(d.id??""));if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Preview was not found in this scope."},404);return S({ok:!0,preview:nr.previews.extend(g.id,Number(d.hours))})}if(N.pathname==="/api/previews/rebuild"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getInstance(String(d.id??""));if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Preview was not found in this scope."},404);let T=mr(a.store,de);return S({ok:!0,operation:nr.enqueueDeploy(g,{actorId:T.id,reason:"manual_rebuild"})})}if(N.pathname==="/api/previews/cleanup"&&I.method==="POST"){let d=await oe(I);if(!d.dryRun&&d.confirm!=="cleanup previews")return S({ok:!1,error:'Type "cleanup previews" to confirm teardown.'},409);let g=mr(a.store,de);return S({ok:!0,...nr.cleanup({dryRun:d.dryRun===!0,maxAgeHours:Number(d.maxAgeHours)||void 0,keepCount:Number(d.keepCount)||void 0,actorId:g.id})})}if(N.pathname==="/api/control-plane/events")return S({events:a.store.listEvents({organizationId:a.organization.id,projectId:a.project.id,operationId:N.searchParams.get("operationId")??void 0,correlationId:N.searchParams.get("correlationId")??void 0,afterSequence:Number(N.searchParams.get("afterSequence"))||void 0,limit:Number(N.searchParams.get("limit"))||200})});if(N.pathname==="/api/search"){let d=String(N.searchParams.get("q")??"").trim().slice(0,128),g=si.role==="member"?new Set(Object.keys(si.sites)):void 0,T=d?Cs(a.store,{projectId:a.project.id,query:d,allowedResourceSlugs:g,limit:Number(N.searchParams.get("limit"))||20}):[];return S({query:d,results:T,stale:!1})}if(N.pathname==="/api/search/preferences"&&I.method==="GET"){let d=`dashboard:${de.username.toLowerCase()}`;return S({savedFilters:a.store.listSavedFilters(d),navigation:a.store.listNavigation(d)})}if(N.pathname==="/api/search/preferences"&&I.method==="POST"){let d=`dashboard:${de.username.toLowerCase()}`,g=await oe(I),T=String(g.action??"");if(T==="save-filter")return S({savedFilter:a.store.saveFilter(d,String(g.name??""),String(g.routeId??""),g.query??{})});if(T==="favorite")return S({navigation:a.store.setFavorite(d,String(g.entityType??""),String(g.entityId??""),g.favorite!==!1)});if(T==="visit")return S({navigation:a.store.recordNavigation(d,String(g.entityType??""),String(g.entityId??""))});return S({ok:!1,error:"Unknown search preference action."},422)}if(N.pathname==="/api/search/preferences"&&I.method==="DELETE"){let d=`dashboard:${de.username.toLowerCase()}`,g=await oe(I);return S({ok:a.store.deleteSavedFilter(d,String(g.id??""))})}if(N.pathname==="/api/organization"&&I.method==="GET"){let d=a.store.listMemberships(a.organization.id,{includeRevoked:!0}).map((g)=>{let T=a.store.getActor(g.actorId);return{...g,actor:T?{id:T.id,displayName:T.displayName,externalId:T.externalId,disabledAt:T.disabledAt}:void 0,grants:a.store.listGrants(g.id)}});return S({organization:a.organization,project:a.project,environments:a.store.listEnvironments(a.project.id),resources:a.store.listResources(a.project.id).map((g)=>({id:g.id,environmentId:g.environmentId,kind:g.kind,slug:g.slug,name:g.name})),memberships:d,invitations:a.store.listInvitations(a.organization.id)})}if(N.pathname==="/api/organization/invitations"&&I.method==="GET")return S({invitations:a.store.listInvitations(a.organization.id)});if(N.pathname==="/api/organization/invitations"&&I.method==="POST"){let d=await oe(I),g=wd(d.roleTemplate),T=Ua(d);if(!g||!T)return S({ok:!1,error:"Choose a valid role template and resource scope."},422);let _=Me(de);if(!_.actor||!_.membership)return S({ok:!1,error:"Your organization membership is unavailable."},403);if(g==="owner"&&(!Ti(String(d.password??""),de.passwordHash)||_.membership.roleTemplate!=="owner"))return S({ok:!1,error:"Owner invitations require an owner to re-enter their password."},401);try{let L=a.store.createInvitation({organizationId:a.organization.id,email:String(d.email??""),roleTemplate:g,scope:T,invitedByActorId:_.actor.id,expiresInMs:Number(d.expiresInMs)||void 0}),K=`${N.origin}/accept-invitation?token=${encodeURIComponent(L.token)}`,B=await Sa(o,{to:L.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${K}
493
+ `)),Q.close()}};if(fe(),!K)M=setInterval(fe,500);I.signal.addEventListener("abort",()=>{if(K=!0,M)clearInterval(M);try{Q.close()}catch{}},{once:!0})},cancel(){if(K=!0,M)clearInterval(M)}});return new Response(B,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no"}})}if(N.pathname==="/api/queue/cancel"&&I.method==="POST"){let d=await oe(I),g=String(d.id??"");if(!ws(de,g,"deployments:cancel"))return S({ok:!1,error:"Operation was not found or cannot be cancelled in this scope."},404);let T=mr(a.store,de);try{return S({ok:!0,operation:kt.requestCancellation(g,T.id)})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Cancellation failed."},409)}}if(N.pathname==="/api/queue/retry"&&I.method==="POST"){let d=await oe(I),g=String(d.id??"");if(!ws(de,g,"deployments:create"))return S({ok:!1,error:"Operation was not found or cannot be retried in this scope."},404);let T=mr(a.store,de);try{return S({ok:!0,operation:kt.retry(g,String(d.errorClass??"manual"),{delayMs:Number(d.delayMs)||0,actorId:T.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Retry failed."},409)}}if(N.pathname==="/api/queue/settings"&&I.method==="GET")return S({concurrency:kt.limits});if(N.pathname==="/api/queue/settings"&&I.method==="PATCH"){let d=await oe(I);if(d.confirm!=="update queue limits")return S({ok:!1,error:'Type "update queue limits" to confirm production concurrency changes.'},409);let g=mr(a.store,de);return S({ok:!0,concurrency:kt.configureConcurrency(d.concurrency??{},{organizationId:a.organization.id,actorId:g.id})})}if(N.pathname==="/api/queue/history"&&I.method==="DELETE"){let d=await oe(I);if(d.confirm!=="clear completed")return S({ok:!1,error:'Type "clear completed" to confirm retained history cleanup.'},409);let g=mr(a.store,de);return S({ok:!0,deleted:kt.clearCompleted({projectId:a.project.id,before:typeof d.before==="string"?d.before:void 0,actorId:g.id})})}if(N.pathname==="/api/previews"&&I.method==="GET"){let d=nr.previews.listInstances({projectId:a.project.id}).filter((_)=>Ar(de,_.resourceId,"deployments:read")),g=nr.previews.listDefinitions(a.project.id).filter((_)=>Ar(de,_.resourceId,"project:read")),T=a.store.listResources(a.project.id).filter((_)=>_.kind==="application"&&Ar(de,_.id,"project:read")).map((_)=>({id:_.id,slug:_.slug,name:_.name,environmentId:_.environmentId}));return S({previews:d,definitions:g,resources:T,environments:[...a.environments.values()]})}if(N.pathname==="/api/releases"&&I.method==="GET"){let d=[...a.environments.values()],g=a.store.listResources(a.project.id).filter((M)=>Ar(de,M.id,"deployments:read")),T=new Set(g.map((M)=>M.id)),_=ii.releases.list({projectId:a.project.id}).filter((M)=>T.has(M.resourceId)).map((M)=>{let K=g.find((fe)=>fe.id===M.resourceId),B=d.find((fe)=>fe.id===M.environmentId),Q=M.previousReleaseId?ii.releases.get(M.previousReleaseId):void 0;return{...M,resource:K?{id:K.id,name:K.name,slug:K.slug,provider:K.provider}:void 0,environment:B?{id:B.id,name:B.name,slug:B.slug,kind:B.kind}:void 0,artifact:ii.releases.getArtifact(M.artifactId),transitions:ii.releases.transitions(M.id),approvals:ii.releases.approvals(M.id),previous:Q,comparison:Q?ii.releases.compare(Q.id,M.id):void 0,capabilities:Yt({kind:M.kind,provider:K?.provider,hasHealthGate:!!M.healthGate,replicas:Number(M.manifest?.replicas)||1})}});return S({releases:_,resources:g.map((M)=>({id:M.id,name:M.name,slug:M.slug,environmentId:M.environmentId,provider:M.provider})),environments:d})}if(N.pathname==="/api/releases/action"&&I.method==="POST"){let d=await oe(I),g=ii.releases.get(String(d.id??"")),T=String(d.action??"");if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Release was not found in this scope."},404);let _=mr(a.store,de);try{if(T==="activate")return S({ok:!0,operation:ii.enqueueActivation(g,{actorId:_.id})});if(T==="rollback"){let M=a.store.getResource(g.resourceId);if(d.confirm!==M?.slug)return S({ok:!1,error:`Type "${M?.slug??""}" to confirm rollback.`},409);return S({ok:!0,operation:ii.enqueueRollback(g,{actorId:_.id,targetReleaseId:typeof d.targetReleaseId==="string"?d.targetReleaseId:void 0})})}if(T==="approve"){let M=a.store.listEnvironments(g.projectId).find((K)=>K.id===g.environmentId);if(d.confirm!==M?.slug)return S({ok:!1,error:`Type "${M?.slug??""}" to confirm the environment gate.`},409);return S({ok:!0,release:ii.releases.approve(g.id,{actorId:_.id,decision:d.decision==="rejected"?"rejected":"approved",comment:typeof d.comment==="string"?d.comment:void 0})})}if(T==="pin")return S({ok:!0,release:ii.releases.pin(g.id,d.pinned!==!1,typeof d.reason==="string"?d.reason:void 0)});if(T==="promote"){let M=a.store.getResource(String(d.targetResourceId??"")),K=M?a.store.listEnvironments(g.projectId).find((B)=>B.id===M.environmentId):void 0;if(!M||!K||!Ar(de,M.id,"deployments:create"))return S({ok:!1,error:"Promotion target was not found in this scope."},404);if(d.confirm!==K.slug)return S({ok:!1,error:`Type "${K.slug}" to confirm promotion.`},409);return S({ok:!0,release:ii.releases.promote(g.id,{targetEnvironmentId:K.id,targetResourceId:M.id,config:d.config&&typeof d.config==="object"?d.config:{},strategy:typeof d.strategy==="string"?d.strategy:void 0,actorId:_.id,approvalRequired:d.approvalRequired===!0})})}return S({ok:!1,error:"Unsupported release action."},422)}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"Release action failed."},409)}}if(N.pathname==="/api/compose"&&I.method==="GET"){let d=ho.applications.list({projectId:a.project.id}).filter((g)=>Ar(de,g.resourceId,"applications:read")).map((g)=>({...g,services:ho.applications.services(g.id)}));return S({applications:d,templates:tr(),environments:[...a.environments.values()]})}if(N.pathname==="/api/compose/preview"&&I.method==="POST"){let d=await oe(I),g=String(d.environmentId??"");if(!pa(de,g,"applications:manage"))return S({ok:!1,error:"Environment was not found in this scope."},404);try{return S({ok:!0,result:ho.applications.preview(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:g})})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Compose could not be parsed."},422)}}if((N.pathname==="/api/compose/import"||N.pathname==="/api/compose/template")&&I.method==="POST"){let d=await oe(I),g=String(d.environmentId??"");if(!pa(de,g,"applications:manage"))return S({ok:!1,error:"Environment was not found in this scope."},404);let T=mr(a.store,de);try{let _=N.pathname.endsWith("/template")?ho.applications.fromTemplate(String(d.templateId??""),d.inputs&&typeof d.inputs==="object"?d.inputs:{},{name:String(d.name??""),projectId:a.project.id,environmentId:g,version:typeof d.templateVersion==="string"?d.templateVersion:void 0,createdByActorId:T.id}):ho.applications.import(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:g,createdByActorId:T.id});return S({ok:!0,application:_.application,diagnostics:_.parsed.diagnostics})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Compose application could not be saved."},422)}}if(N.pathname==="/api/compose/action"&&I.method==="POST"){let d=await oe(I),g=ho.applications.get(String(d.id??"")),T=String(d.action??""),_=T==="delete"||T==="stop"?"deployments:cancel":"deployments:create";if(!g||!Ar(de,g.resourceId,_))return S({ok:!1,error:"Compose application was not found in this scope."},404);try{let M=mr(a.store,de);return S({ok:!0,operation:ho.enqueue(g,T,{actorId:M.id,service:typeof d.service==="string"?d.service:void 0,replicas:Number.isFinite(Number(d.replicas))?Number(d.replicas):void 0,removeVolumes:d.removeVolumes===!0,confirmation:typeof d.confirm==="string"?d.confirm:void 0})})}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"Compose operation could not be queued."},409)}}if((N.pathname==="/api/compose/logs"||N.pathname==="/api/compose/shell")&&I.method==="POST"){let d=await oe(I),g=ho.applications.get(String(d.id??"")),T=N.pathname.endsWith("/shell"),_=T?"runtime:terminal":"runtime:logs";if(!g||!Ar(de,g.resourceId,_))return S({ok:!1,error:"Compose service was not found in this scope."},404);let M=String(d.service??"");if(!g.manifest.spec.services[M])return S({ok:!1,error:"Compose service was not found."},404);if(T&&d.confirm!==M)return S({ok:!1,error:`Type "${M}" to run a service command.`},409);let K=a.store.listEnvironments(g.projectId).find((Q)=>Q.id===g.environmentId)?.slug;if(!K)return S({ok:!1,error:"Compose environment was not found."},404);let B=T?zn(g.manifest,M,Array.isArray(d.command)?d.command.map(String):["sh"]):Vn(g.manifest,M,Number(d.lines)||200);return S(await Qt(o,K,B))}if(N.pathname==="/api/previews/definitions"&&I.method==="POST"){let d=await oe(I),g=String(d.resourceId??"");if(!Ar(de,g,"config:write"))return S({ok:!1,error:"Application was not found in this scope."},404);let T=mr(a.store,de);try{return S({ok:!0,definition:nr.previews.createDefinition({...d,projectId:a.project.id,resourceId:g,baseEnvironmentId:String(d.baseEnvironmentId??""),domainPattern:String(d.domainPattern??""),createdByActorId:T.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Preview policy could not be created."},409)}}if(N.pathname==="/api/previews/deploy"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getDefinition(String(d.definitionId??""));if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Preview policy was not found in this scope."},404);let T=mr(a.store,de);try{let _=nr.previews.upsert({definitionId:g.id,sourceProvider:"dashboard",repository:"dashboard",branch:String(d.branch??""),pullRequestNumber:Number(d.pullRequestNumber)||void 0,commitSha:String(d.commitSha??""),createdByActorId:T.id});return S({ok:!0,preview:_.preview,operation:nr.enqueueDeploy(_.preview,{created:_.created,actorId:T.id})})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Preview could not be queued."},409)}}if(N.pathname==="/api/previews/destroy"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getInstance(String(d.id??""));if(!g||!Ar(de,g.resourceId,"deployments:cancel"))return S({ok:!1,error:"Preview was not found in this scope."},404);if(d.confirm!==g.name)return S({ok:!1,error:`Type "${g.name}" to confirm tagged teardown.`},409);let T=mr(a.store,de);return S({ok:!0,operation:nr.enqueueDestroy(g,"dashboard",T.id)})}if(N.pathname==="/api/previews/extend"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getInstance(String(d.id??""));if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Preview was not found in this scope."},404);return S({ok:!0,preview:nr.previews.extend(g.id,Number(d.hours))})}if(N.pathname==="/api/previews/rebuild"&&I.method==="POST"){let d=await oe(I),g=nr.previews.getInstance(String(d.id??""));if(!g||!Ar(de,g.resourceId,"deployments:create"))return S({ok:!1,error:"Preview was not found in this scope."},404);let T=mr(a.store,de);return S({ok:!0,operation:nr.enqueueDeploy(g,{actorId:T.id,reason:"manual_rebuild"})})}if(N.pathname==="/api/previews/cleanup"&&I.method==="POST"){let d=await oe(I);if(!d.dryRun&&d.confirm!=="cleanup previews")return S({ok:!1,error:'Type "cleanup previews" to confirm teardown.'},409);let g=mr(a.store,de);return S({ok:!0,...nr.cleanup({dryRun:d.dryRun===!0,maxAgeHours:Number(d.maxAgeHours)||void 0,keepCount:Number(d.keepCount)||void 0,actorId:g.id})})}if(N.pathname==="/api/control-plane/events")return S({events:a.store.listEvents({organizationId:a.organization.id,projectId:a.project.id,operationId:N.searchParams.get("operationId")??void 0,correlationId:N.searchParams.get("correlationId")??void 0,afterSequence:Number(N.searchParams.get("afterSequence"))||void 0,limit:Number(N.searchParams.get("limit"))||200})});if(N.pathname==="/api/search"){let d=String(N.searchParams.get("q")??"").trim().slice(0,128),g=si.role==="member"?new Set(Object.keys(si.sites)):void 0,T=d?Cs(a.store,{projectId:a.project.id,query:d,allowedResourceSlugs:g,limit:Number(N.searchParams.get("limit"))||20}):[];return S({query:d,results:T,stale:!1})}if(N.pathname==="/api/search/preferences"&&I.method==="GET"){let d=`dashboard:${de.username.toLowerCase()}`;return S({savedFilters:a.store.listSavedFilters(d),navigation:a.store.listNavigation(d)})}if(N.pathname==="/api/search/preferences"&&I.method==="POST"){let d=`dashboard:${de.username.toLowerCase()}`,g=await oe(I),T=String(g.action??"");if(T==="save-filter")return S({savedFilter:a.store.saveFilter(d,String(g.name??""),String(g.routeId??""),g.query??{})});if(T==="favorite")return S({navigation:a.store.setFavorite(d,String(g.entityType??""),String(g.entityId??""),g.favorite!==!1)});if(T==="visit")return S({navigation:a.store.recordNavigation(d,String(g.entityType??""),String(g.entityId??""))});return S({ok:!1,error:"Unknown search preference action."},422)}if(N.pathname==="/api/search/preferences"&&I.method==="DELETE"){let d=`dashboard:${de.username.toLowerCase()}`,g=await oe(I);return S({ok:a.store.deleteSavedFilter(d,String(g.id??""))})}if(N.pathname==="/api/organization"&&I.method==="GET"){let d=a.store.listMemberships(a.organization.id,{includeRevoked:!0}).map((g)=>{let T=a.store.getActor(g.actorId);return{...g,actor:T?{id:T.id,displayName:T.displayName,externalId:T.externalId,disabledAt:T.disabledAt}:void 0,grants:a.store.listGrants(g.id)}});return S({organization:a.organization,project:a.project,environments:a.store.listEnvironments(a.project.id),resources:a.store.listResources(a.project.id).map((g)=>({id:g.id,environmentId:g.environmentId,kind:g.kind,slug:g.slug,name:g.name})),memberships:d,invitations:a.store.listInvitations(a.organization.id)})}if(N.pathname==="/api/organization/invitations"&&I.method==="GET")return S({invitations:a.store.listInvitations(a.organization.id)});if(N.pathname==="/api/organization/invitations"&&I.method==="POST"){let d=await oe(I),g=wd(d.roleTemplate),T=Ua(d);if(!g||!T)return S({ok:!1,error:"Choose a valid role template and resource scope."},422);let _=Me(de);if(!_.actor||!_.membership)return S({ok:!1,error:"Your organization membership is unavailable."},403);if(g==="owner"&&(!Ti(String(d.password??""),de.passwordHash)||_.membership.roleTemplate!=="owner"))return S({ok:!1,error:"Owner invitations require an owner to re-enter their password."},401);try{let M=a.store.createInvitation({organizationId:a.organization.id,email:String(d.email??""),roleTemplate:g,scope:T,invitedByActorId:_.actor.id,expiresInMs:Number(d.expiresInMs)||void 0}),K=`${N.origin}/accept-invitation?token=${encodeURIComponent(M.token)}`,B=await Sa(o,{to:M.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${K}
494
494
 
495
- This link expires ${L.invitation.expiresAt} and can be used once.`});return S({invitation:L.invitation,token:L.token,acceptUrl:K,delivered:B},201)}catch(L){return S({ok:!1,error:L instanceof Error?L.message:"Invitation could not be created."},422)}}if(N.pathname==="/api/organization/invitations"&&I.method==="DELETE"){let d=await oe(I),g=Me(de);try{return S({invitation:a.store.revokeInvitation(String(d.id??""),g.actor?.id)})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Invitation could not be revoked."},409)}}if(N.pathname==="/api/organization/invitations/resend"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{let T=a.store.reissueInvitation(String(d.id??""),g.actor?.id),_=`${N.origin}/accept-invitation?token=${encodeURIComponent(T.token)}`,L=await Sa(o,{to:T.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${_}
495
+ This link expires ${M.invitation.expiresAt} and can be used once.`});return S({invitation:M.invitation,token:M.token,acceptUrl:K,delivered:B},201)}catch(M){return S({ok:!1,error:M instanceof Error?M.message:"Invitation could not be created."},422)}}if(N.pathname==="/api/organization/invitations"&&I.method==="DELETE"){let d=await oe(I),g=Me(de);try{return S({invitation:a.store.revokeInvitation(String(d.id??""),g.actor?.id)})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Invitation could not be revoked."},409)}}if(N.pathname==="/api/organization/invitations/resend"&&I.method==="POST"){let d=await oe(I),g=Me(de);try{let T=a.store.reissueInvitation(String(d.id??""),g.actor?.id),_=`${N.origin}/accept-invitation?token=${encodeURIComponent(T.token)}`,M=await Sa(o,{to:T.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${_}
496
496
 
497
- This replacement link expires ${T.invitation.expiresAt} and can be used once.`});return S({invitation:T.invitation,token:T.token,acceptUrl:_,delivered:L})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Invitation could not be resent."},409)}}if(N.pathname==="/api/organization/memberships"&&I.method==="PATCH"){let d=await oe(I),g=a.store.getMembership(String(d.id??"")),T=wd(d.roleTemplate),_=Ua(d);if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Membership was not found."},404);if(!T||!_)return S({ok:!1,error:"Choose a valid role template and resource scope."},422);let L=Me(de);if((g.roleTemplate==="owner"||T==="owner")&&(!Ti(String(d.password??""),de.passwordHash)||L.membership?.roleTemplate!=="owner"))return S({ok:!1,error:"Ownership changes require an owner to re-enter their password."},401);let B=a.store.resolveAuthorizationTarget(a.organization.id,_)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),Q=a.store.listGrants(g.id),fe=en({membership:g,grants:Q,target:B}),ue={...g,roleTemplate:T,scope:_},He=en({membership:ue,grants:Q,target:B}),be={gained:He.filter((Le)=>!fe.includes(Le)),lost:fe.filter((Le)=>!He.includes(Le))};if(d.preview===!0)return S({membership:g,proposed:{roleTemplate:T,scope:_},accessDiff:be});if(String(d.confirm??"")!==g.id)return S({ok:!1,error:`Confirm this change with membership ID ${g.id}.`,accessDiff:be},409);try{return S({membership:a.store.updateMembership({id:g.id,roleTemplate:T,scope:_,actorId:L.actor?.id}),accessDiff:be})}catch(Le){return S({ok:!1,error:Le instanceof Error?Le.message:"Membership could not be updated."},409)}}if(N.pathname==="/api/organization/memberships"&&I.method==="DELETE"){let d=await oe(I),g=a.store.getMembership(String(d.id??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Membership was not found."},404);if(String(d.confirm??"")!==g.id)return S({ok:!1,error:`Confirm removal with membership ID ${g.id}.`},409);let T=Me(de);if(g.roleTemplate==="owner"&&(T.membership?.roleTemplate!=="owner"||!Ti(String(d.password??""),de.passwordHash)))return S({ok:!1,error:"Removing an owner requires an owner to re-enter their current password."},401);try{return S({membership:a.store.revokeMembership(g.id,T.actor?.id)})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Membership could not be removed."},409)}}if(N.pathname==="/api/organization/grants"&&I.method==="POST"){let d=await oe(I),g=String(d.capability??""),T=d.effect==="deny"?"deny":d.effect==="allow"?"allow":void 0,_=Ua(d),L=Me(de);if(!T||!_||!ie.includes(g))return S({ok:!1,error:"Choose a valid capability, effect, and resource scope."},422);try{return S({grant:a.store.upsertGrant({organizationId:a.organization.id,membershipId:String(d.membershipId??""),effect:T,capability:g,scope:_,actorId:L.actor?.id})},201)}catch(K){return S({ok:!1,error:K instanceof Error?K.message:"Grant could not be created."},422)}}if(N.pathname==="/api/organization/grants"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=a.store.getGrant(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Grant was not found."},404);return S({ok:a.store.removeGrant(T.id,g.actor?.id)})}if(N.pathname==="/api/tags"&&I.method==="GET")return S({tags:a.store.listTags(a.project.id),assignments:a.store.listResourceTags(a.project.id)});if(N.pathname==="/api/tags"&&I.method==="POST"){let d=await oe(I),g=a.store.upsertTag(a.project.id,String(d.name??""),String(d.color??"#5a8be0"));if(d.resourceId)a.store.assignTag(String(d.resourceId),g.id);return S({tag:g},201)}if(N.pathname==="/api/tags"&&I.method==="DELETE"){let d=await oe(I);return a.store.removeTag(String(d.resourceId??""),String(d.tagId??"")),S({ok:!0})}if(N.pathname==="/"&&!ab(N.pathname,si))return new Response(null,{status:302,headers:{location:`/server/sites?env=${encodeURIComponent(ye)}`}});if(N.pathname==="/"&&Mt?.mode==="serverless")return new Response(null,{status:302,headers:{location:`/serverless?env=${encodeURIComponent(ye)}`}});let Ka=uy(N.pathname);if(Ka)return new Response(null,{status:308,headers:{location:`${Ka}?env=${encodeURIComponent(ye)}`}});if(N.pathname==="/api/env"&&I.method==="POST"){let d=await oe(I),g=String(d.env??"");if(!m.includes(g))return S({ok:!1,error:`Unknown environment '${g}'.`,environments:m},404);return S({ok:!0,environment:g,environments:m,href:`?env=${encodeURIComponent(g)}`})}if(N.pathname==="/api/config"){let d={...oA(o),environment:ye,environments:m};return S(py(d,si))}if(N.pathname==="/api/ssh-keys"&&I.method==="GET")return S({configPath:D,keys:Ot(ca(o))});if(N.pathname==="/api/ssh-keys"&&I.method==="POST"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=await Fi(D,"utf8"),T=ca(o),_=_a({configText:g,name:String(d.name??""),publicKey:String(d.publicKey??""),existingKeys:T});return await ys(D,_),nb(o,[...T,{name:String(d.name??"").trim(),publicKey:String(d.publicKey??"").trim().replace(/\s+/g," ")}]),S({ok:!0,configPath:D,keys:Ot(ca(o))})}if(N.pathname==="/api/ssh-keys"&&I.method==="DELETE"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??N.searchParams.get("name")??""),T=await Fi(D,"utf8"),_=ca(o),L=$a({configText:T,name:g,existingKeys:_});return await ys(D,L),nb(o,_.filter((K)=>K.name!==g.trim())),S({ok:!0,configPath:D,keys:Ot(ca(o))})}if(N.pathname==="/api/firewall"&&I.method==="GET")return S({configPath:D,alwaysOpen:[22,80,443],ports:rp(o)});if(N.pathname==="/api/firewall"&&I.method==="POST"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=Number(d.port);if(!ja(g))return S({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=rp(o),_=await Fi(D,"utf8");try{await ys(D,Sy(_,g,T))}catch(B){return S({ok:!1,error:B?.message??String(B)},422)}let L=hs([...T,g]);ib(o,L);let K=d.apply===!1?null:await Qt(o,ye,`ufw allow ${g}/tcp`).catch((B)=>({ok:!1,error:String(B?.message??B)}));return S({ok:!0,configPath:D,ports:L,apply:K})}if(N.pathname==="/api/firewall"&&I.method==="DELETE"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=Number(d.port??N.searchParams.get("port"));if(!ja(g))return S({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=rp(o),_=await Fi(D,"utf8");await ys(D,vy(_,g,T));let L=hs(T.filter((B)=>B!==g));ib(o,L);let K=d.apply===!1?null:await Qt(o,ye,`ufw delete allow ${g}/tcp`).catch((B)=>({ok:!1,error:String(B?.message??B)}));return S({ok:!0,configPath:D,ports:L,apply:K})}if(N.pathname==="/api/sites"&&I.method==="POST"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??"").trim(),T=String(d.root??"").trim();if(!g||!T)return S({ok:!1,error:"Site name and root are required."},422);let _={deploy:d.deploy==="bucket"?"bucket":"server",root:T,path:String(d.path??"").trim()||void 0,domain:String(d.domain??"").trim()||void 0,build:String(d.build??"").trim()||void 0,start:String(d.start??"").trim()||void 0,port:d.port?Number(d.port):void 0,type:String(d.type??"").trim()||void 0};if(_.port!==void 0&&(!Number.isInteger(_.port)||_.port<1||_.port>65535))return S({ok:!1,error:"Port must be a number between 1 and 65535."},422);let L=await Fi(D,"utf8"),K=un({configText:L,name:g,root:_.root,domain:_.domain,path:_.path,deploy:_.deploy,build:_.build,start:_.start,port:_.port,type:_.type});return await ys(D,K),YT(o,g,Object.fromEntries(Object.entries(_).filter(([,B])=>B!==void 0))),Mt=await bs(o,ye),q.set(ye,Mt),S({ok:!0,configPath:D,site:g,data:Mt})}if(N.pathname==="/api/sites"&&I.method==="DELETE"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??N.searchParams.get("name")??"").trim();if(!g||!o.sites?.[g])return S({ok:!1,error:`Site '${g}' was not found.`},404);let T=await Fi(D,"utf8");return await ys(D,My({configText:T,name:g})),delete o.sites[g],Mt=await bs(o,ye),q.set(ye,Mt),S({ok:!0,configPath:D,site:g,data:Mt})}if(N.pathname==="/api/sites"&&I.method==="PATCH"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??"").trim(),T=o.sites?.[g];if(!g||!T)return S({ok:!1,error:`Site '${g}' was not found.`},404);if(si.role==="member"){let K=fy(d);if(!K.ok)return S({ok:!1,error:K.error},403);let B=hy({siteName:g,body:d,sites:o.sites??{},ownSites:Object.keys(si.sites)});if(!B.ok)return S({ok:!1,error:B.error},409)}if(d.port!==void 0&&d.port!==null&&d.port!==""&&(!Number.isInteger(Number(d.port))||Number(d.port)<1||Number(d.port)>65535))return S({ok:!1,error:"Port must be a number between 1 and 65535."},422);if(typeof d.domain==="string"&&d.domain.trim()&&!Zl(d.domain.trim()))return S({ok:!1,error:`Domain '${d.domain.trim()}' is not a valid hostname.`},422);let _=await Fi(D,"utf8"),L=(K,B)=>{_=Ly({configText:_,siteName:g,key:K,valueText:B})};if(d.ssl!==void 0)L("ssl",By(d.ssl)),T.ssl=d.ssl;if(d.env!==void 0&&d.env&&typeof d.env==="object")L("env",Fy(d.env)),T.env=d.env;if(d.aliases!==void 0&&Array.isArray(d.aliases)){let K=d.aliases.map((B)=>String(B));L("aliases",Uy(K)),T.aliases=K.map((B)=>B.trim().toLowerCase()).filter(Boolean)}if(d.redirects!==void 0&&d.redirects&&typeof d.redirects==="object")L("redirects",zy(d.redirects)),T.redirects=d.redirects;for(let K of["domain","path","build","start","type","root","php"])if(typeof d[K]==="string"&&d[K].trim())L(K,jy(String(d[K]).trim())),T[K]=String(d[K]).trim();if(d.port!==void 0&&d.port!==null&&d.port!=="")L("port",String(Number(d.port))),T.port=Number(d.port);return await ys(D,_),Mt=await bs(o,ye),q.set(ye,Mt),S({ok:!0,configPath:D,site:g,data:Mt})}if(N.pathname==="/api/sites/deploy"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim();if(!g||!o.sites?.[g])return S({ok:!1,error:`Site '${g}' was not found.`},404);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to deploy this site.`},409);let T=ae(a,String(ye));await new ps(et).run(new Oa,{...T,artifactRoot:t}),od(et,T,Mt??{});let _=Zt(et,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(_.decision.outcome==="block")return S({ok:!1,error:`Deployment blocked by security policy: ${_.decision.explanation}`,securityReview:_},409);let L={id:`deploy:${g}`,label:`Deploy ${g}`,description:`Deploy the ${g} site for ${ye}.`,command:["deploy","--env",ye,"--site",g,"--yes"],mutates:!0},K=await ao({controlPlane:a,environment:ye,actor:de,kind:"dashboard.site.deploy",resourceSlug:g,input:{site:g},execute:()=>np(L,{cwd:t,cliEntry:i})});return S({...K.result,controlPlaneOperation:K.operation,securityReview:_})}if(N.pathname==="/api/actions")return S(gb(ye));if(N.pathname==="/api/server/operations")return S(Dr(o,Mt));if(N.pathname==="/api/runtime/workloads"&&I.method==="GET"){let d=await Si(o,ye);return S(d)}if(N.pathname==="/api/runtime/logs"&&I.method==="GET"){let d=String(N.searchParams.get("workload")??"");if(!d)return S({ok:!1,error:"A workload query parameter is required."},422);let g=Math.min(1000,Math.max(1,Number(N.searchParams.get("limit"))||200));try{return S(await new ge(o,ye).logs(d,{limit:g}))}catch(T){return S({ok:!1,error:String(T?.message??T)},404)}}if(N.pathname==="/api/runtime/log-sessions"&&I.method==="POST"){let d=await oe(I),g=String(d.workloadId??"");if(!g)return S({ok:!1,error:"A workloadId is required."},422);let T=await Si(o,ye),_=T.workloads.find((B)=>B.id===g);if(!_)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);if(!_.capabilities.logs.supported)return S({ok:!1,error:_.capabilities.logs.reason??"Logs are unsupported for this workload."},409);let L=new ge(o,ye,{inventory:async()=>T}),K=ar.create("logs",g);return(async()=>{let B=new Date(Date.now()-Math.min(3600000,Math.max(1000,Number(d.sinceMs)||60000)));try{for(let Q=0;Q<200&&!ar.signal(K.id)?.aborted;Q++){let fe=await L.logs(g,{limit:Math.min(500,Math.max(1,Number(d.limit)||200)),since:B});for(let ue of fe.lines)if(ar.append(K.id,`${ue.timestamp?`${ue.timestamp} `:""}${ue.message}
498
- `),ue.timestamp)B=new Date(Math.max(B.getTime(),new Date(ue.timestamp).getTime()+1));await Bun.sleep(3000)}if(!ar.signal(K.id)?.aborted)ar.close(K.id,"complete")}catch(Q){ar.append(K.id,Q instanceof Error?Q.message:String(Q),"stderr"),ar.close(K.id,"failed",Q instanceof Error?Q.message:String(Q))}})(),S({ok:!0,session:K,streamUrl:`/api/runtime/log-stream?id=${encodeURIComponent(K.id)}&workload=${encodeURIComponent(g)}`},201)}if((N.pathname==="/api/runtime/log-stream"||N.pathname==="/api/runtime/exec-stream")&&I.method==="GET"){let d=String(N.searchParams.get("id")??""),g=String(N.searchParams.get("workload")??""),T=Number(I.headers.get("last-event-id")??N.searchParams.get("after")??0)||0,_=ar.read(d,g,T),L=N.pathname.includes("exec")?"exec":"logs";if(!_||_.kind!==L)return S({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return zT(ar,_,T,I.signal)}if((N.pathname==="/api/runtime/log-sessions"||N.pathname==="/api/runtime/exec-sessions")&&I.method==="DELETE"){let d=await oe(I),g=ar.cancel(String(d.id??""),String(d.workloadId??""));if(!g)return S({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return S({ok:!0,session:g})}if(N.pathname==="/api/runtime/exec-sessions"&&I.method==="POST"){let d=await oe(I),g=String(d.workloadId??""),T=await Si(o,ye),_=T.workloads.find((Q)=>Q.id===g);if(!_)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);let L=Bt.resolveSession(I),K=new ge(o,ye,{inventory:async()=>T}),B=ar.create("exec",g);return ao({controlPlane:a,environment:ye,actor:de,kind:"runtime.exec",resourceSlug:_.links.service,input:{workloadId:g,provider:_.provider,preset:d.preset?String(d.preset):null,freeForm:!!String(d.command??"").trim()},execute:()=>K.exec({workloadId:g,preset:["process","sockets","filesystem"].includes(String(d.preset))?String(d.preset):void 0,command:typeof d.command==="string"?d.command:void 0,confirm:String(d.confirm??""),recentAuth:!Re||!!L&&ve.isRecentlyAuthenticated(L)})}).then(({result:Q,operation:fe})=>{if(ar.append(B.id,`operation ${fe.id}
499
- `,"system"),Q.stdout)ar.append(B.id,Q.stdout,"stdout");if(Q.stderr)ar.append(B.id,Q.stderr,"stderr");ar.close(B.id,Q.ok?"complete":"failed",Q.error)}).catch((Q)=>{let fe=Q instanceof Error?Q.message:String(Q);ar.append(B.id,fe,"stderr"),ar.close(B.id,"failed",fe)}),S({ok:!0,session:B,streamUrl:`/api/runtime/exec-stream?id=${encodeURIComponent(B.id)}&workload=${encodeURIComponent(g)}`},202)}if(N.pathname==="/api/runtime/files/read"&&I.method==="POST"){let d=await oe(I),g=await Si(o,ye),T=Bt.resolveSession(I),_=await new ge(o,ye,{inventory:async()=>g}).readFile({workloadId:String(d.workloadId??""),path:String(d.path??""),confirm:String(d.confirm??""),recentAuth:!Re||!!T&&ve.isRecentlyAuthenticated(T)});return S(_,_.ok?200:409)}if(N.pathname==="/api/runtime/files/write"&&I.method==="POST"){let d=await oe(I),g=await Si(o,ye),T=String(d.workloadId??""),_=g.workloads.find((Q)=>Q.id===T);if(!_)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);let L=Bt.resolveSession(I),K=new ge(o,ye,{inventory:async()=>g}),B=await ao({controlPlane:a,environment:ye,actor:de,kind:"runtime.file.write",resourceSlug:_.links.service,input:{workloadId:T,provider:_.provider,path:String(d.path??""),bytes:Buffer.from(String(d.contentBase64??""),"base64").byteLength},execute:()=>K.writeFile({workloadId:T,path:String(d.path??""),contentBase64:String(d.contentBase64??""),confirm:String(d.confirm??""),recentAuth:!Re||!!L&&ve.isRecentlyAuthenticated(L)})});return S({...B.result,controlPlaneOperation:B.operation},B.result.ok?200:409)}if(N.pathname==="/api/runtime/operations"&&I.method==="POST"){let d=await oe(I),g=String(d.workloadId??""),T=String(d.action??"");if(!g||!["start","stop","restart","redeploy","scale","inspect"].includes(T))return S({ok:!1,error:"A valid workloadId and lifecycle action are required."},422);let _=await Si(o,ye),L=_.workloads.find((fe)=>fe.id===g);if(!L)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);let K=Bt.resolveSession(I),B=new ge(o,ye,{inventory:async()=>_}),Q=await ao({controlPlane:a,environment:ye,actor:de,kind:`runtime.${T}`,resourceSlug:L.links.service,input:{workloadId:g,provider:L.provider,action:T,replicas:d.replicas==null?null:Number(d.replicas)},execute:()=>B.run({workloadId:g,action:T,replicas:d.replicas==null?void 0:Number(d.replicas),confirm:String(d.confirm??""),recentAuth:!Re||!!K&&ve.isRecentlyAuthenticated(K)})});return S({...Q.result,controlPlaneOperation:Q.operation},Q.result.ok?200:409)}if(N.pathname.startsWith("/api/protection")){let d=de.role==="admin"||Ga(de,"security:read"),g=de.role==="admin"||Ga(de,"security:manage");if(!d)return S({ok:!1,error:"Protection controls require security:read."},403);let{ProtectionControlStore:T,describePosture:_}=await import("./chunk-xw9vcdwt.js"),L=new T(a.store),K=()=>{if(!g)throw Error("Changing protection controls requires security:manage.")};if(N.pathname==="/api/protection"&&I.method==="GET"){let B=L.current();return S({ok:!0,posture:_(B),controls:B,raw:L.raw()})}if(N.pathname==="/api/protection/attack-mode"&&I.method==="POST"){K();let B=await oe(I);if(B.enabled===!1)return S({ok:!0,disabled:L.disableAttackMode()});return S({ok:!0,control:L.enableAttackMode({hours:B.hours==null?void 0:Number(B.hours),reason:String(B.reason??"Enabled from the dashboard."),actorId:Me(de).actor?.id})})}if(N.pathname==="/api/protection/pause"&&I.method==="POST"){K();let B=await oe(I);if(B.enabled===!1)return S({ok:!0,resumed:L.resumeMitigations()});return S({ok:!0,control:L.pauseMitigations({hours:B.hours==null?void 0:Number(B.hours),reason:String(B.reason??""),actorId:Me(de).actor?.id})})}if(N.pathname==="/api/protection/ip-rules"&&I.method==="GET")return S({ok:!0,ipRules:L.current().ipRules});if(N.pathname==="/api/protection/ip-rules"&&(I.method==="POST"||I.method==="DELETE")){K();let B=await oe(I),Q=B.list==="allow"?"allow":"block",fe=I.method==="POST"?L.addIpRule(Q,String(B.cidr??"")):L.removeIpRule(Q,String(B.cidr??""));return S({ok:!0,ipRules:fe})}return S({ok:!1,error:"Protection endpoint was not found."},404)}if(N.pathname.startsWith("/api/spend/")||N.pathname==="/api/usage"){let d=await bb(),{store:g,service:T,gate:_}=d,L=de.role==="admin"||Ga(de,"billing:read"),K=de.role==="admin"||Ga(de,"billing:manage");if(!L)return S({ok:!1,error:"Spend data requires the billing:read capability."},403);let B=a.environments.get(ye),Q={organizationId:a.organization.id,projectId:a.project.id,environmentId:B?.id},fe=()=>{if(!K)throw Error("Changing a budget requires the billing:manage capability.")};if(N.pathname==="/api/usage"&&I.method==="GET")return S({ok:!0,...T.usageReport({organizationId:Q.organizationId,projectId:Q.projectId,period:N.searchParams.get("period")??"monthly",timezone:N.searchParams.get("timezone")??void 0})});if(N.pathname==="/api/spend/budgets"&&I.method==="GET")return S({ok:!0,budgets:g.listBudgets({organizationId:Q.organizationId,projectId:Q.projectId}).map((ue)=>({...ue,status:T.status(ue)}))});if(N.pathname==="/api/spend/budgets"&&I.method==="POST"){fe();let ue=await oe(I),He=String(ue.scope??"project"),be=g.createBudget({organizationId:Q.organizationId,projectId:He==="organization"?void 0:Q.projectId,environmentId:He==="environment"?Q.environmentId:void 0,name:String(ue.name??"").trim(),period:ue.period??"monthly",timezone:ue.timezone?String(ue.timezone):void 0,softLimitCents:ue.softLimitCents==null?void 0:Math.round(Number(ue.softLimitCents)),hardLimitCents:ue.hardLimitCents==null?void 0:Math.round(Number(ue.hardLimitCents)),graceSeconds:ue.graceSeconds==null?void 0:Number(ue.graceSeconds),dryRun:ue.dryRun!==!1});return S({ok:!0,budget:be})}if(N.pathname==="/api/spend/budgets"&&I.method==="PATCH"){fe();let ue=await oe(I),He=String(ue.id??""),be=g.getBudget(He);if(!be||be.organizationId!==Q.organizationId)return S({ok:!1,error:"Budget was not found."},404);return S({ok:!0,budget:g.updateBudget(He,{softLimitCents:ue.softLimitCents==null?be.softLimitCents:Math.round(Number(ue.softLimitCents)),hardLimitCents:ue.hardLimitCents==null?be.hardLimitCents:Math.round(Number(ue.hardLimitCents)),enabled:ue.enabled==null?be.enabled:ue.enabled===!0,dryRun:ue.dryRun==null?be.dryRun:ue.dryRun===!0},ue.expectedVersion==null?void 0:Number(ue.expectedVersion))})}if(N.pathname==="/api/spend/budgets"&&I.method==="DELETE"){fe();let ue=await oe(I),He=String(ue.id??""),be=g.getBudget(He);if(!be||be.organizationId!==Q.organizationId)return S({ok:!1,error:"Budget was not found."},404);let Le=_.closeBudget(He);return g.deleteBudget(He),S({ok:!0,deleted:!0,lifted:Le})}if(N.pathname==="/api/spend/check"&&I.method==="POST"){fe();let ue=await oe(I),{SpendRunner:He}=await import("./chunk-bdgkeqv6.js"),be=new He({controlPlane:a.store,store:g,alerts:Ge});if(ue.apply!==!0){let Se=g.budgetsForScope(Q.organizationId,Q.projectId,Q.environmentId);return S({ok:!0,applied:!1,preview:Se.map((Te)=>T.status(Te))})}let Le=await be.run({...Q,environmentKind:B?.kind});return S({ok:!0,applied:!0,result:Le})}if(N.pathname==="/api/spend/enforcement"&&I.method==="GET")return S({ok:!0,enforcement:_.listUnder({organizationId:Q.organizationId})});if(N.pathname==="/api/spend/release"&&I.method==="POST"){fe();let ue=await oe(I),He=_.close(String(ue.budgetId??""),ue.action);return S({ok:He,released:He,note:He?"The next spend cycle re-applies this if spend is still over the threshold.":"That action was not in force."})}if(N.pathname==="/api/spend/anomalies"&&I.method==="GET")return S({ok:!0,anomalies:g.listAnomalies({organizationId:Q.organizationId,projectId:Q.projectId,unacknowledgedOnly:N.searchParams.get("unacknowledged")==="true"})});if(N.pathname==="/api/spend/anomalies/acknowledge"&&I.method==="POST"){fe();let ue=await oe(I);return S({ok:!0,acknowledged:g.acknowledgeAnomaly(String(ue.id??""))})}return S({ok:!1,error:"Spend endpoint was not found."},404)}if(N.pathname.startsWith("/api/health/")||N.pathname.startsWith("/api/alerts")||N.pathname.startsWith("/api/notifications/")){let d=a.environments.get(ye),g=a.store.listResources(a.project.id,d?.id),T=de.role==="admin"||!!d&&pa(de,d.id,"runtime:read")?g:g.filter((B)=>Ar(de,B.id,"runtime:read")),_=(B)=>!B||T.some((Q)=>Q.id===B),L=(B)=>{if(!B)return;let Q=g.find((fe)=>fe.id===B||fe.slug===B);if(!Q)throw Error("Alert resource was not found.");if(!_(Q.id))throw Error("Alert resource is outside your authorized scope.");return Q.id},K=Me(de).actor;if(N.pathname==="/api/health/checks"&&I.method==="GET")return S({ok:!0,checks:Ge.listHealthChecks(a.project.id,d?.id).filter((B)=>_(B.resourceId)).map((B)=>({...B,results:Ge.listHealthResults(B.id,20)}))});if(N.pathname==="/api/health/checks"&&I.method==="POST"){let B=await oe(I),Q=String(B.kind??"http");if(Q==="command"&&de.role!=="admin")return S({ok:!1,error:"Command health checks require an administrator."},403);let fe={method:String(B.config?.method??"GET").toUpperCase().slice(0,10),path:B.config?.path?String(B.config.path).slice(0,500):void 0,port:B.config?.port==null?void 0:Number(B.config.port),command:Array.isArray(B.config?.command)?B.config.command.map(String).slice(0,20):void 0,expectedStatuses:Array.isArray(B.config?.expectedStatuses)?B.config.expectedStatuses.map(Number).filter(Number.isInteger).slice(0,20):void 0,expectedBody:B.config?.expectedBody?String(B.config.expectedBody).slice(0,500):void 0};return S({ok:!0,check:Ge.createHealthCheck({projectId:a.project.id,environmentId:d?.id,resourceId:L(B.resourceId??B.resource),name:String(B.name??""),kind:Q,target:String(B.target??""),config:fe,intervalSeconds:Number(B.intervalSeconds)||60,timeoutSeconds:Number(B.timeoutSeconds)||10,failureThreshold:Number(B.failureThreshold)||3,recoveryThreshold:Number(B.recoveryThreshold)||2,regions:Array.isArray(B.regions)?B.regions.map(String):["local"],enabled:B.enabled!==!1})},201)}if(N.pathname==="/api/health/checks"&&I.method==="PATCH"){let B=await oe(I),Q=Ge.getHealthCheck(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Health check was not found."},404);return S({ok:!0,check:Ge.setHealthCheckEnabled(Q.id,B.enabled!==!1)})}if(N.pathname==="/api/health/checks/test"&&I.method==="POST"){let B=await oe(I),Q=Ge.getHealthCheck(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Health check was not found."},404);return S({ok:!0,productionIncidentCreated:!1,result:await new Oe(Ge).probe(Q)})}if(N.pathname==="/api/health/checks/run"&&I.method==="POST"){let B=await oe(I),Q=Ge.getHealthCheck(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Health check was not found."},404);let fe=await new Oe(Ge).runAndEvaluate(Q),ue=[];for(let He of fe.evaluations.filter((be)=>be.notify&&be.alert)){let be=oi.enqueue(a.organization.id,He.alert,He.transition);ue.push(...await oi.deliverAll(be))}return S({ok:!0,...fe,deliveries:ue})}if(N.pathname==="/api/alerts/rules"&&I.method==="GET")return S({ok:!0,rules:Ge.listRules(a.project.id,d?.id).filter((B)=>_(B.resourceId))});if(N.pathname==="/api/alerts/rules"&&I.method==="POST"){let B=await oe(I),Q=B.healthCheckId?Ge.getHealthCheck(String(B.healthCheckId)):void 0;if(B.healthCheckId&&(!Q||!_(Q.resourceId)))return S({ok:!1,error:"Health check was not found."},404);return S({ok:!0,rule:Ge.createRule({projectId:a.project.id,environmentId:d?.id,resourceId:L(B.resourceId??B.resource)??Q?.resourceId,healthCheckId:Q?.id,name:String(B.name??""),signal:String(B.signal??(Q?"health":"")),operator:String(B.operator??(Q?"unhealthy":"gt")),threshold:B.threshold==null?void 0:Number(B.threshold),recoveryThreshold:B.recoveryThreshold==null?void 0:Number(B.recoveryThreshold),windowMs:Number(B.windowMs)||300000,consecutive:Number(B.consecutive)||Q?.failureThreshold||3,recoveryConsecutive:Number(B.recoveryConsecutive)||Q?.recoveryThreshold||2,noDataPolicy:["ignore","pending","firing"].includes(String(B.noDataPolicy))?B.noDataPolicy:"pending",severity:["info","warning","critical"].includes(String(B.severity))?B.severity:"warning",groupBy:Array.isArray(B.groupBy)?B.groupBy.map(String):[],labels:B.labels&&typeof B.labels==="object"?B.labels:{},enabled:B.enabled!==!1})},201)}if(N.pathname==="/api/alerts/rules"&&I.method==="PATCH"){let B=await oe(I),Q=Ge.getRule(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Alert rule was not found."},404);return S({ok:!0,rule:Ge.setRuleEnabled(Q.id,B.enabled!==!1)})}if(N.pathname==="/api/alerts/evaluate"&&I.method==="POST")return S({ok:!0,...await pp(d?.id)});if(N.pathname==="/api/alerts"&&I.method==="GET")return S({ok:!0,alerts:Ge.listAlerts(a.project.id,{environmentId:d?.id,states:N.searchParams.getAll("state").length?N.searchParams.getAll("state"):void 0,limit:Number(N.searchParams.get("limit"))||200}).filter((B)=>_(B.resourceId)).map((B)=>({...B,deliveries:Ge.listDeliveries({alertId:B.id,limit:50})}))});if(N.pathname==="/api/alerts/action"&&I.method==="POST"){let B=await oe(I),Q=Ge.getAlert(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Alert was not found."},404);let fe=String(B.action??"");if(fe==="acknowledge")return S({ok:!0,alert:Ge.acknowledge(Q.id,K?.id??"")});if(fe==="assign")return S({ok:!0,alert:Ge.assign(Q.id,B.ownerActorId==="me"?K?.id:B.ownerActorId?String(B.ownerActorId):void 0,K?.id)});if(fe==="silence"){if(de.role!=="admin")return S({ok:!1,error:"Silencing production alerts requires an administrator."},403);let ue=Bt.resolveSession(I);if(Re&&(!ue||!ve.isRecentlyAuthenticated(ue)))return S({ok:!1,error:"Recent authentication is required to silence alerts.",stepUpRequired:!0},401);return S({ok:!0,alert:Ge.silenceAlert(Q.id,String(B.until??""),K?.id)})}return S({ok:!1,error:"Action must be acknowledge, assign, or silence."},422)}if(N.pathname==="/api/alerts/silences"&&I.method==="POST"){let B=await oe(I);return S({ok:!0,id:Ge.createSilence({projectId:a.project.id,environmentId:d?.id,resourceId:L(B.resourceId??B.resource),matcher:B.matcher,reason:String(B.reason??""),startsAt:String(B.startsAt??new Date().toISOString()),endsAt:String(B.endsAt??""),timezone:String(B.timezone??"UTC"),actorId:K?.id})},201)}if(N.pathname==="/api/notifications/channels"&&I.method==="GET")return S({ok:!0,channels:Ge.listChannels(a.organization.id)});if(N.pathname==="/api/notifications/channels"&&I.method==="POST"){let B=await oe(I),Q=String(B.kind??""),fe=Q==="email"?{to:B.config?.to,from:B.config?.from}:Q==="telegram"?{chatId:String(B.config?.chatId??"")}:{};return S({ok:!0,channel:Ge.createChannel({organizationId:a.organization.id,name:String(B.name??""),kind:Q,config:fe,credential:B.credential?String(B.credential):void 0,actorId:K?.id})},201)}if(N.pathname==="/api/notifications/channels"&&I.method==="PATCH"){let B=await oe(I),Q=String(B.id??"");if(B.credential)return S({ok:!0,channel:Ge.rotateChannel(Q,String(B.credential))});let fe=String(B.status??"paused");if(!["active","paused","disabled"].includes(fe))return S({ok:!1,error:"Channel status must be active, paused, or disabled."},422);return S({ok:!0,channel:Ge.setChannelStatus(Q,fe)})}if(N.pathname==="/api/notifications/channels/test"&&I.method==="POST"){let B=await oe(I);return S({ok:!0,productionIncidentCreated:!1,result:await oi.testChannel(String(B.id??""))})}if(N.pathname==="/api/notifications/routes"&&I.method==="GET")return S({ok:!0,routes:Ge.listRoutes(a.organization.id)});if(N.pathname==="/api/notifications/routes"&&I.method==="POST"){let B=await oe(I),Q=Array.isArray(B.channelIds)?B.channelIds.map(String):[];if(Q.some((fe)=>Ge.getChannel(fe)?.organizationId!==a.organization.id))return S({ok:!1,error:"Route contains an unavailable channel."},422);return S({ok:!0,route:Ge.createRoute({organizationId:a.organization.id,name:String(B.name??""),priority:Number(B.priority)||0,matcher:B.matcher&&typeof B.matcher==="object"?B.matcher:{},channelIds:Q,quietHours:B.quietHours,groupWaitSeconds:Number(B.groupWaitSeconds)||30,reminderSeconds:B.reminderSeconds==null?void 0:Number(B.reminderSeconds),escalation:Array.isArray(B.escalation)?B.escalation:[],template:B.template?String(B.template):void 0,rateLimitPerMinute:Number(B.rateLimitPerMinute)||60,enabled:B.enabled!==!1})},201)}if(N.pathname==="/api/notifications/routes"&&I.method==="PATCH"){let B=await oe(I),Q=Ge.getRoute(String(B.id??""));if(!Q||Q.organizationId!==a.organization.id)return S({ok:!1,error:"Notification route was not found."},404);return S({ok:!0,route:Ge.setRouteEnabled(Q.id,B.enabled!==!1)})}if(N.pathname==="/api/notifications/routes/preview"&&I.method==="POST"){let B=await oe(I),fe=(B.alertId?Ge.getAlert(String(B.alertId)):void 0)??{id:"preview",ruleId:"preview",projectId:a.project.id,environmentId:d?.id,resourceId:L(B.resourceId??B.resource),dedupKey:"preview",groupKey:String(B.groupKey??"default"),state:"firing",severity:["info","warning","critical"].includes(String(B.severity))?B.severity:"warning",title:String(B.title??"Rule preview"),evidence:{},failureCount:1,recoveryCount:0,occurrenceCount:1,firstSeenAt:new Date().toISOString(),lastSeenAt:new Date().toISOString(),firingAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return S({ok:!0,productionIncidentCreated:!1,matches:oi.preview(a.organization.id,fe,String(B.eventType??"firing")).map((ue)=>({route:ue.route,channels:ue.channels,quiet:ue.quiet}))})}if(N.pathname==="/api/notifications/deliveries"&&I.method==="GET")return S({ok:!0,deliveries:Ge.listDeliveries({alertId:N.searchParams.get("alertId")??void 0,states:N.searchParams.getAll("state"),limit:Number(N.searchParams.get("limit"))||200})});if(N.pathname==="/api/notifications/deliveries/retry"&&I.method==="POST"){let B=await oe(I),Q=Ge.getDelivery(String(B.id??""));if(!Q)return S({ok:!1,error:"Delivery was not found."},404);return Ge.updateDelivery(Q.id,{state:"retrying",attempt:Math.max(0,Q.attempt-1),nextAttemptAt:new Date().toISOString()}),S({ok:!0,delivery:await oi.deliver(Q.id)})}}if(N.pathname.startsWith("/api/jobs")||N.pathname.startsWith("/api/workers")){let d=a.environments.get(ye),g=a.store.listResources(a.project.id,d?.id),_=de.role==="admin"||!!d&&pa(de,d.id,"automation:read")?g:g.filter((Se)=>Ar(de,Se.id,"automation:read")),L=(Se)=>!Se||_.some((Te)=>Te.id===Se),K=Me(de).actor,B=q.get(ye)??O,Q=Dr(o,B),fe=Q.filter((Se)=>!Se.danger&&["scheduler","backup","worker"].includes(Se.group)),ue=V(o),He=()=>{let Se=Bt.resolveSession(I);return!Re||!!Se&&ve.isRecentlyAuthenticated(Se)},be=(Se)=>{if(!Se||typeof Se!=="object"||Array.isArray(Se))return{};let Te=Object.entries(Se).slice(0,50);if(Te.some(([,Xe])=>typeof Xe!=="string"||!/^(?:secret|ssm|arn|env):\/\//.test(Xe)))throw Error("Job payload values must be secret or environment references, never inline values.");return Object.fromEntries(Te)},Le=(Se,Te,Xe)=>a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,resourceId:Xe,actorId:K?.id,type:`job.${Se}`,payload:Te});if(N.pathname==="/api/jobs/preview"&&I.method==="POST"){let Se=await oe(I);try{return S({ok:!0,productionExecutionCreated:!1,preview:ot(String(Se.expression??""),String(Se.timezone??"UTC"),new Date(Se.from?String(Se.from):Date.now()),Number(Se.count)||5)})}catch(Te){return S({ok:!1,error:Te instanceof Error?Te.message:"Schedule preview could not be generated.",productionExecutionCreated:!1},422)}}if(N.pathname==="/api/jobs"&&I.method==="GET")return S({ok:!0,jobs:Er.list(a.project.id,{environmentId:d?.id}).filter((Se)=>L(Se.resourceId)).map((Se)=>({...Se,preview:ot(Se.normalizedExpression,Se.timezone,new Date,5),capability:On(Se),lastExecution:Er.listExecutions(Se.id,1)[0]}))});if(N.pathname==="/api/jobs"&&I.method==="POST"){let Se=await oe(I),Te=String(Se.provider??(ue==="serverless"?"eventbridge":"server")),Xe=ue==="serverless"?"eventbridge":"server";if(Te!==Xe)return S({ok:!1,error:`${ue} environments accept ${Xe} schedules through this adapter.`},422);let ut=Se.operationId?String(Se.operationId):void 0;if(Te==="server"&&(!ut||!fe.some((dr)=>dr.id===ut)))return S({ok:!1,error:"Server jobs require an allowlisted operation target."},422);let yt=On({provider:Te,expression:String(Se.expression??""),flexibleMinutes:Number(Se.flexibleMinutes)||0,missedRunPolicy:Se.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String(Se.overlapPolicy))?Se.overlapPolicy:"forbid"});if(!yt.supported)return S({ok:!1,error:yt.notes.join(" ")},422);let Yn=Se.resourceId?g.find((dr)=>dr.id===Se.resourceId||dr.slug===Se.resourceId):void 0;if(Se.resourceId&&(!Yn||!L(Yn.id)))return S({ok:!1,error:"Job resource was not found."},404);try{let dr=Te==="server"?{kind:"dashboard_operation",operationId:ut}:{kind:"serverless_scheduler",action:"run"},bo=Er.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:Yn?.id,name:String(Se.name??""),provider:Te,expression:String(Se.expression??""),timezone:String(Se.timezone??"UTC"),startsAt:Se.startsAt?String(Se.startsAt):void 0,endsAt:Se.endsAt?String(Se.endsAt):void 0,flexibleMinutes:Number(Se.flexibleMinutes)||0,target:dr,payloadRefs:be(Se.payloadRefs),missedRunPolicy:Se.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String(Se.overlapPolicy))?Se.overlapPolicy:"forbid",retryPolicy:{maxAttempts:Number(Se.maxAttempts)||3,backoffSeconds:Number(Se.backoffSeconds)||30,deadLetterRef:Se.deadLetterRef?String(Se.deadLetterRef):void 0},timeoutSeconds:Number(Se.timeoutSeconds)||900,enabled:Se.enabled!==!1,origin:"managed",ownerActorId:K?.id,observedState:{},reconciliationStatus:"pending"});return Le("created",{jobId:bo.id,provider:bo.provider,expression:bo.normalizedExpression},bo.resourceId),S({ok:!0,job:bo,capability:yt},201)}catch(dr){return S({ok:!1,error:dr instanceof Error?dr.message:"Scheduled job could not be created."},422)}}if(N.pathname==="/api/jobs"&&I.method==="PATCH"){let Se=await oe(I),Te=Er.get(String(Se.id??""));if(!Te||!L(Te.resourceId))return S({ok:!1,error:"Scheduled job was not found."},404);if(Te.origin==="config")return S({ok:!1,error:"Config-defined schedules must be edited in cloud.config.ts and reconciled."},409);let Xe=Se.missedRunPolicy==null?void 0:String(Se.missedRunPolicy),ut=Se.overlapPolicy==null?void 0:String(Se.overlapPolicy);if(Xe&&!["skip","catch_up"].includes(Xe))return S({ok:!1,error:"Missed-run policy must be skip or catch_up."},422);if(ut&&!["allow","forbid","replace"].includes(ut))return S({ok:!1,error:"Overlap policy must be allow, forbid, or replace."},422);try{let yt=Er.updateSchedule(Te.id,{expression:Se.expression?String(Se.expression):void 0,timezone:Se.timezone?String(Se.timezone):void 0,missedRunPolicy:Xe,overlapPolicy:ut,timeoutSeconds:Se.timeoutSeconds==null?void 0:Number(Se.timeoutSeconds)});return Le("updated",{jobId:yt.id,expression:yt.normalizedExpression,version:yt.version},yt.resourceId),S({ok:!0,job:yt})}catch(yt){return S({ok:!1,error:yt instanceof Error?yt.message:"Scheduled job could not be updated."},422)}}if(N.pathname==="/api/jobs/action"&&I.method==="POST"){let Se=await oe(I),Te=Er.get(String(Se.id??""));if(!Te||!L(Te.resourceId))return S({ok:!1,error:"Scheduled job was not found."},404);let Xe=String(Se.action??"");if(Xe==="run"){let ut=lp.enqueue(Te,{trigger:"manual",actorId:K?.id});return Le("run_queued",{jobId:Te.id,executionId:ut.id},Te.resourceId),S({ok:!0,execution:ut},202)}if(["disable","delete"].includes(Xe)&&d?.kind==="production"){if(String(Se.confirm??"")!==Xe)return S({ok:!1,error:`Type "${Xe}" to confirm this production change.`},409);if(!He())return S({ok:!1,error:"Recent authentication is required for this production change.",stepUpRequired:!0},401)}if(Xe==="enable"||Xe==="disable"){let ut=Er.setEnabled(Te.id,Xe==="enable");return Le(Xe==="enable"?"enabled":"disabled",{jobId:Te.id},Te.resourceId),S({ok:!0,job:ut})}if(Xe==="delete")try{return Er.remove(Te.id),Le("deleted",{jobId:Te.id,name:Te.name},Te.resourceId),S({ok:!0,deleted:Te.id})}catch(ut){return S({ok:!1,error:ut instanceof Error?ut.message:"Scheduled job could not be deleted."},409)}return S({ok:!1,error:"Action must be run, enable, disable, or delete."},422)}if(N.pathname==="/api/jobs/history"&&I.method==="GET"){let Se=Er.get(String(N.searchParams.get("jobId")??""));if(!Se||!L(Se.resourceId))return S({ok:!1,error:"Scheduled job was not found."},404);return S({ok:!0,executions:Er.listExecutions(Se.id,Number(N.searchParams.get("limit"))||100).map((Te)=>({...Te,logs:Te.operationId?kt.logs(Te.operationId,{limit:500}):[]}))})}if(N.pathname==="/api/jobs/reconcile"&&I.method==="POST"){if(!d)return S({ok:!1,error:"Environment was not found."},404);let Se=$r(Er,o,{organization:a.organization,project:a.project,environment:d,resources:g});return Le("reconciled",Se),S({ok:!0,reconciliation:Se})}if(N.pathname==="/api/workers"&&I.method==="GET"){let Se=Array.isArray(B.workersDetail??B.workers)?B.workersDetail??B.workers:[];return S({ok:!0,workers:Er.listWorkers(a.project.id,d?.id).filter((Te)=>L(Te.resourceId)).map((Te)=>{let Xe=Se.find((ut)=>ut.name===Te.name||ut.site===Te.target.site);return Xe?{...Te,observedState:{...Te.observedState,status:Xe.status??"configured",currentJob:Xe.currentJob??null,failures:Number(Xe.failed??Xe.failures)||0,processed:Number(Xe.processed)||0}}:Te})})}if(N.pathname==="/api/workers/action"&&I.method==="POST"){let Se=await oe(I),Te=Er.getWorker(String(Se.id??""));if(!Te||!L(Te.resourceId))return S({ok:!1,error:"Worker was not found."},404);let Xe=String(Se.action??"");if(Xe==="restart"){if(String(Se.confirm??"")!==Te.name)return S({ok:!1,error:`Type "${Te.name}" to restart this worker.`},409);let ut=Q.find((dr)=>dr.id===Te.target.operationId);if(!ut)return S({ok:!1,error:"The allowlisted worker restart operation is unavailable."},409);let yt=await kr(o,ye,ut),Yn=Er.reconcileWorker(Te.id,yt.ok?"in_sync":"unavailable",{...Te.observedState,lastRestartAt:new Date().toISOString(),command:yt.command??null,error:yt.error??yt.stderr??null});return Le("worker_restarted",{workerId:Te.id,ok:yt.ok},Te.resourceId),S({...yt,worker:Yn},yt.ok?200:409)}if(Xe==="scale")return S({ok:!1,error:Te.provider==="systemd"?"Systemd worker scale is config-managed; edit the worker definition and reconcile.":"This provider does not expose safe worker scaling through the current adapter."},422);return S({ok:!1,error:"Action must be restart or scale."},422)}}if(N.pathname.startsWith("/api/telemetry/")){let d=a.environments.get(ye),g=new Ve(a.store),T=a.store.listResources(a.project.id,d?.id),_=["/api/telemetry/query","/api/telemetry/tail","/api/telemetry/export","/api/telemetry/saved-queries","/api/telemetry/refresh"].includes(N.pathname)?"runtime:logs":"runtime:read",L=de.role==="admin"||!!d&&pa(de,d.id,_),K=L?T:T.filter((be)=>Ar(de,be.id,_)),B=(be)=>Jy(K,L,be),Q=(be)=>{let Le=new Date,Se={"1h":3600000,"6h":21600000,"24h":86400000,"7d":604800000,"30d":2592000000},Te=String(be.to??Le.toISOString()),Xe=String(be.from??new Date(new Date(Te).getTime()-(Se[String(be.range??"1h")]??Se["1h"])).toISOString()),ut=(Yn)=>{let dr=(Array.isArray(Yn)?Yn:String(Yn??"").split(",")).map(String).filter(Boolean);return dr.length?dr:void 0},yt=ut(be.kinds)?.filter((Yn)=>["metric","log","trace","request","event"].includes(Yn));return{projectId:a.project.id,environmentId:d?.id,resourceIds:B(be.resources),kinds:yt,names:ut(be.names),sources:ut(be.sources),levels:ut(be.levels),from:Xe,to:Te,text:String(be.text??"")||void 0,traceId:String(be.traceId??"")||void 0,requestId:String(be.requestId??"")||void 0,deploymentId:String(be.deploymentId??"")||void 0,releaseId:String(be.releaseId??"")||void 0,workloadId:String(be.workloadId??"")||void 0,cursor:String(be.cursor??"")||void 0,limit:Number(be.limit)||void 0}},fe=Object.fromEntries(N.searchParams.entries()),ue=(be=!1)=>Bn({controlPlane:a.store,projectId:a.project.id,environmentId:d?.id,config:o,environment:ye,force:be,lightweight:!be}),He=()=>{let be=a.store.getSetting(`telemetry.collection:${a.project.id}:${d?.id??"all"}`)??{};return{generatedAt:String(be.generatedAt??new Date().toISOString()),cached:!0,statuses:Array.isArray(be.statuses)?be.statuses:[],errors:Array.isArray(be.errors)?be.errors:[],policy:be.policy??je(a.store,a.project.id)}};if(N.pathname==="/api/telemetry/status"&&I.method==="GET"){ue(!1);let be=He(),Le=L?be.statuses:g.status(a.project.id,d?.id,be.policy.rawDays,be.policy.samplingRate,K.map((Te)=>Te.id)),Se=Le.reduce((Te,Xe)=>Te+Xe.estimatedDailyBytes*30,0);return S({ok:!0,generatedAt:be.generatedAt,cached:be.cached,sources:Le,errors:L?be.errors:[],policy:be.policy,retention:{rawDays:be.policy.rawDays,downsampleAfterDays:be.policy.downsampleAfterDays,downsampleBucketMs:be.policy.downsampleBucketMs,maxRecords:be.policy.maxRecords},estimatedMonthlyBytes:Se,estimatedMonthlyCostUsd:Hn(Se,be.policy),costEstimateConfigured:be.policy.estimatedStorageUsdPerGbMonth>0})}if(N.pathname==="/api/telemetry/settings"&&I.method==="GET")return S({ok:!0,policy:je(a.store,a.project.id)});if(N.pathname==="/api/telemetry/settings"&&I.method==="PATCH"){let be=qn(a.store,a.project.id,await oe(I));return Xy(a.project.id),S({ok:!0,policy:be})}if(N.pathname==="/api/telemetry/query"&&I.method==="GET"){ue(!1);let be=He();return S({ok:!0,collection:{generatedAt:be.generatedAt,cached:be.cached},...g.query(Q(fe))})}if(N.pathname==="/api/telemetry/tail"&&I.method==="GET"){ue(!1);let be=new TextEncoder,Le=new Date,Se=Q({...fe,kinds:fe.kinds||"log,request,event,trace",from:fe.from||new Date(Le.getTime()-120000).toISOString(),to:Le.toISOString(),limit:Math.min(1000,Number(fe.limit)||200),cursor:void 0}),Te=I.headers.get("last-event-id")||String(fe.cursor??"")||void 0,Xe,ut=!1,yt=!1,Yn=new ReadableStream({start(dr){let bo=()=>{if(ut)return;if(ut=!0,Xe)clearInterval(Xe);I.signal.removeEventListener("abort",bo);try{dr.close()}catch{}},Ep=async()=>{if(ut||yt)return;yt=!0;try{let zo=g.tail({...Se,to:new Date(Date.now()+1000).toISOString()},Te);for(let Tp of zo.records)Te=Ii(Tp)??Te,dr.enqueue(be.encode(`id: ${Te??""}
497
+ This replacement link expires ${T.invitation.expiresAt} and can be used once.`});return S({invitation:T.invitation,token:T.token,acceptUrl:_,delivered:M})}catch(T){return S({ok:!1,error:T instanceof Error?T.message:"Invitation could not be resent."},409)}}if(N.pathname==="/api/organization/memberships"&&I.method==="PATCH"){let d=await oe(I),g=a.store.getMembership(String(d.id??"")),T=wd(d.roleTemplate),_=Ua(d);if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Membership was not found."},404);if(!T||!_)return S({ok:!1,error:"Choose a valid role template and resource scope."},422);let M=Me(de);if((g.roleTemplate==="owner"||T==="owner")&&(!Ti(String(d.password??""),de.passwordHash)||M.membership?.roleTemplate!=="owner"))return S({ok:!1,error:"Ownership changes require an owner to re-enter their password."},401);let B=a.store.resolveAuthorizationTarget(a.organization.id,_)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),Q=a.store.listGrants(g.id),fe=en({membership:g,grants:Q,target:B}),ue={...g,roleTemplate:T,scope:_},He=en({membership:ue,grants:Q,target:B}),be={gained:He.filter((Le)=>!fe.includes(Le)),lost:fe.filter((Le)=>!He.includes(Le))};if(d.preview===!0)return S({membership:g,proposed:{roleTemplate:T,scope:_},accessDiff:be});if(String(d.confirm??"")!==g.id)return S({ok:!1,error:`Confirm this change with membership ID ${g.id}.`,accessDiff:be},409);try{return S({membership:a.store.updateMembership({id:g.id,roleTemplate:T,scope:_,actorId:M.actor?.id}),accessDiff:be})}catch(Le){return S({ok:!1,error:Le instanceof Error?Le.message:"Membership could not be updated."},409)}}if(N.pathname==="/api/organization/memberships"&&I.method==="DELETE"){let d=await oe(I),g=a.store.getMembership(String(d.id??""));if(!g||g.organizationId!==a.organization.id)return S({ok:!1,error:"Membership was not found."},404);if(String(d.confirm??"")!==g.id)return S({ok:!1,error:`Confirm removal with membership ID ${g.id}.`},409);let T=Me(de);if(g.roleTemplate==="owner"&&(T.membership?.roleTemplate!=="owner"||!Ti(String(d.password??""),de.passwordHash)))return S({ok:!1,error:"Removing an owner requires an owner to re-enter their current password."},401);try{return S({membership:a.store.revokeMembership(g.id,T.actor?.id)})}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:"Membership could not be removed."},409)}}if(N.pathname==="/api/organization/grants"&&I.method==="POST"){let d=await oe(I),g=String(d.capability??""),T=d.effect==="deny"?"deny":d.effect==="allow"?"allow":void 0,_=Ua(d),M=Me(de);if(!T||!_||!ie.includes(g))return S({ok:!1,error:"Choose a valid capability, effect, and resource scope."},422);try{return S({grant:a.store.upsertGrant({organizationId:a.organization.id,membershipId:String(d.membershipId??""),effect:T,capability:g,scope:_,actorId:M.actor?.id})},201)}catch(K){return S({ok:!1,error:K instanceof Error?K.message:"Grant could not be created."},422)}}if(N.pathname==="/api/organization/grants"&&I.method==="DELETE"){let d=await oe(I),g=Me(de),T=a.store.getGrant(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return S({ok:!1,error:"Grant was not found."},404);return S({ok:a.store.removeGrant(T.id,g.actor?.id)})}if(N.pathname==="/api/tags"&&I.method==="GET")return S({tags:a.store.listTags(a.project.id),assignments:a.store.listResourceTags(a.project.id)});if(N.pathname==="/api/tags"&&I.method==="POST"){let d=await oe(I),g=a.store.upsertTag(a.project.id,String(d.name??""),String(d.color??"#5a8be0"));if(d.resourceId)a.store.assignTag(String(d.resourceId),g.id);return S({tag:g},201)}if(N.pathname==="/api/tags"&&I.method==="DELETE"){let d=await oe(I);return a.store.removeTag(String(d.resourceId??""),String(d.tagId??"")),S({ok:!0})}if(N.pathname==="/"&&!ab(N.pathname,si))return new Response(null,{status:302,headers:{location:`/server/sites?env=${encodeURIComponent(ye)}`}});if(N.pathname==="/"&&Mt?.mode==="serverless")return new Response(null,{status:302,headers:{location:`/serverless?env=${encodeURIComponent(ye)}`}});let Ka=uy(N.pathname);if(Ka)return new Response(null,{status:308,headers:{location:`${Ka}?env=${encodeURIComponent(ye)}`}});if(N.pathname==="/api/env"&&I.method==="POST"){let d=await oe(I),g=String(d.env??"");if(!m.includes(g))return S({ok:!1,error:`Unknown environment '${g}'.`,environments:m},404);return S({ok:!0,environment:g,environments:m,href:`?env=${encodeURIComponent(g)}`})}if(N.pathname==="/api/config"){let d={...oA(o),environment:ye,environments:m};return S(py(d,si))}if(N.pathname==="/api/ssh-keys"&&I.method==="GET")return S({configPath:D,keys:Ot(ca(o))});if(N.pathname==="/api/ssh-keys"&&I.method==="POST"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=await Fi(D,"utf8"),T=ca(o),_=_a({configText:g,name:String(d.name??""),publicKey:String(d.publicKey??""),existingKeys:T});return await ys(D,_),nb(o,[...T,{name:String(d.name??"").trim(),publicKey:String(d.publicKey??"").trim().replace(/\s+/g," ")}]),S({ok:!0,configPath:D,keys:Ot(ca(o))})}if(N.pathname==="/api/ssh-keys"&&I.method==="DELETE"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??N.searchParams.get("name")??""),T=await Fi(D,"utf8"),_=ca(o),M=$a({configText:T,name:g,existingKeys:_});return await ys(D,M),nb(o,_.filter((K)=>K.name!==g.trim())),S({ok:!0,configPath:D,keys:Ot(ca(o))})}if(N.pathname==="/api/firewall"&&I.method==="GET")return S({configPath:D,alwaysOpen:[22,80,443],ports:rp(o)});if(N.pathname==="/api/firewall"&&I.method==="POST"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=Number(d.port);if(!ja(g))return S({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=rp(o),_=await Fi(D,"utf8");try{await ys(D,Sy(_,g,T))}catch(B){return S({ok:!1,error:B?.message??String(B)},422)}let M=hs([...T,g]);ib(o,M);let K=d.apply===!1?null:await Qt(o,ye,`ufw allow ${g}/tcp`).catch((B)=>({ok:!1,error:String(B?.message??B)}));return S({ok:!0,configPath:D,ports:M,apply:K})}if(N.pathname==="/api/firewall"&&I.method==="DELETE"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=Number(d.port??N.searchParams.get("port"));if(!ja(g))return S({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=rp(o),_=await Fi(D,"utf8");await ys(D,vy(_,g,T));let M=hs(T.filter((B)=>B!==g));ib(o,M);let K=d.apply===!1?null:await Qt(o,ye,`ufw delete allow ${g}/tcp`).catch((B)=>({ok:!1,error:String(B?.message??B)}));return S({ok:!0,configPath:D,ports:M,apply:K})}if(N.pathname==="/api/sites"&&I.method==="POST"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??"").trim(),T=String(d.root??"").trim();if(!g||!T)return S({ok:!1,error:"Site name and root are required."},422);let _={deploy:d.deploy==="bucket"?"bucket":"server",root:T,path:String(d.path??"").trim()||void 0,domain:String(d.domain??"").trim()||void 0,build:String(d.build??"").trim()||void 0,start:String(d.start??"").trim()||void 0,port:d.port?Number(d.port):void 0,type:String(d.type??"").trim()||void 0};if(_.port!==void 0&&(!Number.isInteger(_.port)||_.port<1||_.port>65535))return S({ok:!1,error:"Port must be a number between 1 and 65535."},422);let M=await Fi(D,"utf8"),K=un({configText:M,name:g,root:_.root,domain:_.domain,path:_.path,deploy:_.deploy,build:_.build,start:_.start,port:_.port,type:_.type});return await ys(D,K),YT(o,g,Object.fromEntries(Object.entries(_).filter(([,B])=>B!==void 0))),Mt=await bs(o,ye),q.set(ye,Mt),S({ok:!0,configPath:D,site:g,data:Mt})}if(N.pathname==="/api/sites"&&I.method==="DELETE"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??N.searchParams.get("name")??"").trim();if(!g||!o.sites?.[g])return S({ok:!1,error:`Site '${g}' was not found.`},404);let T=await Fi(D,"utf8");return await ys(D,My({configText:T,name:g})),delete o.sites[g],Mt=await bs(o,ye),q.set(ye,Mt),S({ok:!0,configPath:D,site:g,data:Mt})}if(N.pathname==="/api/sites"&&I.method==="PATCH"){if(!D)return S({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await oe(I),g=String(d.name??"").trim(),T=o.sites?.[g];if(!g||!T)return S({ok:!1,error:`Site '${g}' was not found.`},404);if(si.role==="member"){let K=fy(d);if(!K.ok)return S({ok:!1,error:K.error},403);let B=hy({siteName:g,body:d,sites:o.sites??{},ownSites:Object.keys(si.sites)});if(!B.ok)return S({ok:!1,error:B.error},409)}if(d.port!==void 0&&d.port!==null&&d.port!==""&&(!Number.isInteger(Number(d.port))||Number(d.port)<1||Number(d.port)>65535))return S({ok:!1,error:"Port must be a number between 1 and 65535."},422);if(typeof d.domain==="string"&&d.domain.trim()&&!Zl(d.domain.trim()))return S({ok:!1,error:`Domain '${d.domain.trim()}' is not a valid hostname.`},422);let _=await Fi(D,"utf8"),M=(K,B)=>{_=Ly({configText:_,siteName:g,key:K,valueText:B})};if(d.ssl!==void 0)M("ssl",By(d.ssl)),T.ssl=d.ssl;if(d.env!==void 0&&d.env&&typeof d.env==="object")M("env",Fy(d.env)),T.env=d.env;if(d.aliases!==void 0&&Array.isArray(d.aliases)){let K=d.aliases.map((B)=>String(B));M("aliases",Uy(K)),T.aliases=K.map((B)=>B.trim().toLowerCase()).filter(Boolean)}if(d.redirects!==void 0&&d.redirects&&typeof d.redirects==="object")M("redirects",zy(d.redirects)),T.redirects=d.redirects;for(let K of["domain","path","build","start","type","root","php"])if(typeof d[K]==="string"&&d[K].trim())M(K,jy(String(d[K]).trim())),T[K]=String(d[K]).trim();if(d.port!==void 0&&d.port!==null&&d.port!=="")M("port",String(Number(d.port))),T.port=Number(d.port);return await ys(D,_),Mt=await bs(o,ye),q.set(ye,Mt),S({ok:!0,configPath:D,site:g,data:Mt})}if(N.pathname==="/api/sites/deploy"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim();if(!g||!o.sites?.[g])return S({ok:!1,error:`Site '${g}' was not found.`},404);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to deploy this site.`},409);let T=ae(a,String(ye));await new ps(et).run(new Oa,{...T,artifactRoot:t}),od(et,T,Mt??{});let _=Zt(et,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(_.decision.outcome==="block")return S({ok:!1,error:`Deployment blocked by security policy: ${_.decision.explanation}`,securityReview:_},409);let M={id:`deploy:${g}`,label:`Deploy ${g}`,description:`Deploy the ${g} site for ${ye}.`,command:["deploy","--env",ye,"--site",g,"--yes"],mutates:!0},K=await ao({controlPlane:a,environment:ye,actor:de,kind:"dashboard.site.deploy",resourceSlug:g,input:{site:g},execute:()=>np(M,{cwd:t,cliEntry:i})});return S({...K.result,controlPlaneOperation:K.operation,securityReview:_})}if(N.pathname==="/api/actions")return S(gb(ye));if(N.pathname==="/api/server/operations")return S(Dr(o,Mt));if(N.pathname==="/api/runtime/workloads"&&I.method==="GET"){let d=await Si(o,ye);return S(d)}if(N.pathname==="/api/runtime/logs"&&I.method==="GET"){let d=String(N.searchParams.get("workload")??"");if(!d)return S({ok:!1,error:"A workload query parameter is required."},422);let g=Math.min(1000,Math.max(1,Number(N.searchParams.get("limit"))||200));try{return S(await new ge(o,ye).logs(d,{limit:g}))}catch(T){return S({ok:!1,error:String(T?.message??T)},404)}}if(N.pathname==="/api/runtime/log-sessions"&&I.method==="POST"){let d=await oe(I),g=String(d.workloadId??"");if(!g)return S({ok:!1,error:"A workloadId is required."},422);let T=await Si(o,ye),_=T.workloads.find((B)=>B.id===g);if(!_)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);if(!_.capabilities.logs.supported)return S({ok:!1,error:_.capabilities.logs.reason??"Logs are unsupported for this workload."},409);let M=new ge(o,ye,{inventory:async()=>T}),K=ar.create("logs",g);return(async()=>{let B=new Date(Date.now()-Math.min(3600000,Math.max(1000,Number(d.sinceMs)||60000)));try{for(let Q=0;Q<200&&!ar.signal(K.id)?.aborted;Q++){let fe=await M.logs(g,{limit:Math.min(500,Math.max(1,Number(d.limit)||200)),since:B});for(let ue of fe.lines)if(ar.append(K.id,`${ue.timestamp?`${ue.timestamp} `:""}${ue.message}
498
+ `),ue.timestamp)B=new Date(Math.max(B.getTime(),new Date(ue.timestamp).getTime()+1));await Bun.sleep(3000)}if(!ar.signal(K.id)?.aborted)ar.close(K.id,"complete")}catch(Q){ar.append(K.id,Q instanceof Error?Q.message:String(Q),"stderr"),ar.close(K.id,"failed",Q instanceof Error?Q.message:String(Q))}})(),S({ok:!0,session:K,streamUrl:`/api/runtime/log-stream?id=${encodeURIComponent(K.id)}&workload=${encodeURIComponent(g)}`},201)}if((N.pathname==="/api/runtime/log-stream"||N.pathname==="/api/runtime/exec-stream")&&I.method==="GET"){let d=String(N.searchParams.get("id")??""),g=String(N.searchParams.get("workload")??""),T=Number(I.headers.get("last-event-id")??N.searchParams.get("after")??0)||0,_=ar.read(d,g,T),M=N.pathname.includes("exec")?"exec":"logs";if(!_||_.kind!==M)return S({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return zT(ar,_,T,I.signal)}if((N.pathname==="/api/runtime/log-sessions"||N.pathname==="/api/runtime/exec-sessions")&&I.method==="DELETE"){let d=await oe(I),g=ar.cancel(String(d.id??""),String(d.workloadId??""));if(!g)return S({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return S({ok:!0,session:g})}if(N.pathname==="/api/runtime/exec-sessions"&&I.method==="POST"){let d=await oe(I),g=String(d.workloadId??""),T=await Si(o,ye),_=T.workloads.find((Q)=>Q.id===g);if(!_)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);let M=Bt.resolveSession(I),K=new ge(o,ye,{inventory:async()=>T}),B=ar.create("exec",g);return ao({controlPlane:a,environment:ye,actor:de,kind:"runtime.exec",resourceSlug:_.links.service,input:{workloadId:g,provider:_.provider,preset:d.preset?String(d.preset):null,freeForm:!!String(d.command??"").trim()},execute:()=>K.exec({workloadId:g,preset:["process","sockets","filesystem"].includes(String(d.preset))?String(d.preset):void 0,command:typeof d.command==="string"?d.command:void 0,confirm:String(d.confirm??""),recentAuth:!Re||!!M&&ve.isRecentlyAuthenticated(M)})}).then(({result:Q,operation:fe})=>{if(ar.append(B.id,`operation ${fe.id}
499
+ `,"system"),Q.stdout)ar.append(B.id,Q.stdout,"stdout");if(Q.stderr)ar.append(B.id,Q.stderr,"stderr");ar.close(B.id,Q.ok?"complete":"failed",Q.error)}).catch((Q)=>{let fe=Q instanceof Error?Q.message:String(Q);ar.append(B.id,fe,"stderr"),ar.close(B.id,"failed",fe)}),S({ok:!0,session:B,streamUrl:`/api/runtime/exec-stream?id=${encodeURIComponent(B.id)}&workload=${encodeURIComponent(g)}`},202)}if(N.pathname==="/api/runtime/files/read"&&I.method==="POST"){let d=await oe(I),g=await Si(o,ye),T=Bt.resolveSession(I),_=await new ge(o,ye,{inventory:async()=>g}).readFile({workloadId:String(d.workloadId??""),path:String(d.path??""),confirm:String(d.confirm??""),recentAuth:!Re||!!T&&ve.isRecentlyAuthenticated(T)});return S(_,_.ok?200:409)}if(N.pathname==="/api/runtime/files/write"&&I.method==="POST"){let d=await oe(I),g=await Si(o,ye),T=String(d.workloadId??""),_=g.workloads.find((Q)=>Q.id===T);if(!_)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);let M=Bt.resolveSession(I),K=new ge(o,ye,{inventory:async()=>g}),B=await ao({controlPlane:a,environment:ye,actor:de,kind:"runtime.file.write",resourceSlug:_.links.service,input:{workloadId:T,provider:_.provider,path:String(d.path??""),bytes:Buffer.from(String(d.contentBase64??""),"base64").byteLength},execute:()=>K.writeFile({workloadId:T,path:String(d.path??""),contentBase64:String(d.contentBase64??""),confirm:String(d.confirm??""),recentAuth:!Re||!!M&&ve.isRecentlyAuthenticated(M)})});return S({...B.result,controlPlaneOperation:B.operation},B.result.ok?200:409)}if(N.pathname==="/api/runtime/operations"&&I.method==="POST"){let d=await oe(I),g=String(d.workloadId??""),T=String(d.action??"");if(!g||!["start","stop","restart","redeploy","scale","inspect"].includes(T))return S({ok:!1,error:"A valid workloadId and lifecycle action are required."},422);let _=await Si(o,ye),M=_.workloads.find((fe)=>fe.id===g);if(!M)return S({ok:!1,error:"Workload was not found in the current project and environment."},404);let K=Bt.resolveSession(I),B=new ge(o,ye,{inventory:async()=>_}),Q=await ao({controlPlane:a,environment:ye,actor:de,kind:`runtime.${T}`,resourceSlug:M.links.service,input:{workloadId:g,provider:M.provider,action:T,replicas:d.replicas==null?null:Number(d.replicas)},execute:()=>B.run({workloadId:g,action:T,replicas:d.replicas==null?void 0:Number(d.replicas),confirm:String(d.confirm??""),recentAuth:!Re||!!K&&ve.isRecentlyAuthenticated(K)})});return S({...Q.result,controlPlaneOperation:Q.operation},Q.result.ok?200:409)}if(N.pathname.startsWith("/api/protection")){let d=de.role==="admin"||Ga(de,"security:read"),g=de.role==="admin"||Ga(de,"security:manage");if(!d)return S({ok:!1,error:"Protection controls require security:read."},403);let{ProtectionControlStore:T,describePosture:_}=await import("./chunk-xw9vcdwt.js"),M=new T(a.store),K=()=>{if(!g)throw Error("Changing protection controls requires security:manage.")};if(N.pathname==="/api/protection"&&I.method==="GET"){let B=M.current();return S({ok:!0,posture:_(B),controls:B,raw:M.raw()})}if(N.pathname==="/api/protection/attack-mode"&&I.method==="POST"){K();let B=await oe(I);if(B.enabled===!1)return S({ok:!0,disabled:M.disableAttackMode()});return S({ok:!0,control:M.enableAttackMode({hours:B.hours==null?void 0:Number(B.hours),reason:String(B.reason??"Enabled from the dashboard."),actorId:Me(de).actor?.id})})}if(N.pathname==="/api/protection/pause"&&I.method==="POST"){K();let B=await oe(I);if(B.enabled===!1)return S({ok:!0,resumed:M.resumeMitigations()});return S({ok:!0,control:M.pauseMitigations({hours:B.hours==null?void 0:Number(B.hours),reason:String(B.reason??""),actorId:Me(de).actor?.id})})}if(N.pathname==="/api/protection/ip-rules"&&I.method==="GET")return S({ok:!0,ipRules:M.current().ipRules});if(N.pathname==="/api/protection/ip-rules"&&(I.method==="POST"||I.method==="DELETE")){K();let B=await oe(I),Q=B.list==="allow"?"allow":"block",fe=I.method==="POST"?M.addIpRule(Q,String(B.cidr??"")):M.removeIpRule(Q,String(B.cidr??""));return S({ok:!0,ipRules:fe})}return S({ok:!1,error:"Protection endpoint was not found."},404)}if(N.pathname.startsWith("/api/spend/")||N.pathname==="/api/usage"){let d=await bb(),{store:g,service:T,gate:_}=d,M=de.role==="admin"||Ga(de,"billing:read"),K=de.role==="admin"||Ga(de,"billing:manage");if(!M)return S({ok:!1,error:"Spend data requires the billing:read capability."},403);let B=a.environments.get(ye),Q={organizationId:a.organization.id,projectId:a.project.id,environmentId:B?.id},fe=()=>{if(!K)throw Error("Changing a budget requires the billing:manage capability.")};if(N.pathname==="/api/usage"&&I.method==="GET")return S({ok:!0,...T.usageReport({organizationId:Q.organizationId,projectId:Q.projectId,period:N.searchParams.get("period")??"monthly",timezone:N.searchParams.get("timezone")??void 0})});if(N.pathname==="/api/spend/budgets"&&I.method==="GET")return S({ok:!0,budgets:g.listBudgets({organizationId:Q.organizationId,projectId:Q.projectId}).map((ue)=>({...ue,status:T.status(ue)}))});if(N.pathname==="/api/spend/budgets"&&I.method==="POST"){fe();let ue=await oe(I),He=String(ue.scope??"project"),be=g.createBudget({organizationId:Q.organizationId,projectId:He==="organization"?void 0:Q.projectId,environmentId:He==="environment"?Q.environmentId:void 0,name:String(ue.name??"").trim(),period:ue.period??"monthly",timezone:ue.timezone?String(ue.timezone):void 0,softLimitCents:ue.softLimitCents==null?void 0:Math.round(Number(ue.softLimitCents)),hardLimitCents:ue.hardLimitCents==null?void 0:Math.round(Number(ue.hardLimitCents)),graceSeconds:ue.graceSeconds==null?void 0:Number(ue.graceSeconds),dryRun:ue.dryRun!==!1});return S({ok:!0,budget:be})}if(N.pathname==="/api/spend/budgets"&&I.method==="PATCH"){fe();let ue=await oe(I),He=String(ue.id??""),be=g.getBudget(He);if(!be||be.organizationId!==Q.organizationId)return S({ok:!1,error:"Budget was not found."},404);return S({ok:!0,budget:g.updateBudget(He,{softLimitCents:ue.softLimitCents==null?be.softLimitCents:Math.round(Number(ue.softLimitCents)),hardLimitCents:ue.hardLimitCents==null?be.hardLimitCents:Math.round(Number(ue.hardLimitCents)),enabled:ue.enabled==null?be.enabled:ue.enabled===!0,dryRun:ue.dryRun==null?be.dryRun:ue.dryRun===!0},ue.expectedVersion==null?void 0:Number(ue.expectedVersion))})}if(N.pathname==="/api/spend/budgets"&&I.method==="DELETE"){fe();let ue=await oe(I),He=String(ue.id??""),be=g.getBudget(He);if(!be||be.organizationId!==Q.organizationId)return S({ok:!1,error:"Budget was not found."},404);let Le=_.closeBudget(He);return g.deleteBudget(He),S({ok:!0,deleted:!0,lifted:Le})}if(N.pathname==="/api/spend/check"&&I.method==="POST"){fe();let ue=await oe(I),{SpendRunner:He}=await import("./chunk-bdgkeqv6.js"),be=new He({controlPlane:a.store,store:g,alerts:Ge});if(ue.apply!==!0){let Se=g.budgetsForScope(Q.organizationId,Q.projectId,Q.environmentId);return S({ok:!0,applied:!1,preview:Se.map((Te)=>T.status(Te))})}let Le=await be.run({...Q,environmentKind:B?.kind});return S({ok:!0,applied:!0,result:Le})}if(N.pathname==="/api/spend/enforcement"&&I.method==="GET")return S({ok:!0,enforcement:_.listUnder({organizationId:Q.organizationId})});if(N.pathname==="/api/spend/release"&&I.method==="POST"){fe();let ue=await oe(I),He=_.close(String(ue.budgetId??""),ue.action);return S({ok:He,released:He,note:He?"The next spend cycle re-applies this if spend is still over the threshold.":"That action was not in force."})}if(N.pathname==="/api/spend/anomalies"&&I.method==="GET")return S({ok:!0,anomalies:g.listAnomalies({organizationId:Q.organizationId,projectId:Q.projectId,unacknowledgedOnly:N.searchParams.get("unacknowledged")==="true"})});if(N.pathname==="/api/spend/anomalies/acknowledge"&&I.method==="POST"){fe();let ue=await oe(I);return S({ok:!0,acknowledged:g.acknowledgeAnomaly(String(ue.id??""))})}return S({ok:!1,error:"Spend endpoint was not found."},404)}if(N.pathname.startsWith("/api/health/")||N.pathname.startsWith("/api/alerts")||N.pathname.startsWith("/api/notifications/")){let d=a.environments.get(ye),g=a.store.listResources(a.project.id,d?.id),T=de.role==="admin"||!!d&&pa(de,d.id,"runtime:read")?g:g.filter((B)=>Ar(de,B.id,"runtime:read")),_=(B)=>!B||T.some((Q)=>Q.id===B),M=(B)=>{if(!B)return;let Q=g.find((fe)=>fe.id===B||fe.slug===B);if(!Q)throw Error("Alert resource was not found.");if(!_(Q.id))throw Error("Alert resource is outside your authorized scope.");return Q.id},K=Me(de).actor;if(N.pathname==="/api/health/checks"&&I.method==="GET")return S({ok:!0,checks:Ge.listHealthChecks(a.project.id,d?.id).filter((B)=>_(B.resourceId)).map((B)=>({...B,results:Ge.listHealthResults(B.id,20)}))});if(N.pathname==="/api/health/checks"&&I.method==="POST"){let B=await oe(I),Q=String(B.kind??"http");if(Q==="command"&&de.role!=="admin")return S({ok:!1,error:"Command health checks require an administrator."},403);let fe={method:String(B.config?.method??"GET").toUpperCase().slice(0,10),path:B.config?.path?String(B.config.path).slice(0,500):void 0,port:B.config?.port==null?void 0:Number(B.config.port),command:Array.isArray(B.config?.command)?B.config.command.map(String).slice(0,20):void 0,expectedStatuses:Array.isArray(B.config?.expectedStatuses)?B.config.expectedStatuses.map(Number).filter(Number.isInteger).slice(0,20):void 0,expectedBody:B.config?.expectedBody?String(B.config.expectedBody).slice(0,500):void 0};return S({ok:!0,check:Ge.createHealthCheck({projectId:a.project.id,environmentId:d?.id,resourceId:M(B.resourceId??B.resource),name:String(B.name??""),kind:Q,target:String(B.target??""),config:fe,intervalSeconds:Number(B.intervalSeconds)||60,timeoutSeconds:Number(B.timeoutSeconds)||10,failureThreshold:Number(B.failureThreshold)||3,recoveryThreshold:Number(B.recoveryThreshold)||2,regions:Array.isArray(B.regions)?B.regions.map(String):["local"],enabled:B.enabled!==!1})},201)}if(N.pathname==="/api/health/checks"&&I.method==="PATCH"){let B=await oe(I),Q=Ge.getHealthCheck(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Health check was not found."},404);return S({ok:!0,check:Ge.setHealthCheckEnabled(Q.id,B.enabled!==!1)})}if(N.pathname==="/api/health/checks/test"&&I.method==="POST"){let B=await oe(I),Q=Ge.getHealthCheck(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Health check was not found."},404);return S({ok:!0,productionIncidentCreated:!1,result:await new Oe(Ge).probe(Q)})}if(N.pathname==="/api/health/checks/run"&&I.method==="POST"){let B=await oe(I),Q=Ge.getHealthCheck(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Health check was not found."},404);let fe=await new Oe(Ge).runAndEvaluate(Q),ue=[];for(let He of fe.evaluations.filter((be)=>be.notify&&be.alert)){let be=oi.enqueue(a.organization.id,He.alert,He.transition);ue.push(...await oi.deliverAll(be))}return S({ok:!0,...fe,deliveries:ue})}if(N.pathname==="/api/alerts/rules"&&I.method==="GET")return S({ok:!0,rules:Ge.listRules(a.project.id,d?.id).filter((B)=>_(B.resourceId))});if(N.pathname==="/api/alerts/rules"&&I.method==="POST"){let B=await oe(I),Q=B.healthCheckId?Ge.getHealthCheck(String(B.healthCheckId)):void 0;if(B.healthCheckId&&(!Q||!_(Q.resourceId)))return S({ok:!1,error:"Health check was not found."},404);return S({ok:!0,rule:Ge.createRule({projectId:a.project.id,environmentId:d?.id,resourceId:M(B.resourceId??B.resource)??Q?.resourceId,healthCheckId:Q?.id,name:String(B.name??""),signal:String(B.signal??(Q?"health":"")),operator:String(B.operator??(Q?"unhealthy":"gt")),threshold:B.threshold==null?void 0:Number(B.threshold),recoveryThreshold:B.recoveryThreshold==null?void 0:Number(B.recoveryThreshold),windowMs:Number(B.windowMs)||300000,consecutive:Number(B.consecutive)||Q?.failureThreshold||3,recoveryConsecutive:Number(B.recoveryConsecutive)||Q?.recoveryThreshold||2,noDataPolicy:["ignore","pending","firing"].includes(String(B.noDataPolicy))?B.noDataPolicy:"pending",severity:["info","warning","critical"].includes(String(B.severity))?B.severity:"warning",groupBy:Array.isArray(B.groupBy)?B.groupBy.map(String):[],labels:B.labels&&typeof B.labels==="object"?B.labels:{},enabled:B.enabled!==!1})},201)}if(N.pathname==="/api/alerts/rules"&&I.method==="PATCH"){let B=await oe(I),Q=Ge.getRule(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Alert rule was not found."},404);return S({ok:!0,rule:Ge.setRuleEnabled(Q.id,B.enabled!==!1)})}if(N.pathname==="/api/alerts/evaluate"&&I.method==="POST")return S({ok:!0,...await pp(d?.id)});if(N.pathname==="/api/alerts"&&I.method==="GET")return S({ok:!0,alerts:Ge.listAlerts(a.project.id,{environmentId:d?.id,states:N.searchParams.getAll("state").length?N.searchParams.getAll("state"):void 0,limit:Number(N.searchParams.get("limit"))||200}).filter((B)=>_(B.resourceId)).map((B)=>({...B,deliveries:Ge.listDeliveries({alertId:B.id,limit:50})}))});if(N.pathname==="/api/alerts/action"&&I.method==="POST"){let B=await oe(I),Q=Ge.getAlert(String(B.id??""));if(!Q||!_(Q.resourceId))return S({ok:!1,error:"Alert was not found."},404);let fe=String(B.action??"");if(fe==="acknowledge")return S({ok:!0,alert:Ge.acknowledge(Q.id,K?.id??"")});if(fe==="assign")return S({ok:!0,alert:Ge.assign(Q.id,B.ownerActorId==="me"?K?.id:B.ownerActorId?String(B.ownerActorId):void 0,K?.id)});if(fe==="silence"){if(de.role!=="admin")return S({ok:!1,error:"Silencing production alerts requires an administrator."},403);let ue=Bt.resolveSession(I);if(Re&&(!ue||!ve.isRecentlyAuthenticated(ue)))return S({ok:!1,error:"Recent authentication is required to silence alerts.",stepUpRequired:!0},401);return S({ok:!0,alert:Ge.silenceAlert(Q.id,String(B.until??""),K?.id)})}return S({ok:!1,error:"Action must be acknowledge, assign, or silence."},422)}if(N.pathname==="/api/alerts/silences"&&I.method==="POST"){let B=await oe(I);return S({ok:!0,id:Ge.createSilence({projectId:a.project.id,environmentId:d?.id,resourceId:M(B.resourceId??B.resource),matcher:B.matcher,reason:String(B.reason??""),startsAt:String(B.startsAt??new Date().toISOString()),endsAt:String(B.endsAt??""),timezone:String(B.timezone??"UTC"),actorId:K?.id})},201)}if(N.pathname==="/api/notifications/channels"&&I.method==="GET")return S({ok:!0,channels:Ge.listChannels(a.organization.id)});if(N.pathname==="/api/notifications/channels"&&I.method==="POST"){let B=await oe(I),Q=String(B.kind??""),fe=Q==="email"?{to:B.config?.to,from:B.config?.from}:Q==="telegram"?{chatId:String(B.config?.chatId??"")}:{};return S({ok:!0,channel:Ge.createChannel({organizationId:a.organization.id,name:String(B.name??""),kind:Q,config:fe,credential:B.credential?String(B.credential):void 0,actorId:K?.id})},201)}if(N.pathname==="/api/notifications/channels"&&I.method==="PATCH"){let B=await oe(I),Q=String(B.id??"");if(B.credential)return S({ok:!0,channel:Ge.rotateChannel(Q,String(B.credential))});let fe=String(B.status??"paused");if(!["active","paused","disabled"].includes(fe))return S({ok:!1,error:"Channel status must be active, paused, or disabled."},422);return S({ok:!0,channel:Ge.setChannelStatus(Q,fe)})}if(N.pathname==="/api/notifications/channels/test"&&I.method==="POST"){let B=await oe(I);return S({ok:!0,productionIncidentCreated:!1,result:await oi.testChannel(String(B.id??""))})}if(N.pathname==="/api/notifications/routes"&&I.method==="GET")return S({ok:!0,routes:Ge.listRoutes(a.organization.id)});if(N.pathname==="/api/notifications/routes"&&I.method==="POST"){let B=await oe(I),Q=Array.isArray(B.channelIds)?B.channelIds.map(String):[];if(Q.some((fe)=>Ge.getChannel(fe)?.organizationId!==a.organization.id))return S({ok:!1,error:"Route contains an unavailable channel."},422);return S({ok:!0,route:Ge.createRoute({organizationId:a.organization.id,name:String(B.name??""),priority:Number(B.priority)||0,matcher:B.matcher&&typeof B.matcher==="object"?B.matcher:{},channelIds:Q,quietHours:B.quietHours,groupWaitSeconds:Number(B.groupWaitSeconds)||30,reminderSeconds:B.reminderSeconds==null?void 0:Number(B.reminderSeconds),escalation:Array.isArray(B.escalation)?B.escalation:[],template:B.template?String(B.template):void 0,rateLimitPerMinute:Number(B.rateLimitPerMinute)||60,enabled:B.enabled!==!1})},201)}if(N.pathname==="/api/notifications/routes"&&I.method==="PATCH"){let B=await oe(I),Q=Ge.getRoute(String(B.id??""));if(!Q||Q.organizationId!==a.organization.id)return S({ok:!1,error:"Notification route was not found."},404);return S({ok:!0,route:Ge.setRouteEnabled(Q.id,B.enabled!==!1)})}if(N.pathname==="/api/notifications/routes/preview"&&I.method==="POST"){let B=await oe(I),fe=(B.alertId?Ge.getAlert(String(B.alertId)):void 0)??{id:"preview",ruleId:"preview",projectId:a.project.id,environmentId:d?.id,resourceId:M(B.resourceId??B.resource),dedupKey:"preview",groupKey:String(B.groupKey??"default"),state:"firing",severity:["info","warning","critical"].includes(String(B.severity))?B.severity:"warning",title:String(B.title??"Rule preview"),evidence:{},failureCount:1,recoveryCount:0,occurrenceCount:1,firstSeenAt:new Date().toISOString(),lastSeenAt:new Date().toISOString(),firingAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return S({ok:!0,productionIncidentCreated:!1,matches:oi.preview(a.organization.id,fe,String(B.eventType??"firing")).map((ue)=>({route:ue.route,channels:ue.channels,quiet:ue.quiet}))})}if(N.pathname==="/api/notifications/deliveries"&&I.method==="GET")return S({ok:!0,deliveries:Ge.listDeliveries({alertId:N.searchParams.get("alertId")??void 0,states:N.searchParams.getAll("state"),limit:Number(N.searchParams.get("limit"))||200})});if(N.pathname==="/api/notifications/deliveries/retry"&&I.method==="POST"){let B=await oe(I),Q=Ge.getDelivery(String(B.id??""));if(!Q)return S({ok:!1,error:"Delivery was not found."},404);return Ge.updateDelivery(Q.id,{state:"retrying",attempt:Math.max(0,Q.attempt-1),nextAttemptAt:new Date().toISOString()}),S({ok:!0,delivery:await oi.deliver(Q.id)})}}if(N.pathname.startsWith("/api/jobs")||N.pathname.startsWith("/api/workers")){let d=a.environments.get(ye),g=a.store.listResources(a.project.id,d?.id),_=de.role==="admin"||!!d&&pa(de,d.id,"automation:read")?g:g.filter((Se)=>Ar(de,Se.id,"automation:read")),M=(Se)=>!Se||_.some((Te)=>Te.id===Se),K=Me(de).actor,B=q.get(ye)??O,Q=Dr(o,B),fe=Q.filter((Se)=>!Se.danger&&["scheduler","backup","worker"].includes(Se.group)),ue=V(o),He=()=>{let Se=Bt.resolveSession(I);return!Re||!!Se&&ve.isRecentlyAuthenticated(Se)},be=(Se)=>{if(!Se||typeof Se!=="object"||Array.isArray(Se))return{};let Te=Object.entries(Se).slice(0,50);if(Te.some(([,Xe])=>typeof Xe!=="string"||!/^(?:secret|ssm|arn|env):\/\//.test(Xe)))throw Error("Job payload values must be secret or environment references, never inline values.");return Object.fromEntries(Te)},Le=(Se,Te,Xe)=>a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,resourceId:Xe,actorId:K?.id,type:`job.${Se}`,payload:Te});if(N.pathname==="/api/jobs/preview"&&I.method==="POST"){let Se=await oe(I);try{return S({ok:!0,productionExecutionCreated:!1,preview:ot(String(Se.expression??""),String(Se.timezone??"UTC"),new Date(Se.from?String(Se.from):Date.now()),Number(Se.count)||5)})}catch(Te){return S({ok:!1,error:Te instanceof Error?Te.message:"Schedule preview could not be generated.",productionExecutionCreated:!1},422)}}if(N.pathname==="/api/jobs"&&I.method==="GET")return S({ok:!0,jobs:Er.list(a.project.id,{environmentId:d?.id}).filter((Se)=>M(Se.resourceId)).map((Se)=>({...Se,preview:ot(Se.normalizedExpression,Se.timezone,new Date,5),capability:On(Se),lastExecution:Er.listExecutions(Se.id,1)[0]}))});if(N.pathname==="/api/jobs"&&I.method==="POST"){let Se=await oe(I),Te=String(Se.provider??(ue==="serverless"?"eventbridge":"server")),Xe=ue==="serverless"?"eventbridge":"server";if(Te!==Xe)return S({ok:!1,error:`${ue} environments accept ${Xe} schedules through this adapter.`},422);let ut=Se.operationId?String(Se.operationId):void 0;if(Te==="server"&&(!ut||!fe.some((dr)=>dr.id===ut)))return S({ok:!1,error:"Server jobs require an allowlisted operation target."},422);let yt=On({provider:Te,expression:String(Se.expression??""),flexibleMinutes:Number(Se.flexibleMinutes)||0,missedRunPolicy:Se.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String(Se.overlapPolicy))?Se.overlapPolicy:"forbid"});if(!yt.supported)return S({ok:!1,error:yt.notes.join(" ")},422);let Yn=Se.resourceId?g.find((dr)=>dr.id===Se.resourceId||dr.slug===Se.resourceId):void 0;if(Se.resourceId&&(!Yn||!M(Yn.id)))return S({ok:!1,error:"Job resource was not found."},404);try{let dr=Te==="server"?{kind:"dashboard_operation",operationId:ut}:{kind:"serverless_scheduler",action:"run"},bo=Er.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:Yn?.id,name:String(Se.name??""),provider:Te,expression:String(Se.expression??""),timezone:String(Se.timezone??"UTC"),startsAt:Se.startsAt?String(Se.startsAt):void 0,endsAt:Se.endsAt?String(Se.endsAt):void 0,flexibleMinutes:Number(Se.flexibleMinutes)||0,target:dr,payloadRefs:be(Se.payloadRefs),missedRunPolicy:Se.missedRunPolicy==="catch_up"?"catch_up":"skip",overlapPolicy:["allow","forbid","replace"].includes(String(Se.overlapPolicy))?Se.overlapPolicy:"forbid",retryPolicy:{maxAttempts:Number(Se.maxAttempts)||3,backoffSeconds:Number(Se.backoffSeconds)||30,deadLetterRef:Se.deadLetterRef?String(Se.deadLetterRef):void 0},timeoutSeconds:Number(Se.timeoutSeconds)||900,enabled:Se.enabled!==!1,origin:"managed",ownerActorId:K?.id,observedState:{},reconciliationStatus:"pending"});return Le("created",{jobId:bo.id,provider:bo.provider,expression:bo.normalizedExpression},bo.resourceId),S({ok:!0,job:bo,capability:yt},201)}catch(dr){return S({ok:!1,error:dr instanceof Error?dr.message:"Scheduled job could not be created."},422)}}if(N.pathname==="/api/jobs"&&I.method==="PATCH"){let Se=await oe(I),Te=Er.get(String(Se.id??""));if(!Te||!M(Te.resourceId))return S({ok:!1,error:"Scheduled job was not found."},404);if(Te.origin==="config")return S({ok:!1,error:"Config-defined schedules must be edited in cloud.config.ts and reconciled."},409);let Xe=Se.missedRunPolicy==null?void 0:String(Se.missedRunPolicy),ut=Se.overlapPolicy==null?void 0:String(Se.overlapPolicy);if(Xe&&!["skip","catch_up"].includes(Xe))return S({ok:!1,error:"Missed-run policy must be skip or catch_up."},422);if(ut&&!["allow","forbid","replace"].includes(ut))return S({ok:!1,error:"Overlap policy must be allow, forbid, or replace."},422);try{let yt=Er.updateSchedule(Te.id,{expression:Se.expression?String(Se.expression):void 0,timezone:Se.timezone?String(Se.timezone):void 0,missedRunPolicy:Xe,overlapPolicy:ut,timeoutSeconds:Se.timeoutSeconds==null?void 0:Number(Se.timeoutSeconds)});return Le("updated",{jobId:yt.id,expression:yt.normalizedExpression,version:yt.version},yt.resourceId),S({ok:!0,job:yt})}catch(yt){return S({ok:!1,error:yt instanceof Error?yt.message:"Scheduled job could not be updated."},422)}}if(N.pathname==="/api/jobs/action"&&I.method==="POST"){let Se=await oe(I),Te=Er.get(String(Se.id??""));if(!Te||!M(Te.resourceId))return S({ok:!1,error:"Scheduled job was not found."},404);let Xe=String(Se.action??"");if(Xe==="run"){let ut=lp.enqueue(Te,{trigger:"manual",actorId:K?.id});return Le("run_queued",{jobId:Te.id,executionId:ut.id},Te.resourceId),S({ok:!0,execution:ut},202)}if(["disable","delete"].includes(Xe)&&d?.kind==="production"){if(String(Se.confirm??"")!==Xe)return S({ok:!1,error:`Type "${Xe}" to confirm this production change.`},409);if(!He())return S({ok:!1,error:"Recent authentication is required for this production change.",stepUpRequired:!0},401)}if(Xe==="enable"||Xe==="disable"){let ut=Er.setEnabled(Te.id,Xe==="enable");return Le(Xe==="enable"?"enabled":"disabled",{jobId:Te.id},Te.resourceId),S({ok:!0,job:ut})}if(Xe==="delete")try{return Er.remove(Te.id),Le("deleted",{jobId:Te.id,name:Te.name},Te.resourceId),S({ok:!0,deleted:Te.id})}catch(ut){return S({ok:!1,error:ut instanceof Error?ut.message:"Scheduled job could not be deleted."},409)}return S({ok:!1,error:"Action must be run, enable, disable, or delete."},422)}if(N.pathname==="/api/jobs/history"&&I.method==="GET"){let Se=Er.get(String(N.searchParams.get("jobId")??""));if(!Se||!M(Se.resourceId))return S({ok:!1,error:"Scheduled job was not found."},404);return S({ok:!0,executions:Er.listExecutions(Se.id,Number(N.searchParams.get("limit"))||100).map((Te)=>({...Te,logs:Te.operationId?kt.logs(Te.operationId,{limit:500}):[]}))})}if(N.pathname==="/api/jobs/reconcile"&&I.method==="POST"){if(!d)return S({ok:!1,error:"Environment was not found."},404);let Se=$r(Er,o,{organization:a.organization,project:a.project,environment:d,resources:g});return Le("reconciled",Se),S({ok:!0,reconciliation:Se})}if(N.pathname==="/api/workers"&&I.method==="GET"){let Se=Array.isArray(B.workersDetail??B.workers)?B.workersDetail??B.workers:[];return S({ok:!0,workers:Er.listWorkers(a.project.id,d?.id).filter((Te)=>M(Te.resourceId)).map((Te)=>{let Xe=Se.find((ut)=>ut.name===Te.name||ut.site===Te.target.site);return Xe?{...Te,observedState:{...Te.observedState,status:Xe.status??"configured",currentJob:Xe.currentJob??null,failures:Number(Xe.failed??Xe.failures)||0,processed:Number(Xe.processed)||0}}:Te})})}if(N.pathname==="/api/workers/action"&&I.method==="POST"){let Se=await oe(I),Te=Er.getWorker(String(Se.id??""));if(!Te||!M(Te.resourceId))return S({ok:!1,error:"Worker was not found."},404);let Xe=String(Se.action??"");if(Xe==="restart"){if(String(Se.confirm??"")!==Te.name)return S({ok:!1,error:`Type "${Te.name}" to restart this worker.`},409);let ut=Q.find((dr)=>dr.id===Te.target.operationId);if(!ut)return S({ok:!1,error:"The allowlisted worker restart operation is unavailable."},409);let yt=await kr(o,ye,ut),Yn=Er.reconcileWorker(Te.id,yt.ok?"in_sync":"unavailable",{...Te.observedState,lastRestartAt:new Date().toISOString(),command:yt.command??null,error:yt.error??yt.stderr??null});return Le("worker_restarted",{workerId:Te.id,ok:yt.ok},Te.resourceId),S({...yt,worker:Yn},yt.ok?200:409)}if(Xe==="scale")return S({ok:!1,error:Te.provider==="systemd"?"Systemd worker scale is config-managed; edit the worker definition and reconcile.":"This provider does not expose safe worker scaling through the current adapter."},422);return S({ok:!1,error:"Action must be restart or scale."},422)}}if(N.pathname.startsWith("/api/telemetry/")){let d=a.environments.get(ye),g=new Ve(a.store),T=a.store.listResources(a.project.id,d?.id),_=["/api/telemetry/query","/api/telemetry/tail","/api/telemetry/export","/api/telemetry/saved-queries","/api/telemetry/refresh"].includes(N.pathname)?"runtime:logs":"runtime:read",M=de.role==="admin"||!!d&&pa(de,d.id,_),K=M?T:T.filter((be)=>Ar(de,be.id,_)),B=(be)=>Jy(K,M,be),Q=(be)=>{let Le=new Date,Se={"1h":3600000,"6h":21600000,"24h":86400000,"7d":604800000,"30d":2592000000},Te=String(be.to??Le.toISOString()),Xe=String(be.from??new Date(new Date(Te).getTime()-(Se[String(be.range??"1h")]??Se["1h"])).toISOString()),ut=(Yn)=>{let dr=(Array.isArray(Yn)?Yn:String(Yn??"").split(",")).map(String).filter(Boolean);return dr.length?dr:void 0},yt=ut(be.kinds)?.filter((Yn)=>["metric","log","trace","request","event"].includes(Yn));return{projectId:a.project.id,environmentId:d?.id,resourceIds:B(be.resources),kinds:yt,names:ut(be.names),sources:ut(be.sources),levels:ut(be.levels),from:Xe,to:Te,text:String(be.text??"")||void 0,traceId:String(be.traceId??"")||void 0,requestId:String(be.requestId??"")||void 0,deploymentId:String(be.deploymentId??"")||void 0,releaseId:String(be.releaseId??"")||void 0,workloadId:String(be.workloadId??"")||void 0,cursor:String(be.cursor??"")||void 0,limit:Number(be.limit)||void 0}},fe=Object.fromEntries(N.searchParams.entries()),ue=(be=!1)=>Bn({controlPlane:a.store,projectId:a.project.id,environmentId:d?.id,config:o,environment:ye,force:be,lightweight:!be}),He=()=>{let be=a.store.getSetting(`telemetry.collection:${a.project.id}:${d?.id??"all"}`)??{};return{generatedAt:String(be.generatedAt??new Date().toISOString()),cached:!0,statuses:Array.isArray(be.statuses)?be.statuses:[],errors:Array.isArray(be.errors)?be.errors:[],policy:be.policy??je(a.store,a.project.id)}};if(N.pathname==="/api/telemetry/status"&&I.method==="GET"){ue(!1);let be=He(),Le=M?be.statuses:g.status(a.project.id,d?.id,be.policy.rawDays,be.policy.samplingRate,K.map((Te)=>Te.id)),Se=Le.reduce((Te,Xe)=>Te+Xe.estimatedDailyBytes*30,0);return S({ok:!0,generatedAt:be.generatedAt,cached:be.cached,sources:Le,errors:M?be.errors:[],policy:be.policy,retention:{rawDays:be.policy.rawDays,downsampleAfterDays:be.policy.downsampleAfterDays,downsampleBucketMs:be.policy.downsampleBucketMs,maxRecords:be.policy.maxRecords},estimatedMonthlyBytes:Se,estimatedMonthlyCostUsd:Hn(Se,be.policy),costEstimateConfigured:be.policy.estimatedStorageUsdPerGbMonth>0})}if(N.pathname==="/api/telemetry/settings"&&I.method==="GET")return S({ok:!0,policy:je(a.store,a.project.id)});if(N.pathname==="/api/telemetry/settings"&&I.method==="PATCH"){let be=qn(a.store,a.project.id,await oe(I));return Xy(a.project.id),S({ok:!0,policy:be})}if(N.pathname==="/api/telemetry/query"&&I.method==="GET"){ue(!1);let be=He();return S({ok:!0,collection:{generatedAt:be.generatedAt,cached:be.cached},...g.query(Q(fe))})}if(N.pathname==="/api/telemetry/tail"&&I.method==="GET"){ue(!1);let be=new TextEncoder,Le=new Date,Se=Q({...fe,kinds:fe.kinds||"log,request,event,trace",from:fe.from||new Date(Le.getTime()-120000).toISOString(),to:Le.toISOString(),limit:Math.min(1000,Number(fe.limit)||200),cursor:void 0}),Te=I.headers.get("last-event-id")||String(fe.cursor??"")||void 0,Xe,ut=!1,yt=!1,Yn=new ReadableStream({start(dr){let bo=()=>{if(ut)return;if(ut=!0,Xe)clearInterval(Xe);I.signal.removeEventListener("abort",bo);try{dr.close()}catch{}},Ep=async()=>{if(ut||yt)return;yt=!0;try{let zo=g.tail({...Se,to:new Date(Date.now()+1000).toISOString()},Te);for(let Tp of zo.records)Te=Ii(Tp)??Te,dr.enqueue(be.encode(`id: ${Te??""}
500
500
  event: record
501
501
  data: ${JSON.stringify(Tp)}
502
502
 
@@ -507,5 +507,5 @@ data: ${JSON.stringify({message:zo instanceof Error?zo.message:String(zo)})}
507
507
  data: ${JSON.stringify({cursor:Te,at:new Date().toISOString()})}
508
508
 
509
509
  `))},5000),Xe.unref?.(),I.signal.addEventListener("abort",bo,{once:!0})},cancel(){if(ut=!0,Xe)clearInterval(Xe)}});return new Response(Yn,{headers:{"cache-control":"no-cache, no-transform",connection:"keep-alive","content-type":"text/event-stream; charset=utf-8","x-accel-buffering":"no"}})}if(N.pathname==="/api/telemetry/series"&&I.method==="GET"){ue(!1);let be=He(),Le=["sum","avg","min","max","count","p50","p90","p95","p99"].includes(String(fe.aggregation))?fe.aggregation:"avg",Se=Q({...fe,kinds:"metric",limit:5000}),Te=g.series({...Se,bucketMs:Number(fe.bucketMs)||60000,aggregation:Le,timezone:String(fe.timezone??"UTC"),compareFrom:fe.compareFrom,compareTo:fe.compareTo});return S({ok:!0,collection:{generatedAt:be.generatedAt,cached:be.cached},query:{aggregation:Le,bucketMs:Number(fe.bucketMs)||60000,timezone:String(fe.timezone??"UTC")},series:Te})}if(N.pathname==="/api/telemetry/refresh"&&I.method==="POST")return S({ok:!0,...await ue(!0)});if(N.pathname==="/api/telemetry/export"&&I.method==="POST"){let be=await oe(I);await ue(!1);let Le=g.query({...Q(be),limit:Math.min(5000,Number(be.limit)||5000),cursor:void 0});if((be.format==="csv"?"csv":"json")==="json")return new Response(JSON.stringify({exportedAt:new Date().toISOString(),query:Q(be),...Le},null,2),{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.json"',"content-type":"application/json; charset=utf-8"}});let Te=["timestamp","kind","source","name","level","value","unit","message","traceId","requestId","deploymentId","releaseId","workloadId"],Xe=[Te.join(","),...Le.records.map((ut)=>Te.map((yt)=>`"${String(ut[yt]??"").replaceAll('"','""')}"`).join(","))].join(`
510
- `);return new Response(Xe,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(N.pathname==="/api/telemetry/saved-queries"&&I.method==="GET"){let be=Me(de);return S({ok:!0,queries:g.listSavedQueries(a.project.id,be.actor?.id)})}if(N.pathname==="/api/telemetry/saved-queries"&&I.method==="POST"){let be=await oe(I),Le=Me(de);return S({ok:!0,query:g.saveQuery(a.project.id,Le.actor?.id,String(be.name??""),Q(be.query??be))},201)}if(N.pathname==="/api/telemetry/saved-queries"&&I.method==="DELETE"){let be=await oe(I),Le=Me(de),Se=g.deleteSavedQuery(a.project.id,Le.actor?.id,String(be.id??""));return S({ok:Se},Se?200:404)}}if(N.pathname.startsWith("/api/configuration")){let d=a.environments.get(ye),g=de.role==="admin"||!!si.capabilities?.includes("secrets:read"),T=de.role==="admin"||!!si.capabilities?.includes("secrets:write"),_={projectId:a.project.id,environmentId:d?.id},L={"cache-control":"no-store"};if(N.pathname==="/api/configuration"&&I.method==="GET"){let K=Object.fromEntries(N.searchParams),B=K.scopeType||K.scopeId?sa(K,_):void 0,Q=["variable","secret"].includes(String(K.kind))?K.kind:void 0,fe=B?.type==="preview"?nr.previews.getInstance(B.id):void 0,ue=fe?nr.previews.getDefinition(fe.definitionId):void 0,He=B?await Jn.resolve({projectId:a.project.id,environmentId:B.environmentId,resourceId:B.resourceId,functionId:B.type==="function"?B.id:void 0,previewId:B.previewId,trustedPreview:!!fe&&!fe.fork,allowedPreviewSecrets:ue?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:g}):void 0,be=a.store.listResources(a.project.id);return S({ok:!0,entries:Jn.list({projectId:a.project.id,scope:B,kind:Q,search:K.search,canReadSecretMetadata:g}),effectiveEntries:He?Object.values(He.entries).filter((Le)=>!Q||Le.kind===Q).filter((Le)=>!K.search||Le.key.toLowerCase().includes(String(K.search).toLowerCase())):[],configurationHash:He?.configurationHash,warnings:He?.warnings??[],scopes:{project:a.project,environments:a.store.listEnvironments(a.project.id),resources:be.filter((Le)=>Le.kind!=="function"),functions:be.filter((Le)=>Le.kind==="function"),previews:nr.previews.listInstances({projectId:a.project.id}).filter((Le)=>Le.status!=="destroyed").map((Le)=>({id:Le.id,name:Le.name,environmentId:Le.baseEnvironmentId,resourceId:Le.resourceId,fork:Le.fork,status:Le.status}))}},200,L)}if(N.pathname==="/api/configuration/export"&&I.method==="GET"){let K=sa(Object.fromEntries(N.searchParams),_);return new Response(Jn.exportVariables({projectId:a.project.id,scope:K}),{headers:{...L,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(N.pathname==="/api/configuration/plan"&&I.method==="POST"){let K=await oe(I),B=sa(K,_),Q=K.values&&typeof K.values==="object"&&!Array.isArray(K.values)?Object.fromEntries(Object.entries(K.values).map(([fe,ue])=>[fe,String(ue)])):{};return S({ok:!0,plan:Jn.plan({projectId:a.project.id,scope:B,values:Q,removeMissing:K.removeMissing===!0})},200,L)}if(N.pathname==="/api/configuration"&&I.method==="POST"){let K=await oe(I),B=sa(K,_),Q=K.kind==="secret"?"secret":"variable",fe=String(K.key??"");if(Q==="secret"&&!T)return S({ok:!1,error:"Secret write permission is required."},403,L);try{let ue=await Jn.set({organizationId:a.organization.id,projectId:a.project.id,scope:B,key:fe,kind:Q,value:K.value==null?void 0:String(K.value),reference:K.reference==null?void 0:String(K.reference),backend:K.backend,required:K.required===!0,expectedVersion:K.expectedVersion==null?void 0:Number(K.expectedVersion),confirmed:String(K.confirm??"")===fe,idempotencyKey:I.headers.get("idempotency-key")??K.idempotencyKey,actorId:Me(de).actor?.id});return S({ok:!0,entry:Jn.list({projectId:a.project.id,scope:B,canReadSecretMetadata:g}).find((He)=>He.id===ue.entry.id),mutation:ue.mutation,warnings:ue.warnings},ue.mutation.added.length?201:200,L)}catch(ue){return S({ok:!1,error:ue instanceof Error?ue.message:String(ue)},409,L)}}if(N.pathname==="/api/configuration/import"&&I.method==="POST"){let K=await oe(I),B=sa(K,_),Q=Array.isArray(K.secretKeys)?K.secretKeys.map(String):[];if(Q.length&&!T)return S({ok:!1,error:"Secret write permission is required."},403,L);try{let fe=await Jn.importDotenv({organizationId:a.organization.id,projectId:a.project.id,scope:B,source:String(K.source??""),secretKeys:Q,backend:K.backend,confirmed:K.confirm==="import",idempotencyKey:I.headers.get("idempotency-key")??K.idempotencyKey,actorId:Me(de).actor?.id});return S({ok:fe.document.valid,diagnostics:fe.document.diagnostics,mutation:fe.mutation,warnings:fe.warnings},fe.document.valid?200:422,L)}catch(fe){return S({ok:!1,error:fe instanceof Error?fe.message:String(fe)},409,L)}}if(N.pathname==="/api/configuration/dependencies"&&I.method==="POST"){let K=await oe(I),B=go.get(String(K.entryId??"")),Q=a.store.getResource(String(K.resourceId??""));if(!B||B.projectId!==a.project.id||!Q||Q.projectId!==a.project.id)return S({ok:!1,error:"Configuration entry or dependent resource was not found."},404,L);return S({ok:!0,dependency:go.setDependency({entryId:B.id,resourceId:Q.id,injectionTarget:["native_reference","file"].includes(String(K.injectionTarget))?K.injectionTarget:"environment",required:K.required!==!1,requiresRedeploy:K.requiresRedeploy!==!1,lastDeployedVersion:K.lastDeployedVersion==null?void 0:Number(K.lastDeployedVersion)})},200,L)}if(N.pathname==="/api/configuration/transfer"&&I.method==="POST"){let K=await oe(I),B=go.get(String(K.id??"")),Q=sa({...K,scopeType:K.targetScopeType,scopeId:K.targetScopeId},_);if(!B||B.projectId!==a.project.id)return S({ok:!1,error:"Configuration entry was not found."},404,L);if(B.kind==="secret"&&!T)return S({ok:!1,error:"Secret write permission is required."},403,L);try{let fe=await Jn.transfer({entryId:B.id,targetScope:Q,mode:K.mode==="move"?"move":"copy",confirmed:K.confirm===B.key,actorId:Me(de).actor?.id,idempotencyKey:I.headers.get("idempotency-key")??K.idempotencyKey});return S({ok:!0,entry:Jn.list({projectId:a.project.id,scope:Q,canReadSecretMetadata:g}).find((ue)=>ue.id===fe.entry.id),mutation:fe.mutation},200,L)}catch(fe){return S({ok:!1,error:fe instanceof Error?fe.message:String(fe)},409,L)}}if(N.pathname==="/api/configuration/bulk"&&I.method==="POST"){let K=await oe(I),B=Array.isArray(K.ids)?K.ids.map(String).slice(0,500):[],Q=B.map((ue)=>go.get(ue)).filter((ue)=>!!ue&&ue.projectId===a.project.id);if(Q.length!==B.length)return S({ok:!1,error:"One or more configuration entries were not found."},404,L);if(Q.some((ue)=>ue.kind==="secret")&&!T)return S({ok:!1,error:"Secret write permission is required."},403,L);if(K.action!=="delete"||K.confirm!=="bulk")return S({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,L);let fe=[];try{for(let ue of Q)fe.push(await Jn.remove({entryId:ue.id,expectedVersion:ue.version,confirmed:!0,actorId:Me(de).actor?.id}));return S({ok:!0,removed:fe.flatMap((ue)=>ue.removed),affectedResourceIds:[...new Set(fe.flatMap((ue)=>ue.affectedResourceIds))].sort()},200,L)}catch(ue){return S({ok:!1,error:ue instanceof Error?ue.message:String(ue),partial:fe.flatMap((He)=>He.removed)},409,L)}}if(N.pathname==="/api/configuration/reveal"&&I.method==="POST"){let K=await oe(I),B=Bt.resolveSession(I);try{return S({ok:!0,value:await Jn.reveal({entryId:String(K.id??""),canRevealSecrets:g,recentlyAuthenticated:!Re||!!B&&ve.isRecentlyAuthenticated(B),actorId:Me(de).actor?.id})},200,L)}catch(Q){return S({ok:!1,error:Q instanceof Error?Q.message:String(Q)},403,L)}}if(N.pathname==="/api/configuration"&&I.method==="DELETE"){let K=await oe(I),B=go.get(String(K.id??""));if(B?.kind==="secret"&&!T)return S({ok:!1,error:"Secret write permission is required."},403,L);if(!B||B.projectId!==a.project.id)return S({ok:!1,error:"Configuration entry was not found."},404,L);try{return S({ok:!0,mutation:await Jn.remove({entryId:B.id,expectedVersion:Number(K.expectedVersion),confirmed:String(K.confirm??"")===B.key,actorId:Me(de).actor?.id})},200,L)}catch(Q){return S({ok:!1,error:Q instanceof Error?Q.message:String(Q)},409,L)}}}if(N.pathname.startsWith("/api/fleet")){let d=Me(de).actor?.id,g=(T,_=409)=>S({ok:!1,error:T instanceof Error?T.message:String(T)},_,{"cache-control":"no-store"});if(N.pathname==="/api/fleet"&&I.method==="GET")return S({ok:!0,servers:ua.list(a.project.id),resources:a.store.listResources(a.project.id),operations:kt.list({projectId:a.project.id,limit:200}).filter((T)=>T.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(N.pathname==="/api/fleet"&&I.method==="POST"){let T=await oe(I);try{return S({ok:!0,server:Oi.enroll({organizationId:a.organization.id,projectId:a.project.id,name:String(T.name??""),provider:["aws","hetzner"].includes(String(T.provider))?T.provider:"ssh",providerId:T.providerId?String(T.providerId):void 0,region:T.region?String(T.region):void 0,zone:T.zone?String(T.zone):void 0,endpoint:String(T.endpoint??""),sshUser:String(T.sshUser??"deploy"),sshPort:T.sshPort?Number(T.sshPort):22,credentialRef:String(T.credentialRef??""),roles:Array.isArray(T.roles)?T.roles:[],labels:T.labels&&typeof T.labels==="object"?T.labels:{}})},201)}catch(_){return g(_,422)}}if(N.pathname==="/api/fleet/action"&&I.method==="POST"){let T=await oe(I),_=String(T.id??""),L=String(T.action??"");try{if(L==="test")return S({ok:!0,server:await Oi.test(_)});if(L==="validate")return S({ok:!0,server:await Oi.validate(_)});if(L==="review_host_key")return S({ok:!0,server:Oi.reviewHostKey(_,String(T.fingerprint??""))});if(L==="bootstrap")return S({ok:!0,...Oi.bootstrap(_,T.confirmed===!0)},T.confirmed===!0?202:200);if(L==="heartbeat")return S({ok:!0,server:Oi.heartbeat(_,{usage:T.usage&&typeof T.usage==="object"?T.usage:{}})});if(L==="drain")return S({ok:!0,server:Oi.drain(_,T.completed===!0)});if(L==="uncordon")return S({ok:!0,server:Oi.uncordon(_)});if(L==="archive")return S({ok:!0,server:Oi.archive(_,String(T.confirmation??""))});return g("Unsupported fleet action.",422)}catch(K){return g(K)}}}if(N.pathname.startsWith("/api/capacity")){let d=(g,T=409)=>S({ok:!1,error:g instanceof Error?g.message:String(g)},T,{"cache-control":"no-store"});if(N.pathname==="/api/capacity"&&I.method==="GET")return S({ok:!0,pools:fo.listPools(a.project.id),placements:fo.listPlacements(a.project.id),servers:ua.list(a.project.id)},200,{"cache-control":"no-store"});if(N.pathname==="/api/capacity"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,pool:fo.createPool({organizationId:a.organization.id,projectId:a.project.id,name:String(g.name??""),purpose:String(g.purpose??"application"),backend:String(g.backend??"server"),region:g.region?String(g.region):void 0,architecture:g.architecture?String(g.architecture):void 0,labels:g.labels&&typeof g.labels==="object"?g.labels:{},requiredServerLabels:g.requiredServerLabels&&typeof g.requiredServerLabels==="object"?g.requiredServerLabels:{},toleratedTaints:Array.isArray(g.toleratedTaints)?g.toleratedTaints.map(String):[],capacity:g.capacity&&typeof g.capacity==="object"?g.capacity:{},maxWorkloads:Number(g.maxWorkloads??10),costWeight:Number(g.costWeight??1),spreadKey:g.spreadKey?String(g.spreadKey):void 0,concurrency:Number(g.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/capacity/member"&&I.method==="POST"){let g=await oe(I);try{return fo.addMember(String(g.poolId??""),String(g.serverId??"")),S({ok:!0,pool:fo.getPool(String(g.poolId??""))})}catch(T){return d(T,422)}}if(N.pathname==="/api/capacity/explain"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,decisions:cp.explain(a.project.id,{purpose:String(g.purpose??"application"),resources:g.resources&&typeof g.resources==="object"?g.resources:{},region:g.region?String(g.region):void 0,architecture:g.architecture?String(g.architecture):void 0,labels:g.labels&&typeof g.labels==="object"?g.labels:{}})})}catch(T){return d(T,422)}}if(N.pathname==="/api/capacity/action"&&I.method==="POST"){let g=await oe(I);try{if(g.action==="drain")return S({ok:!0,...cp.drainPool(String(g.poolId??""))});if(g.action==="enable")return S({ok:!0,pool:fo.updatePool(String(g.poolId??""),{status:"active"})});if(g.action==="disable")return S({ok:!0,pool:fo.updatePool(String(g.poolId??""),{status:"disabled"})});return d("Unsupported capacity action.",422)}catch(T){return d(T,422)}}}if(N.pathname.startsWith("/api/regions")){let d=(g,T=409)=>S({ok:!1,error:g instanceof Error?g.message:String(g)},T,{"cache-control":"no-store"});if(N.pathname==="/api/regions"&&I.method==="GET")return S({ok:!0,topologies:Fo.list(a.project.id).map((g)=>({topology:g,targets:Fo.targets(g.id),channels:Fo.channels(g.id),route:Fo.route(g.id),executions:Fo.executions(g.id)}))},200,{"cache-control":"no-store"});if(N.pathname==="/api/regions"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,topology:dp.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:a.environments.get(ye)?.id,name:String(g.name??""),hostname:String(g.hostname??""),regions:Array.isArray(g.regions)?g.regions:[],trafficPolicy:g.trafficPolicy==="weighted"||g.trafficPolicy==="latency"?g.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(g.replicate)?g.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(g.maxLagSeconds??30),retainOnDestroy:g.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:g.cdnEnabled===!0,wafEnabled:g.wafEnabled===!0})},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/regions/action"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,...dp.enqueue({topologyId:String(g.topologyId??""),kind:String(g.action??""),targetRegion:g.targetRegion?String(g.targetRegion):void 0,revision:g.revision?String(g.revision):void 0,manifest:g.manifest&&typeof g.manifest==="object"?g.manifest:{},confirmation:g.confirmation?String(g.confirmation):void 0,deleteData:g.deleteData===!0})},202)}catch(T){return d(T,422)}}}if(N.pathname.startsWith("/api/maintenance")){let d=(g,T=409)=>S({ok:!1,error:g instanceof Error?g.message:String(g)},T,{"cache-control":"no-store"});if(N.pathname==="/api/maintenance"&&I.method==="GET")return S({ok:!0,manifests:qi.manifests(a.organization.id),windows:qi.windows(a.project.id),campaigns:qi.campaigns(a.project.id).map((g)=>({campaign:g,targets:qi.targets(g.id)})),cleanups:qi.cleanups(a.project.id),drills:qi.drills(a.project.id)},200,{"cache-control":"no-store"});if(N.pathname==="/api/maintenance/cleanup-preview"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,plan:await Rd.previewCleanup({projectId:a.project.id,kind:String(g.kind??"operations"),criteria:{olderThanDays:Number(g.olderThanDays??30)}},up)},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/maintenance/cleanup-apply"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,...Rd.enqueueCleanup(String(g.planId??""),String(g.confirmation??""))},202)}catch(T){return d(T,422)}}if(N.pathname==="/api/maintenance/drill"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,drill:qi.createDrill({projectId:a.project.id,scenario:String(g.scenario??"control_plane"),isolatedTarget:String(g.isolatedTarget??""),expectedRpoMinutes:Number(g.expectedRpoMinutes??60),expectedRtoMinutes:Number(g.expectedRtoMinutes??30),recoveryPointId:g.recoveryPointId?String(g.recoveryPointId):void 0,topologyId:g.topologyId?String(g.topologyId):void 0})},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/maintenance/drill-run"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,...Rd.enqueueDrill(String(g.drillId??""))},202)}catch(T){return d(T,422)}}}if(N.pathname.startsWith("/api/volumes")){let d=a.environments.get(ye),g=Me(de).actor?.id,T=(_,L=409)=>S({ok:!1,error:_ instanceof Error?_.message:String(_)},L,{"cache-control":"no-store"});if(N.pathname==="/api/volumes"&&I.method==="GET"){let _=Ad.inventory(a.project.id,d?.id),L=a.store.listResources(a.project.id,d?.id).map((K)=>({id:K.id,name:K.name,slug:K.slug,kind:K.kind,provider:K.provider,providerId:K.providerId}));return S({ok:!0,volumes:_,resources:L,operations:kt.list({projectId:a.project.id,limit:100}).filter((K)=>K.operation.kind.startsWith("volume.")),recoveryPoints:sr.listRecoveryPoints(a.project.id).filter((K)=>K.kind==="volume"),providers:kd.map((K)=>({provider:K.provider,type:K.type,capabilities:K.capabilities()}))},200,{"cache-control":"no-store"})}if(N.pathname==="/api/volumes"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:_.resourceId?String(_.resourceId):void 0,name:String(_.name??""),provider:String(_.provider??"docker"),type:_.type==="docker"?"docker":_.type,capacityBytes:_.capacityBytes==null?void 0:Number(_.capacityBytes),filesystem:_.filesystem?String(_.filesystem):void 0,encrypted:_.encrypted===!0,desiredState:_.desiredState&&typeof _.desiredState==="object"?_.desiredState:{},actorId:g})},202,{"cache-control":"no-store"})}catch(L){return T(L,422)}}if(N.pathname==="/api/volumes/attach"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.attach(String(_.volumeId??""),{resourceId:String(_.resourceId??""),targetPath:String(_.targetPath??""),readOnly:_.readOnly===!0,uid:_.uid==null?void 0:Number(_.uid),gid:_.gid==null?void 0:Number(_.gid),mode:_.mode?String(_.mode):void 0,propagation:_.propagation,driverOptions:_.driverOptions&&typeof _.driverOptions==="object"?_.driverOptions:{},actorId:g})},202)}catch(L){return T(L,422)}}if(N.pathname==="/api/volumes/detach"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.detach(String(_.volumeId??""),String(_.attachmentId??""),{force:_.force===!0,drained:_.drained===!0,unmounted:_.unmounted===!0,confirmation:_.confirmation?String(_.confirmation):void 0,actorId:g})},202)}catch(L){return T(L)}}if(N.pathname==="/api/volumes/resize"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.resize(String(_.volumeId??""),Number(_.capacityBytes),{drained:_.drained===!0,actorId:g})},202)}catch(L){return T(L,422)}}if(N.pathname==="/api/volumes/snapshot"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.snapshot(String(_.volumeId??""),{name:_.name?String(_.name):void 0,actorId:g})},202)}catch(L){return T(L,422)}}if(N.pathname==="/api/volumes/restore"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.restore(String(_.snapshotId??""),{name:String(_.name??""),actorId:g})},202)}catch(L){return T(L,422)}}if(N.pathname==="/api/volumes/discover"&&I.method==="POST")try{return S({ok:!0,volumes:await Vi.discover({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,actorId:g})})}catch(_){return T(_,502)}if(N.pathname==="/api/volumes/adopt"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,volume:Vi.adopt(String(_.volumeId??""),{name:String(_.name??""),actorId:g})})}catch(L){return T(L,422)}}if(N.pathname==="/api/volumes"&&I.method==="DELETE"){let _=await oe(I),L=Bt.resolveSession(I);try{return S({ok:!0,...Vi.delete(String(_.volumeId??""),{recentAuthAt:!Re||L&&ve.isRecentlyAuthenticated(L)?new Date().toISOString():void 0,confirmation:_.confirmation?String(_.confirmation):void 0,backupOverride:_.backupOverride===!0,backupOverrideConfirmation:_.backupOverrideConfirmation?String(_.backupOverrideConfirmation):void 0,actorId:g})},202)}catch(K){return T(K)}}}if(N.pathname==="/api/backups"&&I.method==="GET"){let d=a.environments.get(ye),g=sr.listPolicies(a.project.id,d?.id),T=new Set(g.map((Q)=>Q.id)),_=sr.listRecoveryPoints(a.project.id).filter((Q)=>!Q.policyId||T.has(Q.policyId)),L=sr.listJobs(a.project.id).filter((Q)=>!Q.policyId||T.has(Q.policyId)),K=(Q)=>({...Q,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!Q.credentialRef,clientEncryptionConfigured:!!Q.encryptionKeyRef}),B=await Promise.all(sr.listDestinations(a.project.id).map(async(Q)=>({...K(Q),credentialStatus:await Vg(Q,Ui)})));return S({ok:!0,destinations:B,policies:g,recoveryPoints:_,jobs:L,coverage:sr.coverage(a.project.id).filter((Q)=>T.has(Q.policy.id)),resources:d?a.store.listResources(a.project.id,d.id).map((Q)=>({id:Q.id,name:Q.name,slug:Q.slug,kind:Q.kind})):[]})}if(N.pathname==="/api/backups/destinations"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim(),T=String(d.provider??""),_=String(d.encryption??"provider"),L=`secret://data-services/backups/${a.project.id}/${g}`,K=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(T))return S({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(_))return S({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let B,Q;if(d.credentials&&typeof d.credentials==="object"&&!Array.isArray(d.credentials))B=`${L}/credentials`,await Ui.put(B,JSON.stringify(d.credentials)),K.push(B);if(_!=="provider"){let ue=String(d.encryptionKey??"");if(ue.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");Q=`${L}/encryption-key`,await Ui.put(Q,ue),K.push(Q)}let fe=sr.createDestination({organizationId:a.organization.id,projectId:a.project.id,name:g,provider:T,endpoint:d.endpoint?String(d.endpoint):void 0,endpointPolicy:d.endpointPolicy==="allow_private"?"allow_private":"public_https",bucket:d.bucket?String(d.bucket):void 0,prefix:String(d.prefix??""),region:d.region?String(d.region):mo,forcePathStyle:d.forcePathStyle===!0,credentialRef:B,encryption:_,encryptionKeyRef:Q,immutability:d.immutability&&typeof d.immutability==="object"&&!Array.isArray(d.immutability)?d.immutability:{},status:"untested"});return S({ok:!0,destination:{...fe,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!B,clientEncryptionConfigured:!!Q}},201)}catch(B){for(let Q of K)await Ui.remove(Q).catch(()=>{});return S({ok:!1,error:B instanceof Error?B.message:String(B)},422)}}if(N.pathname==="/api/backups/destinations/test"&&I.method==="POST"){let d=await oe(I),g=sr.getDestination(String(d.id??""));if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Backup destination was not found."},404);if(g.provider==="aws_backup")return S({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await ap.test(g),S({ok:!0,destination:sr.recordDestinationTest(g.id,{ok:!0})})}catch(T){let _=T instanceof Error?T.message:String(T);return sr.recordDestinationTest(g.id,{ok:!1,error:_}),S({ok:!1,error:_},502)}}if(N.pathname==="/api/backups/policies"&&I.method==="POST"){let d=await oe(I),g=a.environments.get(ye),T=sr.getDestination(String(d.destinationId??"")),_=String(d.resourceKind??""),L=d.dataServiceId?String(d.dataServiceId):void 0,K=L?_t.get(L):void 0,B=d.resourceId?String(d.resourceId):void 0,Q=B?a.store.getResource(B):void 0;if(!g)return S({ok:!1,error:"Environment was not found."},404);if(!T||T.projectId!==a.project.id)return S({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(_))return S({ok:!1,error:"A supported backup resource kind is required."},422);if(L&&(!K||K.projectId!==a.project.id||K.environmentId!==g.id))return S({ok:!1,error:"Data service was not found in this environment."},404);if(B&&(!Q||Q.projectId!==a.project.id||Q.environmentId!==g.id))return S({ok:!1,error:"Resource was not found in this environment."},404);if(_==="managed_database"&&!K)return S({ok:!1,error:"Managed database policies require a data service."},422);if(_==="logical_database"&&(!K||!["container","server"].includes(K.provider)))return S({ok:!1,error:"Logical database policies require an on-box data service."},422);if(_==="volume"&&(!Q||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(d.volumeName??""))))return S({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let fe=Array.isArray(d.includePatterns)?d.includePatterns.map(String).filter(Boolean):[];if(_==="files"&&(!Q||!fe.length))return S({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(_==="control_plane"&&T.encryption==="provider")return S({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(_==="infrastructure"&&(T.provider!=="aws_backup"||!fe.some((ue)=>ue.startsWith("resource:arn:"))||!fe.some((ue)=>ue.startsWith("role:arn:"))))return S({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let ue=sr.createPolicy({organizationId:a.organization.id,projectId:a.project.id,environmentId:g.id,resourceId:B,dataServiceId:L,destinationId:T.id,name:String(d.name??"").trim(),resourceKind:_,schedule:String(d.schedule??"daily"),timezone:String(d.timezone??"UTC"),retention:d.retention&&typeof d.retention==="object"&&!Array.isArray(d.retention)?d.retention:{keepLast:7,expireAfterDays:30},compression:["none","gzip","zstd"].includes(String(d.compression))?d.compression:"gzip",encryption:["destination","client_side","both"].includes(String(d.encryption))?d.encryption:"destination",includePatterns:_==="volume"?[String(d.volumeName),...fe]:fe,excludePatterns:Array.isArray(d.excludePatterns)?d.excludePatterns.map(String):[],expectedRpoMinutes:Math.max(1,Number(d.expectedRpoMinutes)||1440),expectedRtoMinutes:Math.max(1,Number(d.expectedRtoMinutes)||120),healthCheckId:d.healthCheckId?String(d.healthCheckId):void 0,enabled:d.enabled!==!1});return S({ok:!0,policy:ue},201)}catch(ue){return S({ok:!1,error:ue instanceof Error?ue.message:String(ue)},422)}}if(N.pathname==="/api/backups/run"&&I.method==="POST"){let d=await oe(I),g=sr.getPolicy(String(d.policyId??"")),T=a.environments.get(ye);if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Backup policy was not found in this environment."},404);try{let _=jo.enqueueBackup(g,new Date().toISOString(),Me(de).actor?.id);return S({ok:!0,job:_},202)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:String(_)},409)}}if(N.pathname==="/api/backups/verify"&&I.method==="POST"){let d=await oe(I),g=sr.getRecoveryPoint(String(d.recoveryPointId??""));if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Recovery point was not found."},404);return S({ok:!0,job:jo.enqueueVerification(g)},202)}if(N.pathname==="/api/backups/restore"&&I.method==="POST"){let d=await oe(I),g=sr.getRecoveryPoint(String(d.recoveryPointId??"")),T=d.mode==="in_place"?"in_place":"isolated",_=d.target&&typeof d.target==="object"&&!Array.isArray(d.target)?{...d.target,inPlace:T==="in_place"}:{inPlace:T==="in_place"},L=Bt.resolveSession(I),K={mode:T,target:_,targetName:String(d.targetName??""),confirm:d.confirm?String(d.confirm):void 0,recentAuth:!Re||!!L&&ve.isRecentlyAuthenticated(L),downtimeAcknowledged:d.downtimeAcknowledged===!0,safetyBackupId:d.safetyBackupId?String(d.safetyBackupId):void 0};if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Recovery point was not found."},404);if(d.drill===!0&&T!=="isolated")return S({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let B=jo.planRestore(g,K);if(d.execute!==!0)return S({ok:!0,plan:B,executionCreated:!1});let Q=jo.enqueueRestore(g,{...K,drill:d.drill===!0,actorId:Me(de).actor?.id});return S({ok:!0,plan:B,job:Q},202)}catch(B){return S({ok:!1,error:B instanceof Error?B.message:String(B)},409)}}if(N.pathname==="/api/backups/recovery-points"&&I.method==="POST"){let d=await oe(I),g=sr.getRecoveryPoint(String(d.id??""));if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Recovery point was not found."},404);if(d.held==null&&d.pinned==null)return S({ok:!1,error:"held or pinned must be provided."},422);return S({ok:!0,recoveryPoint:sr.updateRecoveryPoint(g.id,{held:d.held==null?g.held:d.held===!0,pinned:d.pinned==null?g.pinned:d.pinned===!0})})}if(N.pathname==="/api/backups/retention"&&I.method==="POST")return S({ok:!0,jobs:jo.enqueueRetention()},202);if(N.pathname==="/api/data-services/capabilities"&&I.method==="GET"){let d=String(N.searchParams.get("engine")??""),g=String(N.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(d)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(g))return S({ok:!1,error:"A supported engine and provider are required."},422);return S({ok:!0,engine:d,provider:g,capabilities:Ht(d,g)})}if(N.pathname==="/api/data-services"&&I.method==="GET"){let d=a.environments.get(ye),g=_t.list(a.project.id,d?.id).map((T)=>{let _=_t.credential(T.id);return{...T,credentialRef:void 0,credential:_?{configured:!0,username:_.username,version:_.version,rotatedAt:_.rotatedAt}:void 0,dependencies:_t.dependencies(T.id).map((L)=>({resourceId:L.resourceId,requiresRedeploy:L.requiresRedeploy}))}});return S({ok:!0,services:g})}if(N.pathname==="/api/data-services/preview"&&I.method==="POST"){let d=await oe(I);if(d.id){let _=_t.get(String(d.id)),L=a.environments.get(ye),K=String(d.action??"");if(!_||_.projectId!==a.project.id||_.environmentId!==L?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!Id.includes(K))return S({ok:!1,error:`Action must be one of: ${Id.join(", ")}.`},422);try{return S({ok:!0,plan:Va.plan(_,K,d.changes??{})})}catch(B){return S({ok:!1,error:B instanceof Error?B.message:String(B)},422)}}let g=String(d.engine??""),T=String(d.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(g)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return S({ok:!1,error:"A supported engine and provider are required."},422);return S({ok:!0,capabilities:Ht(g,T),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(N.pathname==="/api/data-services"&&I.method==="POST"){let d=await oe(I),g=String(d.engine??""),T=String(d.provider??""),_=a.environments.get(ye),L=Me(de);if(!_)return S({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(g)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return S({ok:!1,error:"A supported engine and provider are required."},422);let K={organizationId:a.organization.id,projectId:a.project.id,environmentId:_.id,resourceId:d.resourceId?String(d.resourceId):void 0,name:String(d.name??"").trim(),engine:g,provider:T,placement:String(d.placement??d.name??"").trim(),engineVersion:d.engineVersion?String(d.engineVersion):void 0,plan:String(d.plan??(T==="aws_elasticache"?"cache.t4g.micro":T==="aws_aurora"?"db.serverless":"db.t4g.micro")),storageGb:d.storageGb==null?void 0:Number(d.storageGb),highAvailability:d.highAvailability===!0,publicExposure:d.publicExposure===!0,allowedCidrs:Array.isArray(d.allowedCidrs)?d.allowedCidrs.map(String):[],desiredState:d.desiredState&&typeof d.desiredState==="object"&&!Array.isArray(d.desiredState)?d.desiredState:{},observedState:{},origin:d.adopt===!0?"adopted":"managed",managementEnabled:d.adopt!==!0,ownerActorId:L.actor?.id,username:d.username?String(d.username):void 0};try{if(d.adopt===!0){let Q=_t.create({...K,status:"adopted",credentialRef:void 0});return S({ok:!0,service:Q,readOnly:!0},201)}if(!sp({provider:T,engine:g}))return S({ok:!1,error:`No ${T}/${g} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let B=await Va.create(K);return S({ok:!0,service:B.service,operationId:B.operationId,oneTimeCredential:B.credential},201)}catch(B){return S({ok:!1,error:B instanceof Error?B.message:String(B)},422)}}if(N.pathname==="/api/data-services/connections"&&I.method==="GET"){let d=_t.get(String(N.searchParams.get("id")??"")),g=a.environments.get(ye);if(!d||d.projectId!==a.project.id||d.environmentId!==g?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);let T=typeof d.observedState.endpoint==="string"?d.observedState.endpoint:void 0,_=typeof d.observedState.readerEndpoint==="string"?d.observedState.readerEndpoint:void 0,L=Number(d.observedState.port)||(d.engine==="postgres"?5432:d.engine==="redis"?6379:d.engine==="mongodb"?27017:d.engine==="libsql"?8080:3306),K=typeof d.observedState.database==="string"?d.observedState.database:void 0,B=typeof d.observedState.tls==="boolean"?d.observedState.tls:d.provider.startsWith("aws_"),Q=[...T?[{type:d.publicExposure?"external":"internal",host:T,port:L,database:K,tls:B}]:[],..._?[{type:"internal",host:_,port:L,database:K,tls:B}]:[],{type:"tunnel",host:T??d.placement,port:L,database:K,tls:B}];return S({ok:!0,serviceId:d.id,guidance:vn(d,Q)})}if(N.pathname==="/api/data-services/action"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye),_=String(d.action??"");if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!Id.includes(_))return S({ok:!1,error:`Action must be one of: ${Id.join(", ")}.`},422);let L=d.changes&&typeof d.changes==="object"&&!Array.isArray(d.changes)?d.changes:{};try{let K=Va.plan(g,_,L);if(d.execute!==!0)return S({ok:!0,plan:K,productionExecutionCreated:!1});let B=Va.enqueue(g,_,L,Me(de).actor?.id);return S({ok:!0,plan:K,operationId:B},202)}catch(K){return S({ok:!1,error:K instanceof Error?K.message:String(K)},409)}}if(N.pathname==="/api/data-services/dependencies"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye),_=a.store.getResource(String(d.resourceId??""));if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!_||_.projectId!==a.project.id||_.environmentId!==T?.id)return S({ok:!1,error:"Dependent resource was not found in this environment."},404);if(d.remove===!0)return S({ok:_t.removeDependency(g.id,_.id)});return _t.addDependency({serviceId:g.id,resourceId:_.id,secretRef:g.credentialRef??`secret://data-services/${g.projectId}/${g.name}`,requiresRedeploy:d.requiresRedeploy!==!1}),S({ok:!0,dependencies:_t.dependencies(g.id).map((L)=>({resourceId:L.resourceId,requiresRedeploy:L.requiresRedeploy}))})}if(N.pathname==="/api/data-services/management"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye);if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(g.origin!=="adopted"||d.reviewed!==!0||d.confirm!==g.name)return S({ok:!1,error:`Enabling management requires reviewed=true and typing ${g.name}.`},409);return S({ok:!0,service:_t.update(g.id,g.version,{managementEnabled:!0})})}if(N.pathname==="/api/data-services/reveal"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye),_=g?_t.credential(g.id):void 0;if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!_)return S({ok:!1,error:"No managed credential is configured."},404);return S({ok:!0,credential:{username:_.username,password:await Ui.resolve(_.secretRef),version:_.version}},200,{"cache-control":"no-store"})}if(N.pathname==="/api/databases"&&I.method==="GET")return S(await Oh(o,ye));if(N.pathname==="/api/databases"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim();if(!uo(g))return S({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return S({...await _h(o,ye,g),name:g})}if(N.pathname==="/api/databases/vitess"&&I.method==="GET"){let d=await Lh(o,ye);return S({...d,unhealthy:Bh(d.tablets),missingPrimary:jh(d)})}if(N.pathname==="/api/databases/vitess/provision"&&I.method==="POST"){let d=await oe(I);try{return S(await Gh(o,ye,{keyspace:String(d.keyspace??""),username:String(d.username??""),password:String(d.password??""),sharded:d.sharded===!0,confirm:String(d.confirm??"")}))}catch(g){return S({ok:!1,error:g instanceof Error?g.message:String(g)},422)}}if(N.pathname==="/api/databases/vitess/migrations"&&I.method==="GET"){let d=N.searchParams.get("keyspace")??void 0;return S(await Wh(o,ye,d))}if(N.pathname==="/api/databases/vitess/migrations/action"&&I.method==="POST"){let d=await oe(I),g=String(d.uuid??"").trim(),T=String(d.action??"");if(!["retry","cancel","cleanup","complete"].includes(T))return S({ok:!1,error:"Unknown migration action."},422);return S(await Hh(o,ye,g,T))}if(N.pathname==="/api/databases/vitess/keyspaces"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim(),T=d.sharded===!0;return S(await Vh(o,ye,g,{sharded:T}))}if(N.pathname==="/api/databases/vitess/vschema"&&I.method==="POST"){let d=await oe(I),g=String(d.keyspace??"").trim(),T=typeof d.vschema==="string"?d.vschema:JSON.stringify(d.vschema??null);return S(await qh(o,ye,g,T))}if(N.pathname==="/api/databases/vitess/schema"&&I.method==="POST"){let d=await oe(I),g=String(d.sql??"");return S(await Jh(o,ye,g))}if(N.pathname==="/api/databases/vitess/install-client"&&I.method==="POST")return S(await zh(o,ye));if(N.pathname==="/api/databases/backups"&&I.method==="GET")return S(await Mh(o,ye));if(N.pathname==="/api/databases/backup"&&I.method==="POST"){let d=await oe(I),g=String(d.database??"").trim();if(!uo(g))return S({ok:!1,error:"Database name must be a valid identifier."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to back up this database.`},409);return S(await $h(o,ye,g))}if(N.pathname==="/api/databases/users"&&I.method==="POST"){let d=await oe(I),g=String(d.username??"").trim(),T=String(d.password??""),_=String(d.database??"").trim()||void 0,L=d.access==="readonly"?"readonly":"all";if(!uo(g))return S({ok:!1,error:"Username must be a valid identifier."},422);if(!T)return S({ok:!1,error:"Password is required."},422);if(_&&!uo(_))return S({ok:!1,error:"Database must be a valid identifier."},422);return S({...await Nh(o,ye,{username:g,password:T,database:_,access:L}),username:g})}if(N.pathname==="/api/dashboard-data")return Mt=q.get(ye)??await Ze(ye),Ze(ye),S(ql(Mt,{user:si,slug:o.project.slug}));if(N.pathname==="/api/users"&&I.method==="GET")return S({ok:!0,users:Fn(t).map(ta)});if(N.pathname==="/api/users"&&I.method==="POST"){let d=await oe(I),g=String(d.username??"").trim();if(!fd(g))return S({ok:!1,error:"Username must be 2-32 characters: letters, numbers, dot, dash or underscore."},422);let T=d.sites&&typeof d.sites==="object"?d.sites:{},_=new Set(Object.keys(o.sites??{})),L={};for(let[Q,fe]of Object.entries(T)){if(!_.has(Q))return S({ok:!1,error:`Site '${Q}' was not found.`},404);if(fe!=="owner"&&fe!=="collaborator")return S({ok:!1,error:`Unknown site role '${fe}'. Use 'owner' or 'collaborator'.`},422);L[Q]=fe}let K=typeof d.password==="string"&&d.password.trim()?d.password.trim():void 0;if(K&&K.length<12)return S({ok:!1,error:"Password must be at least 12 characters."},422);let B=La(t,{username:g,password:K,name:typeof d.name==="string"?d.name:void 0,sites:L});return sd(a,Fn(t)),gi(),S({ok:!0,user:ta(B.user),password:B.password})}if(N.pathname==="/api/users"&&I.method==="DELETE"){let d=await oe(I),g=String(d.username??"").trim();if(g.toLowerCase()===de.username.toLowerCase())return S({ok:!1,error:"You cannot remove your own account."},409);let T=pi(Fn(t),g),_=T?a.store.getActorByExternalId("user",`dashboard:${T.username.toLowerCase()}`):void 0,L=_?a.store.getMembershipForActor(a.organization.id,_.id):void 0;if(L&&L.source!=="legacy")return S({ok:!1,error:"Organization members must be removed from Organization access."},409);let K=zl(t,g);if(!K.ok)return S(K,409);return sd(a,Fn(t)),Ae.clear(),S({ok:!0,username:g})}if(N.pathname==="/api/actions/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=d.action?sA(d.action,ye):void 0;if(!g)return S({ok:!1,error:"Unknown dashboard action."},404);if(g.mutates&&d.confirm!==g.confirm)return S({ok:!1,error:`Type "${g.confirm}" to run this action.`},409);let T=await ao({controlPlane:a,environment:ye,actor:de,kind:`dashboard.action.${g.id}`,input:{action:g.id},execute:()=>np(g,{cwd:t,cliEntry:i})});return S({...T.result,controlPlaneOperation:T.operation})}if(N.pathname==="/api/server/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=d.operation?_n(d.operation,o,Mt):void 0;if(!g)return S({ok:!1,error:"Unknown or unavailable server operation."},404);if(g.mutates&&d.confirm!==g.confirm)return S({ok:!1,error:`Type "${g.confirm}" to run this operation.`},409);let T=ae(a,String(ye));await new ps(et).run(new Oa,{...T,artifactRoot:t});let _=Zt(et,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(_.decision.outcome==="block")return S({ok:!1,error:`Operation blocked by security policy: ${_.decision.explanation}`,securityReview:_},409);let L=await ao({controlPlane:a,environment:ye,actor:de,kind:`dashboard.server.${g.id}`,resourceSlug:g.target,input:{operation:g.id,target:g.target,to:d.to??null},execute:()=>kr(o,ye,g,{to:d.to})});return S({...L.result,controlPlaneOperation:L.operation,securityReview:_})}if(N.pathname==="/api/server/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return S({ok:!1,error:'Type "run" to execute this command on the server.'},409);let g=await ao({controlPlane:a,environment:ye,actor:de,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>Qt(o,ye,String(d.command??""))});return S({...g.result,controlPlaneOperation:g.operation})}if(N.pathname==="/api/serverless/operations")return S(Kl(o,ye,Mt));if(N.pathname==="/api/serverless/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=d.operation?Cy(d.operation,o,ye,Mt):void 0;if(!g)return S({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(g.mutates&&d.confirm!==g.confirm)return S({ok:!1,error:`Type "${g.confirm}" to run this operation.`},409);let T=await ao({controlPlane:a,environment:ye,actor:de,kind:`dashboard.serverless.${g.id}`,input:{operation:g.id,min:d.min??null,max:d.max??null},execute:()=>Ey(o,ye,g,{min:d.min,max:d.max})});return Mt=await bs(o,ye),q.set(ye,Mt),S({...T.result,controlPlaneOperation:T.operation})}if(N.pathname==="/api/serverless/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return S({ok:!1,error:'Type "run" to execute this command.'},409);return S(await Ty(o,ye,String(d.command??"")))}if(N.pathname==="/api/serverless/dlq"&&I.method==="GET"){let d=Number(N.searchParams.get("max"))||10;return S(await Ay(o,ye,d))}if(N.pathname==="/api/serverless/dlq/redrive"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="redrive")return S({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return S(await ky(o,ye,{max:d.max,targetQueue:d.targetQueue}))}if(N.pathname==="/api/serverless/dlq/purge"&&I.method==="POST"){if((await I.json().catch(()=>({}))).confirm!=="purge")return S({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return S(await Ry(o,ye))}if(N.pathname==="/api/serverless/secrets"&&I.method==="GET")return S({secrets:Py(o,ye)});if(N.pathname==="/api/serverless/secrets"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.secretId??"").trim();if(!g)return S({ok:!1,error:"A secret id is required."},422);if(typeof d.value!=="string"||d.value==="")return S({ok:!1,error:"A non-empty value is required."},422);return S(await xy(o,ye,g,d.value))}if(N.pathname==="/api/serverless/secrets"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),g=String(d.secretId??"").trim();if(!g)return S({ok:!1,error:"A secret id is required."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to delete this secret.`},409);return S(await Dy(o,ye,g))}if(N.pathname==="/api/serverless/functions/config"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.mode??"").trim();if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to update this function.`},409);return S(await Oy(o,ye,g,{memory:d.memory,timeout:d.timeout}))}if(N.pathname==="/api/serverless/alarms"&&I.method==="GET")return S(await _y(o,ye));if(N.pathname==="/api/serverless/alarms"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.preset??"").trim(),T=Number(d.threshold);if(!g)return S({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(T))return S({ok:!1,error:"A numeric threshold is required."},422);return S(await Ny(o,ye,g,T))}if(N.pathname==="/api/serverless/alarms"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),g=String(d.name??"").trim();if(!g)return S({ok:!1,error:"An alarm name is required."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to delete this alarm.`},409);return S(await $y(o,ye,g))}if(N.pathname==="/api/serverless/traces"&&I.method==="GET"){let d=Number(N.searchParams.get("minutes"))||30;return S(await Sd(o,ye,d))}if(N.pathname==="/api/serverless/scheduler"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.action??"").trim();if(g!=="enable"&&g!=="disable"&&g!=="run")return S({ok:!1,error:"Unknown scheduler action."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to ${g} the scheduler.`},409);return S(await Xl(o,ye,g))}if(!ab(N.pathname,si))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(ye)}`}});let Ts=await Pi(de,ye);if(!Ts)return Ed("ts-cloud dashboard UI is unavailable.",503);return cb(Ts,N.pathname)}catch(Uo){if(e.verbose)console.error(Uo);return S({ok:!1,error:Uo?.message??String(Uo)},500)}})();if(!ir)return ir;if(mt&&(N.pathname.startsWith("/api/")||N.pathname.startsWith("/auth/"))){let Ye;if((we.headers.get("content-type")||"").includes("application/json"))Ye=await we.json().catch(()=>{return});let Br=Bt.resolveUser(I),wr=Br?Me(Br).actor:void 0;a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,actorId:wr?.id,correlationId:Je,type:ir.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:ir.status<400?"info":"warning",payload:qT(I.method,N.pathname,Ye,ir.status,Date.now()-Ne)})}return ir.headers.set("x-request-id",Je),ir}});qa?.start();let Eb=e.spendLoop??!0,Cp;if(Eb)(async()=>{let{SpendRunner:I,SpendLoopLease:Ee,startSpendLoop:Ne}=await import("./chunk-bdgkeqv6.js"),{store:we}=await ub(a.store),Je=new I({controlPlane:a.store,store:we,alerts:Ge});Cp=Ne(Je,{lease:new Ee(a.store,{owner:`dashboard:${process.pid}`}),onError:(mt)=>console.error(`[ts-cloud] spend cycle failed: ${mt instanceof Error?mt.message:String(mt)}`)})})();let Tb=Is.stop.bind(Is);return Is.stop=(I)=>{clearInterval(Sp),clearInterval(vp),clearInterval(wp),clearInterval(bp),clearInterval(yp),clearInterval(gp),clearInterval(mp),clearInterval(fp),clearInterval(hp),gi(),ar.clear(),qa?.stop(),Cp?.();let Ee=Tb(I);if(qa)qa.settled().finally(()=>a.store.close());else a.store.close();return Ee},{server:Is,url:`http://${r}:${Is.port}/`}}
510
+ `);return new Response(Xe,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(N.pathname==="/api/telemetry/saved-queries"&&I.method==="GET"){let be=Me(de);return S({ok:!0,queries:g.listSavedQueries(a.project.id,be.actor?.id)})}if(N.pathname==="/api/telemetry/saved-queries"&&I.method==="POST"){let be=await oe(I),Le=Me(de);return S({ok:!0,query:g.saveQuery(a.project.id,Le.actor?.id,String(be.name??""),Q(be.query??be))},201)}if(N.pathname==="/api/telemetry/saved-queries"&&I.method==="DELETE"){let be=await oe(I),Le=Me(de),Se=g.deleteSavedQuery(a.project.id,Le.actor?.id,String(be.id??""));return S({ok:Se},Se?200:404)}}if(N.pathname.startsWith("/api/configuration")){let d=a.environments.get(ye),g=de.role==="admin"||!!si.capabilities?.includes("secrets:read"),T=de.role==="admin"||!!si.capabilities?.includes("secrets:write"),_={projectId:a.project.id,environmentId:d?.id},M={"cache-control":"no-store"};if(N.pathname==="/api/configuration"&&I.method==="GET"){let K=Object.fromEntries(N.searchParams),B=K.scopeType||K.scopeId?sa(K,_):void 0,Q=["variable","secret"].includes(String(K.kind))?K.kind:void 0,fe=B?.type==="preview"?nr.previews.getInstance(B.id):void 0,ue=fe?nr.previews.getDefinition(fe.definitionId):void 0,He=B?await Jn.resolve({projectId:a.project.id,environmentId:B.environmentId,resourceId:B.resourceId,functionId:B.type==="function"?B.id:void 0,previewId:B.previewId,trustedPreview:!!fe&&!fe.fork,allowedPreviewSecrets:ue?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:g}):void 0,be=a.store.listResources(a.project.id);return S({ok:!0,entries:Jn.list({projectId:a.project.id,scope:B,kind:Q,search:K.search,canReadSecretMetadata:g}),effectiveEntries:He?Object.values(He.entries).filter((Le)=>!Q||Le.kind===Q).filter((Le)=>!K.search||Le.key.toLowerCase().includes(String(K.search).toLowerCase())):[],configurationHash:He?.configurationHash,warnings:He?.warnings??[],scopes:{project:a.project,environments:a.store.listEnvironments(a.project.id),resources:be.filter((Le)=>Le.kind!=="function"),functions:be.filter((Le)=>Le.kind==="function"),previews:nr.previews.listInstances({projectId:a.project.id}).filter((Le)=>Le.status!=="destroyed").map((Le)=>({id:Le.id,name:Le.name,environmentId:Le.baseEnvironmentId,resourceId:Le.resourceId,fork:Le.fork,status:Le.status}))}},200,M)}if(N.pathname==="/api/configuration/export"&&I.method==="GET"){let K=sa(Object.fromEntries(N.searchParams),_);return new Response(Jn.exportVariables({projectId:a.project.id,scope:K}),{headers:{...M,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(N.pathname==="/api/configuration/plan"&&I.method==="POST"){let K=await oe(I),B=sa(K,_),Q=K.values&&typeof K.values==="object"&&!Array.isArray(K.values)?Object.fromEntries(Object.entries(K.values).map(([fe,ue])=>[fe,String(ue)])):{};return S({ok:!0,plan:Jn.plan({projectId:a.project.id,scope:B,values:Q,removeMissing:K.removeMissing===!0})},200,M)}if(N.pathname==="/api/configuration"&&I.method==="POST"){let K=await oe(I),B=sa(K,_),Q=K.kind==="secret"?"secret":"variable",fe=String(K.key??"");if(Q==="secret"&&!T)return S({ok:!1,error:"Secret write permission is required."},403,M);try{let ue=await Jn.set({organizationId:a.organization.id,projectId:a.project.id,scope:B,key:fe,kind:Q,value:K.value==null?void 0:String(K.value),reference:K.reference==null?void 0:String(K.reference),backend:K.backend,required:K.required===!0,expectedVersion:K.expectedVersion==null?void 0:Number(K.expectedVersion),confirmed:String(K.confirm??"")===fe,idempotencyKey:I.headers.get("idempotency-key")??K.idempotencyKey,actorId:Me(de).actor?.id});return S({ok:!0,entry:Jn.list({projectId:a.project.id,scope:B,canReadSecretMetadata:g}).find((He)=>He.id===ue.entry.id),mutation:ue.mutation,warnings:ue.warnings},ue.mutation.added.length?201:200,M)}catch(ue){return S({ok:!1,error:ue instanceof Error?ue.message:String(ue)},409,M)}}if(N.pathname==="/api/configuration/import"&&I.method==="POST"){let K=await oe(I),B=sa(K,_),Q=Array.isArray(K.secretKeys)?K.secretKeys.map(String):[];if(Q.length&&!T)return S({ok:!1,error:"Secret write permission is required."},403,M);try{let fe=await Jn.importDotenv({organizationId:a.organization.id,projectId:a.project.id,scope:B,source:String(K.source??""),secretKeys:Q,backend:K.backend,confirmed:K.confirm==="import",idempotencyKey:I.headers.get("idempotency-key")??K.idempotencyKey,actorId:Me(de).actor?.id});return S({ok:fe.document.valid,diagnostics:fe.document.diagnostics,mutation:fe.mutation,warnings:fe.warnings},fe.document.valid?200:422,M)}catch(fe){return S({ok:!1,error:fe instanceof Error?fe.message:String(fe)},409,M)}}if(N.pathname==="/api/configuration/dependencies"&&I.method==="POST"){let K=await oe(I),B=go.get(String(K.entryId??"")),Q=a.store.getResource(String(K.resourceId??""));if(!B||B.projectId!==a.project.id||!Q||Q.projectId!==a.project.id)return S({ok:!1,error:"Configuration entry or dependent resource was not found."},404,M);return S({ok:!0,dependency:go.setDependency({entryId:B.id,resourceId:Q.id,injectionTarget:["native_reference","file"].includes(String(K.injectionTarget))?K.injectionTarget:"environment",required:K.required!==!1,requiresRedeploy:K.requiresRedeploy!==!1,lastDeployedVersion:K.lastDeployedVersion==null?void 0:Number(K.lastDeployedVersion)})},200,M)}if(N.pathname==="/api/configuration/transfer"&&I.method==="POST"){let K=await oe(I),B=go.get(String(K.id??"")),Q=sa({...K,scopeType:K.targetScopeType,scopeId:K.targetScopeId},_);if(!B||B.projectId!==a.project.id)return S({ok:!1,error:"Configuration entry was not found."},404,M);if(B.kind==="secret"&&!T)return S({ok:!1,error:"Secret write permission is required."},403,M);try{let fe=await Jn.transfer({entryId:B.id,targetScope:Q,mode:K.mode==="move"?"move":"copy",confirmed:K.confirm===B.key,actorId:Me(de).actor?.id,idempotencyKey:I.headers.get("idempotency-key")??K.idempotencyKey});return S({ok:!0,entry:Jn.list({projectId:a.project.id,scope:Q,canReadSecretMetadata:g}).find((ue)=>ue.id===fe.entry.id),mutation:fe.mutation},200,M)}catch(fe){return S({ok:!1,error:fe instanceof Error?fe.message:String(fe)},409,M)}}if(N.pathname==="/api/configuration/bulk"&&I.method==="POST"){let K=await oe(I),B=Array.isArray(K.ids)?K.ids.map(String).slice(0,500):[],Q=B.map((ue)=>go.get(ue)).filter((ue)=>!!ue&&ue.projectId===a.project.id);if(Q.length!==B.length)return S({ok:!1,error:"One or more configuration entries were not found."},404,M);if(Q.some((ue)=>ue.kind==="secret")&&!T)return S({ok:!1,error:"Secret write permission is required."},403,M);if(K.action!=="delete"||K.confirm!=="bulk")return S({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,M);let fe=[];try{for(let ue of Q)fe.push(await Jn.remove({entryId:ue.id,expectedVersion:ue.version,confirmed:!0,actorId:Me(de).actor?.id}));return S({ok:!0,removed:fe.flatMap((ue)=>ue.removed),affectedResourceIds:[...new Set(fe.flatMap((ue)=>ue.affectedResourceIds))].sort()},200,M)}catch(ue){return S({ok:!1,error:ue instanceof Error?ue.message:String(ue),partial:fe.flatMap((He)=>He.removed)},409,M)}}if(N.pathname==="/api/configuration/reveal"&&I.method==="POST"){let K=await oe(I),B=Bt.resolveSession(I);try{return S({ok:!0,value:await Jn.reveal({entryId:String(K.id??""),canRevealSecrets:g,recentlyAuthenticated:!Re||!!B&&ve.isRecentlyAuthenticated(B),actorId:Me(de).actor?.id})},200,M)}catch(Q){return S({ok:!1,error:Q instanceof Error?Q.message:String(Q)},403,M)}}if(N.pathname==="/api/configuration"&&I.method==="DELETE"){let K=await oe(I),B=go.get(String(K.id??""));if(B?.kind==="secret"&&!T)return S({ok:!1,error:"Secret write permission is required."},403,M);if(!B||B.projectId!==a.project.id)return S({ok:!1,error:"Configuration entry was not found."},404,M);try{return S({ok:!0,mutation:await Jn.remove({entryId:B.id,expectedVersion:Number(K.expectedVersion),confirmed:String(K.confirm??"")===B.key,actorId:Me(de).actor?.id})},200,M)}catch(Q){return S({ok:!1,error:Q instanceof Error?Q.message:String(Q)},409,M)}}}if(N.pathname.startsWith("/api/fleet")){let d=Me(de).actor?.id,g=(T,_=409)=>S({ok:!1,error:T instanceof Error?T.message:String(T)},_,{"cache-control":"no-store"});if(N.pathname==="/api/fleet"&&I.method==="GET")return S({ok:!0,servers:ua.list(a.project.id),resources:a.store.listResources(a.project.id),operations:kt.list({projectId:a.project.id,limit:200}).filter((T)=>T.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(N.pathname==="/api/fleet"&&I.method==="POST"){let T=await oe(I);try{return S({ok:!0,server:Oi.enroll({organizationId:a.organization.id,projectId:a.project.id,name:String(T.name??""),provider:["aws","hetzner"].includes(String(T.provider))?T.provider:"ssh",providerId:T.providerId?String(T.providerId):void 0,region:T.region?String(T.region):void 0,zone:T.zone?String(T.zone):void 0,endpoint:String(T.endpoint??""),sshUser:String(T.sshUser??"deploy"),sshPort:T.sshPort?Number(T.sshPort):22,credentialRef:String(T.credentialRef??""),roles:Array.isArray(T.roles)?T.roles:[],labels:T.labels&&typeof T.labels==="object"?T.labels:{}})},201)}catch(_){return g(_,422)}}if(N.pathname==="/api/fleet/action"&&I.method==="POST"){let T=await oe(I),_=String(T.id??""),M=String(T.action??"");try{if(M==="test")return S({ok:!0,server:await Oi.test(_)});if(M==="validate")return S({ok:!0,server:await Oi.validate(_)});if(M==="review_host_key")return S({ok:!0,server:Oi.reviewHostKey(_,String(T.fingerprint??""))});if(M==="bootstrap")return S({ok:!0,...Oi.bootstrap(_,T.confirmed===!0)},T.confirmed===!0?202:200);if(M==="heartbeat")return S({ok:!0,server:Oi.heartbeat(_,{usage:T.usage&&typeof T.usage==="object"?T.usage:{}})});if(M==="drain")return S({ok:!0,server:Oi.drain(_,T.completed===!0)});if(M==="uncordon")return S({ok:!0,server:Oi.uncordon(_)});if(M==="archive")return S({ok:!0,server:Oi.archive(_,String(T.confirmation??""))});return g("Unsupported fleet action.",422)}catch(K){return g(K)}}}if(N.pathname.startsWith("/api/capacity")){let d=(g,T=409)=>S({ok:!1,error:g instanceof Error?g.message:String(g)},T,{"cache-control":"no-store"});if(N.pathname==="/api/capacity"&&I.method==="GET")return S({ok:!0,pools:fo.listPools(a.project.id),placements:fo.listPlacements(a.project.id),servers:ua.list(a.project.id)},200,{"cache-control":"no-store"});if(N.pathname==="/api/capacity"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,pool:fo.createPool({organizationId:a.organization.id,projectId:a.project.id,name:String(g.name??""),purpose:String(g.purpose??"application"),backend:String(g.backend??"server"),region:g.region?String(g.region):void 0,architecture:g.architecture?String(g.architecture):void 0,labels:g.labels&&typeof g.labels==="object"?g.labels:{},requiredServerLabels:g.requiredServerLabels&&typeof g.requiredServerLabels==="object"?g.requiredServerLabels:{},toleratedTaints:Array.isArray(g.toleratedTaints)?g.toleratedTaints.map(String):[],capacity:g.capacity&&typeof g.capacity==="object"?g.capacity:{},maxWorkloads:Number(g.maxWorkloads??10),costWeight:Number(g.costWeight??1),spreadKey:g.spreadKey?String(g.spreadKey):void 0,concurrency:Number(g.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/capacity/member"&&I.method==="POST"){let g=await oe(I);try{return fo.addMember(String(g.poolId??""),String(g.serverId??"")),S({ok:!0,pool:fo.getPool(String(g.poolId??""))})}catch(T){return d(T,422)}}if(N.pathname==="/api/capacity/explain"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,decisions:cp.explain(a.project.id,{purpose:String(g.purpose??"application"),resources:g.resources&&typeof g.resources==="object"?g.resources:{},region:g.region?String(g.region):void 0,architecture:g.architecture?String(g.architecture):void 0,labels:g.labels&&typeof g.labels==="object"?g.labels:{}})})}catch(T){return d(T,422)}}if(N.pathname==="/api/capacity/action"&&I.method==="POST"){let g=await oe(I);try{if(g.action==="drain")return S({ok:!0,...cp.drainPool(String(g.poolId??""))});if(g.action==="enable")return S({ok:!0,pool:fo.updatePool(String(g.poolId??""),{status:"active"})});if(g.action==="disable")return S({ok:!0,pool:fo.updatePool(String(g.poolId??""),{status:"disabled"})});return d("Unsupported capacity action.",422)}catch(T){return d(T,422)}}}if(N.pathname.startsWith("/api/regions")){let d=(g,T=409)=>S({ok:!1,error:g instanceof Error?g.message:String(g)},T,{"cache-control":"no-store"});if(N.pathname==="/api/regions"&&I.method==="GET")return S({ok:!0,topologies:Fo.list(a.project.id).map((g)=>({topology:g,targets:Fo.targets(g.id),channels:Fo.channels(g.id),route:Fo.route(g.id),executions:Fo.executions(g.id)}))},200,{"cache-control":"no-store"});if(N.pathname==="/api/regions"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,topology:dp.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:a.environments.get(ye)?.id,name:String(g.name??""),hostname:String(g.hostname??""),regions:Array.isArray(g.regions)?g.regions:[],trafficPolicy:g.trafficPolicy==="weighted"||g.trafficPolicy==="latency"?g.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(g.replicate)?g.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(g.maxLagSeconds??30),retainOnDestroy:g.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:g.cdnEnabled===!0,wafEnabled:g.wafEnabled===!0})},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/regions/action"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,...dp.enqueue({topologyId:String(g.topologyId??""),kind:String(g.action??""),targetRegion:g.targetRegion?String(g.targetRegion):void 0,revision:g.revision?String(g.revision):void 0,manifest:g.manifest&&typeof g.manifest==="object"?g.manifest:{},confirmation:g.confirmation?String(g.confirmation):void 0,deleteData:g.deleteData===!0})},202)}catch(T){return d(T,422)}}}if(N.pathname.startsWith("/api/maintenance")){let d=(g,T=409)=>S({ok:!1,error:g instanceof Error?g.message:String(g)},T,{"cache-control":"no-store"});if(N.pathname==="/api/maintenance"&&I.method==="GET")return S({ok:!0,manifests:qi.manifests(a.organization.id),windows:qi.windows(a.project.id),campaigns:qi.campaigns(a.project.id).map((g)=>({campaign:g,targets:qi.targets(g.id)})),cleanups:qi.cleanups(a.project.id),drills:qi.drills(a.project.id)},200,{"cache-control":"no-store"});if(N.pathname==="/api/maintenance/cleanup-preview"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,plan:await Rd.previewCleanup({projectId:a.project.id,kind:String(g.kind??"operations"),criteria:{olderThanDays:Number(g.olderThanDays??30)}},up)},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/maintenance/cleanup-apply"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,...Rd.enqueueCleanup(String(g.planId??""),String(g.confirmation??""))},202)}catch(T){return d(T,422)}}if(N.pathname==="/api/maintenance/drill"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,drill:qi.createDrill({projectId:a.project.id,scenario:String(g.scenario??"control_plane"),isolatedTarget:String(g.isolatedTarget??""),expectedRpoMinutes:Number(g.expectedRpoMinutes??60),expectedRtoMinutes:Number(g.expectedRtoMinutes??30),recoveryPointId:g.recoveryPointId?String(g.recoveryPointId):void 0,topologyId:g.topologyId?String(g.topologyId):void 0})},201)}catch(T){return d(T,422)}}if(N.pathname==="/api/maintenance/drill-run"&&I.method==="POST"){let g=await oe(I);try{return S({ok:!0,...Rd.enqueueDrill(String(g.drillId??""))},202)}catch(T){return d(T,422)}}}if(N.pathname.startsWith("/api/volumes")){let d=a.environments.get(ye),g=Me(de).actor?.id,T=(_,M=409)=>S({ok:!1,error:_ instanceof Error?_.message:String(_)},M,{"cache-control":"no-store"});if(N.pathname==="/api/volumes"&&I.method==="GET"){let _=Ad.inventory(a.project.id,d?.id),M=a.store.listResources(a.project.id,d?.id).map((K)=>({id:K.id,name:K.name,slug:K.slug,kind:K.kind,provider:K.provider,providerId:K.providerId}));return S({ok:!0,volumes:_,resources:M,operations:kt.list({projectId:a.project.id,limit:100}).filter((K)=>K.operation.kind.startsWith("volume.")),recoveryPoints:sr.listRecoveryPoints(a.project.id).filter((K)=>K.kind==="volume"),providers:kd.map((K)=>({provider:K.provider,type:K.type,capabilities:K.capabilities()}))},200,{"cache-control":"no-store"})}if(N.pathname==="/api/volumes"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:_.resourceId?String(_.resourceId):void 0,name:String(_.name??""),provider:String(_.provider??"docker"),type:_.type==="docker"?"docker":_.type,capacityBytes:_.capacityBytes==null?void 0:Number(_.capacityBytes),filesystem:_.filesystem?String(_.filesystem):void 0,encrypted:_.encrypted===!0,desiredState:_.desiredState&&typeof _.desiredState==="object"?_.desiredState:{},actorId:g})},202,{"cache-control":"no-store"})}catch(M){return T(M,422)}}if(N.pathname==="/api/volumes/attach"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.attach(String(_.volumeId??""),{resourceId:String(_.resourceId??""),targetPath:String(_.targetPath??""),readOnly:_.readOnly===!0,uid:_.uid==null?void 0:Number(_.uid),gid:_.gid==null?void 0:Number(_.gid),mode:_.mode?String(_.mode):void 0,propagation:_.propagation,driverOptions:_.driverOptions&&typeof _.driverOptions==="object"?_.driverOptions:{},actorId:g})},202)}catch(M){return T(M,422)}}if(N.pathname==="/api/volumes/detach"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.detach(String(_.volumeId??""),String(_.attachmentId??""),{force:_.force===!0,drained:_.drained===!0,unmounted:_.unmounted===!0,confirmation:_.confirmation?String(_.confirmation):void 0,actorId:g})},202)}catch(M){return T(M)}}if(N.pathname==="/api/volumes/resize"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.resize(String(_.volumeId??""),Number(_.capacityBytes),{drained:_.drained===!0,actorId:g})},202)}catch(M){return T(M,422)}}if(N.pathname==="/api/volumes/snapshot"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.snapshot(String(_.volumeId??""),{name:_.name?String(_.name):void 0,actorId:g})},202)}catch(M){return T(M,422)}}if(N.pathname==="/api/volumes/restore"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,...Vi.restore(String(_.snapshotId??""),{name:String(_.name??""),actorId:g})},202)}catch(M){return T(M,422)}}if(N.pathname==="/api/volumes/discover"&&I.method==="POST")try{return S({ok:!0,volumes:await Vi.discover({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,actorId:g})})}catch(_){return T(_,502)}if(N.pathname==="/api/volumes/adopt"&&I.method==="POST"){let _=await oe(I);try{return S({ok:!0,volume:Vi.adopt(String(_.volumeId??""),{name:String(_.name??""),actorId:g})})}catch(M){return T(M,422)}}if(N.pathname==="/api/volumes"&&I.method==="DELETE"){let _=await oe(I),M=Bt.resolveSession(I);try{return S({ok:!0,...Vi.delete(String(_.volumeId??""),{recentAuthAt:!Re||M&&ve.isRecentlyAuthenticated(M)?new Date().toISOString():void 0,confirmation:_.confirmation?String(_.confirmation):void 0,backupOverride:_.backupOverride===!0,backupOverrideConfirmation:_.backupOverrideConfirmation?String(_.backupOverrideConfirmation):void 0,actorId:g})},202)}catch(K){return T(K)}}}if(N.pathname==="/api/backups"&&I.method==="GET"){let d=a.environments.get(ye),g=sr.listPolicies(a.project.id,d?.id),T=new Set(g.map((Q)=>Q.id)),_=sr.listRecoveryPoints(a.project.id).filter((Q)=>!Q.policyId||T.has(Q.policyId)),M=sr.listJobs(a.project.id).filter((Q)=>!Q.policyId||T.has(Q.policyId)),K=(Q)=>({...Q,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!Q.credentialRef,clientEncryptionConfigured:!!Q.encryptionKeyRef}),B=await Promise.all(sr.listDestinations(a.project.id).map(async(Q)=>({...K(Q),credentialStatus:await Vg(Q,Ui)})));return S({ok:!0,destinations:B,policies:g,recoveryPoints:_,jobs:M,coverage:sr.coverage(a.project.id).filter((Q)=>T.has(Q.policy.id)),resources:d?a.store.listResources(a.project.id,d.id).map((Q)=>({id:Q.id,name:Q.name,slug:Q.slug,kind:Q.kind})):[]})}if(N.pathname==="/api/backups/destinations"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim(),T=String(d.provider??""),_=String(d.encryption??"provider"),M=`secret://data-services/backups/${a.project.id}/${g}`,K=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(T))return S({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(_))return S({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let B,Q;if(d.credentials&&typeof d.credentials==="object"&&!Array.isArray(d.credentials))B=`${M}/credentials`,await Ui.put(B,JSON.stringify(d.credentials)),K.push(B);if(_!=="provider"){let ue=String(d.encryptionKey??"");if(ue.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");Q=`${M}/encryption-key`,await Ui.put(Q,ue),K.push(Q)}let fe=sr.createDestination({organizationId:a.organization.id,projectId:a.project.id,name:g,provider:T,endpoint:d.endpoint?String(d.endpoint):void 0,endpointPolicy:d.endpointPolicy==="allow_private"?"allow_private":"public_https",bucket:d.bucket?String(d.bucket):void 0,prefix:String(d.prefix??""),region:d.region?String(d.region):mo,forcePathStyle:d.forcePathStyle===!0,credentialRef:B,encryption:_,encryptionKeyRef:Q,immutability:d.immutability&&typeof d.immutability==="object"&&!Array.isArray(d.immutability)?d.immutability:{},status:"untested"});return S({ok:!0,destination:{...fe,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!B,clientEncryptionConfigured:!!Q}},201)}catch(B){for(let Q of K)await Ui.remove(Q).catch(()=>{});return S({ok:!1,error:B instanceof Error?B.message:String(B)},422)}}if(N.pathname==="/api/backups/destinations/test"&&I.method==="POST"){let d=await oe(I),g=sr.getDestination(String(d.id??""));if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Backup destination was not found."},404);if(g.provider==="aws_backup")return S({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await ap.test(g),S({ok:!0,destination:sr.recordDestinationTest(g.id,{ok:!0})})}catch(T){let _=T instanceof Error?T.message:String(T);return sr.recordDestinationTest(g.id,{ok:!1,error:_}),S({ok:!1,error:_},502)}}if(N.pathname==="/api/backups/policies"&&I.method==="POST"){let d=await oe(I),g=a.environments.get(ye),T=sr.getDestination(String(d.destinationId??"")),_=String(d.resourceKind??""),M=d.dataServiceId?String(d.dataServiceId):void 0,K=M?_t.get(M):void 0,B=d.resourceId?String(d.resourceId):void 0,Q=B?a.store.getResource(B):void 0;if(!g)return S({ok:!1,error:"Environment was not found."},404);if(!T||T.projectId!==a.project.id)return S({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(_))return S({ok:!1,error:"A supported backup resource kind is required."},422);if(M&&(!K||K.projectId!==a.project.id||K.environmentId!==g.id))return S({ok:!1,error:"Data service was not found in this environment."},404);if(B&&(!Q||Q.projectId!==a.project.id||Q.environmentId!==g.id))return S({ok:!1,error:"Resource was not found in this environment."},404);if(_==="managed_database"&&!K)return S({ok:!1,error:"Managed database policies require a data service."},422);if(_==="logical_database"&&(!K||!["container","server"].includes(K.provider)))return S({ok:!1,error:"Logical database policies require an on-box data service."},422);if(_==="volume"&&(!Q||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(d.volumeName??""))))return S({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let fe=Array.isArray(d.includePatterns)?d.includePatterns.map(String).filter(Boolean):[];if(_==="files"&&(!Q||!fe.length))return S({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(_==="control_plane"&&T.encryption==="provider")return S({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(_==="infrastructure"&&(T.provider!=="aws_backup"||!fe.some((ue)=>ue.startsWith("resource:arn:"))||!fe.some((ue)=>ue.startsWith("role:arn:"))))return S({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let ue=sr.createPolicy({organizationId:a.organization.id,projectId:a.project.id,environmentId:g.id,resourceId:B,dataServiceId:M,destinationId:T.id,name:String(d.name??"").trim(),resourceKind:_,schedule:String(d.schedule??"daily"),timezone:String(d.timezone??"UTC"),retention:d.retention&&typeof d.retention==="object"&&!Array.isArray(d.retention)?d.retention:{keepLast:7,expireAfterDays:30},compression:["none","gzip","zstd"].includes(String(d.compression))?d.compression:"gzip",encryption:["destination","client_side","both"].includes(String(d.encryption))?d.encryption:"destination",includePatterns:_==="volume"?[String(d.volumeName),...fe]:fe,excludePatterns:Array.isArray(d.excludePatterns)?d.excludePatterns.map(String):[],expectedRpoMinutes:Math.max(1,Number(d.expectedRpoMinutes)||1440),expectedRtoMinutes:Math.max(1,Number(d.expectedRtoMinutes)||120),healthCheckId:d.healthCheckId?String(d.healthCheckId):void 0,enabled:d.enabled!==!1});return S({ok:!0,policy:ue},201)}catch(ue){return S({ok:!1,error:ue instanceof Error?ue.message:String(ue)},422)}}if(N.pathname==="/api/backups/run"&&I.method==="POST"){let d=await oe(I),g=sr.getPolicy(String(d.policyId??"")),T=a.environments.get(ye);if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Backup policy was not found in this environment."},404);try{let _=jo.enqueueBackup(g,new Date().toISOString(),Me(de).actor?.id);return S({ok:!0,job:_},202)}catch(_){return S({ok:!1,error:_ instanceof Error?_.message:String(_)},409)}}if(N.pathname==="/api/backups/verify"&&I.method==="POST"){let d=await oe(I),g=sr.getRecoveryPoint(String(d.recoveryPointId??""));if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Recovery point was not found."},404);return S({ok:!0,job:jo.enqueueVerification(g)},202)}if(N.pathname==="/api/backups/restore"&&I.method==="POST"){let d=await oe(I),g=sr.getRecoveryPoint(String(d.recoveryPointId??"")),T=d.mode==="in_place"?"in_place":"isolated",_=d.target&&typeof d.target==="object"&&!Array.isArray(d.target)?{...d.target,inPlace:T==="in_place"}:{inPlace:T==="in_place"},M=Bt.resolveSession(I),K={mode:T,target:_,targetName:String(d.targetName??""),confirm:d.confirm?String(d.confirm):void 0,recentAuth:!Re||!!M&&ve.isRecentlyAuthenticated(M),downtimeAcknowledged:d.downtimeAcknowledged===!0,safetyBackupId:d.safetyBackupId?String(d.safetyBackupId):void 0};if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Recovery point was not found."},404);if(d.drill===!0&&T!=="isolated")return S({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let B=jo.planRestore(g,K);if(d.execute!==!0)return S({ok:!0,plan:B,executionCreated:!1});let Q=jo.enqueueRestore(g,{...K,drill:d.drill===!0,actorId:Me(de).actor?.id});return S({ok:!0,plan:B,job:Q},202)}catch(B){return S({ok:!1,error:B instanceof Error?B.message:String(B)},409)}}if(N.pathname==="/api/backups/recovery-points"&&I.method==="POST"){let d=await oe(I),g=sr.getRecoveryPoint(String(d.id??""));if(!g||g.projectId!==a.project.id)return S({ok:!1,error:"Recovery point was not found."},404);if(d.held==null&&d.pinned==null)return S({ok:!1,error:"held or pinned must be provided."},422);return S({ok:!0,recoveryPoint:sr.updateRecoveryPoint(g.id,{held:d.held==null?g.held:d.held===!0,pinned:d.pinned==null?g.pinned:d.pinned===!0})})}if(N.pathname==="/api/backups/retention"&&I.method==="POST")return S({ok:!0,jobs:jo.enqueueRetention()},202);if(N.pathname==="/api/data-services/capabilities"&&I.method==="GET"){let d=String(N.searchParams.get("engine")??""),g=String(N.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(d)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(g))return S({ok:!1,error:"A supported engine and provider are required."},422);return S({ok:!0,engine:d,provider:g,capabilities:Ht(d,g)})}if(N.pathname==="/api/data-services"&&I.method==="GET"){let d=a.environments.get(ye),g=_t.list(a.project.id,d?.id).map((T)=>{let _=_t.credential(T.id);return{...T,credentialRef:void 0,credential:_?{configured:!0,username:_.username,version:_.version,rotatedAt:_.rotatedAt}:void 0,dependencies:_t.dependencies(T.id).map((M)=>({resourceId:M.resourceId,requiresRedeploy:M.requiresRedeploy}))}});return S({ok:!0,services:g})}if(N.pathname==="/api/data-services/preview"&&I.method==="POST"){let d=await oe(I);if(d.id){let _=_t.get(String(d.id)),M=a.environments.get(ye),K=String(d.action??"");if(!_||_.projectId!==a.project.id||_.environmentId!==M?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!Id.includes(K))return S({ok:!1,error:`Action must be one of: ${Id.join(", ")}.`},422);try{return S({ok:!0,plan:Va.plan(_,K,d.changes??{})})}catch(B){return S({ok:!1,error:B instanceof Error?B.message:String(B)},422)}}let g=String(d.engine??""),T=String(d.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(g)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return S({ok:!1,error:"A supported engine and provider are required."},422);return S({ok:!0,capabilities:Ht(g,T),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(N.pathname==="/api/data-services"&&I.method==="POST"){let d=await oe(I),g=String(d.engine??""),T=String(d.provider??""),_=a.environments.get(ye),M=Me(de);if(!_)return S({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(g)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return S({ok:!1,error:"A supported engine and provider are required."},422);let K={organizationId:a.organization.id,projectId:a.project.id,environmentId:_.id,resourceId:d.resourceId?String(d.resourceId):void 0,name:String(d.name??"").trim(),engine:g,provider:T,placement:String(d.placement??d.name??"").trim(),engineVersion:d.engineVersion?String(d.engineVersion):void 0,plan:String(d.plan??(T==="aws_elasticache"?"cache.t4g.micro":T==="aws_aurora"?"db.serverless":"db.t4g.micro")),storageGb:d.storageGb==null?void 0:Number(d.storageGb),highAvailability:d.highAvailability===!0,publicExposure:d.publicExposure===!0,allowedCidrs:Array.isArray(d.allowedCidrs)?d.allowedCidrs.map(String):[],desiredState:d.desiredState&&typeof d.desiredState==="object"&&!Array.isArray(d.desiredState)?d.desiredState:{},observedState:{},origin:d.adopt===!0?"adopted":"managed",managementEnabled:d.adopt!==!0,ownerActorId:M.actor?.id,username:d.username?String(d.username):void 0};try{if(d.adopt===!0){let Q=_t.create({...K,status:"adopted",credentialRef:void 0});return S({ok:!0,service:Q,readOnly:!0},201)}if(!sp({provider:T,engine:g}))return S({ok:!1,error:`No ${T}/${g} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let B=await Va.create(K);return S({ok:!0,service:B.service,operationId:B.operationId,oneTimeCredential:B.credential},201)}catch(B){return S({ok:!1,error:B instanceof Error?B.message:String(B)},422)}}if(N.pathname==="/api/data-services/connections"&&I.method==="GET"){let d=_t.get(String(N.searchParams.get("id")??"")),g=a.environments.get(ye);if(!d||d.projectId!==a.project.id||d.environmentId!==g?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);let T=typeof d.observedState.endpoint==="string"?d.observedState.endpoint:void 0,_=typeof d.observedState.readerEndpoint==="string"?d.observedState.readerEndpoint:void 0,M=Number(d.observedState.port)||(d.engine==="postgres"?5432:d.engine==="redis"?6379:d.engine==="mongodb"?27017:d.engine==="libsql"?8080:3306),K=typeof d.observedState.database==="string"?d.observedState.database:void 0,B=typeof d.observedState.tls==="boolean"?d.observedState.tls:d.provider.startsWith("aws_"),Q=[...T?[{type:d.publicExposure?"external":"internal",host:T,port:M,database:K,tls:B}]:[],..._?[{type:"internal",host:_,port:M,database:K,tls:B}]:[],{type:"tunnel",host:T??d.placement,port:M,database:K,tls:B}];return S({ok:!0,serviceId:d.id,guidance:vn(d,Q)})}if(N.pathname==="/api/data-services/action"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye),_=String(d.action??"");if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!Id.includes(_))return S({ok:!1,error:`Action must be one of: ${Id.join(", ")}.`},422);let M=d.changes&&typeof d.changes==="object"&&!Array.isArray(d.changes)?d.changes:{};try{let K=Va.plan(g,_,M);if(d.execute!==!0)return S({ok:!0,plan:K,productionExecutionCreated:!1});let B=Va.enqueue(g,_,M,Me(de).actor?.id);return S({ok:!0,plan:K,operationId:B},202)}catch(K){return S({ok:!1,error:K instanceof Error?K.message:String(K)},409)}}if(N.pathname==="/api/data-services/dependencies"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye),_=a.store.getResource(String(d.resourceId??""));if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!_||_.projectId!==a.project.id||_.environmentId!==T?.id)return S({ok:!1,error:"Dependent resource was not found in this environment."},404);if(d.remove===!0)return S({ok:_t.removeDependency(g.id,_.id)});return _t.addDependency({serviceId:g.id,resourceId:_.id,secretRef:g.credentialRef??`secret://data-services/${g.projectId}/${g.name}`,requiresRedeploy:d.requiresRedeploy!==!1}),S({ok:!0,dependencies:_t.dependencies(g.id).map((M)=>({resourceId:M.resourceId,requiresRedeploy:M.requiresRedeploy}))})}if(N.pathname==="/api/data-services/management"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye);if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(g.origin!=="adopted"||d.reviewed!==!0||d.confirm!==g.name)return S({ok:!1,error:`Enabling management requires reviewed=true and typing ${g.name}.`},409);return S({ok:!0,service:_t.update(g.id,g.version,{managementEnabled:!0})})}if(N.pathname==="/api/data-services/reveal"&&I.method==="POST"){let d=await oe(I),g=_t.get(String(d.id??"")),T=a.environments.get(ye),_=g?_t.credential(g.id):void 0;if(!g||g.projectId!==a.project.id||g.environmentId!==T?.id)return S({ok:!1,error:"Data service was not found in this environment."},404);if(!_)return S({ok:!1,error:"No managed credential is configured."},404);return S({ok:!0,credential:{username:_.username,password:await Ui.resolve(_.secretRef),version:_.version}},200,{"cache-control":"no-store"})}if(N.pathname==="/api/databases"&&I.method==="GET")return S(await Oh(o,ye));if(N.pathname==="/api/databases"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim();if(!uo(g))return S({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return S({...await _h(o,ye,g),name:g})}if(N.pathname==="/api/databases/vitess"&&I.method==="GET"){let d=await Lh(o,ye);return S({...d,unhealthy:Bh(d.tablets),missingPrimary:jh(d)})}if(N.pathname==="/api/databases/vitess/provision"&&I.method==="POST"){let d=await oe(I);try{return S(await Gh(o,ye,{keyspace:String(d.keyspace??""),username:String(d.username??""),password:String(d.password??""),sharded:d.sharded===!0,confirm:String(d.confirm??"")}))}catch(g){return S({ok:!1,error:g instanceof Error?g.message:String(g)},422)}}if(N.pathname==="/api/databases/vitess/migrations"&&I.method==="GET"){let d=N.searchParams.get("keyspace")??void 0;return S(await Wh(o,ye,d))}if(N.pathname==="/api/databases/vitess/migrations/action"&&I.method==="POST"){let d=await oe(I),g=String(d.uuid??"").trim(),T=String(d.action??"");if(!["retry","cancel","cleanup","complete"].includes(T))return S({ok:!1,error:"Unknown migration action."},422);return S(await Hh(o,ye,g,T))}if(N.pathname==="/api/databases/vitess/keyspaces"&&I.method==="POST"){let d=await oe(I),g=String(d.name??"").trim(),T=d.sharded===!0;return S(await Vh(o,ye,g,{sharded:T}))}if(N.pathname==="/api/databases/vitess/vschema"&&I.method==="POST"){let d=await oe(I),g=String(d.keyspace??"").trim(),T=typeof d.vschema==="string"?d.vschema:JSON.stringify(d.vschema??null);return S(await qh(o,ye,g,T))}if(N.pathname==="/api/databases/vitess/schema"&&I.method==="POST"){let d=await oe(I),g=String(d.sql??"");return S(await Jh(o,ye,g))}if(N.pathname==="/api/databases/vitess/install-client"&&I.method==="POST")return S(await zh(o,ye));if(N.pathname==="/api/databases/backups"&&I.method==="GET")return S(await Mh(o,ye));if(N.pathname==="/api/databases/backup"&&I.method==="POST"){let d=await oe(I),g=String(d.database??"").trim();if(!uo(g))return S({ok:!1,error:"Database name must be a valid identifier."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to back up this database.`},409);return S(await $h(o,ye,g))}if(N.pathname==="/api/databases/users"&&I.method==="POST"){let d=await oe(I),g=String(d.username??"").trim(),T=String(d.password??""),_=String(d.database??"").trim()||void 0,M=d.access==="readonly"?"readonly":"all";if(!uo(g))return S({ok:!1,error:"Username must be a valid identifier."},422);if(!T)return S({ok:!1,error:"Password is required."},422);if(_&&!uo(_))return S({ok:!1,error:"Database must be a valid identifier."},422);return S({...await Nh(o,ye,{username:g,password:T,database:_,access:M}),username:g})}if(N.pathname==="/api/dashboard-data")return Mt=q.get(ye)??await Ze(ye),Ze(ye),S(ql(Mt,{user:si,slug:o.project.slug}));if(N.pathname==="/api/users"&&I.method==="GET")return S({ok:!0,users:Fn(t).map(ta)});if(N.pathname==="/api/users"&&I.method==="POST"){let d=await oe(I),g=String(d.username??"").trim();if(!fd(g))return S({ok:!1,error:"Username must be 2-32 characters: letters, numbers, dot, dash or underscore."},422);let T=d.sites&&typeof d.sites==="object"?d.sites:{},_=new Set(Object.keys(o.sites??{})),M={};for(let[Q,fe]of Object.entries(T)){if(!_.has(Q))return S({ok:!1,error:`Site '${Q}' was not found.`},404);if(fe!=="owner"&&fe!=="collaborator")return S({ok:!1,error:`Unknown site role '${fe}'. Use 'owner' or 'collaborator'.`},422);M[Q]=fe}let K=typeof d.password==="string"&&d.password.trim()?d.password.trim():void 0;if(K&&K.length<12)return S({ok:!1,error:"Password must be at least 12 characters."},422);let B=La(t,{username:g,password:K,name:typeof d.name==="string"?d.name:void 0,sites:M});return sd(a,Fn(t)),gi(),S({ok:!0,user:ta(B.user),password:B.password})}if(N.pathname==="/api/users"&&I.method==="DELETE"){let d=await oe(I),g=String(d.username??"").trim();if(g.toLowerCase()===de.username.toLowerCase())return S({ok:!1,error:"You cannot remove your own account."},409);let T=pi(Fn(t),g),_=T?a.store.getActorByExternalId("user",`dashboard:${T.username.toLowerCase()}`):void 0,M=_?a.store.getMembershipForActor(a.organization.id,_.id):void 0;if(M&&M.source!=="legacy")return S({ok:!1,error:"Organization members must be removed from Organization access."},409);let K=zl(t,g);if(!K.ok)return S(K,409);return sd(a,Fn(t)),Ae.clear(),S({ok:!0,username:g})}if(N.pathname==="/api/actions/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=d.action?sA(d.action,ye):void 0;if(!g)return S({ok:!1,error:"Unknown dashboard action."},404);if(g.mutates&&d.confirm!==g.confirm)return S({ok:!1,error:`Type "${g.confirm}" to run this action.`},409);let T=await ao({controlPlane:a,environment:ye,actor:de,kind:`dashboard.action.${g.id}`,input:{action:g.id},execute:()=>np(g,{cwd:t,cliEntry:i})});return S({...T.result,controlPlaneOperation:T.operation})}if(N.pathname==="/api/server/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=d.operation?_n(d.operation,o,Mt):void 0;if(!g)return S({ok:!1,error:"Unknown or unavailable server operation."},404);if(g.mutates&&d.confirm!==g.confirm)return S({ok:!1,error:`Type "${g.confirm}" to run this operation.`},409);let T=ae(a,String(ye));await new ps(et).run(new Oa,{...T,artifactRoot:t});let _=Zt(et,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(_.decision.outcome==="block")return S({ok:!1,error:`Operation blocked by security policy: ${_.decision.explanation}`,securityReview:_},409);let M=await ao({controlPlane:a,environment:ye,actor:de,kind:`dashboard.server.${g.id}`,resourceSlug:g.target,input:{operation:g.id,target:g.target,to:d.to??null},execute:()=>kr(o,ye,g,{to:d.to})});return S({...M.result,controlPlaneOperation:M.operation,securityReview:_})}if(N.pathname==="/api/server/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return S({ok:!1,error:'Type "run" to execute this command on the server.'},409);let g=await ao({controlPlane:a,environment:ye,actor:de,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>Qt(o,ye,String(d.command??""))});return S({...g.result,controlPlaneOperation:g.operation})}if(N.pathname==="/api/serverless/operations")return S(Kl(o,ye,Mt));if(N.pathname==="/api/serverless/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=d.operation?Cy(d.operation,o,ye,Mt):void 0;if(!g)return S({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(g.mutates&&d.confirm!==g.confirm)return S({ok:!1,error:`Type "${g.confirm}" to run this operation.`},409);let T=await ao({controlPlane:a,environment:ye,actor:de,kind:`dashboard.serverless.${g.id}`,input:{operation:g.id,min:d.min??null,max:d.max??null},execute:()=>Ey(o,ye,g,{min:d.min,max:d.max})});return Mt=await bs(o,ye),q.set(ye,Mt),S({...T.result,controlPlaneOperation:T.operation})}if(N.pathname==="/api/serverless/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return S({ok:!1,error:'Type "run" to execute this command.'},409);return S(await Ty(o,ye,String(d.command??"")))}if(N.pathname==="/api/serverless/dlq"&&I.method==="GET"){let d=Number(N.searchParams.get("max"))||10;return S(await Ay(o,ye,d))}if(N.pathname==="/api/serverless/dlq/redrive"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="redrive")return S({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return S(await ky(o,ye,{max:d.max,targetQueue:d.targetQueue}))}if(N.pathname==="/api/serverless/dlq/purge"&&I.method==="POST"){if((await I.json().catch(()=>({}))).confirm!=="purge")return S({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return S(await Ry(o,ye))}if(N.pathname==="/api/serverless/secrets"&&I.method==="GET")return S({secrets:Py(o,ye)});if(N.pathname==="/api/serverless/secrets"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.secretId??"").trim();if(!g)return S({ok:!1,error:"A secret id is required."},422);if(typeof d.value!=="string"||d.value==="")return S({ok:!1,error:"A non-empty value is required."},422);return S(await xy(o,ye,g,d.value))}if(N.pathname==="/api/serverless/secrets"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),g=String(d.secretId??"").trim();if(!g)return S({ok:!1,error:"A secret id is required."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to delete this secret.`},409);return S(await Dy(o,ye,g))}if(N.pathname==="/api/serverless/functions/config"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.mode??"").trim();if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to update this function.`},409);return S(await Oy(o,ye,g,{memory:d.memory,timeout:d.timeout}))}if(N.pathname==="/api/serverless/alarms"&&I.method==="GET")return S(await _y(o,ye));if(N.pathname==="/api/serverless/alarms"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.preset??"").trim(),T=Number(d.threshold);if(!g)return S({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(T))return S({ok:!1,error:"A numeric threshold is required."},422);return S(await Ny(o,ye,g,T))}if(N.pathname==="/api/serverless/alarms"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),g=String(d.name??"").trim();if(!g)return S({ok:!1,error:"An alarm name is required."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to delete this alarm.`},409);return S(await $y(o,ye,g))}if(N.pathname==="/api/serverless/traces"&&I.method==="GET"){let d=Number(N.searchParams.get("minutes"))||30;return S(await Sd(o,ye,d))}if(N.pathname==="/api/serverless/scheduler"&&I.method==="POST"){let d=await I.json().catch(()=>({})),g=String(d.action??"").trim();if(g!=="enable"&&g!=="disable"&&g!=="run")return S({ok:!1,error:"Unknown scheduler action."},422);if(d.confirm!==g)return S({ok:!1,error:`Type "${g}" to ${g} the scheduler.`},409);return S(await Xl(o,ye,g))}if(!ab(N.pathname,si))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(ye)}`}});let Ts=await Pi(de,ye);if(!Ts)return Ed("ts-cloud dashboard UI is unavailable.",503);return cb(Ts,N.pathname)}catch(Uo){if(e.verbose)console.error(Uo);return S({ok:!1,error:Uo?.message??String(Uo)},500)}})();if(!ir)return ir;if(mt&&(N.pathname.startsWith("/api/")||N.pathname.startsWith("/auth/"))){let Ye;if((we.headers.get("content-type")||"").includes("application/json"))Ye=await we.json().catch(()=>{return});let Br=Bt.resolveUser(I),wr=Br?Me(Br).actor:void 0;a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,actorId:wr?.id,correlationId:Je,type:ir.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:ir.status<400?"info":"warning",payload:qT(I.method,N.pathname,Ye,ir.status,Date.now()-Ne)})}return ir.headers.set("x-request-id",Je),ir}});qa?.start();let Eb=e.spendLoop??!0,Cp;if(Eb)(async()=>{let{SpendRunner:I,SpendLoopLease:Ee,startSpendLoop:Ne}=await import("./chunk-bdgkeqv6.js"),{store:we}=await ub(a.store),Je=new I({controlPlane:a.store,store:we,alerts:Ge});Cp=Ne(Je,{lease:new Ee(a.store,{owner:`dashboard:${process.pid}`}),onError:(mt)=>console.error(`[ts-cloud] spend cycle failed: ${mt instanceof Error?mt.message:String(mt)}`)})})();let Tb=Is.stop.bind(Is);return Is.stop=(I)=>{clearInterval(Sp),clearInterval(vp),clearInterval(wp),clearInterval(bp),clearInterval(yp),clearInterval(gp),clearInterval(mp),clearInterval(fp),clearInterval(hp),gi(),ar.clear(),qa?.stop(),Cp?.();let Ee=Tb(I);if(qa)qa.settled().finally(()=>a.store.close());else a.store.close();return Ee},{server:Is,url:`http://${r}:${Is.port}/`}}
511
511
  export{ke,k,ln,y,dn,Ei,un,ko,Ir,tt,Ie,pn,mn,gn,fn,hn,yn,Sn,bn,te,Ht,Wt,vn,Rr,Tn,En,wn,Cn,An,In,Rn,Pn,rt,Gt,Kt,Ct,Pr,Jt,Xt,wi,At,Nn,se,Dn,kn,xn,Nr,Dr,_n,kr,Qt,Yt,nt,It,Rt,xr,ae,$n,na,ia,Zt,oa,z,Ci,Ue,it,ot,On,_r,$r,Ln,Mn,Un,Or,xo,ce,me,xe,ge,Bn,er};