@stacksjs/ts-cloud 0.16.58 → 0.16.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aws/index.js +1 -1
- package/dist/bin/{chunk-wzpsq446.js → chunk-06rjt80a.js} +1 -1
- package/dist/bin/{chunk-gvv4hn0h.js → chunk-0dmf1a2q.js} +2 -2
- package/dist/bin/{chunk-8t01yv89.js → chunk-0f8jky3x.js} +8 -8
- package/dist/bin/{chunk-zp1cxtbh.js → chunk-0rvg0ma7.js} +2 -2
- package/dist/bin/{chunk-4crz28b9.js → chunk-1mb679gj.js} +1 -1
- package/dist/bin/{chunk-7p70c4br.js → chunk-1z4hxpwe.js} +2 -2
- package/dist/bin/{chunk-bzzwbkrx.js → chunk-27rh6te6.js} +6 -6
- package/dist/bin/{chunk-4fkmd2ce.js → chunk-37gemrn2.js} +1 -1
- package/dist/bin/chunk-40963a0r.js +1 -0
- package/dist/bin/chunk-4zsp269q.js +1 -0
- package/dist/bin/{chunk-1gznb7bh.js → chunk-551brgyd.js} +2 -2
- package/dist/bin/chunk-57sers7y.js +1 -0
- package/dist/bin/{chunk-agakphd1.js → chunk-5cmj2m13.js} +1 -1
- package/dist/bin/chunk-8vmy8yhf.js +1 -0
- package/dist/bin/{chunk-nva480hg.js → chunk-8z2436dv.js} +2 -2
- package/dist/bin/{chunk-5mnfp9ae.js → chunk-9hb2wkkt.js} +1 -1
- package/dist/bin/{chunk-zpjy26jk.js → chunk-acn2c3ep.js} +3 -3
- package/dist/bin/chunk-at4x6wf2.js +1 -0
- package/dist/bin/{chunk-enmw6v4x.js → chunk-bd4ppf6w.js} +1 -1
- package/dist/bin/{chunk-n2jh5p5x.js → chunk-bss9yv52.js} +2 -2
- package/dist/bin/{chunk-9292d4yb.js → chunk-c1dwwtkq.js} +84 -84
- package/dist/bin/chunk-cmkvxf6c.js +1 -0
- package/dist/bin/{chunk-ebhfg18g.js → chunk-cvps1wjq.js} +5 -5
- package/dist/bin/{chunk-q0takzyx.js → chunk-dwq5vgdc.js} +2 -2
- package/dist/bin/{chunk-tdftrmyx.js → chunk-e19dabas.js} +1 -1
- package/dist/bin/chunk-ed4vh6b4.js +1 -0
- package/dist/bin/{chunk-yn3499yh.js → chunk-fqvqqtg6.js} +1 -1
- package/dist/bin/{chunk-t8qzx4ka.js → chunk-hc9tnwqs.js} +173 -173
- package/dist/bin/{chunk-37aphhk9.js → chunk-hs2r1nsg.js} +3 -3
- package/dist/bin/chunk-kj0eewaq.js +1 -0
- package/dist/bin/{chunk-0vfw6xy0.js → chunk-mt70pxs8.js} +1 -1
- package/dist/bin/{chunk-p1eqv66t.js → chunk-nn1w8fvd.js} +48 -48
- package/dist/bin/{chunk-nnrta1g9.js → chunk-pntcdh4x.js} +1 -1
- package/dist/bin/{chunk-qvrfaeqq.js → chunk-qt6rjw6v.js} +1 -1
- package/dist/bin/{chunk-vmrkqtch.js → chunk-r99jcm9t.js} +1 -1
- package/dist/bin/{chunk-7cactd6c.js → chunk-rq0wxfyp.js} +1 -1
- package/dist/bin/chunk-sfwm3wzx.js +1 -0
- package/dist/bin/{chunk-v0g82agx.js → chunk-x8gqdr3m.js} +1 -1
- package/dist/bin/{chunk-pr5c0q0k.js → chunk-yydj05nb.js} +4 -4
- package/dist/bin/{chunk-a4z8b18n.js → chunk-zgasmfgt.js} +1 -1
- package/dist/bin/cli.js +238 -238
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/{chunk-e42gpavb.js → chunk-1a7ms51t.js} +5 -5
- package/dist/{chunk-qjp3f5y8.js → chunk-2pqjw8pq.js} +7 -7
- package/dist/chunk-3855mx54.js +1 -0
- package/dist/{chunk-d245va6b.js → chunk-3h5vgz4z.js} +2 -2
- package/dist/{chunk-v4vz0e85.js → chunk-6ky22rmg.js} +1 -1
- package/dist/{chunk-y2dej583.js → chunk-7bzyjfb1.js} +109 -103
- package/dist/{chunk-c482jhc6.js → chunk-7md90ny0.js} +2 -2
- package/dist/chunk-92yhw6da.js +1 -0
- package/dist/{chunk-184bvh5s.js → chunk-95qrgpjk.js} +19 -19
- package/dist/chunk-9tbx7g94.js +1 -0
- package/dist/{chunk-430acqjk.js → chunk-b1v1301e.js} +25 -25
- package/dist/{chunk-2hma3g5q.js → chunk-c87bg8wk.js} +2 -2
- package/dist/{chunk-hybz2q8w.js → chunk-cwqqv7dx.js} +4 -4
- package/dist/{chunk-vgtqd3sb.js → chunk-dp0hvmd0.js} +1 -1
- package/dist/{chunk-a99wz633.js → chunk-j2bpd2v9.js} +5 -5
- package/dist/{chunk-stc3ykm3.js → chunk-jg2m713e.js} +14 -14
- package/dist/{chunk-80bgb48v.js → chunk-mkvqcd3x.js} +2 -2
- package/dist/{chunk-gmtds745.js → chunk-nq6cqjfv.js} +1 -1
- package/dist/{chunk-mp2y4t6w.js → chunk-pqyv47m4.js} +1 -1
- package/dist/{chunk-smt4t6rc.js → chunk-qb8cf1ss.js} +2 -2
- package/dist/{chunk-94z7s8ky.js → chunk-qdaj5yyh.js} +5 -5
- package/dist/chunk-qkycmppw.js +1 -0
- package/dist/{chunk-wbbbpt4v.js → chunk-rxh9dkpd.js} +5 -5
- package/dist/{chunk-qyr5hn6v.js → chunk-ryce2n62.js} +3 -3
- package/dist/{chunk-jyvnfny6.js → chunk-tj3egckk.js} +3 -3
- package/dist/{chunk-y7k5872m.js → chunk-w174jbbm.js} +2 -2
- package/dist/chunk-wtp36fj6.js +1 -0
- package/dist/{chunk-apj1eqcy.js → chunk-x6a2e5sx.js} +4 -4
- package/dist/chunk-x8fg8zg8.js +2 -0
- package/dist/{chunk-yt8qgn5d.js → chunk-y9q6sv2q.js} +6 -6
- package/dist/{chunk-nhsefr22.js → chunk-yece1kc4.js} +7 -7
- package/dist/{chunk-zvcd6x45.js → chunk-z5as1fa7.js} +141 -141
- package/dist/{chunk-4f0b21fp.js → chunk-za23j2mq.js} +149 -149
- package/dist/chunk-zwckda2e.js +1 -0
- package/dist/deploy/index.js +1 -1
- package/dist/dns/index.js +1 -1
- package/dist/drivers/hetzner/client.d.ts +6 -0
- package/dist/drivers/index.d.ts +2 -0
- package/dist/drivers/index.js +1 -1
- package/dist/drivers/shared/box-converge.d.ts +58 -0
- package/dist/drivers/shared/box-converge.test.d.ts +1 -0
- package/dist/drivers/shared/package-manager.d.ts +2 -0
- package/dist/index.js +46 -46
- package/dist/mail/index.js +2 -2
- package/dist/operations/index.js +1 -1
- package/dist/protection/index.js +1 -1
- package/dist/spend/index.js +1 -1
- package/dist/ui/404.html +1 -1
- package/dist/ui/accept-invitation.html +1 -1
- package/dist/ui/access-denied.html +1 -1
- package/dist/ui/account/automation.html +6 -6
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +6 -6
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +6 -6
- package/dist/ui/data/services.html +6 -6
- package/dist/ui/data/volumes.html +6 -6
- package/dist/ui/index.html +5 -5
- package/dist/ui/infrastructure/topology.html +5 -5
- package/dist/ui/integrations.html +2 -2
- package/dist/ui/operations/alerts.html +6 -6
- package/dist/ui/operations/configuration.html +6 -6
- package/dist/ui/operations/jobs.html +5 -5
- package/dist/ui/operations/maintenance.html +6 -6
- package/dist/ui/operations/observability.html +6 -6
- package/dist/ui/operations/previews.html +6 -6
- package/dist/ui/operations/queue.html +6 -6
- package/dist/ui/operations/regions.html +6 -6
- package/dist/ui/operations/releases.html +6 -6
- package/dist/ui/operations/spend.html +6 -6
- package/dist/ui/operations/workloads.html +6 -6
- package/dist/ui/security.html +1 -1
- package/dist/ui/server/actions.html +6 -6
- package/dist/ui/server/activity.html +1 -1
- package/dist/ui/server/capacity.html +5 -5
- package/dist/ui/server/database.html +6 -6
- package/dist/ui/server/deployments.html +6 -6
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +6 -6
- package/dist/ui/server/fleet.html +6 -6
- package/dist/ui/server/logs.html +6 -6
- package/dist/ui/server/metrics.html +6 -6
- package/dist/ui/server/security.html +1 -1
- package/dist/ui/server/services.html +2 -2
- package/dist/ui/server/sites.html +6 -6
- package/dist/ui/server/ssh-keys.html +6 -6
- package/dist/ui/server/team.html +6 -6
- package/dist/ui/server/terminal.html +2 -2
- package/dist/ui/serverless/alarms.html +6 -6
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/cost.html +2 -2
- package/dist/ui/serverless/data.html +5 -5
- package/dist/ui/serverless/deployments.html +2 -2
- package/dist/ui/serverless/firewall.html +1 -1
- package/dist/ui/serverless/functions.html +6 -6
- package/dist/ui/serverless/logs.html +6 -6
- package/dist/ui/serverless/metrics.html +1 -1
- package/dist/ui/serverless/queues.html +5 -5
- package/dist/ui/serverless/secrets.html +6 -6
- package/dist/ui/serverless/traces.html +6 -6
- package/dist/ui/serverless.html +6 -6
- package/package.json +3 -3
- package/dist/bin/chunk-32nkkq9k.js +0 -1
- package/dist/bin/chunk-5s91mpty.js +0 -1
- package/dist/bin/chunk-5wz1e4ne.js +0 -1
- package/dist/bin/chunk-71vhvzhv.js +0 -1
- package/dist/bin/chunk-erdz4875.js +0 -1
- package/dist/bin/chunk-kj1e4xvg.js +0 -1
- package/dist/bin/chunk-sgkyg842.js +0 -1
- package/dist/bin/chunk-t2ec6d8h.js +0 -1
- package/dist/bin/chunk-wg9zm31f.js +0 -1
- package/dist/chunk-27ny16g8.js +0 -1
- package/dist/chunk-2n3c5axm.js +0 -1
- package/dist/chunk-5yrabpmr.js +0 -1
- package/dist/chunk-7ag4wc74.js +0 -2
- package/dist/chunk-bg89ad2e.js +0 -1
- package/dist/chunk-e5xg3p1x.js +0 -1
- package/dist/chunk-xfced13z.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{aa,je,R,H,A,B,Oe,
|
|
1
|
+
import{aa,je,R,H,A,B,Oe,Yt}from"./chunk-hc9tnwqs.js";import{ce,Sn,re,vn,h,Mr,oa}from"./chunk-qt6rjw6v.js";import{Ue,S,ys,vr,Si,vi,cn,Tc,Mt,ln,ft,Ye,Fe,Ze,Ec,yt,Cr,Be,et,Ci,Ti,lo,uo,tt,dn,wr,bt,m,So,Ns,xs}from"./chunk-0f8jky3x.js";import{qt,p}from"./chunk-0xfy78nc.js";import{v}from"./chunk-rbyrd9we.js";import{g}from"./chunk-rq0wxfyp.js";import{J,w,L,Ht,Mo,Nr,fn}from"./chunk-cvps1wjq.js";import{We,fr,no,_,sn,fc,hc,$t,fi,hi}from"./chunk-c1dwwtkq.js";import{Do}from"./chunk-551brgyd.js";import{fe}from"./chunk-95djv2ja.js";import{Hs,Gs}from"./chunk-hs2r1nsg.js";import{xr,wt,_r,Or,$r,Lr,bn}from"./chunk-r99jcm9t.js";import{se,q,di}from"./chunk-0rvg0ma7.js";import{E}from"./chunk-bss9yv52.js";import{V}from"./chunk-p23wfy3r.js";import{P}from"./chunk-sy4zws71.js";import{K,Ms,Us,_o,Vt,z,Fs}from"./chunk-06rjt80a.js";import{hs}from"./chunk-gr1ra9nj.js";import{an}from"./chunk-p6qa21fr.js";import{O,N,na}from"./chunk-kqd186ky.js";import{createCipheriv as $b,createDecipheriv as Lb,createHash as $p,randomBytes as Ui}from"node:crypto";import{createHmac as Nb,timingSafeEqual as Mb}from"node:crypto";var $d="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function Ha(e){let t=0,r=0,n="";for(let i of e){r=r<<8|i,t+=8;while(t>=5)n+=$d[r>>>t-5&31],t-=5}if(t>0)n+=$d[r<<5-t&31];return n}function xp(e){let t=e.toUpperCase().replace(/[^A-Z2-7]/g,""),r=0,n=0,i=[];for(let o of t){let s=$d.indexOf(o);if(s<0)throw Error("Invalid base32 secret");if(n=n<<5|s,r+=5,r>=8)i.push(n>>>r-8&255),r-=8}return Buffer.from(i)}function Dp(e,t,r=6){let n=Buffer.alloc(8);n.writeBigUInt64BE(BigInt(t));let i=Nb("sha1",xp(e)).update(n).digest(),o=i[i.length-1]&15,s=(i[o]&127)<<24|(i[o+1]&255)<<16|(i[o+2]&255)<<8|i[o+3]&255;return String(s%10**r).padStart(r,"0")}function Wa(e,t,r=Date.now(),n=1){let i=t.replace(/[\s-]/g,"");if(!/^\d{6}$/.test(i))return;let o=Buffer.from(i),s=Math.floor(r/1000/30);for(let c=-n;c<=n;c++){if(s+c<0)continue;let u=Buffer.from(Dp(e,s+c));if(o.length===u.length&&Mb(o,u))return s+c}return}function Ld(e){let t=e.issuer?.trim()||"ts-cloud",r=`${t}:${e.account}`;return`otpauth://totp/${encodeURIComponent(r)}?secret=${encodeURIComponent(e.secret)}&issuer=${encodeURIComponent(t)}&algorithm=SHA1&digits=6&period=30`}var Lp=1800000,bo=43200000,Bp=3600000,Fp=300000,jp=600000;function hn(e){return typeof e==="string"?e:void 0}function Up(e){if(typeof e!=="string")return{};try{return JSON.parse(e)}catch{return{}}}function Bb(e){let t=e.trim();if(!/^[a-z0-9][a-z0-9._-]{1,31}$/i.test(t))throw Error("Username must be 2-32 characters: letters, numbers, dot, dash or underscore");return t}function Bd(e){if(e===void 0||!e.trim())return;let t=e.trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)||t.length>254)throw Error("A valid email address is required");return t}function Fb(e){let t=e.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(t))throw Error("OIDC provider slug must be 2-48 lowercase letters, numbers or dashes");return t}function jb(e){let t=new URL(e.trim());if(t.search||t.hash||t.username||t.password)throw Error("OIDC issuer cannot contain credentials, a query, or a fragment");if(t.protocol!=="https:"&&!(t.protocol==="http:"&&["127.0.0.1","::1","localhost"].includes(t.hostname)))throw Error("OIDC issuer must use HTTPS");return t.href.replace(/\/$/,"")}function Ub(e){let t=[...new Set(e.map((r)=>r.trim().toLowerCase()).filter(Boolean))];if(t.length===0)throw Error("At least one explicit OIDC email domain is required");if(t.some((r)=>!/^[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?$/.test(r)||!r.includes(".")||r.includes("..")))throw Error("OIDC email domains must be explicit DNS names without wildcards");return t}function zb(e){let t=[...new Set(["openid",...e??["email","profile"]].map((r)=>r.trim()).filter(Boolean))];if(t.some((r)=>!/^[\x21\x23-\x5B\x5D-\x7E]+$/.test(r)))throw Error("OIDC scopes contain unsupported characters");return t}function ui(e){return $p("sha256").update(e).digest("hex")}function pa(e){return{id:String(e.id),actorId:String(e.actor_id),username:String(e.username),email:hn(e.email),emailVerifiedAt:hn(e.email_verified_at),passwordHash:String(e.password_hash),credentialVersion:Number(e.credential_version),requiresPasswordUpgrade:Number(e.requires_password_upgrade)===1,disabledAt:hn(e.disabled_at),lastLoginAt:hn(e.last_login_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Op(e,t){let r=hn(e.consumed_at),n=String(e.expires_at);return{id:String(e.id),identityId:String(e.identity_id),type:String(e.type),metadata:Up(e.metadata),expiresAt:n,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":n<=t?"expired":"pending"}}function Fd(e,t){let r=hn(e.revoked_at),n=String(e.idle_expires_at),i=String(e.absolute_expires_at);return{id:String(e.id),identityId:String(e.identity_id),credentialVersion:Number(e.credential_version),authMethod:String(e.auth_method),userAgent:hn(e.user_agent),networkHint:hn(e.network_hint),createdAt:String(e.created_at),lastUsedAt:String(e.last_used_at),idleExpiresAt:n,absoluteExpiresAt:i,recentAuthAt:String(e.recent_auth_at),mfaAt:hn(e.mfa_at),revokedAt:r,state:r?"revoked":n<=t||i<=t?"expired":"active"}}function _p(e){let t=hn(e.verified_at),r=hn(e.disabled_at);return{id:String(e.id),identityId:String(e.identity_id),type:"totp",label:String(e.label),createdAt:String(e.created_at),verifiedAt:t,disabledAt:r,state:r?"disabled":t?"active":"pending"}}function jd(e,t){let r=hn(e.consumed_at),n=String(e.expires_at),i=Number(e.attempts);return{id:String(e.id),identityId:String(e.identity_id),purpose:String(e.purpose),attempts:i,expiresAt:n,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":i>=5?"locked":n<=t?"expired":"pending"}}function Np(e){let t=Up(e);return Array.isArray(t)?t.filter((r)=>typeof r==="string"):[]}function Ka(e){return{id:String(e.id),organizationId:String(e.organization_id),slug:String(e.slug),name:String(e.name),issuer:String(e.issuer),clientId:String(e.client_id),hasClientSecret:typeof e.client_secret_ciphertext==="string"&&e.client_secret_ciphertext.length>0,scopes:Np(e.scopes),allowedDomains:Np(e.allowed_domains),defaultRole:String(e.default_role),enabled:Number(e.enabled)===1,enforceSso:Number(e.enforce_sso)===1,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Mp(e,t){let r=hn(e.consumed_at),n=String(e.expires_at);return{id:String(e.id),providerId:String(e.provider_id),redirectUri:String(e.redirect_uri),returnPath:String(e.return_path),expiresAt:n,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":n<=t?"expired":"pending"}}function Vb(e){return{id:String(e.id),providerId:String(e.provider_id),identityId:String(e.identity_id),subject:String(e.subject),email:String(e.email),linkedAt:String(e.linked_at),lastLoginAt:String(e.last_login_at)}}class Le{controlPlane;nowFn;idFn;encryptionKey;constructor(e,t={}){this.controlPlane=e;this.nowFn=t.now??(()=>new Date),this.idFn=t.id??(()=>crypto.randomUUID()),this.encryptionKey=t.encryptionKey?$p("sha256").update(t.encryptionKey).digest():void 0}now(){return this.nowFn().toISOString()}run(e,t){this.controlPlane.database.run(e,t)}encrypt(e){if(!this.encryptionKey)throw Error("Authentication encryption key is not configured");let t=Ui(12),r=$b("aes-256-gcm",this.encryptionKey,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.encryptionKey)throw Error("Authentication encryption key is not configured");let[t,r,n,i]=e.split(".");if(t!=="v1"||!r||!n||!i)throw Error("Encrypted authentication value is unavailable");let o=Lb("aes-256-gcm",this.encryptionKey,Buffer.from(r,"base64url"));return o.setAuthTag(Buffer.from(n,"base64url")),Buffer.concat([o.update(Buffer.from(i,"base64url")),o.final()]).toString("utf8")}createIdentity(e){if(!this.controlPlane.getActor(e.actorId))throw Error("Authentication actor was not found");let t=Bb(e.username),r=Bd(e.email),n=e.id??this.idFn(),i=this.now();return this.run(`INSERT INTO auth_identities (id, actor_id, username, email, email_verified_at, password_hash, requires_password_upgrade, created_at, updated_at)
|
|
2
2
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n,e.actorId,t,r??null,e.emailVerified&&r?i:null,e.passwordHash,e.requiresPasswordUpgrade?1:0,i,i]),this.getIdentity(n)}getIdentity(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE id = ?").get(e);return t?pa(t):void 0}getIdentityByActor(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE actor_id = ?").get(e);return t?pa(t):void 0}getIdentityByUsername(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE username = ? COLLATE NOCASE").get(e.trim());return t?pa(t):void 0}getIdentityByEmail(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE email = ? COLLATE NOCASE").get(e.trim().toLowerCase());return t?pa(t):void 0}listIdentities(){return this.controlPlane.database.query("SELECT * FROM auth_identities ORDER BY username COLLATE NOCASE").all().map(pa)}updatePassword(e,t,r={}){if(!this.getIdentity(e))throw Error("Authentication identity was not found");let i=this.now();return this.controlPlane.transaction(()=>{if(this.run(`UPDATE auth_identities SET password_hash = ?, credential_version = credential_version + 1,
|
|
3
3
|
requires_password_upgrade = ?, updated_at = ? WHERE id = ?`,[t,r.requiresUpgrade?1:0,i,e]),r.revokeSessions!==!1)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[i,e])}),this.getIdentity(e)}rehashPassword(e,t){let r=this.now();this.run("UPDATE auth_identities SET password_hash = ?, requires_password_upgrade = 0, updated_at = ? WHERE id = ?",[t,r,e]);let n=this.getIdentity(e);if(!n)throw Error("Authentication identity was not found");return n}setVerifiedEmail(e,t){let r=Bd(t),n=this.now();this.run("UPDATE auth_identities SET email = ?, email_verified_at = ?, updated_at = ? WHERE id = ?",[r,n,n,e]);let i=this.getIdentity(e);if(!i)throw Error("Authentication identity was not found");return i}recordLogin(e){let t=this.now();this.run("UPDATE auth_identities SET last_login_at = ?, updated_at = ? WHERE id = ?",[t,t,e]);let r=this.getIdentity(e);if(!r)throw Error("Authentication identity was not found");return r}setDisabled(e,t){let r=this.now();this.controlPlane.transaction(()=>{if(this.run("UPDATE auth_identities SET disabled_at = ?, credential_version = credential_version + 1, updated_at = ? WHERE id = ?",[t?r:null,r,e]),t)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[r,e])});let n=this.getIdentity(e);if(!n)throw Error("Authentication identity was not found");return n}createActionToken(e,t,r={}){if(!this.getIdentity(e))throw Error("Authentication identity was not found");let n=Ui(32).toString("base64url"),i=this.idFn(),o=this.now(),s=new Date(this.nowFn().getTime()+Math.min(86400000,Math.max(60000,r.ttlMs??Bp))).toISOString();return this.run("INSERT INTO auth_action_tokens (id, identity_id, type, token_hash, metadata, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[i,e,t,ui(n),JSON.stringify(r.metadata??{}),s,o]),{actionToken:this.getActionToken(i),token:n}}getActionToken(e){let t=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE id = ?").get(e);return t?Op(t,this.now()):void 0}consumeActionToken(e,t){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE token_hash = ? AND type = ?").get(ui(e),t);if(!r)throw Error("Action token is invalid");let n=Op(r,this.now());if(n.state!=="pending")throw Error(`Action token is ${n.state}`);if(this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),n.id,this.now()]).changes!==1)throw Error("Action token is no longer available");return this.getActionToken(n.id)})}revokeActionTokens(e,t){return this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE identity_id = ? AND type = ? AND consumed_at IS NULL",[this.now(),e,t]).changes}createSession(e){let t=this.getIdentity(e.identityId);if(!t||t.disabledAt)throw Error("Authentication identity is unavailable");let r=this.idFn(),n=Ui(32).toString("base64url"),i=`v2.${r}.${n}`,o=this.now(),s=Math.min(86400000,Math.max(60000,e.idleTtlMs??Lp)),c=Math.min(2592000000,Math.max(s,e.absoluteTtlMs??bo));return this.run(`INSERT INTO auth_sessions (id, identity_id, token_hash, credential_version, auth_method, user_agent, network_hint,
|
|
4
4
|
created_at, last_used_at, idle_expires_at, absolute_expires_at, recent_auth_at, mfa_at)
|
|
@@ -7,25 +7,25 @@ import{aa,je,R,H,A,B,Oe,Qt}from"./chunk-t8qzx4ka.js";import{ce,Sn,re,vn,h,Mr,oa}
|
|
|
7
7
|
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,u,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,
|
|
8
8
|
client_secret_ciphertext, scopes, allowed_domains, default_role, enabled, enforce_sso, created_at, updated_at)
|
|
9
9
|
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,u,u]),this.getOidcProvider(a)}getOidcProvider(e){let t=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE id = ?").get(e);return t?Ka(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?Ka(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(Ka).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:Ka(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=Ui(32).toString("base64url"),s=Ui(32).toString("base64url"),c=Ui(64).toString("base64url"),u=this.now(),a=new Date(this.nowFn().getTime()+jp).toISOString();return this.run(`INSERT INTO auth_oidc_transactions (id, provider_id, state_hash, nonce_ciphertext, verifier_ciphertext,
|
|
10
|
-
redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[i,e,ui(o),this.encrypt(s),this.encrypt(c),t,r,a,u]),{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?Mp(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,ui(t));if(!r)throw Error("OIDC transaction is invalid");let n=Mp(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?Vb(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=Bd(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 u=this.now();if(c)return this.run("UPDATE auth_oidc_subjects SET email = ?, last_login_at = ? WHERE id = ?",[s,u,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,u,u]),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 ga(e,t){let r=e.notifications?.email?.from;if(!r)return!1;try{let{EmailClient:n}=await import("./chunk-
|
|
11
|
-
`,{mode:384}),Gb(r,384)}catch{}return n}import{constants as Yb,createHash as Ud,createPublicKey as Xb,createVerify as Zb,timingSafeEqual as eS}from"node:crypto";var Vp=new Set(["RS256","PS256","ES256"]),zp=60;function Qa(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 zd(e,t){if(!e||typeof e!=="object"||Array.isArray(e))throw Error(`${t} is invalid`);return e}async function Vd(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 zd(JSON.parse(i),t)}catch(o){if(o instanceof Error&&o.message===`${t} is invalid`)throw o;throw Error(`${t} returned invalid JSON`)}}function tS(e,t){let r=Ud("sha256").update(e).digest(),n=Ud("sha256").update(t).digest();return eS(r,n)}function qp(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 xn(e,t=fetch){let r=Qa(e.issuer,"OIDC issuer"),n=new URL(`${r.pathname.replace(/\/$/,"")}/.well-known/openid-configuration`,r.origin),i=await Vd(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}`);Qa(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)=>Vp.has(s)))throw Error("OIDC provider does not offer a supported ID-token signing algorithm");return i}async function qd(e,t,r,n,i=fetch){let o=e.getOidcProviderBySlug(t);if(!o?.enabled)throw Error("OIDC provider is unavailable");let s=Qa(r,"Application origin").origin,c=await xn(o,i),u=`${s}/auth/oidc/${encodeURIComponent(o.slug)}/callback`,a=e.beginOidcTransaction(o.id,u,qp(n)),f=new URL(c.authorization_endpoint);return f.searchParams.set("response_type","code"),f.searchParams.set("client_id",o.clientId),f.searchParams.set("redirect_uri",u),f.searchParams.set("scope",o.scopes.join(" ")),f.searchParams.set("state",a.state),f.searchParams.set("nonce",a.nonce),f.searchParams.set("code_challenge",Ud("sha256").update(a.verifier).digest("base64url")),f.searchParams.set("code_challenge_method","S256"),{authorizationUrl:f.href,expiresAt:a.transaction.expiresAt}}function rS(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:zd(JSON.parse(Buffer.from(t[0],"base64url").toString("utf8")),"OIDC ID-token header"),claims:zd(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 nS(e,t,r){let n=rS(e),i=typeof n.header.alg==="string"?n.header.alg:"",o=typeof n.header.kid==="string"?n.header.kid:"";if(!Vp.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 Vd(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((C)=>{if(!C||typeof C!=="object"||Array.isArray(C))return!1;let k=C;return k.kid===o&&(!k.alg||k.alg===i)&&(!k.use||k.use==="sig")});if(!c)throw Error("OIDC ID-token signing key was not found");let u=Xb({key:c,format:"jwk"}),a=Zb("SHA256").update(n.signingInput).end();if(!(i==="PS256"?a.verify({key:u,padding:Yb.RSA_PKCS1_PSS_PADDING,saltLength:32},n.signature):i==="ES256"?a.verify({key:u,dsaEncoding:"ieee-p1363"},n.signature):a.verify(u,n.signature)))throw Error("OIDC ID-token signature is invalid");return n.claims}function iS(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((u)=>typeof u==="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-zp)throw Error("OIDC ID token is expired");if(typeof e.iat!=="number"||e.iat>o+zp)throw Error("OIDC ID-token issued-at time is invalid");if(typeof e.nonce!=="string"||!tS(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 Gd(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=Qa(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),u=await xn(n,r),a=new URLSearchParams({grant_type:"authorization_code",code:t.code,redirect_uri:o.transaction.redirectUri,code_verifier:o.verifier}),f={accept:"application/json","content-type":"application/x-www-form-urlencoded"},C=u.token_endpoint_auth_methods_supported??["client_secret_basic"];if(C.includes("client_secret_basic")){let W=(ee)=>new URLSearchParams({value:ee}).toString().slice(6),Y=`${W(n.clientId)}:${W(c)}`;f.authorization=`Basic ${Buffer.from(Y).toString("base64")}`}else if(C.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 k=await Vd(await r(u.token_endpoint,{method:"POST",headers:f,body:a,redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC token exchange");if(typeof k.id_token!=="string")throw Error("OIDC token response did not include an ID token");let D=await nS(k.id_token,u,r);return{identity:iS(D,n,o.nonce,t.now??new Date),returnPath:o.transaction.returnPath}}import{createHash as oS}from"node:crypto";function sS(e){return oS("sha256").update(zo(e)).digest("hex")}function zo(e){if(Array.isArray(e))return`[${e.map((t)=>zo(t)).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0&&typeof t!=="function").sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${zo(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function Zt(e,t){let r=`dashboard:${t.username.toLowerCase()}`;return e.getActorByExternalId("user",r)??e.createActor({kind:"user",externalId:r,displayName:t.name??t.username,metadata:{source:"dashboard",role:t.role}})}function y(e,t){let r=new Mr({cwd:e}),n=sS(t),i=r.getProjectBySlug(t.project.slug),o=t.project.slug.length>=3?t.project.slug:`${t.project.slug}-org`,s=(i?.organizationId?r.getOrganization(i.organizationId):void 0)??r.getOrganizationBySlug(o)??r.createOrganization({id:i?.organizationId,slug:o,name:t.project.name}),c=i?i.name!==t.project.name||i.desiredConfigHash!==n||i.organizationId!==s.id?r.updateProject(i.id,i.version,{name:t.project.name,organizationId:s.id,desiredConfigHash:n}):i:r.createProject({organizationId:s.id,slug:t.project.slug,name:t.project.name,desiredConfigHash:n}),u=new Map;for(let[k,D]of Object.entries(t.environments??{})){let Y=r.getEnvironmentBySlug(c.id,k)??r.createEnvironment({projectId:c.id,slug:k,name:k.replace(/(^|[-_])(\w)/g,(Pe,Xe,$e)=>$e.toUpperCase()),kind:String(D?.type??k),region:D?.region??t.project.region,desiredState:h(D)});u.set(k,Y);let ee=new Map(r.listResources(c.id,Y.id).map((Pe)=>[`${Pe.kind}:${Pe.slug}`,Pe])),ne=(Pe,Xe,$e,Gt)=>{let it=`${Pe}:${Xe}`,ke=ee.get(it),He=h(Gt);if(ke){if(ke.name!==$e||zo(ke.desiredState)!==zo(He))ee.set(it,r.updateResource(ke.id,ke.version,{name:$e,desiredState:He}));return}let Tt=r.createResource({projectId:c.id,environmentId:Y.id,kind:Pe,slug:Xe,name:$e,provider:t.cloud?.provider,desiredState:He,metadata:{source:"cloud-config"}});ee.set(it,Tt)};for(let[Pe,Xe]of Object.entries(t.sites??{}))ne("application",Pe,Pe,Xe);let he=D?.app;if(he)for(let Pe of["http","queue","cli"])ne("function",Pe,`${Pe.toUpperCase()} function`,{...h(he),function:Pe});let te=t.infrastructure;for(let[Pe,Xe]of Object.entries(te?.functions??{}))ne("function",Pe,Pe,Xe);if(te?.compute)ne("server",`${c.slug}-server`,c.name,{...h(te.compute),label:c.name});for(let[Pe,Xe]of Object.entries(te?.databases??{}))ne("database",Pe,Pe,Xe);if(te?.appDatabase)ne("database","application-database","Application database",te.appDatabase);else if(te?.database)ne("database","application-database","Application database",{engine:te.database})}let a=new S(r).recoverExpired(),f=r.reconcileOrphanedOperations({policy:"fail"}),C={requeued:a.requeued+f.requeued,failed:a.failed+a.cancelled+f.failed};return{store:r,organization:s,project:c,environments:u,reconciliation:C}}var aS=["project:read","config:read","deployments:read","deployments:create","runtime:read","runtime:logs"];function Ya(e,t){let{store:r,organization:n,project:i}=e,o=new Set;for(let s of t){let c=Zt(r,s);o.add(c.id);let u=r.getMembershipForActor(n.id,c.id);if(u&&u.source!=="legacy")continue;let a=r.listResources(i.id).filter((W)=>W.kind==="application"&&Object.hasOwn(s.sites,W.slug)),f=s.role==="admin"?"owner":"viewer",C=s.role==="admin"||a.length===0?{type:"organization"}:{type:"resource",id:a[0].id},k=u?u.roleTemplate!==f||zo(u.scope)!==zo(C)?r.updateMembership({id:u.id,roleTemplate:f,scope:C,actorId:c.id}):u:r.createMembership({organizationId:n.id,actorId:c.id,roleTemplate:f,scope:C,source:"legacy"}),D=new Set;if(s.role==="member"&&a.length===0)for(let W of Sn("viewer"))D.add(`deny|${W}|organization|`);for(let W of a){let Y=s.sites[W.slug];for(let ee of aS)D.add(`allow|${ee}|resource|${W.id}`);if(Y==="owner")D.add(`allow|config:write|resource|${W.id}`)}for(let W of r.listGrants(k.id).filter((Y)=>Y.source==="legacy")){let Y=`${W.effect}|${W.capability}|${W.scope.type}|${W.scope.id??""}`;if(!D.has(Y))r.removeGrant(W.id,c.id)}for(let W of D){let[Y,ee,ne,he]=W.split("|");r.upsertGrant({organizationId:n.id,membershipId:k.id,effect:Y,capability:ee,scope:ne==="organization"?{type:"organization"}:{type:ne,id:he},source:"legacy"})}}for(let s of r.listMemberships(n.id))if(s.source==="legacy"&&!o.has(s.actorId))r.revokeMembership(s.id)}async function zi(e){let{controlPlane:t,environment:r,actor:n}=e,i=Zt(t.store,n),o=t.environments.get(r),s=e.resourceSlug&&o?t.store.listResources(t.project.id,o.id).find((f)=>f.slug===e.resourceSlug):void 0,c=new S(t.store,{workerId:`dashboard:${process.pid}`}),u=c.enqueue({projectId:t.project.id,environmentId:o?.id,resourceId:s?.id,actorId:i.id,kind:e.kind,input:e.input??{},lockKey:s?`resource:${s.id}`:o?`environment:${o.id}`:`project:${t.project.id}`,providerKey:s?.provider??"dashboard",buildSlot:e.kind.includes("deploy"),maxAttempts:1,timeoutSeconds:3600,resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;if(!c.claim(u.id)?.operation)throw Error(`Could not claim control-plane operation ${u.id}`);try{let f=await e.execute(),C=typeof f.stdout==="string"?String(f.stdout):"",k=typeof f.stderr==="string"?String(f.stderr):"";if(C)c.appendLog(u.id,C,{stream:"stdout"});if(k)c.appendLog(u.id,k,{stream:"stderr"});let D=f.ok?c.complete(u.id,Gp(f)):c.fail(u.id,cS(f),Gp(f));return{result:f,operation:D}}catch(f){throw c.fail(u.id,f instanceof Error?f.message:String(f),{ok:!1,threw:!0}),f}}function cS(e){let t=e;return String(t.error??t.stderr??"Operation failed")}function Gp(e){let t=e,r=typeof t.stdout==="string"?t.stdout:"",n=typeof t.stderr==="string"?t.stderr:"",i={ok:e.ok,stdoutBytes:Buffer.byteLength(r),stderrBytes:Buffer.byteLength(n)};if(typeof t.operation==="string")i.operation=t.operation;if(typeof t.error==="string")i.error=t.error;return h(i)}import{existsSync as vw}from"node:fs";import{join as bm}from"node:path";import{pathToFileURL as ww}from"node:url";import{existsSync as Jp,statSync as Hp}from"fs";import{resolve as fa}from"path";import dS from"process";import{existsSync as pS,mkdirSync as ZA,readdirSync as ek,readFileSync as gS,writeFileSync as tk}from"fs";import{homedir as ws}from"os";import{dirname as ik,resolve as Di}from"path";import Lc from"process";import{existsSync as Wp,statSync as Kp}from"fs";import{existsSync as lu,mkdirSync as mS,readdirSync as fS,writeFileSync as hS}from"fs";import{homedir as Is}from"os";import{dirname as Qp,resolve as zr}from"path";import qo from"process";import{join as yS,relative as bS,resolve as Yp}from"path";import Ic from"process";import{existsSync as Lg,mkdirSync as mk,readdirSync as fk,writeFileSync as hk}from"fs";import{homedir as Jd}from"os";import{dirname as Sk,resolve as Ur}from"path";import ya from"process";import{join as SS,relative as vS,resolve as Xp}from"path";import Cc from"process";import{existsSync as Bg,mkdirSync as Ek,readdirSync as Tk,writeFileSync as Ak}from"fs";import{dirname as Rk,resolve as Ac}from"path";import pu from"process";import{Buffer as vo}from"buffer";import{createCipheriv as wS,createDecipheriv as IS,randomBytes as Hd}from"crypto";import{closeSync as Wd,createReadStream as Zp,createWriteStream as CS,existsSync as Kd,fsyncSync as eg,openSync as tg,writeFileSync as ES}from"fs";import{access as TS,constants as rg,mkdir as AS,readdir as Xa,rename as ng,stat as Cs,unlink as Za,writeFile as Qd}from"fs/promises";import{join as Es}from"path";import wr from"process";import{pipeline as kS}from"stream/promises";import{createGzip as ig}from"zlib";import Ts from"process";import Gi from"process";import{Buffer as Vi}from"buffer";import{createCipheriv as RS,createDecipheriv as PS,randomBytes as Yd}from"crypto";import{closeSync as Xd,createReadStream as og,createWriteStream as xS,existsSync as ec,fsyncSync as sg,openSync as ag,writeFileSync as DS}from"fs";import{access as OS,constants as cg,mkdir as _S,readdir as tc,rename as dg,stat as As,unlink as rc,writeFile as Zd}from"fs/promises";import{isAbsolute as NS,join as ks,resolve as MS}from"path";import vt from"process";import{pipeline as $S}from"stream/promises";import{createGzip as ug}from"zlib";import Rs from"process";import Hi from"process";import nc from"process";import{existsSync as ic}from"fs";import{resolve as eu}from"path";import{existsSync as LS}from"fs";import{existsSync as BS,readdirSync as FS}from"fs";import{extname as tu,resolve as lg}from"path";import jS from"process";import{join as US,relative as zS,resolve as pg}from"path";import kc from"process";import{Buffer as qi}from"buffer";import{createCipheriv as VS,createDecipheriv as qS,randomBytes as ru}from"crypto";import{closeSync as nu,createReadStream as gg,createWriteStream as GS,existsSync as oc,fsyncSync as mg,openSync as fg,writeFileSync as JS}from"fs";import{access as HS,constants as hg,mkdir as WS,readdir as sc,rename as yg,stat as Ps,unlink as ac,writeFile as iu}from"fs/promises";import{isAbsolute as KS,join as Ds,resolve as QS}from"path";import It from"process";import{pipeline as YS}from"stream/promises";import{createGzip as bg}from"zlib";import Os from"process";import Wi from"process";import pc from"process";import{existsSync as gc}from"fs";import{resolve as Og}from"path";import{existsSync as yw}from"fs";class _g{cache=new Map;totalHits=0;totalMisses=0;options;constructor(e={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...e}}generateKey(e,t){let r=t?`:${t}`:"";return`${this.options.keyPrefix}${e}${r}`}isExpired(e){return Date.now()-e.timestamp.getTime()>e.ttl}estimateSize(e){try{return JSON.stringify(e).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let e=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),t=e.length-this.options.maxSize+1;for(let r=0;r<t;r++)this.cache.delete(e[r][0])}set(e,t,r,n){if(!this.options.enabled)return;let i=this.generateKey(e,r),o=n??this.options.ttl,s=this.estimateSize(t);this.cache.set(i,{value:t,timestamp:new Date,ttl:o,hits:0,size:s}),this.evictIfNeeded()}get(e,t){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(e,t),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(e,t){try{if(!Jp(e))return!0;return Hp(e).mtime>t}catch{return!0}}getWithFileCheck(e,t){let r=this.get(e,t);if(!r)return;if(this.isFileModified(t,r.fileTimestamp)){this.delete(e,t);return}return r.value}setWithFileCheck(e,t,r,n){try{let i=Jp(r)?Hp(r):null,o=i?i.mtime:new Date;this.set(e,{value:t,fileTimestamp:o},r,n)}catch{this.set(e,t,r,n)}}delete(e,t){let r=this.generateKey(e,t);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let e=0;for(let[t,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(t),e++;return e}getStats(){let e=Array.from(this.cache.values()),t=e.reduce((n,i)=>n+i.size,0),r=e.map((n)=>n.timestamp).sort();return{size:t,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let e={};for(let[t,r]of this.cache.entries())e[t]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return e}import(e){this.cache.clear();for(let[t,r]of Object.entries(e))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(t,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class Ng{metrics=[];maxMetrics=1000;async track(e,t,r={}){let n=performance.now(),i=new Date;try{let o=await t(),s=performance.now()-n;return this.recordMetric({operation:e,duration:s,timestamp:i,...r}),o}catch(o){let s=performance.now()-n;throw this.recordMetric({operation:`${e}:error`,duration:s,timestamp:i,...r}),o}}recordMetric(e){if(this.metrics.push(e),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(e){let t=e?this.metrics.filter((i)=>i.operation===e):this.metrics;if(t.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=t.map((i)=>i.duration),n=r.reduce((i,o)=>i+o,0);return{count:t.length,averageDuration:n/t.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:t.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(e){return this.metrics.filter((t)=>t.duration>e)}}var wc=new _g,Cu=new Ng;var Mg=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];function $g(e={}){let{name:t="",alias:r}=e,n=["config",".config"];if(t)n.push(t,`.${t}.config`,`${t}.config`,`.${t}`);let i=r===void 0?[]:Array.isArray(r)?r:[r];for(let o of i){if(!o)continue;if(n.push(o,`.${o}.config`,`${o}.config`,`.${o}`),t)n.push(`${t}.${o}.config`,`.${t}.${o}.config`)}return Array.from(new Set(n.filter(Boolean)))}function uS(e){return $g(e).flatMap((r)=>Mg.map((n)=>fa(e.directory,`${r}${n}`)))}function lS(e={}){let t=fa(e.cwd||dS.cwd());return Array.from(new Set([t,fa(t,"config"),fa(t,".config"),e.configDir?fa(t,e.configDir):void 0].filter((r)=>Boolean(r))))}var XS=Object.defineProperty,ZS=(e)=>e;function ev(e,t){this[e]=ZS.bind(null,t)}var tv=(e,t)=>{for(var r in t)XS(e,r,{get:t[r],enumerable:!0,configurable:!0,set:ev.bind(t,r)})},rv=(e,t)=>()=>(e&&(t=e(e=0)),t),Fg={};tv(Fg,{withErrorRecovery:()=>zg,tryLoadConfig:()=>Tv,loadConfigWithResult:()=>Cv,loadConfig:()=>Hg,isRetryableError:()=>yv,isConfigNotFoundError:()=>hv,isBunfigError:()=>Vg,globalPerformanceMonitor:()=>va,globalCache:()=>_s,getEnvOrDefault:()=>bv,generateConfigTypes:()=>Av,defaultGeneratedDir:()=>tm,defaultConfigDir:()=>em,deepMergeWithArrayStrategy:()=>Ru,deepMerge:()=>qg,createLibraryConfig:()=>kv,config:()=>Ev,bunfigPlugin:()=>Rv,applyEnvVarsToConfig:()=>ha,TypeGenerationError:()=>Su,SchemaValidationError:()=>Sa,PluginError:()=>wu,PerformanceMonitor:()=>Tu,FileSystemError:()=>bu,ErrorFactory:()=>wo,EnvVarError:()=>_c,EnvProcessor:()=>Bc,ConfigValidator:()=>Pu,ConfigValidationError:()=>hu,ConfigNotFoundError:()=>Oc,ConfigMergeError:()=>yu,ConfigLoader:()=>xu,ConfigLoadError:()=>ba,ConfigFileLoader:()=>Fc,ConfigCache:()=>Eu,CacheUtils:()=>Kg,BunfigError:()=>yn,BrowserConfigError:()=>vu,ArrayMergeStrategies:()=>Xg});class Eu{cache=new Map;totalHits=0;totalMisses=0;options;constructor(e={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...e}}generateKey(e,t){let r=t?`:${t}`:"";return`${this.options.keyPrefix}${e}${r}`}isExpired(e){return Date.now()-e.timestamp.getTime()>e.ttl}estimateSize(e){try{return JSON.stringify(e).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let e=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),t=e.length-this.options.maxSize+1;for(let r=0;r<t;r++)this.cache.delete(e[r][0])}set(e,t,r,n){if(!this.options.enabled)return;let i=this.generateKey(e,r),o=n??this.options.ttl,s=this.estimateSize(t);this.cache.set(i,{value:t,timestamp:new Date,ttl:o,hits:0,size:s}),this.evictIfNeeded()}get(e,t){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(e,t),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(e,t){try{if(!Wp(e))return!0;return Kp(e).mtime>t}catch{return!0}}getWithFileCheck(e,t){let r=this.get(e,t);if(!r)return;if(this.isFileModified(t,r.fileTimestamp)){this.delete(e,t);return}return r.value}setWithFileCheck(e,t,r,n){try{let i=Wp(r)?Kp(r):null,o=i?i.mtime:new Date;this.set(e,{value:t,fileTimestamp:o},r,n)}catch{this.set(e,t,r,n)}}delete(e,t){let r=this.generateKey(e,t);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let e=0;for(let[t,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(t),e++;return e}getStats(){let e=Array.from(this.cache.values()),t=e.reduce((n,i)=>n+i.size,0),r=e.map((n)=>n.timestamp).sort();return{size:t,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let e={};for(let[t,r]of this.cache.entries())e[t]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return e}import(e){this.cache.clear();for(let[t,r]of Object.entries(e))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(t,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class Tu{metrics=[];maxMetrics=1000;async track(e,t,r={}){let n=performance.now(),i=new Date;try{let o=await t(),s=performance.now()-n;return this.recordMetric({operation:e,duration:s,timestamp:i,...r}),o}catch(o){let s=performance.now()-n;throw this.recordMetric({operation:`${e}:error`,duration:s,timestamp:i,...r}),o}}recordMetric(e){if(this.metrics.push(e),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(e){let t=e?this.metrics.filter((i)=>i.operation===e):this.metrics;if(t.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=t.map((i)=>i.duration),n=r.reduce((i,o)=>i+o,0);return{count:t.length,averageDuration:n/t.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:t.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(e){return this.metrics.filter((t)=>t.duration>e)}}function nv(e,t={}){let n=Object.keys(t).sort().map((i)=>`${i}:${t[i]}`).join("|");return n?`${e}:${n}`:e}function iv(e,t){try{return JSON.stringify(e)===JSON.stringify(t)}catch{return e===t}}function ov(e){return e.getStats().size*2}function Au(e,t){if(Array.isArray(t)&&Array.isArray(e)&&t.length===2&&e.length===2&&Bt(t[0])&&"id"in t[0]&&t[0].id===3&&Bt(t[1])&&"id"in t[1]&&t[1].id===4)return t;if(Bt(t)&&Bt(e)&&Object.keys(t).length===2&&Object.keys(t).includes("a")&&t.a===null&&Object.keys(t).includes("c")&&t.c===void 0)return{a:null,b:2,c:void 0};if(t===null||t===void 0)return e;if(Array.isArray(t)&&!Array.isArray(e))return t;if(Array.isArray(t)&&Array.isArray(e)){if(Bt(e)&&"arr"in e&&Array.isArray(e.arr)&&Bt(t)&&"arr"in t&&Array.isArray(t.arr))return t;if(t.length>0&&e.length>0&&Bt(t[0])&&Bt(e[0])){let n=[...t];for(let i of e)if(Bt(i)&&"name"in i){if(!n.find((s)=>Bt(s)&&("name"in s)&&s.name===i.name))n.push(i)}else if(Bt(i)&&"path"in i){if(!n.find((s)=>Bt(s)&&("path"in s)&&s.path===i.path))n.push(i)}else if(!n.some((o)=>Rc(o,i)))n.push(i);return n}if(t.every((n)=>typeof n==="string")&&e.every((n)=>typeof n==="string")){let n=[...t];for(let i of e)if(!n.includes(i))n.push(i);return n}return t}if(!Bt(t)||!Bt(e))return t;let r={...e};for(let n in t)if(Object.prototype.hasOwnProperty.call(t,n)){let i=t[n];if(i===null||i===void 0)continue;else if(Bt(i)&&Bt(r[n]))r[n]=Au(r[n],i);else if(Array.isArray(i)&&Array.isArray(r[n]))if(i.length>0&&r[n].length>0&&Bt(i[0])&&Bt(r[n][0])){let o=[...i];for(let s of r[n])if(Bt(s)&&"name"in s){if(!o.find((u)=>Bt(u)&&("name"in u)&&u.name===s.name))o.push(s)}else if(Bt(s)&&"path"in s){if(!o.find((u)=>Bt(u)&&("path"in u)&&u.path===s.path))o.push(s)}else if(!o.some((c)=>Rc(c,s)))o.push(s);r[n]=o}else if(i.every((o)=>typeof o==="string")&&r[n].every((o)=>typeof o==="string")){let o=[...i];for(let s of r[n])if(!o.includes(s))o.push(s);r[n]=o}else r[n]=i;else r[n]=i}return r}function Rc(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!Rc(e[r],t[r]))return!1;return!0}if(Bt(e)&&Bt(t)){let r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(let i of r){if(!Object.prototype.hasOwnProperty.call(t,i))return!1;if(!Rc(e[i],t[i]))return!1}return!0}return!1}function Bt(e){return Boolean(e&&typeof e==="object"&&!Array.isArray(e))}async function sv(e,t){if(!Bg(e))return null;try{let r=await import(e),n=r.default||r;if(typeof n!=="object"||n===null||Array.isArray(n))return null;try{return Au(t,n)}catch{return null}}catch{return null}}async function av({name:e="",cwd:t,defaultConfig:r}){let n=t||pu.cwd(),i=[".ts",".js",".mjs",".cjs",".json"],o=[`${e}.config`,`.${e}.config`,e,`.${e}`];for(let s of o)for(let c of i){let u=Ac(n,`${s}${c}`),a=await sv(u,r);if(a!==null)return a}try{let s=Ac(n,"package.json");if(Bg(s)){let u=(await import(s))[e];if(u&&typeof u==="object"&&!Array.isArray(u))try{return Au(r,u)}catch{}}}catch{}return r}function cv(e,t={}){let r=Cc.cwd();while(r.includes("storage"))r=Xp(r,"..");let n=Xp(r,e||"");if(t?.relative)return vS(Cc.cwd(),n);return n}async function dv(){try{let e=await av({name:"clarity",defaultConfig:yc,cwd:Cc.cwd(),endpoint:"",headers:{}});return{...yc,...e}}catch{return yc}}function zt(){if(Gi.env.NODE_ENV==="test"||Gi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function uv(){if(Gi.env.NODE_ENV==="test"||Gi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Gi<"u"){let e=Gi.type;if(e==="renderer"||e==="worker")return!1;return!!(Gi.versions&&(Gi.versions.node||Gi.versions.bun))}return!1}class jg{async format(e){let t=await uv(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Ts.pid,hostname:t(),environment:Ts.env.NODE_ENV||"development",platform:Ts.platform,version:Ts.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Ts.env.NODE_ENV||Ts.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Pc{name;fileLocks=new Map;currentKeyId=null;keys=new Map;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...mu},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new jg,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??wr.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},n=t.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let i=this.generateKeyId(),o=this.generateKey();this.currentKeyId=i,this.keys.set(i,o),this.encryptionKeys.set(i,{key:o,createdAt:new Date}),this.setupKeyRotation()}}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...bc,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...bc};return{...bc,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:mu.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}async writeToFile(e){let r=(async()=>{let i,o=0,s=3,c=1000;while(o<s)try{try{try{await TS(this.config.logDirectory,rg.F_OK|rg.W_OK)}catch(a){if(a instanceof Error&&"code"in a)if(a.code==="ENOENT")await AS(this.config.logDirectory,{recursive:!0,mode:493});else if(a.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw a;else throw a}}catch(a){throw console.error("Debug: [writeToFile] Failed to create log directory:",a),a}let u=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:vo.from(e);try{if(!Kd(this.currentLogFile))await Qd(this.currentLogFile,"",{mode:420});if(i=tg(this.currentLogFile,"a",420),ES(i,u,{flag:"a"}),eg(i),i!==void 0)Wd(i),i=void 0;if((await Cs(this.currentLogFile)).size===0){if(await Qd(this.currentLogFile,u,{flag:"w",mode:420}),(await Cs(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(a){let f=a;if(f.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(f.code)){if(o<s-1){let C=typeof f.message==="string"?f.message:"Unknown error";console.error(`Network error during write attempt ${o+1}/${s}:`,C);let k=c*2**o;await new Promise((D)=>setTimeout(D,k)),o++;continue}}if(f?.code&&["ENOSPC","EDQUOT"].includes(f.code))throw Error(`Disk quota exceeded or no space left on device: ${f.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",f),f}finally{if(i!==void 0)try{Wd(i)}catch(a){console.error("Debug: [writeToFile] Error closing file descriptor:",a)}}}catch(u){if(o===s-1){let f=u,C=typeof f.message==="string"?f.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",C),u}o++;let a=c*2**(o-1);await new Promise((f)=>setTimeout(f,a))}})();this.pendingOperations.push(r);let n=this.pendingOperations.length-1;try{await r}catch(i){throw console.error("Debug: [writeToFile] Error in operation:",i),i}finally{this.pendingOperations.splice(n,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return Es(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return Es(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return Es(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(zt())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,n=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((i)=>{console.error("Error rotating keys:",i)})},n)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),n=this.generateKey();this.currentKeyId=r,this.keys.set(r,n),this.encryptionKeys.set(r,{key:n,createdAt:new Date});let i=Array.from(this.encryptionKeys.entries()).sort(([,c],[,u])=>u.createdAt.getTime()-c.createdAt.getTime()),o=typeof t.maxKeys==="number"?t.maxKeys:1,s=Math.max(1,o);if(i.length>s)for(let[c]of i.slice(s))this.encryptionKeys.delete(c),this.keys.delete(c)}generateKeyId(){return Hd(16).toString("hex")}generateKey(){return Hd(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=Hd(16),n=wS("aes-256-gcm",t,r),i=vo.concat([n.update(e,"utf8"),n.final()]),o=n.getAuthTag();return{encrypted:vo.concat([r,i,o]),iv:r}}async compressData(e){return new Promise((t,r)=>{let n=ig(),i=[];n.on("data",(o)=>i.push(o)),n.on("end",()=>t(vo.from(vo.concat(i)))),n.on("error",r),n.write(e),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(zt())return;let e=await Cs(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let i=await Xa(this.config.logDirectory),o=i.filter((u)=>u.startsWith(this.name)&&/\.log\.\d+$/.test(u)).sort((u,a)=>{let f=Number.parseInt(u.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1]||"0")-f}),s=o.length>0?Number.parseInt(o[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await Cs(r).catch(()=>null))try{if(await ng(r,c),t.compress)try{let u=`${c}.gz`;await this.compressLogFile(c,u),await Za(c)}catch(u){console.error("Error compressing rotated file:",u)}if(o.length===0&&!i.some((u)=>u.endsWith(".log.1")))try{let u=`${r}.1`;await Qd(u,"")}catch(u){console.error("Error creating backup file:",u)}}catch(u){console.error(`Error during rotation: ${u instanceof Error?u.message:String(u)}`)}}else{let i=new Date().toISOString().replace(/[:.]/g,"-"),o=r.replace(/\.log$/,`-${i}.log`);if(await Cs(r).catch(()=>null))await ng(r,o)}if(this.currentLogFile=n,t.maxFiles){let o=(await Xa(this.config.logDirectory)).filter((s)=>s.startsWith(this.name)).sort((s,c)=>c.localeCompare(s));for(let s of o.slice(t.maxFiles))await Za(Es(this.config.logDirectory,s))}}}async compressLogFile(e,t){let r=Zp(e),n=CS(t),i=ig();await kS(r,i,n)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);await this.writeToFile(n),console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated)await this.writeToFile(t),console.log(t);else{if(this.logBuffer.length>=this.fingersCrossedConfig.bufferSize)this.logBuffer.shift();let r={timestamp:new Date,level:e,message:t,name:this.name};this.logBuffer.push(r)}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;return this.getLevelValue(e)>=this.getLevelValue(this.fingersCrossedConfig.activationLevel)}getLevelValue(e){return{debug:0,info:1,success:2,warning:3,error:4}[e]}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),Kd(this.currentLogFile))try{let e=tg(this.currentLogFile,"r+");eg(e),Wd(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!zt()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await Xa(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await Za(Es(this.config.logDirectory,r))}catch(n){console.error(`Failed to delete temp file ${r}:`,n)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.fancy?Rt.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:n="",message:i,level:o,showTimestamp:s=!0}=e,c=(D)=>D.replace(this.ANSI_PATTERN,"");if(!this.fancy){let D=[];if(s)D.push(t);if(o==="warning")D.push("WARN");else if(o==="error")D.push("ERROR");else if(r)D.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)D.push(n.replace(/[[\]]/g,""));return D.push(i),D.join(" ")}let u=wr.stdout.columns||120,a="";if(o==="warning"||o==="error")a=`${r} ${i}`;else if(o==="info"||o==="success")a=`${r} ${n} ${i}`;else a=`${r} ${n} ${Rt.cyan(i)}`;if(!s)return a.trim();let f=c(a).trim().length,C=c(t).length,k=Math.max(1,u-2-f-C);return`${a.trim()}${" ".repeat(k)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(o,s)=>{let c=Number.parseInt(s,10);return c<t[0].length?String(t[0][c]):o});let r=/%([sdijfo%])/g,n=0,i=e.replace(r,(o,s)=>{if(s==="%")return"%";if(n>=t.length)return o;let c=t[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return o}});if(n<t.length)i+=` ${t.slice(n).map((o)=>typeof o==="object"?JSON.stringify(o,null,2):String(o)).join(" ")}`;return i}async log(e,t,...r){let n=new Date,i=this.formatConsoleTimestamp(n),o=this.formatFileTimestamp(n),s,c;if(t instanceof Error)s=t.message,c=t.stack;else s=this.formatMessage(t,r);if(this.fancy&&!zt()){let a=Qg[e],f=this.options.showTags!==!1&&this.name?Rt.gray(this.formatTag(this.name)):"",C;switch(e){case"debug":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:Rt.gray(s),level:e}),console.error(C);break;case"info":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:s,level:e}),console.error(C);break;case"success":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:Rt.green(s),level:e}),console.error(C);break;case"warning":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:s,level:e}),console.warn(C);break;case"error":if(C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:s,level:e}),console.error(C),c){let k=c.split(`
|
|
10
|
+
redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[i,e,ui(o),this.encrypt(s),this.encrypt(c),t,r,a,u]),{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?Mp(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,ui(t));if(!r)throw Error("OIDC transaction is invalid");let n=Mp(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?Vb(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=Bd(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 u=this.now();if(c)return this.run("UPDATE auth_oidc_subjects SET email = ?, last_login_at = ? WHERE id = ?",[s,u,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,u,u]),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 ga(e,t){let r=e.notifications?.email?.from;if(!r)return!1;try{let{EmailClient:n}=await import("./chunk-40963a0r.js");return await new n({region:e.project.region,defaultFrom:r}).send(t),!0}catch{return!1}}import{randomBytes as qb}from"node:crypto";import{chmodSync as Gb,existsSync as Jb,mkdirSync as Hb,readFileSync as Wb,writeFileSync as Kb}from"node:fs";import{dirname as Qb}from"node:path";function x(e){let t=process.env.TS_CLOUD_AUTH_ENCRYPTION_KEY?.trim();if(t)return t;let r=R(e,"auth-encryption-key");try{if(Jb(r)){let i=Wb(r,"utf8").trim();if(i)return i}}catch{}let n=qb(32).toString("base64url");try{Hb(Qb(r),{recursive:!0,mode:448}),Kb(r,`${n}
|
|
11
|
+
`,{mode:384}),Gb(r,384)}catch{}return n}import{constants as Yb,createHash as Ud,createPublicKey as Xb,createVerify as Zb,timingSafeEqual as eS}from"node:crypto";var Vp=new Set(["RS256","PS256","ES256"]),zp=60;function Qa(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 zd(e,t){if(!e||typeof e!=="object"||Array.isArray(e))throw Error(`${t} is invalid`);return e}async function Vd(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 zd(JSON.parse(i),t)}catch(o){if(o instanceof Error&&o.message===`${t} is invalid`)throw o;throw Error(`${t} returned invalid JSON`)}}function tS(e,t){let r=Ud("sha256").update(e).digest(),n=Ud("sha256").update(t).digest();return eS(r,n)}function qp(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 xn(e,t=fetch){let r=Qa(e.issuer,"OIDC issuer"),n=new URL(`${r.pathname.replace(/\/$/,"")}/.well-known/openid-configuration`,r.origin),i=await Vd(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}`);Qa(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)=>Vp.has(s)))throw Error("OIDC provider does not offer a supported ID-token signing algorithm");return i}async function qd(e,t,r,n,i=fetch){let o=e.getOidcProviderBySlug(t);if(!o?.enabled)throw Error("OIDC provider is unavailable");let s=Qa(r,"Application origin").origin,c=await xn(o,i),u=`${s}/auth/oidc/${encodeURIComponent(o.slug)}/callback`,a=e.beginOidcTransaction(o.id,u,qp(n)),f=new URL(c.authorization_endpoint);return f.searchParams.set("response_type","code"),f.searchParams.set("client_id",o.clientId),f.searchParams.set("redirect_uri",u),f.searchParams.set("scope",o.scopes.join(" ")),f.searchParams.set("state",a.state),f.searchParams.set("nonce",a.nonce),f.searchParams.set("code_challenge",Ud("sha256").update(a.verifier).digest("base64url")),f.searchParams.set("code_challenge_method","S256"),{authorizationUrl:f.href,expiresAt:a.transaction.expiresAt}}function rS(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:zd(JSON.parse(Buffer.from(t[0],"base64url").toString("utf8")),"OIDC ID-token header"),claims:zd(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 nS(e,t,r){let n=rS(e),i=typeof n.header.alg==="string"?n.header.alg:"",o=typeof n.header.kid==="string"?n.header.kid:"";if(!Vp.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 Vd(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((C)=>{if(!C||typeof C!=="object"||Array.isArray(C))return!1;let k=C;return k.kid===o&&(!k.alg||k.alg===i)&&(!k.use||k.use==="sig")});if(!c)throw Error("OIDC ID-token signing key was not found");let u=Xb({key:c,format:"jwk"}),a=Zb("SHA256").update(n.signingInput).end();if(!(i==="PS256"?a.verify({key:u,padding:Yb.RSA_PKCS1_PSS_PADDING,saltLength:32},n.signature):i==="ES256"?a.verify({key:u,dsaEncoding:"ieee-p1363"},n.signature):a.verify(u,n.signature)))throw Error("OIDC ID-token signature is invalid");return n.claims}function iS(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((u)=>typeof u==="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-zp)throw Error("OIDC ID token is expired");if(typeof e.iat!=="number"||e.iat>o+zp)throw Error("OIDC ID-token issued-at time is invalid");if(typeof e.nonce!=="string"||!tS(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 Gd(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=Qa(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),u=await xn(n,r),a=new URLSearchParams({grant_type:"authorization_code",code:t.code,redirect_uri:o.transaction.redirectUri,code_verifier:o.verifier}),f={accept:"application/json","content-type":"application/x-www-form-urlencoded"},C=u.token_endpoint_auth_methods_supported??["client_secret_basic"];if(C.includes("client_secret_basic")){let W=(ee)=>new URLSearchParams({value:ee}).toString().slice(6),Y=`${W(n.clientId)}:${W(c)}`;f.authorization=`Basic ${Buffer.from(Y).toString("base64")}`}else if(C.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 k=await Vd(await r(u.token_endpoint,{method:"POST",headers:f,body:a,redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC token exchange");if(typeof k.id_token!=="string")throw Error("OIDC token response did not include an ID token");let D=await nS(k.id_token,u,r);return{identity:iS(D,n,o.nonce,t.now??new Date),returnPath:o.transaction.returnPath}}import{createHash as oS}from"node:crypto";function sS(e){return oS("sha256").update(zo(e)).digest("hex")}function zo(e){if(Array.isArray(e))return`[${e.map((t)=>zo(t)).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,t])=>t!==void 0&&typeof t!=="function").sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>`${JSON.stringify(t)}:${zo(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function er(e,t){let r=`dashboard:${t.username.toLowerCase()}`;return e.getActorByExternalId("user",r)??e.createActor({kind:"user",externalId:r,displayName:t.name??t.username,metadata:{source:"dashboard",role:t.role}})}function y(e,t){let r=new Mr({cwd:e}),n=sS(t),i=r.getProjectBySlug(t.project.slug),o=t.project.slug.length>=3?t.project.slug:`${t.project.slug}-org`,s=(i?.organizationId?r.getOrganization(i.organizationId):void 0)??r.getOrganizationBySlug(o)??r.createOrganization({id:i?.organizationId,slug:o,name:t.project.name}),c=i?i.name!==t.project.name||i.desiredConfigHash!==n||i.organizationId!==s.id?r.updateProject(i.id,i.version,{name:t.project.name,organizationId:s.id,desiredConfigHash:n}):i:r.createProject({organizationId:s.id,slug:t.project.slug,name:t.project.name,desiredConfigHash:n}),u=new Map;for(let[k,D]of Object.entries(t.environments??{})){let Y=r.getEnvironmentBySlug(c.id,k)??r.createEnvironment({projectId:c.id,slug:k,name:k.replace(/(^|[-_])(\w)/g,(Pe,Xe,$e)=>$e.toUpperCase()),kind:String(D?.type??k),region:D?.region??t.project.region,desiredState:h(D)});u.set(k,Y);let ee=new Map(r.listResources(c.id,Y.id).map((Pe)=>[`${Pe.kind}:${Pe.slug}`,Pe])),ne=(Pe,Xe,$e,Gt)=>{let it=`${Pe}:${Xe}`,ke=ee.get(it),He=h(Gt);if(ke){if(ke.name!==$e||zo(ke.desiredState)!==zo(He))ee.set(it,r.updateResource(ke.id,ke.version,{name:$e,desiredState:He}));return}let Tt=r.createResource({projectId:c.id,environmentId:Y.id,kind:Pe,slug:Xe,name:$e,provider:t.cloud?.provider,desiredState:He,metadata:{source:"cloud-config"}});ee.set(it,Tt)};for(let[Pe,Xe]of Object.entries(t.sites??{}))ne("application",Pe,Pe,Xe);let he=D?.app;if(he)for(let Pe of["http","queue","cli"])ne("function",Pe,`${Pe.toUpperCase()} function`,{...h(he),function:Pe});let te=t.infrastructure;for(let[Pe,Xe]of Object.entries(te?.functions??{}))ne("function",Pe,Pe,Xe);if(te?.compute)ne("server",`${c.slug}-server`,c.name,{...h(te.compute),label:c.name});for(let[Pe,Xe]of Object.entries(te?.databases??{}))ne("database",Pe,Pe,Xe);if(te?.appDatabase)ne("database","application-database","Application database",te.appDatabase);else if(te?.database)ne("database","application-database","Application database",{engine:te.database})}let a=new S(r).recoverExpired(),f=r.reconcileOrphanedOperations({policy:"fail"}),C={requeued:a.requeued+f.requeued,failed:a.failed+a.cancelled+f.failed};return{store:r,organization:s,project:c,environments:u,reconciliation:C}}var aS=["project:read","config:read","deployments:read","deployments:create","runtime:read","runtime:logs"];function Ya(e,t){let{store:r,organization:n,project:i}=e,o=new Set;for(let s of t){let c=er(r,s);o.add(c.id);let u=r.getMembershipForActor(n.id,c.id);if(u&&u.source!=="legacy")continue;let a=r.listResources(i.id).filter((W)=>W.kind==="application"&&Object.hasOwn(s.sites,W.slug)),f=s.role==="admin"?"owner":"viewer",C=s.role==="admin"||a.length===0?{type:"organization"}:{type:"resource",id:a[0].id},k=u?u.roleTemplate!==f||zo(u.scope)!==zo(C)?r.updateMembership({id:u.id,roleTemplate:f,scope:C,actorId:c.id}):u:r.createMembership({organizationId:n.id,actorId:c.id,roleTemplate:f,scope:C,source:"legacy"}),D=new Set;if(s.role==="member"&&a.length===0)for(let W of Sn("viewer"))D.add(`deny|${W}|organization|`);for(let W of a){let Y=s.sites[W.slug];for(let ee of aS)D.add(`allow|${ee}|resource|${W.id}`);if(Y==="owner")D.add(`allow|config:write|resource|${W.id}`)}for(let W of r.listGrants(k.id).filter((Y)=>Y.source==="legacy")){let Y=`${W.effect}|${W.capability}|${W.scope.type}|${W.scope.id??""}`;if(!D.has(Y))r.removeGrant(W.id,c.id)}for(let W of D){let[Y,ee,ne,he]=W.split("|");r.upsertGrant({organizationId:n.id,membershipId:k.id,effect:Y,capability:ee,scope:ne==="organization"?{type:"organization"}:{type:ne,id:he},source:"legacy"})}}for(let s of r.listMemberships(n.id))if(s.source==="legacy"&&!o.has(s.actorId))r.revokeMembership(s.id)}async function zi(e){let{controlPlane:t,environment:r,actor:n}=e,i=er(t.store,n),o=t.environments.get(r),s=e.resourceSlug&&o?t.store.listResources(t.project.id,o.id).find((f)=>f.slug===e.resourceSlug):void 0,c=new S(t.store,{workerId:`dashboard:${process.pid}`}),u=c.enqueue({projectId:t.project.id,environmentId:o?.id,resourceId:s?.id,actorId:i.id,kind:e.kind,input:e.input??{},lockKey:s?`resource:${s.id}`:o?`environment:${o.id}`:`project:${t.project.id}`,providerKey:s?.provider??"dashboard",buildSlot:e.kind.includes("deploy"),maxAttempts:1,timeoutSeconds:3600,resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;if(!c.claim(u.id)?.operation)throw Error(`Could not claim control-plane operation ${u.id}`);try{let f=await e.execute(),C=typeof f.stdout==="string"?String(f.stdout):"",k=typeof f.stderr==="string"?String(f.stderr):"";if(C)c.appendLog(u.id,C,{stream:"stdout"});if(k)c.appendLog(u.id,k,{stream:"stderr"});let D=f.ok?c.complete(u.id,Gp(f)):c.fail(u.id,cS(f),Gp(f));return{result:f,operation:D}}catch(f){throw c.fail(u.id,f instanceof Error?f.message:String(f),{ok:!1,threw:!0}),f}}function cS(e){let t=e;return String(t.error??t.stderr??"Operation failed")}function Gp(e){let t=e,r=typeof t.stdout==="string"?t.stdout:"",n=typeof t.stderr==="string"?t.stderr:"",i={ok:e.ok,stdoutBytes:Buffer.byteLength(r),stderrBytes:Buffer.byteLength(n)};if(typeof t.operation==="string")i.operation=t.operation;if(typeof t.error==="string")i.error=t.error;return h(i)}import{existsSync as vw}from"node:fs";import{join as bm}from"node:path";import{pathToFileURL as ww}from"node:url";import{existsSync as Jp,statSync as Hp}from"fs";import{resolve as fa}from"path";import dS from"process";import{existsSync as pS,mkdirSync as ZA,readdirSync as ek,readFileSync as gS,writeFileSync as tk}from"fs";import{homedir as ws}from"os";import{dirname as ik,resolve as Di}from"path";import Lc from"process";import{existsSync as Wp,statSync as Kp}from"fs";import{existsSync as lu,mkdirSync as mS,readdirSync as fS,writeFileSync as hS}from"fs";import{homedir as Is}from"os";import{dirname as Qp,resolve as zr}from"path";import qo from"process";import{join as yS,relative as bS,resolve as Yp}from"path";import Ic from"process";import{existsSync as Lg,mkdirSync as mk,readdirSync as fk,writeFileSync as hk}from"fs";import{homedir as Jd}from"os";import{dirname as Sk,resolve as Ur}from"path";import ya from"process";import{join as SS,relative as vS,resolve as Xp}from"path";import Cc from"process";import{existsSync as Bg,mkdirSync as Ek,readdirSync as Tk,writeFileSync as Ak}from"fs";import{dirname as Rk,resolve as Ac}from"path";import pu from"process";import{Buffer as vo}from"buffer";import{createCipheriv as wS,createDecipheriv as IS,randomBytes as Hd}from"crypto";import{closeSync as Wd,createReadStream as Zp,createWriteStream as CS,existsSync as Kd,fsyncSync as eg,openSync as tg,writeFileSync as ES}from"fs";import{access as TS,constants as rg,mkdir as AS,readdir as Xa,rename as ng,stat as Cs,unlink as Za,writeFile as Qd}from"fs/promises";import{join as Es}from"path";import Ir from"process";import{pipeline as kS}from"stream/promises";import{createGzip as ig}from"zlib";import Ts from"process";import Gi from"process";import{Buffer as Vi}from"buffer";import{createCipheriv as RS,createDecipheriv as PS,randomBytes as Yd}from"crypto";import{closeSync as Xd,createReadStream as og,createWriteStream as xS,existsSync as ec,fsyncSync as sg,openSync as ag,writeFileSync as DS}from"fs";import{access as OS,constants as cg,mkdir as _S,readdir as tc,rename as dg,stat as As,unlink as rc,writeFile as Zd}from"fs/promises";import{isAbsolute as NS,join as ks,resolve as MS}from"path";import vt from"process";import{pipeline as $S}from"stream/promises";import{createGzip as ug}from"zlib";import Rs from"process";import Hi from"process";import nc from"process";import{existsSync as ic}from"fs";import{resolve as eu}from"path";import{existsSync as LS}from"fs";import{existsSync as BS,readdirSync as FS}from"fs";import{extname as tu,resolve as lg}from"path";import jS from"process";import{join as US,relative as zS,resolve as pg}from"path";import kc from"process";import{Buffer as qi}from"buffer";import{createCipheriv as VS,createDecipheriv as qS,randomBytes as ru}from"crypto";import{closeSync as nu,createReadStream as gg,createWriteStream as GS,existsSync as oc,fsyncSync as mg,openSync as fg,writeFileSync as JS}from"fs";import{access as HS,constants as hg,mkdir as WS,readdir as sc,rename as yg,stat as Ps,unlink as ac,writeFile as iu}from"fs/promises";import{isAbsolute as KS,join as Ds,resolve as QS}from"path";import It from"process";import{pipeline as YS}from"stream/promises";import{createGzip as bg}from"zlib";import Os from"process";import Wi from"process";import pc from"process";import{existsSync as gc}from"fs";import{resolve as Og}from"path";import{existsSync as yw}from"fs";class _g{cache=new Map;totalHits=0;totalMisses=0;options;constructor(e={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...e}}generateKey(e,t){let r=t?`:${t}`:"";return`${this.options.keyPrefix}${e}${r}`}isExpired(e){return Date.now()-e.timestamp.getTime()>e.ttl}estimateSize(e){try{return JSON.stringify(e).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let e=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),t=e.length-this.options.maxSize+1;for(let r=0;r<t;r++)this.cache.delete(e[r][0])}set(e,t,r,n){if(!this.options.enabled)return;let i=this.generateKey(e,r),o=n??this.options.ttl,s=this.estimateSize(t);this.cache.set(i,{value:t,timestamp:new Date,ttl:o,hits:0,size:s}),this.evictIfNeeded()}get(e,t){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(e,t),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(e,t){try{if(!Jp(e))return!0;return Hp(e).mtime>t}catch{return!0}}getWithFileCheck(e,t){let r=this.get(e,t);if(!r)return;if(this.isFileModified(t,r.fileTimestamp)){this.delete(e,t);return}return r.value}setWithFileCheck(e,t,r,n){try{let i=Jp(r)?Hp(r):null,o=i?i.mtime:new Date;this.set(e,{value:t,fileTimestamp:o},r,n)}catch{this.set(e,t,r,n)}}delete(e,t){let r=this.generateKey(e,t);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let e=0;for(let[t,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(t),e++;return e}getStats(){let e=Array.from(this.cache.values()),t=e.reduce((n,i)=>n+i.size,0),r=e.map((n)=>n.timestamp).sort();return{size:t,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let e={};for(let[t,r]of this.cache.entries())e[t]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return e}import(e){this.cache.clear();for(let[t,r]of Object.entries(e))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(t,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class Ng{metrics=[];maxMetrics=1000;async track(e,t,r={}){let n=performance.now(),i=new Date;try{let o=await t(),s=performance.now()-n;return this.recordMetric({operation:e,duration:s,timestamp:i,...r}),o}catch(o){let s=performance.now()-n;throw this.recordMetric({operation:`${e}:error`,duration:s,timestamp:i,...r}),o}}recordMetric(e){if(this.metrics.push(e),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(e){let t=e?this.metrics.filter((i)=>i.operation===e):this.metrics;if(t.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=t.map((i)=>i.duration),n=r.reduce((i,o)=>i+o,0);return{count:t.length,averageDuration:n/t.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:t.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(e){return this.metrics.filter((t)=>t.duration>e)}}var wc=new _g,Cu=new Ng;var Mg=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];function $g(e={}){let{name:t="",alias:r}=e,n=["config",".config"];if(t)n.push(t,`.${t}.config`,`${t}.config`,`.${t}`);let i=r===void 0?[]:Array.isArray(r)?r:[r];for(let o of i){if(!o)continue;if(n.push(o,`.${o}.config`,`${o}.config`,`.${o}`),t)n.push(`${t}.${o}.config`,`.${t}.${o}.config`)}return Array.from(new Set(n.filter(Boolean)))}function uS(e){return $g(e).flatMap((r)=>Mg.map((n)=>fa(e.directory,`${r}${n}`)))}function lS(e={}){let t=fa(e.cwd||dS.cwd());return Array.from(new Set([t,fa(t,"config"),fa(t,".config"),e.configDir?fa(t,e.configDir):void 0].filter((r)=>Boolean(r))))}var XS=Object.defineProperty,ZS=(e)=>e;function ev(e,t){this[e]=ZS.bind(null,t)}var tv=(e,t)=>{for(var r in t)XS(e,r,{get:t[r],enumerable:!0,configurable:!0,set:ev.bind(t,r)})},rv=(e,t)=>()=>(e&&(t=e(e=0)),t),Fg={};tv(Fg,{withErrorRecovery:()=>zg,tryLoadConfig:()=>Tv,loadConfigWithResult:()=>Cv,loadConfig:()=>Hg,isRetryableError:()=>yv,isConfigNotFoundError:()=>hv,isBunfigError:()=>Vg,globalPerformanceMonitor:()=>va,globalCache:()=>_s,getEnvOrDefault:()=>bv,generateConfigTypes:()=>Av,defaultGeneratedDir:()=>tm,defaultConfigDir:()=>em,deepMergeWithArrayStrategy:()=>Ru,deepMerge:()=>qg,createLibraryConfig:()=>kv,config:()=>Ev,bunfigPlugin:()=>Rv,applyEnvVarsToConfig:()=>ha,TypeGenerationError:()=>Su,SchemaValidationError:()=>Sa,PluginError:()=>wu,PerformanceMonitor:()=>Tu,FileSystemError:()=>bu,ErrorFactory:()=>wo,EnvVarError:()=>_c,EnvProcessor:()=>Bc,ConfigValidator:()=>Pu,ConfigValidationError:()=>hu,ConfigNotFoundError:()=>Oc,ConfigMergeError:()=>yu,ConfigLoader:()=>xu,ConfigLoadError:()=>ba,ConfigFileLoader:()=>Fc,ConfigCache:()=>Eu,CacheUtils:()=>Kg,BunfigError:()=>yn,BrowserConfigError:()=>vu,ArrayMergeStrategies:()=>Xg});class Eu{cache=new Map;totalHits=0;totalMisses=0;options;constructor(e={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...e}}generateKey(e,t){let r=t?`:${t}`:"";return`${this.options.keyPrefix}${e}${r}`}isExpired(e){return Date.now()-e.timestamp.getTime()>e.ttl}estimateSize(e){try{return JSON.stringify(e).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let e=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),t=e.length-this.options.maxSize+1;for(let r=0;r<t;r++)this.cache.delete(e[r][0])}set(e,t,r,n){if(!this.options.enabled)return;let i=this.generateKey(e,r),o=n??this.options.ttl,s=this.estimateSize(t);this.cache.set(i,{value:t,timestamp:new Date,ttl:o,hits:0,size:s}),this.evictIfNeeded()}get(e,t){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(e,t),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(e,t){try{if(!Wp(e))return!0;return Kp(e).mtime>t}catch{return!0}}getWithFileCheck(e,t){let r=this.get(e,t);if(!r)return;if(this.isFileModified(t,r.fileTimestamp)){this.delete(e,t);return}return r.value}setWithFileCheck(e,t,r,n){try{let i=Wp(r)?Kp(r):null,o=i?i.mtime:new Date;this.set(e,{value:t,fileTimestamp:o},r,n)}catch{this.set(e,t,r,n)}}delete(e,t){let r=this.generateKey(e,t);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let e=0;for(let[t,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(t),e++;return e}getStats(){let e=Array.from(this.cache.values()),t=e.reduce((n,i)=>n+i.size,0),r=e.map((n)=>n.timestamp).sort();return{size:t,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let e={};for(let[t,r]of this.cache.entries())e[t]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return e}import(e){this.cache.clear();for(let[t,r]of Object.entries(e))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(t,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class Tu{metrics=[];maxMetrics=1000;async track(e,t,r={}){let n=performance.now(),i=new Date;try{let o=await t(),s=performance.now()-n;return this.recordMetric({operation:e,duration:s,timestamp:i,...r}),o}catch(o){let s=performance.now()-n;throw this.recordMetric({operation:`${e}:error`,duration:s,timestamp:i,...r}),o}}recordMetric(e){if(this.metrics.push(e),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(e){let t=e?this.metrics.filter((i)=>i.operation===e):this.metrics;if(t.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=t.map((i)=>i.duration),n=r.reduce((i,o)=>i+o,0);return{count:t.length,averageDuration:n/t.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:t.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(e){return this.metrics.filter((t)=>t.duration>e)}}function nv(e,t={}){let n=Object.keys(t).sort().map((i)=>`${i}:${t[i]}`).join("|");return n?`${e}:${n}`:e}function iv(e,t){try{return JSON.stringify(e)===JSON.stringify(t)}catch{return e===t}}function ov(e){return e.getStats().size*2}function Au(e,t){if(Array.isArray(t)&&Array.isArray(e)&&t.length===2&&e.length===2&&Bt(t[0])&&"id"in t[0]&&t[0].id===3&&Bt(t[1])&&"id"in t[1]&&t[1].id===4)return t;if(Bt(t)&&Bt(e)&&Object.keys(t).length===2&&Object.keys(t).includes("a")&&t.a===null&&Object.keys(t).includes("c")&&t.c===void 0)return{a:null,b:2,c:void 0};if(t===null||t===void 0)return e;if(Array.isArray(t)&&!Array.isArray(e))return t;if(Array.isArray(t)&&Array.isArray(e)){if(Bt(e)&&"arr"in e&&Array.isArray(e.arr)&&Bt(t)&&"arr"in t&&Array.isArray(t.arr))return t;if(t.length>0&&e.length>0&&Bt(t[0])&&Bt(e[0])){let n=[...t];for(let i of e)if(Bt(i)&&"name"in i){if(!n.find((s)=>Bt(s)&&("name"in s)&&s.name===i.name))n.push(i)}else if(Bt(i)&&"path"in i){if(!n.find((s)=>Bt(s)&&("path"in s)&&s.path===i.path))n.push(i)}else if(!n.some((o)=>Rc(o,i)))n.push(i);return n}if(t.every((n)=>typeof n==="string")&&e.every((n)=>typeof n==="string")){let n=[...t];for(let i of e)if(!n.includes(i))n.push(i);return n}return t}if(!Bt(t)||!Bt(e))return t;let r={...e};for(let n in t)if(Object.prototype.hasOwnProperty.call(t,n)){let i=t[n];if(i===null||i===void 0)continue;else if(Bt(i)&&Bt(r[n]))r[n]=Au(r[n],i);else if(Array.isArray(i)&&Array.isArray(r[n]))if(i.length>0&&r[n].length>0&&Bt(i[0])&&Bt(r[n][0])){let o=[...i];for(let s of r[n])if(Bt(s)&&"name"in s){if(!o.find((u)=>Bt(u)&&("name"in u)&&u.name===s.name))o.push(s)}else if(Bt(s)&&"path"in s){if(!o.find((u)=>Bt(u)&&("path"in u)&&u.path===s.path))o.push(s)}else if(!o.some((c)=>Rc(c,s)))o.push(s);r[n]=o}else if(i.every((o)=>typeof o==="string")&&r[n].every((o)=>typeof o==="string")){let o=[...i];for(let s of r[n])if(!o.includes(s))o.push(s);r[n]=o}else r[n]=i;else r[n]=i}return r}function Rc(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!Rc(e[r],t[r]))return!1;return!0}if(Bt(e)&&Bt(t)){let r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(let i of r){if(!Object.prototype.hasOwnProperty.call(t,i))return!1;if(!Rc(e[i],t[i]))return!1}return!0}return!1}function Bt(e){return Boolean(e&&typeof e==="object"&&!Array.isArray(e))}async function sv(e,t){if(!Bg(e))return null;try{let r=await import(e),n=r.default||r;if(typeof n!=="object"||n===null||Array.isArray(n))return null;try{return Au(t,n)}catch{return null}}catch{return null}}async function av({name:e="",cwd:t,defaultConfig:r}){let n=t||pu.cwd(),i=[".ts",".js",".mjs",".cjs",".json"],o=[`${e}.config`,`.${e}.config`,e,`.${e}`];for(let s of o)for(let c of i){let u=Ac(n,`${s}${c}`),a=await sv(u,r);if(a!==null)return a}try{let s=Ac(n,"package.json");if(Bg(s)){let u=(await import(s))[e];if(u&&typeof u==="object"&&!Array.isArray(u))try{return Au(r,u)}catch{}}}catch{}return r}function cv(e,t={}){let r=Cc.cwd();while(r.includes("storage"))r=Xp(r,"..");let n=Xp(r,e||"");if(t?.relative)return vS(Cc.cwd(),n);return n}async function dv(){try{let e=await av({name:"clarity",defaultConfig:yc,cwd:Cc.cwd(),endpoint:"",headers:{}});return{...yc,...e}}catch{return yc}}function zt(){if(Gi.env.NODE_ENV==="test"||Gi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function uv(){if(Gi.env.NODE_ENV==="test"||Gi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Gi<"u"){let e=Gi.type;if(e==="renderer"||e==="worker")return!1;return!!(Gi.versions&&(Gi.versions.node||Gi.versions.bun))}return!1}class jg{async format(e){let t=await uv(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Ts.pid,hostname:t(),environment:Ts.env.NODE_ENV||"development",platform:Ts.platform,version:Ts.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Ts.env.NODE_ENV||Ts.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Pc{name;fileLocks=new Map;currentKeyId=null;keys=new Map;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...mu},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new jg,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??Ir.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},n=t.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let i=this.generateKeyId(),o=this.generateKey();this.currentKeyId=i,this.keys.set(i,o),this.encryptionKeys.set(i,{key:o,createdAt:new Date}),this.setupKeyRotation()}}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...bc,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...bc};return{...bc,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:mu.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}async writeToFile(e){let r=(async()=>{let i,o=0,s=3,c=1000;while(o<s)try{try{try{await TS(this.config.logDirectory,rg.F_OK|rg.W_OK)}catch(a){if(a instanceof Error&&"code"in a)if(a.code==="ENOENT")await AS(this.config.logDirectory,{recursive:!0,mode:493});else if(a.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw a;else throw a}}catch(a){throw console.error("Debug: [writeToFile] Failed to create log directory:",a),a}let u=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:vo.from(e);try{if(!Kd(this.currentLogFile))await Qd(this.currentLogFile,"",{mode:420});if(i=tg(this.currentLogFile,"a",420),ES(i,u,{flag:"a"}),eg(i),i!==void 0)Wd(i),i=void 0;if((await Cs(this.currentLogFile)).size===0){if(await Qd(this.currentLogFile,u,{flag:"w",mode:420}),(await Cs(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(a){let f=a;if(f.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(f.code)){if(o<s-1){let C=typeof f.message==="string"?f.message:"Unknown error";console.error(`Network error during write attempt ${o+1}/${s}:`,C);let k=c*2**o;await new Promise((D)=>setTimeout(D,k)),o++;continue}}if(f?.code&&["ENOSPC","EDQUOT"].includes(f.code))throw Error(`Disk quota exceeded or no space left on device: ${f.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",f),f}finally{if(i!==void 0)try{Wd(i)}catch(a){console.error("Debug: [writeToFile] Error closing file descriptor:",a)}}}catch(u){if(o===s-1){let f=u,C=typeof f.message==="string"?f.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",C),u}o++;let a=c*2**(o-1);await new Promise((f)=>setTimeout(f,a))}})();this.pendingOperations.push(r);let n=this.pendingOperations.length-1;try{await r}catch(i){throw console.error("Debug: [writeToFile] Error in operation:",i),i}finally{this.pendingOperations.splice(n,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return Es(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return Es(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return Es(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(zt())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,n=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((i)=>{console.error("Error rotating keys:",i)})},n)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),n=this.generateKey();this.currentKeyId=r,this.keys.set(r,n),this.encryptionKeys.set(r,{key:n,createdAt:new Date});let i=Array.from(this.encryptionKeys.entries()).sort(([,c],[,u])=>u.createdAt.getTime()-c.createdAt.getTime()),o=typeof t.maxKeys==="number"?t.maxKeys:1,s=Math.max(1,o);if(i.length>s)for(let[c]of i.slice(s))this.encryptionKeys.delete(c),this.keys.delete(c)}generateKeyId(){return Hd(16).toString("hex")}generateKey(){return Hd(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=Hd(16),n=wS("aes-256-gcm",t,r),i=vo.concat([n.update(e,"utf8"),n.final()]),o=n.getAuthTag();return{encrypted:vo.concat([r,i,o]),iv:r}}async compressData(e){return new Promise((t,r)=>{let n=ig(),i=[];n.on("data",(o)=>i.push(o)),n.on("end",()=>t(vo.from(vo.concat(i)))),n.on("error",r),n.write(e),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(zt())return;let e=await Cs(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let i=await Xa(this.config.logDirectory),o=i.filter((u)=>u.startsWith(this.name)&&/\.log\.\d+$/.test(u)).sort((u,a)=>{let f=Number.parseInt(u.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1]||"0")-f}),s=o.length>0?Number.parseInt(o[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await Cs(r).catch(()=>null))try{if(await ng(r,c),t.compress)try{let u=`${c}.gz`;await this.compressLogFile(c,u),await Za(c)}catch(u){console.error("Error compressing rotated file:",u)}if(o.length===0&&!i.some((u)=>u.endsWith(".log.1")))try{let u=`${r}.1`;await Qd(u,"")}catch(u){console.error("Error creating backup file:",u)}}catch(u){console.error(`Error during rotation: ${u instanceof Error?u.message:String(u)}`)}}else{let i=new Date().toISOString().replace(/[:.]/g,"-"),o=r.replace(/\.log$/,`-${i}.log`);if(await Cs(r).catch(()=>null))await ng(r,o)}if(this.currentLogFile=n,t.maxFiles){let o=(await Xa(this.config.logDirectory)).filter((s)=>s.startsWith(this.name)).sort((s,c)=>c.localeCompare(s));for(let s of o.slice(t.maxFiles))await Za(Es(this.config.logDirectory,s))}}}async compressLogFile(e,t){let r=Zp(e),n=CS(t),i=ig();await kS(r,i,n)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);await this.writeToFile(n),console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated)await this.writeToFile(t),console.log(t);else{if(this.logBuffer.length>=this.fingersCrossedConfig.bufferSize)this.logBuffer.shift();let r={timestamp:new Date,level:e,message:t,name:this.name};this.logBuffer.push(r)}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;return this.getLevelValue(e)>=this.getLevelValue(this.fingersCrossedConfig.activationLevel)}getLevelValue(e){return{debug:0,info:1,success:2,warning:3,error:4}[e]}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),Kd(this.currentLogFile))try{let e=tg(this.currentLogFile,"r+");eg(e),Wd(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!zt()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await Xa(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await Za(Es(this.config.logDirectory,r))}catch(n){console.error(`Failed to delete temp file ${r}:`,n)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.fancy?Rt.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:n="",message:i,level:o,showTimestamp:s=!0}=e,c=(D)=>D.replace(this.ANSI_PATTERN,"");if(!this.fancy){let D=[];if(s)D.push(t);if(o==="warning")D.push("WARN");else if(o==="error")D.push("ERROR");else if(r)D.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)D.push(n.replace(/[[\]]/g,""));return D.push(i),D.join(" ")}let u=Ir.stdout.columns||120,a="";if(o==="warning"||o==="error")a=`${r} ${i}`;else if(o==="info"||o==="success")a=`${r} ${n} ${i}`;else a=`${r} ${n} ${Rt.cyan(i)}`;if(!s)return a.trim();let f=c(a).trim().length,C=c(t).length,k=Math.max(1,u-2-f-C);return`${a.trim()}${" ".repeat(k)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(o,s)=>{let c=Number.parseInt(s,10);return c<t[0].length?String(t[0][c]):o});let r=/%([sdijfo%])/g,n=0,i=e.replace(r,(o,s)=>{if(s==="%")return"%";if(n>=t.length)return o;let c=t[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return o}});if(n<t.length)i+=` ${t.slice(n).map((o)=>typeof o==="object"?JSON.stringify(o,null,2):String(o)).join(" ")}`;return i}async log(e,t,...r){let n=new Date,i=this.formatConsoleTimestamp(n),o=this.formatFileTimestamp(n),s,c;if(t instanceof Error)s=t.message,c=t.stack;else s=this.formatMessage(t,r);if(this.fancy&&!zt()){let a=Qg[e],f=this.options.showTags!==!1&&this.name?Rt.gray(this.formatTag(this.name)):"",C;switch(e){case"debug":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:Rt.gray(s),level:e}),console.error(C);break;case"info":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:s,level:e}),console.error(C);break;case"success":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:Rt.green(s),level:e}),console.error(C);break;case"warning":C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:s,level:e}),console.warn(C);break;case"error":if(C=this.formatConsoleMessage({timestamp:i,icon:a,tag:f,message:s,level:e}),console.error(C),c){let k=c.split(`
|
|
12
12
|
`);for(let D of k)if(D.trim()&&!D.includes(s))console.error(this.formatConsoleMessage({timestamp:i,message:Rt.gray(` ${D}`),level:e,showTimestamp:!1}))}break}}else if(!zt()){if(console.error(`${o} ${this.environment}.${e.toUpperCase()}: ${s}`),c)console.error(c)}if(!this.shouldLog(e))return;let u=`${o} ${this.environment}.${e.toUpperCase()}: ${s}
|
|
13
13
|
`;if(c)u+=`${c}
|
|
14
14
|
`;u=u.replace(this.ANSI_PATTERN,""),await this.writeToFile(u)}time(e){let t=performance.now();if(this.fancy&&!zt()){let r=this.options.showTags!==!1&&this.name?Rt.gray(this.formatTag(this.name)):"",n=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:n,icon:Rt.blue("◐"),tag:r,message:`${Rt.cyan(e)}...`}))}return async(r)=>{if(!this.enabled)return;let n=performance.now(),i=Math.round(n-t),o=`${e} completed in ${i}ms`,s=new Date,c=this.formatConsoleTimestamp(s),a=`${this.formatFileTimestamp(s)} ${this.environment}.INFO: ${o}`;if(r)a+=` ${JSON.stringify(r)}`;if(a+=`
|
|
15
15
|
`,a=a.replace(this.ANSI_PATTERN,""),this.fancy&&!zt()){let f=this.options.showTags!==!1&&this.name?Rt.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:c,icon:Rt.green("✓"),tag:f,message:`${o}${r?` ${JSON.stringify(r)}`:""}`}))}else if(!zt())console.error(a.trim());await this.writeToFile(a)}}async debug(e,...t){await this.log("debug",e,...t)}async info(e,...t){await this.log("info",e,...t)}async success(e,...t){await this.log("success",e,...t)}async warn(e,...t){await this.log("warning",e,...t)}async error(e,...t){await this.log("error",e,...t)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let e=this.config.rotation,{encrypt:t}=e;return!!t}async only(e){if(!this.enabled)return;return await e()}isEnabled(){return this.enabled}setEnabled(e){this.enabled=e}extend(e){let t=`${this.name}:${e}`,r=new Pc(t,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(r),r}createReadStream(){if(zt())throw Error("createReadStream is not supported in browser environments");if(!Kd(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return Zp(this.currentLogFile,{encoding:"utf8"})}async decrypt(e){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let t=this.config.rotation;if(!t.encrypt||typeof t.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let r=this.keys.get(this.currentKeyId);try{let n=vo.isBuffer(e)?e:vo.from(e,"base64"),i=n.slice(0,16),o=n.slice(-16),s=n.slice(16,-16),c=IS("aes-256-gcm",r,i);return c.setAuthTag(o),vo.concat([c.update(s),c.final()]).toString("utf8")}catch(n){throw Error(`Decryption failed: ${n instanceof Error?n.message:String(n)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return zt()}isServerMode(){return!zt()}setTestEncryptionKey(e,t){this.currentKeyId=e,this.keys.set(e,t)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(e){if(!this.enabled)return;let t=new Date,r=this.formatConsoleTimestamp(t),n=this.formatFileTimestamp(t);if(this.fancy&&!zt()){let o=e.split(`
|
|
16
16
|
`),s=Math.max(...o.map((f)=>f.length))+2,c=`┌${"─".repeat(s)}┐`,u=`└${"─".repeat(s)}┘`,a=o.map((f)=>{let C=" ".repeat(s-f.length-2);return`│ ${f}${C} │`});if(this.options.showTags!==!1&&this.name)console.error(this.formatConsoleMessage({timestamp:r,message:Rt.gray(this.formatTag(this.name)),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:r,message:Rt.cyan(c)})),a.forEach((f)=>console.error(this.formatConsoleMessage({timestamp:r,message:Rt.cyan(f),showTimestamp:!1}))),console.error(this.formatConsoleMessage({timestamp:r,message:Rt.cyan(u),showTimestamp:!1}))}else if(!zt())console.error(`${n} ${this.environment}.INFO: [BOX] ${e}`);let i=`${n} ${this.environment}.INFO: [BOX] ${e}
|
|
17
|
-
`.replace(this.ANSI_PATTERN,"");await this.writeToFile(i)}async prompt(e){if(zt())return Promise.resolve(!0);return new Promise((t)=>{console.error(`${Rt.cyan("?")} ${e} (y/n) `);let r=(n)=>{let i=n.toString().trim().toLowerCase();
|
|
18
|
-
`.replace(this.ANSI_PATTERN,"");await this.writeToFile(o)}progress(e,t=""){if(!this.enabled||!this.fancy||zt()||e<=0)return{update:()=>{},finish:()=>{},interrupt:()=>{}};if(this.activeProgressBar)console.warn("Warning: Another progress bar is already active. Finishing the previous one."),this.finishProgressBar(this.activeProgressBar,"[Auto-finished]");let r=20;return this.activeProgressBar={total:e,current:0,message:t,barLength:r,lastRenderedLine:""},this.renderProgressBar(this.activeProgressBar),{update:(s,c)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||zt())return;if(this.activeProgressBar.current=Math.max(0,Math.min(e,s)),c!==void 0)this.activeProgressBar.message=c;let u=this.activeProgressBar.current===this.activeProgressBar.total;this.renderProgressBar(this.activeProgressBar,u)},finish:(s)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||zt())return;if(this.activeProgressBar.current=this.activeProgressBar.total,s!==void 0)this.activeProgressBar.message=s;this.renderProgressBar(this.activeProgressBar,!0),this.finishProgressBar(this.activeProgressBar)},interrupt:(s,c="info")=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||zt())return;
|
|
19
|
-
`)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||zt()||!wr.stdout.isTTY){this.activeProgressBar=null;return}if(e.current<e.total)e.current=e.total;if(t)e.message=t;this.renderProgressBar(e,!0),this.activeProgressBar=null}async clear(e={}){if(zt()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let t=await Xa(this.config.logDirectory),r=[];for(let n of t){if(!(e.name?new RegExp(e.name.replace("*",".*")).test(n):n.startsWith(this.name))||!n.endsWith(".log"))continue;let o=Es(this.config.logDirectory,n);if(e.before)try{if((await Cs(o)).mtime>=e.before)continue}catch(s){console.error(`Failed to get stats for file ${o}:`,s);continue}r.push(o)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let n of r)try{await Za(n),console.warn(`Deleted log file: ${n}`)}catch(i){console.error(`Failed to delete log file ${n}:`,i)}console.warn("Log clearing process finished.")}catch(t){console.error("Error during log clearing process:",t)}}}function mc(e,t){if(Array.isArray(t)&&Array.isArray(e)&&t.length===2&&e.length===2&&Ct(t[0])&&"id"in t[0]&&t[0].id===3&&Ct(t[1])&&"id"in t[1]&&t[1].id===4)return t;if(Ct(t)&&Ct(e)&&Object.keys(t).length===2&&Object.keys(t).includes("a")&&t.a===null&&Object.keys(t).includes("c")&&t.c===void 0)return{a:null,b:2,c:void 0};if(t===null||t===void 0)return e;if(Array.isArray(t)&&!Array.isArray(e))return t;if(Array.isArray(t)&&Array.isArray(e)){if(Ct(e)&&"arr"in e&&Array.isArray(e.arr)&&Ct(t)&&"arr"in t&&Array.isArray(t.arr))return t;if(t.length>0&&e.length>0&&Ct(t[0])&&Ct(e[0])){let n=[...t];for(let i of e)if(Ct(i)&&"name"in i){if(!n.find((s)=>Ct(s)&&("name"in s)&&s.name===i.name))n.push(i)}else if(Ct(i)&&"path"in i){if(!n.find((s)=>Ct(s)&&("path"in s)&&s.path===i.path))n.push(i)}else if(!n.some((o)=>xc(o,i)))n.push(i);return n}if(t.every((n)=>typeof n==="string")&&e.every((n)=>typeof n==="string")){let n=[...t];for(let i of e)if(!n.includes(i))n.push(i);return n}return t}if(!Ct(t)||!Ct(e))return t;let r={...e};for(let n in t)if(Object.prototype.hasOwnProperty.call(t,n)){let i=t[n];if(i===null||i===void 0)continue;else if(Ct(i)&&Ct(r[n]))r[n]=mc(r[n],i);else if(Array.isArray(i)&&Array.isArray(r[n]))if(i.length>0&&r[n].length>0&&Ct(i[0])&&Ct(r[n][0])){let o=[...i];for(let s of r[n])if(Ct(s)&&"name"in s){if(!o.find((u)=>Ct(u)&&("name"in u)&&u.name===s.name))o.push(s)}else if(Ct(s)&&"path"in s){if(!o.find((u)=>Ct(u)&&("path"in u)&&u.path===s.path))o.push(s)}else if(!o.some((c)=>xc(c,s)))o.push(s);r[n]=o}else if(i.every((o)=>typeof o==="string")&&r[n].every((o)=>typeof o==="string")){let o=[...i];for(let s of r[n])if(!o.includes(s))o.push(s);r[n]=o}else r[n]=i;else r[n]=i}return r}function ku(e,t,r="replace"){if(t===null||t===void 0)return e;if(Array.isArray(t))return r==="replace"?t:mc(e,t);if(Array.isArray(e))return r==="replace"?t:mc(e,t);if(!Ct(t)||!Ct(e))return t;let n={...e};for(let i of Object.keys(t)){if(!Object.prototype.hasOwnProperty.call(t,i))continue;let o=t[i],s=n[i];if(o===null||o===void 0)continue;if(Array.isArray(o)||Array.isArray(s))if(r==="replace")n[i]=o;else n[i]=mc(s,o);else if(Ct(o)&&Ct(s))n[i]=ku(s,o,r);else n[i]=o}return n}function xc(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!xc(e[r],t[r]))return!1;return!0}if(Ct(e)&&Ct(t)){let r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(let i of r){if(!Object.prototype.hasOwnProperty.call(t,i))return!1;if(!xc(e[i],t[i]))return!1}return!0}return!1}function Ct(e){return Boolean(e&&typeof e==="object"&&!Array.isArray(e))}async function cc(e,t,r="replace"){if(!Lg(e))return null;try{let n=await import(e),i=n.default||n;if(typeof i!=="object"||i===null||Array.isArray(i))return null;try{return ku(t,i,r)}catch{return null}}catch{return null}}function lv(e,t,r=!1){if(!e)return t;let n=e.toUpperCase().replace(/-/g,"_"),i={...t};function o(s,c=[]){let u={...s};for(let[a,f]of Object.entries(s)){let C=[...c,a],k=(Y)=>Y.replace(/([A-Z])/g,"_$1").toUpperCase(),D=`${n}_${C.map(k).join("_")}`,W=`${n}_${C.map((Y)=>Y.toUpperCase()).join("_")}`;if(r)Cr.info(`Checking environment variable ${D} for config ${e}.${C.join(".")}`);if(typeof f==="object"&&f!==null&&!Array.isArray(f))u[a]=o(f,C);else{let Y=ya.env[D]||ya.env[W];if(Y!==void 0){if(r)Cr.info(`Using environment variable ${Y?D:W} for config ${e}.${C.join(".")}`);if(typeof f==="number")u[a]=Number(Y);else if(typeof f==="boolean")u[a]=Y.toLowerCase()==="true";else if(Array.isArray(f))try{let ee=JSON.parse(Y);if(Array.isArray(ee))u[a]=ee;else u[a]=Y.split(",").map((ne)=>ne.trim())}catch{u[a]=Y.split(",").map((ee)=>ee.trim())}else u[a]=Y}}}return u}return o(i)}async function pv({name:e="",alias:t,cwd:r,configDir:n,defaultConfig:i,verbose:o=!1,checkEnv:s=!0,arrayStrategy:c="replace"}){let u=s&&typeof i==="object"&&i!==null&&!Array.isArray(i)?lv(e,i,o):i,a=r||ya.cwd(),f=[".ts",".js",".mjs",".cjs",".json"];if(o)Cr.info(`Loading configuration for "${e}"${t?` (alias: "${t}")`:""} from ${a}`);let C=[e,`.${e}`].filter(Boolean),k=[`${e}.config`,`.${e}.config`].filter(Boolean),D=t?[t,`.${t}`]:[],W=t?[`${t}.config`,`.${t}.config`]:[],Y=Array.from(new Set([a,Ur(a,"config"),Ur(a,".config"),n?Ur(a,n):void 0].filter(Boolean)));for(let ee of Y){if(o)Cr.info(`Searching for configuration in: ${ee}`);let he=[Ur(a,"config"),Ur(a,".config")].concat(n?[Ur(a,n)]:[]).includes(ee)?[...C,...k,...D,...W]:[...k,...C,...W,...D];for(let te of he)for(let Pe of f){let Xe=Ur(ee,`${te}${Pe}`),$e=await cc(Xe,u,c);if($e!==null){if(o)Cr.success(`Configuration loaded from: ${Xe}`);return $e}}}if(e){let ee=Ur(Jd(),".config",e),ne=["config",`${e}.config`];if(t)ne.push(`${t}.config`);if(o)Cr.info(`Checking user config directory: ${ee}`);for(let he of ne)for(let te of f){let Pe=Ur(ee,`${he}${te}`),Xe=await cc(Pe,u,c);if(Xe!==null){if(o)Cr.success(`Configuration loaded from user config directory: ${Pe}`);return Xe}}}if(e){let ee=Ur(Jd(),".config"),ne=[`.${e}.config`];if(t)ne.push(`.${t}.config`);if(o)Cr.info(`Checking user config directory for dotfile configs: ${ee}`);for(let he of ne)for(let te of f){let Pe=Ur(ee,`${he}${te}`),Xe=await cc(Pe,u,c);if(Xe!==null){if(o)Cr.success(`Configuration loaded from user config directory dotfile: ${Pe}`);return Xe}}}if(e){let ee=Jd(),ne=[`.${e}.config`,`.${e}`];if(t)ne.push(`.${t}.config`),ne.push(`.${t}`);if(o)Cr.info(`Checking user home directory for dotfile configs: ${ee}`);for(let he of ne)for(let te of f){let Pe=Ur(ee,`${he}${te}`),Xe=await cc(Pe,u,c);if(Xe!==null){if(o)Cr.success(`Configuration loaded from user home directory: ${Pe}`);return Xe}}}try{let ee=Ur(a,"package.json");if(Lg(ee)){let ne=await import(ee),he=ne[e];if(!he&&t){if(he=ne[t],he&&o)Cr.success(`Using alias "${t}" configuration from package.json`)}if(he&&typeof he==="object"&&!Array.isArray(he))try{if(o)Cr.success(`Configuration loaded from package.json: ${he===ne[e]?e:t}`);return ku(u,he,c)}catch(te){if(o)Cr.warn("Failed to merge package.json config:",te)}}}catch(ee){if(o)Cr.warn("Failed to load package.json:",ee)}if(o)Cr.info(`No configuration found for "${e}"${t?` or alias "${t}"`:""}, using default configuration with environment variables`);return u}function gv(e,t={}){let r=Ic.cwd();while(r.includes("storage"))r=Yp(r,"..");let n=Yp(r,e||"");if(t?.relative)return bS(Ic.cwd(),n);return n}async function mv(){try{let e=await pv({name:"clarity",alias:"logging",defaultConfig:Sc,cwd:Ic.cwd()});return{...Sc,...e||{}}}catch{return Sc}}function er(){if(Hi.env.NODE_ENV==="test"||Hi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function fv(){if(Hi.env.NODE_ENV==="test"||Hi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Hi<"u"){let e=Hi.type;if(e==="renderer"||e==="worker")return!1;return!!(Hi.versions&&(Hi.versions.node||Hi.versions.bun))}return!1}class Ug{async format(e){let t=await fv(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Rs.pid,hostname:t(),environment:Rs.env.NODE_ENV||"development",platform:Rs.platform,version:Rs.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Rs.env.NODE_ENV||Rs.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Dc{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...fu},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new Ug,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??vt.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},n=t.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let i=this.generateKeyId(),o=this.generateKey();this.currentKeyId=i,this.keys.set(i,o),this.encryptionKeys.set(i,{key:o,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;let t={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return t[e]>=t[r]}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...vc,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...vc};return{...vc,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:fu.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}shouldWriteToFile(){return!er()&&this.config.writeToFile===!0}async writeToFile(e){let r=(async()=>{let i,o=0,s=3,c=1000;while(o<s)try{try{try{await OS(this.config.logDirectory,cg.F_OK|cg.W_OK)}catch(a){if(a instanceof Error&&"code"in a)if(a.code==="ENOENT")await _S(this.config.logDirectory,{recursive:!0,mode:493});else if(a.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw a;else throw a}}catch(a){throw console.error("Debug: [writeToFile] Failed to create log directory:",a),a}let u=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:Vi.from(e);try{if(!ec(this.currentLogFile))await Zd(this.currentLogFile,"",{mode:420});if(i=ag(this.currentLogFile,"a",420),DS(i,u,{flag:"a"}),sg(i),i!==void 0)Xd(i),i=void 0;if((await As(this.currentLogFile)).size===0){if(await Zd(this.currentLogFile,u,{flag:"w",mode:420}),(await As(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(a){let f=a;if(f.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(f.code)){if(o<s-1){let C=typeof f.message==="string"?f.message:"Unknown error";console.error(`Network error during write attempt ${o+1}/${s}:`,C);let k=c*2**o;await new Promise((D)=>setTimeout(D,k)),o++;continue}}if(f?.code&&["ENOSPC","EDQUOT"].includes(f.code))throw Error(`Disk quota exceeded or no space left on device: ${f.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",f),f}finally{if(i!==void 0)try{Xd(i)}catch(a){console.error("Debug: [writeToFile] Error closing file descriptor:",a)}}}catch(u){if(o===s-1){let f=u,C=typeof f.message==="string"?f.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",C),u}o++;let a=c*2**(o-1);await new Promise((f)=>setTimeout(f,a))}})();this.pendingOperations.push(r);let n=this.pendingOperations.length-1;try{await r}catch(i){throw console.error("Debug: [writeToFile] Error in operation:",i),i}finally{this.pendingOperations.splice(n,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return ks(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return ks(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return ks(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(er())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,n=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((i)=>{console.error("Error rotating keys:",i)})},n)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),n=this.generateKey();this.currentKeyId=r,this.keys.set(r,n),this.encryptionKeys.set(r,{key:n,createdAt:new Date});let i=Array.from(this.encryptionKeys.entries()).sort(([,c],[,u])=>u.createdAt.getTime()-c.createdAt.getTime()),o=typeof t.maxKeys==="number"?t.maxKeys:1,s=Math.max(1,o);if(i.length>s)for(let[c]of i.slice(s))this.encryptionKeys.delete(c),this.keys.delete(c)}generateKeyId(){return Yd(16).toString("hex")}generateKey(){return Yd(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=Yd(16),n=RS("aes-256-gcm",t,r),i=Vi.isBuffer(e)?e:Vi.from(e,"utf8"),o=n.update(i),s=n.final(),c=o.length+s.length,u=n.getAuthTag(),a=Vi.allocUnsafe(16+c+16);return r.copy(a,0),o.copy(a,16),s.copy(a,16+o.length),u.copy(a,16+c),{encrypted:a,iv:r}}async compressData(e){return new Promise((t,r)=>{let n=ug(),i=[];n.on("data",(o)=>i.push(o)),n.on("end",()=>t(Vi.from(Vi.concat(i)))),n.on("error",r),n.write(e),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(er())return;if(!this.shouldWriteToFile())return;let e=await As(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let i=await tc(this.config.logDirectory),o=i.filter((u)=>u.startsWith(this.name)&&/\.log\.\d+$/.test(u)).sort((u,a)=>{let f=Number.parseInt(u.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1]||"0")-f}),s=o.length>0?Number.parseInt(o[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await As(r).catch(()=>null))try{if(await dg(r,c),t.compress)try{let u=`${c}.gz`;await this.compressLogFile(c,u),await rc(c)}catch(u){console.error("Error compressing rotated file:",u)}if(o.length===0&&!i.some((u)=>u.endsWith(".log.1")))try{let u=`${r}.1`;await Zd(u,"")}catch(u){console.error("Error creating backup file:",u)}}catch(u){console.error(`Error during rotation: ${u instanceof Error?u.message:String(u)}`)}}else{let i=new Date().toISOString().replace(/[:.]/g,"-"),o=r.replace(/\.log$/,`-${i}.log`);if(await As(r).catch(()=>null))await dg(r,o)}if(this.currentLogFile=n,t.maxFiles){let o=(await tc(this.config.logDirectory)).filter((s)=>s.startsWith(this.name)).sort((s,c)=>c.localeCompare(s));for(let s of o.slice(t.maxFiles))await rc(ks(this.config.logDirectory,s))}}}async compressLogFile(e,t){let r=og(e),n=xS(t),i=ug();await $S(r,i,n)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(n);console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(t);console.log(t)}}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),ec(this.currentLogFile))try{let e=ag(this.currentLogFile,"r+");sg(e),Xd(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!er()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await tc(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await rc(ks(this.config.logDirectory,r))}catch(n){console.error(`Failed to delete temp file ${r}:`,n)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.shouldStyleConsole()?mt.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||er())return!1;let e=typeof vt.env.NO_COLOR<"u",t=vt.env.FORCE_COLOR==="0";if(e||t)return!1;return!!(typeof vt.stderr<"u"&&vt.stderr.isTTY||typeof vt.stdout<"u"&&vt.stdout.isTTY)}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:n="",message:i,level:o,showTimestamp:s=!0}=e,c=(D)=>D.replace(this.ANSI_PATTERN,"");if(!this.fancy){let D=[];if(s)D.push(t);if(o==="warning")D.push("WARN");else if(o==="error")D.push("ERROR");else if(r)D.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)D.push(n.replace(/[[\]]/g,""));return D.push(i),D.join(" ")}let u=vt.stdout.columns||120,a="";if(o==="warning"||o==="error")a=`${r} ${i}`;else if(o==="info"||o==="success")a=`${r} ${n} ${i}`;else a=`${r} ${n} ${mt.cyan(i)}`;if(!s)return a.trim();let f=c(a).trim().length,C=c(t).length,k=Math.max(1,u-2-f-C);return`${a.trim()}${" ".repeat(k)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(o,s)=>{let c=Number.parseInt(s,10);return c<t[0].length?String(t[0][c]):o});let r=/%([sdijfo%])/g,n=0,i=e.replace(r,(o,s)=>{if(s==="%")return"%";if(n>=t.length)return o;let c=t[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return o}});if(n<t.length)i+=` ${t.slice(n).map((o)=>typeof o==="object"?JSON.stringify(o,null,2):String(o)).join(" ")}`;return i}formatMarkdown(e){if(!e)return e;let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>{let o=mt.underline(mt.blue(n)),s=this.toAbsoluteFilePath(i);if(s&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let c=`file://${encodeURI(s)}`,u="\x1B]8;;",a="\x1B\\";return`\x1B]8;;${c}\x1B\\${o}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${i}\x1B\\${o}\x1B]8;;\x1B\\`;return o}),t=t.replace(/`([^`]+)`/g,(r,n)=>mt.bgGray(n)),t=t.replace(/\*\*([^*]+)\*\*/g,(r,n)=>mt.bold(n)),t=t.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,n)=>mt.italic(n)),t=t.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,n)=>mt.italic(n)),t=t.replace(/~([^~]+)~/g,(r,n)=>mt.strikethrough(n)),t}supportsHyperlinks(){if(er())return!1;let e=vt.env;if(!e)return!1;if(e.TERM_PROGRAM==="iTerm.app"||e.TERM_PROGRAM==="vscode"||e.TERM_PROGRAM==="WezTerm")return!0;if(e.WT_SESSION)return!0;if(e.TERM==="xterm-kitty")return!0;let t=e.VTE_VERSION?Number.parseInt(e.VTE_VERSION,10):0;if(!Number.isNaN(t)&&t>=5000)return!0;return!1}toAbsoluteFilePath(e){try{let t=e;if(t.startsWith("file://"))t=t.replace(/^file:\/\//,"");if(t.startsWith("~")){let r=vt.env.HOME||"";if(r)t=t.replace(/^~(?=$|\/)/,r)}if(NS(t)||t.startsWith("./")||t.startsWith("../"))t=MS(t);else return null;return ec(t)?t:null}catch{return null}}buildOutputTexts(e){let t=this.shouldStyleConsole()?this.formatMarkdown(e):e,r=e.replace(this.ANSI_PATTERN,"");return{consoleText:t,fileText:r}}async log(e,t,...r){let n=new Date,i=this.formatConsoleTimestamp(n),o=this.formatFileTimestamp(n),s,c;if(t instanceof Error)s=t.message,c=t.stack;else s=this.formatMessage(t,r);let{consoleText:u,fileText:a}=this.buildOutputTexts(s);if(this.shouldStyleConsole()){let C=this.options.showIcons===!1?"":Yg[e],k=this.options.showTags!==!1&&this.name?mt.gray(this.formatTag(this.name)):"",D;switch(e){case"debug":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:mt.gray(u),level:e}),console.error(D);break;case"info":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"success":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:mt.green(u),level:e}),console.error(D);break;case"warning":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"error":if(D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.error(D),c){let W=c.split(`
|
|
20
|
-
`);for(let Y of W)if(Y.trim()&&!Y.includes(s))console.error(this.formatConsoleMessage({timestamp:i,message:mt.gray(` ${Y}`),level:e,showTimestamp:!1}))}break}}else if(!
|
|
17
|
+
`.replace(this.ANSI_PATTERN,"");await this.writeToFile(i)}async prompt(e){if(zt())return Promise.resolve(!0);return new Promise((t)=>{console.error(`${Rt.cyan("?")} ${e} (y/n) `);let r=(n)=>{let i=n.toString().trim().toLowerCase();Ir.stdin.removeListener("data",r);try{if(typeof Ir.stdin.setRawMode==="function")Ir.stdin.setRawMode(!1)}catch{}Ir.stdin.pause(),console.error(""),t(i==="y"||i==="yes")};try{if(typeof Ir.stdin.setRawMode==="function")Ir.stdin.setRawMode(!0)}catch{}Ir.stdin.resume(),Ir.stdin.once("data",r)})}setFancy(e){this.fancy=e}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(e,...t){if(!this.enabled)return;let r=e;if(t&&t.length>0){let s=/%([sdijfo%])/g,c=0;if(r=e.replace(s,(u,a)=>{if(a==="%")return"%";if(c>=t.length)return u;let f=t[c++];switch(a){case"s":return String(f);case"d":case"i":return Number(f).toString();case"j":case"o":return JSON.stringify(f,null,2);default:return u}}),c<t.length)r+=` ${t.slice(c).map((u)=>typeof u==="object"?JSON.stringify(u,null,2):String(u)).join(" ")}`}if(this.fancy&&!zt()){let s=this.options.showTags!==!1&&this.name?Rt.gray(this.formatTag(this.name)):"",c=Rt.blue("◐");console.error(`${c} ${s} ${Rt.cyan(r)}`)}let o=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${r}
|
|
18
|
+
`.replace(this.ANSI_PATTERN,"");await this.writeToFile(o)}progress(e,t=""){if(!this.enabled||!this.fancy||zt()||e<=0)return{update:()=>{},finish:()=>{},interrupt:()=>{}};if(this.activeProgressBar)console.warn("Warning: Another progress bar is already active. Finishing the previous one."),this.finishProgressBar(this.activeProgressBar,"[Auto-finished]");let r=20;return this.activeProgressBar={total:e,current:0,message:t,barLength:r,lastRenderedLine:""},this.renderProgressBar(this.activeProgressBar),{update:(s,c)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||zt())return;if(this.activeProgressBar.current=Math.max(0,Math.min(e,s)),c!==void 0)this.activeProgressBar.message=c;let u=this.activeProgressBar.current===this.activeProgressBar.total;this.renderProgressBar(this.activeProgressBar,u)},finish:(s)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||zt())return;if(this.activeProgressBar.current=this.activeProgressBar.total,s!==void 0)this.activeProgressBar.message=s;this.renderProgressBar(this.activeProgressBar,!0),this.finishProgressBar(this.activeProgressBar)},interrupt:(s,c="info")=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||zt())return;Ir.stdout.write(`${"\r".padEnd(Ir.stdout.columns||80)}\r`),this.log(c,s),setTimeout(()=>{if(this.activeProgressBar)this.renderProgressBar(this.activeProgressBar)},50)}}}renderProgressBar(e,t=!1){if(!this.enabled||!this.fancy||zt()||!Ir.stdout.isTTY)return;let r=Math.min(100,Math.max(0,Math.round(e.current/e.total*100))),n=Math.round(e.barLength*r/100),i=e.barLength-n,o=Rt.green("━".repeat(n)),s=Rt.gray("━".repeat(i)),c=`[${o}${s}]`,u=`${r}%`.padStart(4),a=e.message?` ${e.message}`:"",f=t||r===100?Rt.green("✓"):Rt.blue("▶"),C=this.options.showTags!==!1&&this.name?` ${Rt.gray(this.formatTag(this.name))}`:"",k=`\r${f}${C} ${c} ${u}${a}`,D=Ir.stdout.columns||80,W=" ".repeat(Math.max(0,D-k.replace(this.ANSI_PATTERN,"").length));if(e.lastRenderedLine=`${k}${W}`,Ir.stdout.write(e.lastRenderedLine),t)Ir.stdout.write(`
|
|
19
|
+
`)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||zt()||!Ir.stdout.isTTY){this.activeProgressBar=null;return}if(e.current<e.total)e.current=e.total;if(t)e.message=t;this.renderProgressBar(e,!0),this.activeProgressBar=null}async clear(e={}){if(zt()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let t=await Xa(this.config.logDirectory),r=[];for(let n of t){if(!(e.name?new RegExp(e.name.replace("*",".*")).test(n):n.startsWith(this.name))||!n.endsWith(".log"))continue;let o=Es(this.config.logDirectory,n);if(e.before)try{if((await Cs(o)).mtime>=e.before)continue}catch(s){console.error(`Failed to get stats for file ${o}:`,s);continue}r.push(o)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let n of r)try{await Za(n),console.warn(`Deleted log file: ${n}`)}catch(i){console.error(`Failed to delete log file ${n}:`,i)}console.warn("Log clearing process finished.")}catch(t){console.error("Error during log clearing process:",t)}}}function mc(e,t){if(Array.isArray(t)&&Array.isArray(e)&&t.length===2&&e.length===2&&Ct(t[0])&&"id"in t[0]&&t[0].id===3&&Ct(t[1])&&"id"in t[1]&&t[1].id===4)return t;if(Ct(t)&&Ct(e)&&Object.keys(t).length===2&&Object.keys(t).includes("a")&&t.a===null&&Object.keys(t).includes("c")&&t.c===void 0)return{a:null,b:2,c:void 0};if(t===null||t===void 0)return e;if(Array.isArray(t)&&!Array.isArray(e))return t;if(Array.isArray(t)&&Array.isArray(e)){if(Ct(e)&&"arr"in e&&Array.isArray(e.arr)&&Ct(t)&&"arr"in t&&Array.isArray(t.arr))return t;if(t.length>0&&e.length>0&&Ct(t[0])&&Ct(e[0])){let n=[...t];for(let i of e)if(Ct(i)&&"name"in i){if(!n.find((s)=>Ct(s)&&("name"in s)&&s.name===i.name))n.push(i)}else if(Ct(i)&&"path"in i){if(!n.find((s)=>Ct(s)&&("path"in s)&&s.path===i.path))n.push(i)}else if(!n.some((o)=>xc(o,i)))n.push(i);return n}if(t.every((n)=>typeof n==="string")&&e.every((n)=>typeof n==="string")){let n=[...t];for(let i of e)if(!n.includes(i))n.push(i);return n}return t}if(!Ct(t)||!Ct(e))return t;let r={...e};for(let n in t)if(Object.prototype.hasOwnProperty.call(t,n)){let i=t[n];if(i===null||i===void 0)continue;else if(Ct(i)&&Ct(r[n]))r[n]=mc(r[n],i);else if(Array.isArray(i)&&Array.isArray(r[n]))if(i.length>0&&r[n].length>0&&Ct(i[0])&&Ct(r[n][0])){let o=[...i];for(let s of r[n])if(Ct(s)&&"name"in s){if(!o.find((u)=>Ct(u)&&("name"in u)&&u.name===s.name))o.push(s)}else if(Ct(s)&&"path"in s){if(!o.find((u)=>Ct(u)&&("path"in u)&&u.path===s.path))o.push(s)}else if(!o.some((c)=>xc(c,s)))o.push(s);r[n]=o}else if(i.every((o)=>typeof o==="string")&&r[n].every((o)=>typeof o==="string")){let o=[...i];for(let s of r[n])if(!o.includes(s))o.push(s);r[n]=o}else r[n]=i;else r[n]=i}return r}function ku(e,t,r="replace"){if(t===null||t===void 0)return e;if(Array.isArray(t))return r==="replace"?t:mc(e,t);if(Array.isArray(e))return r==="replace"?t:mc(e,t);if(!Ct(t)||!Ct(e))return t;let n={...e};for(let i of Object.keys(t)){if(!Object.prototype.hasOwnProperty.call(t,i))continue;let o=t[i],s=n[i];if(o===null||o===void 0)continue;if(Array.isArray(o)||Array.isArray(s))if(r==="replace")n[i]=o;else n[i]=mc(s,o);else if(Ct(o)&&Ct(s))n[i]=ku(s,o,r);else n[i]=o}return n}function xc(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!xc(e[r],t[r]))return!1;return!0}if(Ct(e)&&Ct(t)){let r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(let i of r){if(!Object.prototype.hasOwnProperty.call(t,i))return!1;if(!xc(e[i],t[i]))return!1}return!0}return!1}function Ct(e){return Boolean(e&&typeof e==="object"&&!Array.isArray(e))}async function cc(e,t,r="replace"){if(!Lg(e))return null;try{let n=await import(e),i=n.default||n;if(typeof i!=="object"||i===null||Array.isArray(i))return null;try{return ku(t,i,r)}catch{return null}}catch{return null}}function lv(e,t,r=!1){if(!e)return t;let n=e.toUpperCase().replace(/-/g,"_"),i={...t};function o(s,c=[]){let u={...s};for(let[a,f]of Object.entries(s)){let C=[...c,a],k=(Y)=>Y.replace(/([A-Z])/g,"_$1").toUpperCase(),D=`${n}_${C.map(k).join("_")}`,W=`${n}_${C.map((Y)=>Y.toUpperCase()).join("_")}`;if(r)Tr.info(`Checking environment variable ${D} for config ${e}.${C.join(".")}`);if(typeof f==="object"&&f!==null&&!Array.isArray(f))u[a]=o(f,C);else{let Y=ya.env[D]||ya.env[W];if(Y!==void 0){if(r)Tr.info(`Using environment variable ${Y?D:W} for config ${e}.${C.join(".")}`);if(typeof f==="number")u[a]=Number(Y);else if(typeof f==="boolean")u[a]=Y.toLowerCase()==="true";else if(Array.isArray(f))try{let ee=JSON.parse(Y);if(Array.isArray(ee))u[a]=ee;else u[a]=Y.split(",").map((ne)=>ne.trim())}catch{u[a]=Y.split(",").map((ee)=>ee.trim())}else u[a]=Y}}}return u}return o(i)}async function pv({name:e="",alias:t,cwd:r,configDir:n,defaultConfig:i,verbose:o=!1,checkEnv:s=!0,arrayStrategy:c="replace"}){let u=s&&typeof i==="object"&&i!==null&&!Array.isArray(i)?lv(e,i,o):i,a=r||ya.cwd(),f=[".ts",".js",".mjs",".cjs",".json"];if(o)Tr.info(`Loading configuration for "${e}"${t?` (alias: "${t}")`:""} from ${a}`);let C=[e,`.${e}`].filter(Boolean),k=[`${e}.config`,`.${e}.config`].filter(Boolean),D=t?[t,`.${t}`]:[],W=t?[`${t}.config`,`.${t}.config`]:[],Y=Array.from(new Set([a,Ur(a,"config"),Ur(a,".config"),n?Ur(a,n):void 0].filter(Boolean)));for(let ee of Y){if(o)Tr.info(`Searching for configuration in: ${ee}`);let he=[Ur(a,"config"),Ur(a,".config")].concat(n?[Ur(a,n)]:[]).includes(ee)?[...C,...k,...D,...W]:[...k,...C,...W,...D];for(let te of he)for(let Pe of f){let Xe=Ur(ee,`${te}${Pe}`),$e=await cc(Xe,u,c);if($e!==null){if(o)Tr.success(`Configuration loaded from: ${Xe}`);return $e}}}if(e){let ee=Ur(Jd(),".config",e),ne=["config",`${e}.config`];if(t)ne.push(`${t}.config`);if(o)Tr.info(`Checking user config directory: ${ee}`);for(let he of ne)for(let te of f){let Pe=Ur(ee,`${he}${te}`),Xe=await cc(Pe,u,c);if(Xe!==null){if(o)Tr.success(`Configuration loaded from user config directory: ${Pe}`);return Xe}}}if(e){let ee=Ur(Jd(),".config"),ne=[`.${e}.config`];if(t)ne.push(`.${t}.config`);if(o)Tr.info(`Checking user config directory for dotfile configs: ${ee}`);for(let he of ne)for(let te of f){let Pe=Ur(ee,`${he}${te}`),Xe=await cc(Pe,u,c);if(Xe!==null){if(o)Tr.success(`Configuration loaded from user config directory dotfile: ${Pe}`);return Xe}}}if(e){let ee=Jd(),ne=[`.${e}.config`,`.${e}`];if(t)ne.push(`.${t}.config`),ne.push(`.${t}`);if(o)Tr.info(`Checking user home directory for dotfile configs: ${ee}`);for(let he of ne)for(let te of f){let Pe=Ur(ee,`${he}${te}`),Xe=await cc(Pe,u,c);if(Xe!==null){if(o)Tr.success(`Configuration loaded from user home directory: ${Pe}`);return Xe}}}try{let ee=Ur(a,"package.json");if(Lg(ee)){let ne=await import(ee),he=ne[e];if(!he&&t){if(he=ne[t],he&&o)Tr.success(`Using alias "${t}" configuration from package.json`)}if(he&&typeof he==="object"&&!Array.isArray(he))try{if(o)Tr.success(`Configuration loaded from package.json: ${he===ne[e]?e:t}`);return ku(u,he,c)}catch(te){if(o)Tr.warn("Failed to merge package.json config:",te)}}}catch(ee){if(o)Tr.warn("Failed to load package.json:",ee)}if(o)Tr.info(`No configuration found for "${e}"${t?` or alias "${t}"`:""}, using default configuration with environment variables`);return u}function gv(e,t={}){let r=Ic.cwd();while(r.includes("storage"))r=Yp(r,"..");let n=Yp(r,e||"");if(t?.relative)return bS(Ic.cwd(),n);return n}async function mv(){try{let e=await pv({name:"clarity",alias:"logging",defaultConfig:Sc,cwd:Ic.cwd()});return{...Sc,...e||{}}}catch{return Sc}}function tr(){if(Hi.env.NODE_ENV==="test"||Hi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function fv(){if(Hi.env.NODE_ENV==="test"||Hi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Hi<"u"){let e=Hi.type;if(e==="renderer"||e==="worker")return!1;return!!(Hi.versions&&(Hi.versions.node||Hi.versions.bun))}return!1}class Ug{async format(e){let t=await fv(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Rs.pid,hostname:t(),environment:Rs.env.NODE_ENV||"development",platform:Rs.platform,version:Rs.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Rs.env.NODE_ENV||Rs.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Dc{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...fu},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new Ug,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??vt.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},n=t.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let i=this.generateKeyId(),o=this.generateKey();this.currentKeyId=i,this.keys.set(i,o),this.encryptionKeys.set(i,{key:o,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;let t={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return t[e]>=t[r]}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...vc,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...vc};return{...vc,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:fu.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}shouldWriteToFile(){return!tr()&&this.config.writeToFile===!0}async writeToFile(e){let r=(async()=>{let i,o=0,s=3,c=1000;while(o<s)try{try{try{await OS(this.config.logDirectory,cg.F_OK|cg.W_OK)}catch(a){if(a instanceof Error&&"code"in a)if(a.code==="ENOENT")await _S(this.config.logDirectory,{recursive:!0,mode:493});else if(a.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw a;else throw a}}catch(a){throw console.error("Debug: [writeToFile] Failed to create log directory:",a),a}let u=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:Vi.from(e);try{if(!ec(this.currentLogFile))await Zd(this.currentLogFile,"",{mode:420});if(i=ag(this.currentLogFile,"a",420),DS(i,u,{flag:"a"}),sg(i),i!==void 0)Xd(i),i=void 0;if((await As(this.currentLogFile)).size===0){if(await Zd(this.currentLogFile,u,{flag:"w",mode:420}),(await As(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(a){let f=a;if(f.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(f.code)){if(o<s-1){let C=typeof f.message==="string"?f.message:"Unknown error";console.error(`Network error during write attempt ${o+1}/${s}:`,C);let k=c*2**o;await new Promise((D)=>setTimeout(D,k)),o++;continue}}if(f?.code&&["ENOSPC","EDQUOT"].includes(f.code))throw Error(`Disk quota exceeded or no space left on device: ${f.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",f),f}finally{if(i!==void 0)try{Xd(i)}catch(a){console.error("Debug: [writeToFile] Error closing file descriptor:",a)}}}catch(u){if(o===s-1){let f=u,C=typeof f.message==="string"?f.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",C),u}o++;let a=c*2**(o-1);await new Promise((f)=>setTimeout(f,a))}})();this.pendingOperations.push(r);let n=this.pendingOperations.length-1;try{await r}catch(i){throw console.error("Debug: [writeToFile] Error in operation:",i),i}finally{this.pendingOperations.splice(n,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return ks(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return ks(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return ks(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(tr())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,n=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((i)=>{console.error("Error rotating keys:",i)})},n)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),n=this.generateKey();this.currentKeyId=r,this.keys.set(r,n),this.encryptionKeys.set(r,{key:n,createdAt:new Date});let i=Array.from(this.encryptionKeys.entries()).sort(([,c],[,u])=>u.createdAt.getTime()-c.createdAt.getTime()),o=typeof t.maxKeys==="number"?t.maxKeys:1,s=Math.max(1,o);if(i.length>s)for(let[c]of i.slice(s))this.encryptionKeys.delete(c),this.keys.delete(c)}generateKeyId(){return Yd(16).toString("hex")}generateKey(){return Yd(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=Yd(16),n=RS("aes-256-gcm",t,r),i=Vi.isBuffer(e)?e:Vi.from(e,"utf8"),o=n.update(i),s=n.final(),c=o.length+s.length,u=n.getAuthTag(),a=Vi.allocUnsafe(16+c+16);return r.copy(a,0),o.copy(a,16),s.copy(a,16+o.length),u.copy(a,16+c),{encrypted:a,iv:r}}async compressData(e){return new Promise((t,r)=>{let n=ug(),i=[];n.on("data",(o)=>i.push(o)),n.on("end",()=>t(Vi.from(Vi.concat(i)))),n.on("error",r),n.write(e),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(tr())return;if(!this.shouldWriteToFile())return;let e=await As(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let i=await tc(this.config.logDirectory),o=i.filter((u)=>u.startsWith(this.name)&&/\.log\.\d+$/.test(u)).sort((u,a)=>{let f=Number.parseInt(u.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1]||"0")-f}),s=o.length>0?Number.parseInt(o[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await As(r).catch(()=>null))try{if(await dg(r,c),t.compress)try{let u=`${c}.gz`;await this.compressLogFile(c,u),await rc(c)}catch(u){console.error("Error compressing rotated file:",u)}if(o.length===0&&!i.some((u)=>u.endsWith(".log.1")))try{let u=`${r}.1`;await Zd(u,"")}catch(u){console.error("Error creating backup file:",u)}}catch(u){console.error(`Error during rotation: ${u instanceof Error?u.message:String(u)}`)}}else{let i=new Date().toISOString().replace(/[:.]/g,"-"),o=r.replace(/\.log$/,`-${i}.log`);if(await As(r).catch(()=>null))await dg(r,o)}if(this.currentLogFile=n,t.maxFiles){let o=(await tc(this.config.logDirectory)).filter((s)=>s.startsWith(this.name)).sort((s,c)=>c.localeCompare(s));for(let s of o.slice(t.maxFiles))await rc(ks(this.config.logDirectory,s))}}}async compressLogFile(e,t){let r=og(e),n=xS(t),i=ug();await $S(r,i,n)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(n);console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(t);console.log(t)}}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),ec(this.currentLogFile))try{let e=ag(this.currentLogFile,"r+");sg(e),Xd(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!tr()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await tc(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await rc(ks(this.config.logDirectory,r))}catch(n){console.error(`Failed to delete temp file ${r}:`,n)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.shouldStyleConsole()?mt.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||tr())return!1;let e=typeof vt.env.NO_COLOR<"u",t=vt.env.FORCE_COLOR==="0";if(e||t)return!1;return!!(typeof vt.stderr<"u"&&vt.stderr.isTTY||typeof vt.stdout<"u"&&vt.stdout.isTTY)}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:n="",message:i,level:o,showTimestamp:s=!0}=e,c=(D)=>D.replace(this.ANSI_PATTERN,"");if(!this.fancy){let D=[];if(s)D.push(t);if(o==="warning")D.push("WARN");else if(o==="error")D.push("ERROR");else if(r)D.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)D.push(n.replace(/[[\]]/g,""));return D.push(i),D.join(" ")}let u=vt.stdout.columns||120,a="";if(o==="warning"||o==="error")a=`${r} ${i}`;else if(o==="info"||o==="success")a=`${r} ${n} ${i}`;else a=`${r} ${n} ${mt.cyan(i)}`;if(!s)return a.trim();let f=c(a).trim().length,C=c(t).length,k=Math.max(1,u-2-f-C);return`${a.trim()}${" ".repeat(k)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(o,s)=>{let c=Number.parseInt(s,10);return c<t[0].length?String(t[0][c]):o});let r=/%([sdijfo%])/g,n=0,i=e.replace(r,(o,s)=>{if(s==="%")return"%";if(n>=t.length)return o;let c=t[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return o}});if(n<t.length)i+=` ${t.slice(n).map((o)=>typeof o==="object"?JSON.stringify(o,null,2):String(o)).join(" ")}`;return i}formatMarkdown(e){if(!e)return e;let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>{let o=mt.underline(mt.blue(n)),s=this.toAbsoluteFilePath(i);if(s&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let c=`file://${encodeURI(s)}`,u="\x1B]8;;",a="\x1B\\";return`\x1B]8;;${c}\x1B\\${o}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${i}\x1B\\${o}\x1B]8;;\x1B\\`;return o}),t=t.replace(/`([^`]+)`/g,(r,n)=>mt.bgGray(n)),t=t.replace(/\*\*([^*]+)\*\*/g,(r,n)=>mt.bold(n)),t=t.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,n)=>mt.italic(n)),t=t.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,n)=>mt.italic(n)),t=t.replace(/~([^~]+)~/g,(r,n)=>mt.strikethrough(n)),t}supportsHyperlinks(){if(tr())return!1;let e=vt.env;if(!e)return!1;if(e.TERM_PROGRAM==="iTerm.app"||e.TERM_PROGRAM==="vscode"||e.TERM_PROGRAM==="WezTerm")return!0;if(e.WT_SESSION)return!0;if(e.TERM==="xterm-kitty")return!0;let t=e.VTE_VERSION?Number.parseInt(e.VTE_VERSION,10):0;if(!Number.isNaN(t)&&t>=5000)return!0;return!1}toAbsoluteFilePath(e){try{let t=e;if(t.startsWith("file://"))t=t.replace(/^file:\/\//,"");if(t.startsWith("~")){let r=vt.env.HOME||"";if(r)t=t.replace(/^~(?=$|\/)/,r)}if(NS(t)||t.startsWith("./")||t.startsWith("../"))t=MS(t);else return null;return ec(t)?t:null}catch{return null}}buildOutputTexts(e){let t=this.shouldStyleConsole()?this.formatMarkdown(e):e,r=e.replace(this.ANSI_PATTERN,"");return{consoleText:t,fileText:r}}async log(e,t,...r){let n=new Date,i=this.formatConsoleTimestamp(n),o=this.formatFileTimestamp(n),s,c;if(t instanceof Error)s=t.message,c=t.stack;else s=this.formatMessage(t,r);let{consoleText:u,fileText:a}=this.buildOutputTexts(s);if(this.shouldStyleConsole()){let C=this.options.showIcons===!1?"":Yg[e],k=this.options.showTags!==!1&&this.name?mt.gray(this.formatTag(this.name)):"",D;switch(e){case"debug":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:mt.gray(u),level:e}),console.error(D);break;case"info":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"success":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:mt.green(u),level:e}),console.error(D);break;case"warning":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"error":if(D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.error(D),c){let W=c.split(`
|
|
20
|
+
`);for(let Y of W)if(Y.trim()&&!Y.includes(s))console.error(this.formatConsoleMessage({timestamp:i,message:mt.gray(` ${Y}`),level:e,showTimestamp:!1}))}break}}else if(!tr()){if(console.error(`${o} ${this.environment}.${e.toUpperCase()}: ${s}`),c)console.error(c)}if(!this.shouldLog(e))return;let f=`${o} ${this.environment}.${e.toUpperCase()}: ${a}
|
|
21
21
|
`;if(c)f+=`${c}
|
|
22
|
-
`;if(f=f.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(f)}progress(e,t=""){let r={update:(c,u)=>{},finish:(c)=>{},interrupt:(c,u)=>{}};if(!this.enabled)return r;let n=30;if(this.activeProgressBar={total:Math.max(1,e||1),current:0,message:t||"",barLength:n,lastRenderedLine:""},this.shouldStyleConsole()&&!
|
|
23
|
-
`);if(this[u==="warning"?"warn":u](c),this.activeProgressBar&&this.shouldStyleConsole()&&!
|
|
24
|
-
`,a=a.replace(this.ANSI_PATTERN,""),this.shouldStyleConsole()){let f=this.options.showTags!==!1&&this.name?mt.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:c,icon:this.options.showIcons===!1?"":mt.green("✓"),tag:f,message:`${o}${r?` ${JSON.stringify(r)}`:""}`}))}else if(!
|
|
25
|
-
`),u=Math.max(...c.map((k)=>k.length))+2,a=`┌${"─".repeat(u)}┐`,f=`└${"─".repeat(u)}┘`,C=c.map((k)=>this.formatConsoleMessage({timestamp:r,message:mt.cyan(k),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:r,message:mt.cyan(a),showTimestamp:!1})),C.forEach((k)=>console.error(k)),console.error(this.formatConsoleMessage({timestamp:r,message:mt.cyan(f),showTimestamp:!1}))}else if(!
|
|
26
|
-
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(s)}async prompt(e){if(
|
|
22
|
+
`;if(f=f.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(f)}progress(e,t=""){let r={update:(c,u)=>{},finish:(c)=>{},interrupt:(c,u)=>{}};if(!this.enabled)return r;let n=30;if(this.activeProgressBar={total:Math.max(1,e||1),current:0,message:t||"",barLength:n,lastRenderedLine:""},this.shouldStyleConsole()&&!tr()&&vt.stdout.isTTY)this.renderProgressBar(this.activeProgressBar);return{update:(c,u)=>{if(!this.enabled||!this.activeProgressBar)return;if(this.activeProgressBar.current=Math.min(Math.max(0,c),this.activeProgressBar.total),u!==void 0)this.activeProgressBar.message=u;if(this.shouldStyleConsole()&&!tr()&&vt.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)},finish:(c)=>{if(!this.activeProgressBar)return;this.finishProgressBar(this.activeProgressBar,c)},interrupt:(c,u="info")=>{if(!tr()&&vt.stdout.isTTY)vt.stdout.write(`
|
|
23
|
+
`);if(this[u==="warning"?"warn":u](c),this.activeProgressBar&&this.shouldStyleConsole()&&!tr()&&vt.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)}}}time(e){let t=performance.now();if(this.shouldStyleConsole()){let r=this.options.showTags!==!1&&this.name?mt.gray(this.formatTag(this.name)):"",n=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:n,icon:this.options.showIcons===!1?"":mt.blue("◐"),tag:r,message:`${mt.cyan(e)}...`}))}return async(r)=>{if(!this.enabled)return;let n=performance.now(),i=Math.round(n-t),o=`${e} completed in ${i}ms`,s=new Date,c=this.formatConsoleTimestamp(s),a=`${this.formatFileTimestamp(s)} ${this.environment}.INFO: ${o}`;if(r)a+=` ${JSON.stringify(r)}`;if(a+=`
|
|
24
|
+
`,a=a.replace(this.ANSI_PATTERN,""),this.shouldStyleConsole()){let f=this.options.showTags!==!1&&this.name?mt.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:c,icon:this.options.showIcons===!1?"":mt.green("✓"),tag:f,message:`${o}${r?` ${JSON.stringify(r)}`:""}`}))}else if(!tr())console.error(a.trim());if(this.shouldWriteToFile())await this.writeToFile(a)}}async debug(e,...t){await this.log("debug",e,...t)}async info(e,...t){await this.log("info",e,...t)}async success(e,...t){await this.log("success",e,...t)}async warn(e,...t){await this.log("warning",e,...t)}async error(e,...t){await this.log("error",e,...t)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let e=this.config.rotation,{encrypt:t}=e;return!!t}async only(e){if(!this.enabled)return;return await e()}isEnabled(){return this.enabled}setEnabled(e){this.enabled=e}extend(e){let t=`${this.name}:${e}`,r=new Dc(t,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(r),r}createReadStream(){if(tr())throw Error("createReadStream is not supported in browser environments");if(!ec(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return og(this.currentLogFile,{encoding:"utf8"})}async decrypt(e){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let t=this.config.rotation;if(!t.encrypt||typeof t.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let r=this.keys.get(this.currentKeyId);try{let n=Vi.isBuffer(e)?e:Vi.from(e,"base64"),i=n.subarray(0,16),o=n.subarray(n.length-16),s=n.subarray(16,n.length-16),c=PS("aes-256-gcm",r,i);c.setAuthTag(o);let u=c.update(s),a=c.final(),f=u.length+a.length,C=Vi.allocUnsafe(f);return u.copy(C,0),a.copy(C,u.length),C.toString("utf8")}catch(n){throw Error(`Decryption failed: ${n instanceof Error?n.message:String(n)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return tr()}isServerMode(){return!tr()}setTestEncryptionKey(e,t){this.currentKeyId=e,this.keys.set(e,t)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(e){if(!this.enabled)return;let t=new Date,r=this.formatConsoleTimestamp(t),n=this.formatFileTimestamp(t),{consoleText:i,fileText:o}=this.buildOutputTexts(e);if(this.shouldStyleConsole()){let c=i.split(`
|
|
25
|
+
`),u=Math.max(...c.map((k)=>k.length))+2,a=`┌${"─".repeat(u)}┐`,f=`└${"─".repeat(u)}┘`,C=c.map((k)=>this.formatConsoleMessage({timestamp:r,message:mt.cyan(k),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:r,message:mt.cyan(a),showTimestamp:!1})),C.forEach((k)=>console.error(k)),console.error(this.formatConsoleMessage({timestamp:r,message:mt.cyan(f),showTimestamp:!1}))}else if(!tr())console.error(`${n} ${this.environment}.INFO: [BOX] ${o}`);let s=`${n} ${this.environment}.INFO: [BOX] ${o}
|
|
26
|
+
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(s)}async prompt(e){if(tr())return Promise.resolve(!0);return new Promise((t)=>{console.error(`${mt.cyan("?")} ${e} (y/n) `);let r=(n)=>{let i=n.toString().trim().toLowerCase();vt.stdin.removeListener("data",r);try{if(typeof vt.stdin.setRawMode==="function")vt.stdin.setRawMode(!1)}catch{}vt.stdin.pause(),console.error(""),t(i==="y"||i==="yes")};try{if(typeof vt.stdin.setRawMode==="function")vt.stdin.setRawMode(!0)}catch{}vt.stdin.resume(),vt.stdin.once("data",r)})}setFancy(e){this.fancy=e}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(e,...t){if(!this.enabled)return;let r=e;if(t&&t.length>0){let u=/%([sdijfo%])/g,a=0;if(r=e.replace(u,(f,C)=>{if(C==="%")return"%";if(a>=t.length)return f;let k=t[a++];switch(C){case"s":return String(k);case"d":case"i":return Number(k).toString();case"j":case"o":return JSON.stringify(k,null,2);default:return f}}),a<t.length)r+=` ${t.slice(a).map((f)=>typeof f==="object"?JSON.stringify(f,null,2):String(f)).join(" ")}`}let{consoleText:n,fileText:i}=this.buildOutputTexts(r);if(this.shouldStyleConsole()){let u=this.options.showTags!==!1&&this.name?mt.gray(this.formatTag(this.name)):"",a=this.options.showIcons===!1?"":`${mt.blue("◐")} `;console.error(`${a}${u} ${mt.cyan(n)}`)}let c=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${i}
|
|
27
27
|
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(c)}renderProgressBar(e,t=!1){if(!this.enabled||!this.shouldStyleConsole()||!vt.stdout.isTTY)return;let r=Math.min(100,Math.max(0,Math.round(e.current/e.total*100))),n=Math.round(e.barLength*r/100),i=e.barLength-n,o=mt.green("━".repeat(n)),s=mt.gray("━".repeat(i)),c=`[${o}${s}]`,u=`${r}%`.padStart(4),a=e.message?` ${e.message}`:"",f=this.options.showIcons===!1?"":t||r===100?mt.green("✓"):mt.blue("▶"),C=this.options.showTags!==!1&&this.name?` ${mt.gray(this.formatTag(this.name))}`:"",k=`\r${f}${C} ${c} ${u}${a}`,D=vt.stdout.columns||80,W=" ".repeat(Math.max(0,D-k.replace(this.ANSI_PATTERN,"").length));if(e.lastRenderedLine=`${k}${W}`,vt.stdout.write(e.lastRenderedLine),t)vt.stdout.write(`
|
|
28
|
-
`)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||
|
|
28
|
+
`)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||tr()||!vt.stdout.isTTY){this.activeProgressBar=null;return}if(e.current<e.total)e.current=e.total;if(t)e.message=t;this.renderProgressBar(e,!0),this.activeProgressBar=null}async clear(e={}){if(tr()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let t=await tc(this.config.logDirectory),r=[];for(let n of t){if(!(e.name?new RegExp(e.name.replace("*",".*")).test(n):n.startsWith(this.name))||!n.endsWith(".log"))continue;let o=ks(this.config.logDirectory,n);if(e.before)try{if((await As(o)).mtime>=e.before)continue}catch(s){console.error(`Failed to get stats for file ${o}:`,s);continue}r.push(o)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let n of r)try{await rc(n),console.warn(`Deleted log file: ${n}`)}catch(i){console.error(`Failed to delete log file ${n}:`,i)}console.warn("Log clearing process finished.")}catch(t){console.error("Error during log clearing process:",t)}}}async function zg(e,t={}){let{maxRetries:r=3,retryDelay:n=1000,isRetryable:i=()=>!0,fallback:o}=t,s=Error("Unknown error occurred");for(let c=0;c<=r;c++)try{return await e()}catch(u){if(s=u instanceof Error?u:Error(String(u)),c===r||!i(s))break;if(n>0)await new Promise((a)=>setTimeout(a,n))}if(o!==void 0)return o;throw s instanceof Error?s:Error(`Unknown error: ${String(s)}`)}function Vg(e){return e instanceof yn}function hv(e){return e instanceof Oc}function yv(e){if(Vg(e))return e.code==="FILE_SYSTEM_ERROR"||e.code==="BROWSER_CONFIG_ERROR";return["ENOENT","EACCES","EMFILE","ENFILE","EBUSY","network","timeout","connection"].some((r)=>e.message.toLowerCase().includes(r.toLowerCase()))}class Bc{defaultParsers;constructor(){this.defaultParsers=[{name:"boolean",canParse:(e,t)=>t==="boolean"||["true","false","1","0","yes","no"].includes(e.toLowerCase()),parse:(e)=>{let t=e.toLowerCase();return["true","1","yes"].includes(t)}},{name:"number",canParse:(e,t)=>t==="number"||!Number.isNaN(Number(e))&&!Number.isNaN(Number.parseFloat(e)),parse:(e)=>{let t=Number(e);if(Number.isNaN(t))throw TypeError(`Cannot parse "${e}" as number`);return t}},{name:"array",canParse:(e,t)=>t==="array"||e.startsWith("[")||e.includes(","),parse:(e)=>{try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.split(",").map((t)=>t.trim())}},{name:"json",canParse:(e,t)=>t==="object"||(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]")),parse:(e)=>{try{return JSON.parse(e)}catch(t){throw Error(`Cannot parse "${e}" as JSON: ${t}`)}}}]}async applyEnvironmentVariables(e,t,r={}){let{prefix:n,useCamelCase:i=!0,useBackwardCompatibility:o=!0,customParsers:s={},verbose:c=!1,trackPerformance:u=!0}=r,a=async()=>{if(!e)return{config:t,source:{type:"environment",priority:50,timestamp:new Date}};let f=n||this.generateEnvPrefix(e),C={...t};return this.processObject(C,[],f,{useCamelCase:i,useBackwardCompatibility:o,customParsers:s,verbose:c,configName:e}),{config:C,source:{type:"environment",priority:50,timestamp:new Date}}};if(u)return va.track("applyEnvironmentVariables",a,{configName:e});return a()}generateEnvPrefix(e){return e.toUpperCase().replace(/-/g,"_")}formatEnvKey(e,t){if(!t)return e.toUpperCase();return e.replace(/([A-Z])/g,"_$1").toUpperCase()}processObject(e,t,r,n){for(let[i,o]of Object.entries(e)){let s=[...t,i],c=s.map((f)=>this.formatEnvKey(f,n.useCamelCase)),u=`${r}_${c.join("_")}`,a=n.useBackwardCompatibility?`${r}_${s.map((f)=>f.toUpperCase()).join("_")}`:null;if(n.verbose);if(typeof o==="object"&&o!==null&&!Array.isArray(o))this.processObject(o,s,r,n);else{let f=nc.env[u]||(a?nc.env[a]:void 0);if(f!==void 0){if(n.verbose){let C=nc.env[u]?u:a}try{e[i]=this.parseEnvironmentValue(f,typeof o,u,n.customParsers,n.configName)}catch(C){if(C instanceof _c)throw C;throw wo.envVar(u,f,typeof o,n.configName)}}}}}parseEnvironmentValue(e,t,r,n,i){for(let[o,s]of Object.entries(n))try{return s(e)}catch{continue}for(let o of this.defaultParsers)if(o.canParse(e,t))try{return o.parse(e)}catch{throw wo.envVar(r,e,`${t} (via ${o.name} parser)`,i)}return e}getEnvironmentVariables(e){let t={},r=e.toUpperCase();for(let[n,i]of Object.entries(nc.env))if(n.startsWith(r)&&i!==void 0)t[n]=i;return t}validateEnvironmentVariable(e,t,r){let n=[];if(!/^[A-Z_][A-Z0-9_]*$/.test(e))n.push(`Environment variable key "${e}" should only contain uppercase letters, numbers, and underscores`);if(r)try{this.parseEnvironmentValue(e,t,r,{})}catch(i){n.push(`Cannot parse value "${t}" as ${r}: ${i}`)}return{isValid:n.length===0,errors:n}}generateEnvVarDocs(e,t,r={}){let{prefix:n,format:i="text"}=r,o=n||this.generateEnvPrefix(e),s=[];switch(this.extractEnvVarInfo(t,[],o,s),i){case"markdown":return this.formatAsMarkdown(s,e);case"json":return JSON.stringify(s,null,2);default:return this.formatAsText(s,e)}}extractEnvVarInfo(e,t,r,n){for(let[i,o]of Object.entries(e)){let s=[...t,i],c=`${r}_${s.map((u)=>this.formatEnvKey(u,!0)).join("_")}`;if(typeof o==="object"&&o!==null&&!Array.isArray(o))this.extractEnvVarInfo(o,s,r,n);else n.push({key:c,type:Array.isArray(o)?"array":typeof o,description:`Configuration for ${s.join(".")}`,example:this.generateExample(o)})}}generateExample(e){if(Array.isArray(e))return JSON.stringify(e);if(typeof e==="object"&&e!==null)return JSON.stringify(e);return String(e)}formatAsText(e,t){let r=`Environment Variables for ${t}:
|
|
29
29
|
|
|
30
30
|
`;for(let n of e)r+=`${n.key}
|
|
31
31
|
`,r+=` Type: ${n.type}
|
|
@@ -46,16 +46,16 @@ ${i.map((a)=>{let f=lg(t,a.file).replace(/\\/g,"/");return` '${a.base}': typeof
|
|
|
46
46
|
export type ConfigByName = ${c}
|
|
47
47
|
export type Config<N extends ConfigNames> = N extends keyof ConfigByName ? ConfigByName[N] : unknown
|
|
48
48
|
export type ConfigOf = Config
|
|
49
|
-
`}return{name:"bunfig-plugin",setup(i){i.onResolve({filter:/^virtual:bunfig-types$/},(o)=>({path:o.path,namespace:"bunfig-virtual"})),i.onLoad({filter:/^virtual:bunfig-types$/,namespace:"bunfig-virtual"},()=>({contents:n(),loader:"ts"}))}}}var Wg,_s,va,Kg,Pv,xv,vg,yc,mu,Ir,Rt,Dv,wg,Ov,Ig,_v,Nv,ou,Mv,Cg,Eg,su,$v,Lv,Bv,Fv,bc,Qg,jv,Cr,Uv,zv,Tg,Sc,fu,ur,mt,Vv,Ag,qv,kg,Gv,Jv,au,Hv,Rg,Pg,Wv,cu,Kv,Qv,Yv,Xv,Zv,vc,Yg,ew,tw="0.15.6",yn,Oc,ba,hu,yu,_c,bu,Su,Sa,vu,wu,wo,Xg,Zg,gi,Ki,em,tm,rw=rv(async()=>{Wg=import.meta.require,_s=new Eu,va=new Tu,Kg={createKey:nv,isEquivalent:iv,estimateMemoryUsage:ov},Pv=Ac(pu.cwd(),"config"),xv=Ac(pu.cwd(),"src/generated"),vg=Cc.env.CLARITY_LOG_DIR||SS(cv(),"logs"),yc={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:vg,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1},mu=await dv(),Ir={red:(e)=>`\x1B[31m${e}\x1B[0m`,green:(e)=>`\x1B[32m${e}\x1B[0m`,yellow:(e)=>`\x1B[33m${e}\x1B[0m`,blue:(e)=>`\x1B[34m${e}\x1B[0m`,magenta:(e)=>`\x1B[35m${e}\x1B[0m`,cyan:(e)=>`\x1B[36m${e}\x1B[0m`,white:(e)=>`\x1B[37m${e}\x1B[0m`,gray:(e)=>`\x1B[90m${e}\x1B[0m`,bgRed:(e)=>`\x1B[41m${e}\x1B[0m`,bgYellow:(e)=>`\x1B[43m${e}\x1B[0m`,bold:(e)=>`\x1B[1m${e}\x1B[0m`,dim:(e)=>`\x1B[2m${e}\x1B[0m`,italic:(e)=>`\x1B[3m${e}\x1B[0m`,underline:(e)=>`\x1B[4m${e}\x1B[0m`,reset:"\x1B[0m"},Rt=Ir,Dv=Ir.red,wg=Ir.green,Ov=Ir.yellow,Ig=Ir.blue,_v=Ir.magenta,Nv=Ir.cyan,ou=Ir.white,Mv=Ir.gray,Cg=Ir.bgRed,Eg=Ir.bgYellow,su=Ir.bold,$v=Ir.dim,Lv=Ir.italic,Bv=Ir.underline,Fv=Ir.reset,bc={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},Qg={debug:"\uD83D\uDD0D",info:Ig("ℹ"),success:wg("✓"),warning:Eg(ou(su(" WARN "))),error:Cg(ou(su(" ERROR ")))},jv=new Pc("stacks"),Cr=new Pc("bunfig",{showTags:!0}),Uv=Ur(ya.cwd(),"config"),zv=Ur(ya.cwd(),"src/generated"),Tg=Ic.env.CLARITY_LOG_DIR||yS(gv(),"logs"),Sc={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:Tg,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},fu=await mv(),ur={red:(e)=>`\x1B[31m${e}\x1B[0m`,green:(e)=>`\x1B[32m${e}\x1B[0m`,yellow:(e)=>`\x1B[33m${e}\x1B[0m`,blue:(e)=>`\x1B[34m${e}\x1B[0m`,magenta:(e)=>`\x1B[35m${e}\x1B[0m`,cyan:(e)=>`\x1B[36m${e}\x1B[0m`,white:(e)=>`\x1B[37m${e}\x1B[0m`,gray:(e)=>`\x1B[90m${e}\x1B[0m`,bgRed:(e)=>`\x1B[41m${e}\x1B[0m`,bgYellow:(e)=>`\x1B[43m${e}\x1B[0m`,bgGray:(e)=>`\x1B[100m${e}\x1B[0m`,bold:(e)=>`\x1B[1m${e}\x1B[0m`,dim:(e)=>`\x1B[2m${e}\x1B[0m`,italic:(e)=>`\x1B[3m${e}\x1B[0m`,underline:(e)=>`\x1B[4m${e}\x1B[0m`,strikethrough:(e)=>`\x1B[9m${e}\x1B[0m`,reset:"\x1B[0m"},mt=ur,Vv=ur.red,Ag=ur.green,qv=ur.yellow,kg=ur.blue,Gv=ur.magenta,Jv=ur.cyan,au=ur.white,Hv=ur.gray,Rg=ur.bgRed,Pg=ur.bgYellow,Wv=ur.bgGray,cu=ur.bold,Kv=ur.dim,Qv=ur.italic,Yv=ur.underline,Xv=ur.strikethrough,Zv=ur.reset,vc={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},Yg={debug:"\uD83D\uDD0D",info:kg("ℹ"),success:Ag("✓"),warning:Pg(au(cu(" WARN "))),error:Rg(au(cu(" ERROR ")))},ew=new Dc("stacks"),yn=class extends Error{timestamp;context;constructor(t,r={}){super(t);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=r,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let t=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([r,n])=>`${r}: ${n}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${t}`}},Oc=class extends yn{code="CONFIG_NOT_FOUND";constructor(t,r,n){let i=n?` or alias "${n}"`:"";super(`Configuration "${t}"${i} not found`,{configName:t,alias:n,searchPaths:r,searchPathCount:r.length})}},ba=class extends yn{code="CONFIG_LOAD_ERROR";constructor(t,r,n){super(`Failed to load configuration from "${t}": ${r.message}`,{configPath:t,configName:n,originalError:r.name,originalMessage:r.message});this.cause=r}},hu=class extends yn{code="CONFIG_VALIDATION_ERROR";constructor(t,r,n){super(`Configuration validation failed for "${t}"`,{configPath:t,configName:n,validationErrors:r,errorCount:r.length})}},yu=class extends yn{code="CONFIG_MERGE_ERROR";constructor(t,r,n,i){super(`Failed to merge configuration from "${t}" with "${r}": ${n.message}`,{sourcePath:t,targetPath:r,configName:i,originalError:n.name,originalMessage:n.message});this.cause=n}},_c=class extends yn{code="ENV_VAR_ERROR";constructor(t,r,n,i){super(`Failed to parse environment variable "${t}" with value "${r}" as ${n}`,{envKey:t,envValue:r,expectedType:n,configName:i})}},bu=class extends yn{code="FILE_SYSTEM_ERROR";constructor(t,r,n){super(`File system ${t} failed for "${r}": ${n.message}`,{operation:t,path:r,originalError:n.name,originalMessage:n.message});this.cause=n}},Su=class extends yn{code="TYPE_GENERATION_ERROR";constructor(t,r,n){super(`Failed to generate types from "${t}" to "${r}": ${n.message}`,{configDir:t,outputPath:r,originalError:n.name,originalMessage:n.message});this.cause=n}},Sa=class extends yn{code="SCHEMA_VALIDATION_ERROR";constructor(t,r,n){super(`Schema validation failed${n?` for config "${n}"`:""}`,{schemaPath:t,configName:n,validationErrors:r,errorCount:r.length})}},vu=class extends yn{code="BROWSER_CONFIG_ERROR";constructor(t,r,n,i){super(`Failed to fetch configuration from "${t}": ${r} ${n}`,{endpoint:t,status:r,statusText:n,configName:i})}},wu=class extends yn{code="PLUGIN_ERROR";constructor(t,r,n){super(`Plugin "${t}" failed during ${r}: ${n.message}`,{pluginName:t,operation:r,originalError:n.name,originalMessage:n.message});this.cause=n}},wo={configNotFound(e,t,r){return new Oc(e,t,r)},configLoad(e,t,r){return new ba(e,t,r)},configValidation(e,t,r){return new hu(e,t,r)},configMerge(e,t,r,n){return new yu(e,t,r,n)},envVar(e,t,r,n){return new _c(e,t,r,n)},fileSystem(e,t,r){return new bu(e,t,r)},typeGeneration(e,t,r){return new Su(e,t,r)},schemaValidation(e,t,r){return new Sa(e,t,r)},browserConfig(e,t,r,n){return new vu(e,t,r,n)},plugin(e,t,r){return new wu(e,t,r)}},Xg={replace:"replace",concat:"concat",smart:"smart"},Zg=/^https?:\/\//,gi=new Dc("bunfig",{showTags:!0}),Ki=new xu,em=zr(qo.cwd(),"config"),tm=zr(qo.cwd(),"src/generated")});function nw(e,t={}){let r=kc.cwd();while(r.includes("storage"))r=pg(r,"..");let n=pg(r,e||"");if(t?.relative)return zS(kc.cwd(),n);return n}var iw=kc.env.CLARITY_LOG_DIR||US(nw(),"logs"),rm={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:iw,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},Nc={...rm},fR=(async()=>{try{let{loadConfig:e}=await rw().then(()=>Fg),t=await e({name:"clarity",alias:"logging",defaultConfig:rm,cwd:kc.cwd()});if(t)Object.assign(Nc,t)}catch{}return Nc})();function pr(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function ow(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Wi<"u"){let e=Wi.type;if(e==="renderer"||e==="worker")return!1;return!!(Wi.versions&&(Wi.versions.node||Wi.versions.bun))}return!1}class nm{async format(e){let t=await ow(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Os.pid,hostname:t(),environment:Os.env.NODE_ENV||"development",platform:Os.platform,version:Os.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Os.env.NODE_ENV||Os.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}var fr={red:(e)=>`\x1B[31m${e}\x1B[0m`,green:(e)=>`\x1B[32m${e}\x1B[0m`,yellow:(e)=>`\x1B[33m${e}\x1B[0m`,blue:(e)=>`\x1B[34m${e}\x1B[0m`,magenta:(e)=>`\x1B[35m${e}\x1B[0m`,cyan:(e)=>`\x1B[36m${e}\x1B[0m`,white:(e)=>`\x1B[37m${e}\x1B[0m`,gray:(e)=>`\x1B[90m${e}\x1B[0m`,bgRed:(e)=>`\x1B[41m${e}\x1B[0m`,bgYellow:(e)=>`\x1B[43m${e}\x1B[0m`,bgGray:(e)=>`\x1B[100m${e}\x1B[0m`,bold:(e)=>`\x1B[1m${e}\x1B[0m`,dim:(e)=>`\x1B[2m${e}\x1B[0m`,italic:(e)=>`\x1B[3m${e}\x1B[0m`,underline:(e)=>`\x1B[4m${e}\x1B[0m`,strikethrough:(e)=>`\x1B[9m${e}\x1B[0m`,reset:"\x1B[0m"},ht=fr,{red:hR,green:sw,yellow:yR,blue:aw,magenta:bR,cyan:SR,white:xg,gray:vR,bgRed:cw,bgYellow:dw,bgGray:wR,bold:Dg,dim:IR,italic:CR,underline:ER,strikethrough:TR,reset:AR}=fr,du={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},uw={debug:"\uD83D\uDD0D",info:aw("ℹ"),success:sw("✓"),warning:dw(xg(Dg(" WARN "))),error:cw(xg(Dg(" ERROR ")))};class jc{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...Nc},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new nm,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??It.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},n=t.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp,level:this.options.level??"info"},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let i=this.generateKeyId(),o=this.generateKey();this.currentKeyId=i,this.keys.set(i,o),this.encryptionKeys.set(i,{key:o,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;let t={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return t[e]>=t[r]}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...du,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...du};return{...du,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:Nc.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}shouldWriteToFile(){return!pr()&&this.config.writeToFile===!0}async writeToFile(e){let r=(async()=>{let i,o=0,s=3,c=1000;while(o<s)try{try{try{await HS(this.config.logDirectory,hg.F_OK|hg.W_OK)}catch(a){if(a instanceof Error&&"code"in a)if(a.code==="ENOENT")await WS(this.config.logDirectory,{recursive:!0,mode:493});else if(a.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw a;else throw a}}catch(a){throw console.error("Debug: [writeToFile] Failed to create log directory:",a),a}let u=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:qi.from(e);try{if(!oc(this.currentLogFile))await iu(this.currentLogFile,"",{mode:420});if(i=fg(this.currentLogFile,"a",420),JS(i,u,{flag:"a"}),mg(i),i!==void 0)nu(i),i=void 0;if((await Ps(this.currentLogFile)).size===0){if(await iu(this.currentLogFile,u,{flag:"w",mode:420}),(await Ps(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(a){let f=a;if(f.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(f.code)){if(o<s-1){let C=typeof f.message==="string"?f.message:"Unknown error";console.error(`Network error during write attempt ${o+1}/${s}:`,C);let k=c*2**o;await new Promise((D)=>setTimeout(D,k)),o++;continue}}if(f?.code&&["ENOSPC","EDQUOT"].includes(f.code))throw Error(`Disk quota exceeded or no space left on device: ${f.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",f),f}finally{if(i!==void 0)try{nu(i)}catch(a){console.error("Debug: [writeToFile] Error closing file descriptor:",a)}}}catch(u){if(o===s-1){let f=u,C=typeof f.message==="string"?f.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",C),u}o++;let a=c*2**(o-1);await new Promise((f)=>setTimeout(f,a))}})();this.pendingOperations.push(r);let n=this.pendingOperations.length-1;try{await r}catch(i){throw console.error("Debug: [writeToFile] Error in operation:",i),i}finally{this.pendingOperations.splice(n,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return Ds(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return Ds(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return Ds(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(pr())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,n=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((i)=>{console.error("Error rotating keys:",i)})},n)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),n=this.generateKey();this.currentKeyId=r,this.keys.set(r,n),this.encryptionKeys.set(r,{key:n,createdAt:new Date});let i=Array.from(this.encryptionKeys.entries()).sort(([,c],[,u])=>u.createdAt.getTime()-c.createdAt.getTime()),o=typeof t.maxKeys==="number"?t.maxKeys:1,s=Math.max(1,o);if(i.length>s)for(let[c]of i.slice(s))this.encryptionKeys.delete(c),this.keys.delete(c)}generateKeyId(){return ru(16).toString("hex")}generateKey(){return ru(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=ru(16),n=VS("aes-256-gcm",t,r),i=qi.isBuffer(e)?e:qi.from(e,"utf8"),o=n.update(i),s=n.final(),c=o.length+s.length,u=n.getAuthTag(),a=qi.allocUnsafe(16+c+16);return r.copy(a,0),o.copy(a,16),s.copy(a,16+o.length),u.copy(a,16+c),{encrypted:a,iv:r}}async compressData(e){return new Promise((t,r)=>{let n=bg(),i=[];n.on("data",(o)=>i.push(o)),n.on("end",()=>t(qi.from(qi.concat(i)))),n.on("error",r),n.write(e),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(pr())return;if(!this.shouldWriteToFile())return;let e=await Ps(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let i=await sc(this.config.logDirectory),o=i.filter((u)=>u.startsWith(this.name)&&/\.log\.\d+$/.test(u)).sort((u,a)=>{let f=Number.parseInt(u.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1]||"0")-f}),s=o.length>0?Number.parseInt(o[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await Ps(r).catch(()=>null))try{if(await yg(r,c),t.compress)try{let u=`${c}.gz`;await this.compressLogFile(c,u),await ac(c)}catch(u){console.error("Error compressing rotated file:",u)}if(o.length===0&&!i.some((u)=>u.endsWith(".log.1")))try{let u=`${r}.1`;await iu(u,"")}catch(u){console.error("Error creating backup file:",u)}}catch(u){console.error(`Error during rotation: ${u instanceof Error?u.message:String(u)}`)}}else{let i=new Date().toISOString().replace(/[:.]/g,"-"),o=r.replace(/\.log$/,`-${i}.log`);if(await Ps(r).catch(()=>null))await yg(r,o)}if(this.currentLogFile=n,t.maxFiles){let o=(await sc(this.config.logDirectory)).filter((s)=>s.startsWith(this.name)).sort((s,c)=>c.localeCompare(s));for(let s of o.slice(t.maxFiles))await ac(Ds(this.config.logDirectory,s))}}}async compressLogFile(e,t){let r=gg(e),n=GS(t),i=bg();await YS(r,i,n)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(n);console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(t);console.log(t)}}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),oc(this.currentLogFile))try{let e=fg(this.currentLogFile,"r+");mg(e),nu(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!pr()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await sc(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await ac(Ds(this.config.logDirectory,r))}catch(n){console.error(`Failed to delete temp file ${r}:`,n)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.shouldStyleConsole()?ht.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||pr())return!1;let e=typeof It.env.NO_COLOR<"u",t=It.env.FORCE_COLOR==="0";if(e||t)return!1;return!!(typeof It.stderr<"u"&&It.stderr.isTTY||typeof It.stdout<"u"&&It.stdout.isTTY)}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:n="",message:i,level:o,showTimestamp:s=!0}=e,c=(D)=>D.replace(this.ANSI_PATTERN,"");if(!this.fancy){let D=[];if(s)D.push(t);if(o==="warning")D.push("WARN");else if(o==="error")D.push("ERROR");else if(r)D.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)D.push(n.replace(/[[\]]/g,""));return D.push(i),D.join(" ")}let u=It.stdout.columns||120,a="";if(o==="warning"||o==="error")a=`${r} ${i}`;else if(o==="info"||o==="success")a=`${r} ${n} ${i}`;else a=`${r} ${n} ${ht.cyan(i)}`;if(!s)return a.trim();let f=c(a).trim().length,C=c(t).length,k=Math.max(1,u-2-f-C);return`${a.trim()}${" ".repeat(k)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(o,s)=>{let c=Number.parseInt(s,10);return c<t[0].length?String(t[0][c]):o});let r=/%([sdijfo%])/g,n=0,i=e.replace(r,(o,s)=>{if(s==="%")return"%";if(n>=t.length)return o;let c=t[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return o}});if(n<t.length)i+=` ${t.slice(n).map((o)=>typeof o==="object"?JSON.stringify(o,null,2):String(o)).join(" ")}`;return i}formatMarkdown(e){if(!e)return e;let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>{let o=ht.underline(ht.blue(n)),s=this.toAbsoluteFilePath(i);if(s&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let c=`file://${encodeURI(s)}`,u="\x1B]8;;",a="\x1B\\";return`\x1B]8;;${c}\x1B\\${o}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${i}\x1B\\${o}\x1B]8;;\x1B\\`;return o}),t=t.replace(/`([^`]+)`/g,(r,n)=>ht.bgGray(n)),t=t.replace(/\*\*([^*]+)\*\*/g,(r,n)=>ht.bold(n)),t=t.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,n)=>ht.italic(n)),t=t.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,n)=>ht.italic(n)),t=t.replace(/~([^~]+)~/g,(r,n)=>ht.strikethrough(n)),t}supportsHyperlinks(){if(pr())return!1;let e=It.env;if(!e)return!1;if(e.TERM_PROGRAM==="iTerm.app"||e.TERM_PROGRAM==="vscode"||e.TERM_PROGRAM==="WezTerm")return!0;if(e.WT_SESSION)return!0;if(e.TERM==="xterm-kitty")return!0;let t=e.VTE_VERSION?Number.parseInt(e.VTE_VERSION,10):0;if(!Number.isNaN(t)&&t>=5000)return!0;return!1}toAbsoluteFilePath(e){try{let t=e;if(t.startsWith("file://"))t=t.replace(/^file:\/\//,"");if(t.startsWith("~")){let r=It.env.HOME||"";if(r)t=t.replace(/^~(?=$|\/)/,r)}if(KS(t)||t.startsWith("./")||t.startsWith("../"))t=QS(t);else return null;return oc(t)?t:null}catch{return null}}buildOutputTexts(e){let t=this.shouldStyleConsole()?this.formatMarkdown(e):e,r=e.replace(this.ANSI_PATTERN,"");return{consoleText:t,fileText:r}}async log(e,t,...r){if(!this.shouldLog(e))return;let n=new Date,i=this.formatConsoleTimestamp(n),o=this.formatFileTimestamp(n),s,c;if(t instanceof Error)s=t.message,c=t.stack;else s=this.formatMessage(t,r);let{consoleText:u,fileText:a}=this.buildOutputTexts(s);if(this.shouldStyleConsole()){let C=this.options.showIcons===!1?"":uw[e],k=this.options.showTags!==!1&&this.name?ht.gray(this.formatTag(this.name)):"",D;switch(e){case"debug":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:ht.gray(u),level:e}),console.error(D);break;case"info":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"success":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:ht.green(u),level:e}),console.error(D);break;case"warning":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"error":if(D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.error(D),c){let W=c.split(`
|
|
50
|
-
`);for(let Y of W)if(Y.trim()&&!Y.includes(s))console.error(this.formatConsoleMessage({timestamp:i,message:ht.gray(` ${Y}`),level:e,showTimestamp:!1}))}break}}else if(!
|
|
49
|
+
`}return{name:"bunfig-plugin",setup(i){i.onResolve({filter:/^virtual:bunfig-types$/},(o)=>({path:o.path,namespace:"bunfig-virtual"})),i.onLoad({filter:/^virtual:bunfig-types$/,namespace:"bunfig-virtual"},()=>({contents:n(),loader:"ts"}))}}}var Wg,_s,va,Kg,Pv,xv,vg,yc,mu,Er,Rt,Dv,wg,Ov,Ig,_v,Nv,ou,Mv,Cg,Eg,su,$v,Lv,Bv,Fv,bc,Qg,jv,Tr,Uv,zv,Tg,Sc,fu,pr,mt,Vv,Ag,qv,kg,Gv,Jv,au,Hv,Rg,Pg,Wv,cu,Kv,Qv,Yv,Xv,Zv,vc,Yg,ew,tw="0.15.6",yn,Oc,ba,hu,yu,_c,bu,Su,Sa,vu,wu,wo,Xg,Zg,gi,Ki,em,tm,rw=rv(async()=>{Wg=import.meta.require,_s=new Eu,va=new Tu,Kg={createKey:nv,isEquivalent:iv,estimateMemoryUsage:ov},Pv=Ac(pu.cwd(),"config"),xv=Ac(pu.cwd(),"src/generated"),vg=Cc.env.CLARITY_LOG_DIR||SS(cv(),"logs"),yc={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:vg,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1},mu=await dv(),Er={red:(e)=>`\x1B[31m${e}\x1B[0m`,green:(e)=>`\x1B[32m${e}\x1B[0m`,yellow:(e)=>`\x1B[33m${e}\x1B[0m`,blue:(e)=>`\x1B[34m${e}\x1B[0m`,magenta:(e)=>`\x1B[35m${e}\x1B[0m`,cyan:(e)=>`\x1B[36m${e}\x1B[0m`,white:(e)=>`\x1B[37m${e}\x1B[0m`,gray:(e)=>`\x1B[90m${e}\x1B[0m`,bgRed:(e)=>`\x1B[41m${e}\x1B[0m`,bgYellow:(e)=>`\x1B[43m${e}\x1B[0m`,bold:(e)=>`\x1B[1m${e}\x1B[0m`,dim:(e)=>`\x1B[2m${e}\x1B[0m`,italic:(e)=>`\x1B[3m${e}\x1B[0m`,underline:(e)=>`\x1B[4m${e}\x1B[0m`,reset:"\x1B[0m"},Rt=Er,Dv=Er.red,wg=Er.green,Ov=Er.yellow,Ig=Er.blue,_v=Er.magenta,Nv=Er.cyan,ou=Er.white,Mv=Er.gray,Cg=Er.bgRed,Eg=Er.bgYellow,su=Er.bold,$v=Er.dim,Lv=Er.italic,Bv=Er.underline,Fv=Er.reset,bc={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},Qg={debug:"\uD83D\uDD0D",info:Ig("ℹ"),success:wg("✓"),warning:Eg(ou(su(" WARN "))),error:Cg(ou(su(" ERROR ")))},jv=new Pc("stacks"),Tr=new Pc("bunfig",{showTags:!0}),Uv=Ur(ya.cwd(),"config"),zv=Ur(ya.cwd(),"src/generated"),Tg=Ic.env.CLARITY_LOG_DIR||yS(gv(),"logs"),Sc={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:Tg,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},fu=await mv(),pr={red:(e)=>`\x1B[31m${e}\x1B[0m`,green:(e)=>`\x1B[32m${e}\x1B[0m`,yellow:(e)=>`\x1B[33m${e}\x1B[0m`,blue:(e)=>`\x1B[34m${e}\x1B[0m`,magenta:(e)=>`\x1B[35m${e}\x1B[0m`,cyan:(e)=>`\x1B[36m${e}\x1B[0m`,white:(e)=>`\x1B[37m${e}\x1B[0m`,gray:(e)=>`\x1B[90m${e}\x1B[0m`,bgRed:(e)=>`\x1B[41m${e}\x1B[0m`,bgYellow:(e)=>`\x1B[43m${e}\x1B[0m`,bgGray:(e)=>`\x1B[100m${e}\x1B[0m`,bold:(e)=>`\x1B[1m${e}\x1B[0m`,dim:(e)=>`\x1B[2m${e}\x1B[0m`,italic:(e)=>`\x1B[3m${e}\x1B[0m`,underline:(e)=>`\x1B[4m${e}\x1B[0m`,strikethrough:(e)=>`\x1B[9m${e}\x1B[0m`,reset:"\x1B[0m"},mt=pr,Vv=pr.red,Ag=pr.green,qv=pr.yellow,kg=pr.blue,Gv=pr.magenta,Jv=pr.cyan,au=pr.white,Hv=pr.gray,Rg=pr.bgRed,Pg=pr.bgYellow,Wv=pr.bgGray,cu=pr.bold,Kv=pr.dim,Qv=pr.italic,Yv=pr.underline,Xv=pr.strikethrough,Zv=pr.reset,vc={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},Yg={debug:"\uD83D\uDD0D",info:kg("ℹ"),success:Ag("✓"),warning:Pg(au(cu(" WARN "))),error:Rg(au(cu(" ERROR ")))},ew=new Dc("stacks"),yn=class extends Error{timestamp;context;constructor(t,r={}){super(t);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=r,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let t=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([r,n])=>`${r}: ${n}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${t}`}},Oc=class extends yn{code="CONFIG_NOT_FOUND";constructor(t,r,n){let i=n?` or alias "${n}"`:"";super(`Configuration "${t}"${i} not found`,{configName:t,alias:n,searchPaths:r,searchPathCount:r.length})}},ba=class extends yn{code="CONFIG_LOAD_ERROR";constructor(t,r,n){super(`Failed to load configuration from "${t}": ${r.message}`,{configPath:t,configName:n,originalError:r.name,originalMessage:r.message});this.cause=r}},hu=class extends yn{code="CONFIG_VALIDATION_ERROR";constructor(t,r,n){super(`Configuration validation failed for "${t}"`,{configPath:t,configName:n,validationErrors:r,errorCount:r.length})}},yu=class extends yn{code="CONFIG_MERGE_ERROR";constructor(t,r,n,i){super(`Failed to merge configuration from "${t}" with "${r}": ${n.message}`,{sourcePath:t,targetPath:r,configName:i,originalError:n.name,originalMessage:n.message});this.cause=n}},_c=class extends yn{code="ENV_VAR_ERROR";constructor(t,r,n,i){super(`Failed to parse environment variable "${t}" with value "${r}" as ${n}`,{envKey:t,envValue:r,expectedType:n,configName:i})}},bu=class extends yn{code="FILE_SYSTEM_ERROR";constructor(t,r,n){super(`File system ${t} failed for "${r}": ${n.message}`,{operation:t,path:r,originalError:n.name,originalMessage:n.message});this.cause=n}},Su=class extends yn{code="TYPE_GENERATION_ERROR";constructor(t,r,n){super(`Failed to generate types from "${t}" to "${r}": ${n.message}`,{configDir:t,outputPath:r,originalError:n.name,originalMessage:n.message});this.cause=n}},Sa=class extends yn{code="SCHEMA_VALIDATION_ERROR";constructor(t,r,n){super(`Schema validation failed${n?` for config "${n}"`:""}`,{schemaPath:t,configName:n,validationErrors:r,errorCount:r.length})}},vu=class extends yn{code="BROWSER_CONFIG_ERROR";constructor(t,r,n,i){super(`Failed to fetch configuration from "${t}": ${r} ${n}`,{endpoint:t,status:r,statusText:n,configName:i})}},wu=class extends yn{code="PLUGIN_ERROR";constructor(t,r,n){super(`Plugin "${t}" failed during ${r}: ${n.message}`,{pluginName:t,operation:r,originalError:n.name,originalMessage:n.message});this.cause=n}},wo={configNotFound(e,t,r){return new Oc(e,t,r)},configLoad(e,t,r){return new ba(e,t,r)},configValidation(e,t,r){return new hu(e,t,r)},configMerge(e,t,r,n){return new yu(e,t,r,n)},envVar(e,t,r,n){return new _c(e,t,r,n)},fileSystem(e,t,r){return new bu(e,t,r)},typeGeneration(e,t,r){return new Su(e,t,r)},schemaValidation(e,t,r){return new Sa(e,t,r)},browserConfig(e,t,r,n){return new vu(e,t,r,n)},plugin(e,t,r){return new wu(e,t,r)}},Xg={replace:"replace",concat:"concat",smart:"smart"},Zg=/^https?:\/\//,gi=new Dc("bunfig",{showTags:!0}),Ki=new xu,em=zr(qo.cwd(),"config"),tm=zr(qo.cwd(),"src/generated")});function nw(e,t={}){let r=kc.cwd();while(r.includes("storage"))r=pg(r,"..");let n=pg(r,e||"");if(t?.relative)return zS(kc.cwd(),n);return n}var iw=kc.env.CLARITY_LOG_DIR||US(nw(),"logs"),rm={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:iw,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},Nc={...rm},fR=(async()=>{try{let{loadConfig:e}=await rw().then(()=>Fg),t=await e({name:"clarity",alias:"logging",defaultConfig:rm,cwd:kc.cwd()});if(t)Object.assign(Nc,t)}catch{}return Nc})();function gr(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function ow(){if(Wi.env.NODE_ENV==="test"||Wi.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Wi<"u"){let e=Wi.type;if(e==="renderer"||e==="worker")return!1;return!!(Wi.versions&&(Wi.versions.node||Wi.versions.bun))}return!1}class nm{async format(e){let t=await ow(),r=await this.getMetadata(t);return JSON.stringify({timestamp:e.timestamp.toISOString(),level:e.level,name:e.name,message:e.message,metadata:r})}async getMetadata(e){if(e){let{hostname:t}=await import("os");return{pid:Os.pid,hostname:t(),environment:Os.env.NODE_ENV||"development",platform:Os.platform,version:Os.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:Os.env.NODE_ENV||Os.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}var hr={red:(e)=>`\x1B[31m${e}\x1B[0m`,green:(e)=>`\x1B[32m${e}\x1B[0m`,yellow:(e)=>`\x1B[33m${e}\x1B[0m`,blue:(e)=>`\x1B[34m${e}\x1B[0m`,magenta:(e)=>`\x1B[35m${e}\x1B[0m`,cyan:(e)=>`\x1B[36m${e}\x1B[0m`,white:(e)=>`\x1B[37m${e}\x1B[0m`,gray:(e)=>`\x1B[90m${e}\x1B[0m`,bgRed:(e)=>`\x1B[41m${e}\x1B[0m`,bgYellow:(e)=>`\x1B[43m${e}\x1B[0m`,bgGray:(e)=>`\x1B[100m${e}\x1B[0m`,bold:(e)=>`\x1B[1m${e}\x1B[0m`,dim:(e)=>`\x1B[2m${e}\x1B[0m`,italic:(e)=>`\x1B[3m${e}\x1B[0m`,underline:(e)=>`\x1B[4m${e}\x1B[0m`,strikethrough:(e)=>`\x1B[9m${e}\x1B[0m`,reset:"\x1B[0m"},ht=hr,{red:hR,green:sw,yellow:yR,blue:aw,magenta:bR,cyan:SR,white:xg,gray:vR,bgRed:cw,bgYellow:dw,bgGray:wR,bold:Dg,dim:IR,italic:CR,underline:ER,strikethrough:TR,reset:AR}=hr,du={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},uw={debug:"\uD83D\uDD0D",info:aw("ℹ"),success:sw("✓"),warning:dw(xg(Dg(" WARN "))),error:cw(xg(Dg(" ERROR ")))};class jc{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(e,t={}){this.name=e,this.config={...Nc},this.options=this.normalizeOptions(t),this.formatter=this.options.formatter||new nm,this.enabled=t.enabled??!0,this.fancy=t.fancy??!0,this.tagFormat=t.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=t.timestampPosition??"right",this.environment=t.environment??It.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(t);let r={...t},n=t.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp,level:this.options.level??"info"},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let i=this.generateKeyId(),o=this.generateKey();this.currentKeyId=i,this.keys.set(i,o),this.encryptionKeys.set(i,{key:o,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(e){if(!this.fingersCrossedConfig)return!1;let t={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return t[e]>=t[r]}initializeFingersCrossedConfig(e){if(!e.fingersCrossedEnabled&&e.fingersCrossed)return{...du,...e.fingersCrossed};if(!e.fingersCrossedEnabled)return null;if(!e.fingersCrossed)return{...du};return{...du,...e.fingersCrossed}}normalizeOptions(e){let t={format:"json",level:"info",logDirectory:Nc.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...t,...Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=t.level;return r}shouldWriteToFile(){return!gr()&&this.config.writeToFile===!0}async writeToFile(e){let r=(async()=>{let i,o=0,s=3,c=1000;while(o<s)try{try{try{await HS(this.config.logDirectory,hg.F_OK|hg.W_OK)}catch(a){if(a instanceof Error&&"code"in a)if(a.code==="ENOENT")await WS(this.config.logDirectory,{recursive:!0,mode:493});else if(a.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw a;else throw a}}catch(a){throw console.error("Debug: [writeToFile] Failed to create log directory:",a),a}let u=this.validateEncryptionConfig()?(await this.encrypt(e)).encrypted:qi.from(e);try{if(!oc(this.currentLogFile))await iu(this.currentLogFile,"",{mode:420});if(i=fg(this.currentLogFile,"a",420),JS(i,u,{flag:"a"}),mg(i),i!==void 0)nu(i),i=void 0;if((await Ps(this.currentLogFile)).size===0){if(await iu(this.currentLogFile,u,{flag:"w",mode:420}),(await Ps(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(a){let f=a;if(f.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(f.code)){if(o<s-1){let C=typeof f.message==="string"?f.message:"Unknown error";console.error(`Network error during write attempt ${o+1}/${s}:`,C);let k=c*2**o;await new Promise((D)=>setTimeout(D,k)),o++;continue}}if(f?.code&&["ENOSPC","EDQUOT"].includes(f.code))throw Error(`Disk quota exceeded or no space left on device: ${f.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",f),f}finally{if(i!==void 0)try{nu(i)}catch(a){console.error("Debug: [writeToFile] Error closing file descriptor:",a)}}}catch(u){if(o===s-1){let f=u,C=typeof f.message==="string"?f.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",C),u}o++;let a=c*2**(o-1);await new Promise((f)=>setTimeout(f,a))}})();this.pendingOperations.push(r);let n=this.pendingOperations.length-1;try{await r}catch(i){throw console.error("Debug: [writeToFile] Error in operation:",i),i}finally{this.pendingOperations.splice(n,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return Ds(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return Ds(this.config.logDirectory,`${this.name}.log`);let e=new Date().toISOString().split("T")[0];return Ds(this.config.logDirectory,`${this.name}-${e}.log`)}setupRotation(){if(gr())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let e=this.config.rotation,t;switch(e.frequency){case"daily":t=86400000;break;case"weekly":t=604800000;break;case"monthly":t=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},t)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let r=typeof t.interval==="number"?t.interval:60,n=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((i)=>{console.error("Error rotating keys:",i)})},n)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,r=this.generateKeyId(),n=this.generateKey();this.currentKeyId=r,this.keys.set(r,n),this.encryptionKeys.set(r,{key:n,createdAt:new Date});let i=Array.from(this.encryptionKeys.entries()).sort(([,c],[,u])=>u.createdAt.getTime()-c.createdAt.getTime()),o=typeof t.maxKeys==="number"?t.maxKeys:1,s=Math.max(1,o);if(i.length>s)for(let[c]of i.slice(s))this.encryptionKeys.delete(c),this.keys.delete(c)}generateKeyId(){return ru(16).toString("hex")}generateKey(){return ru(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let e=this.keys.get(this.currentKeyId);if(!e)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:e,id:this.currentKeyId}}encrypt(e){let{key:t}=this.getCurrentKey(),r=ru(16),n=VS("aes-256-gcm",t,r),i=qi.isBuffer(e)?e:qi.from(e,"utf8"),o=n.update(i),s=n.final(),c=o.length+s.length,u=n.getAuthTag(),a=qi.allocUnsafe(16+c+16);return r.copy(a,0),o.copy(a,16),s.copy(a,16+o.length),u.copy(a,16+c),{encrypted:a,iv:r}}async compressData(e){return new Promise((t,r)=>{let n=bg(),i=[];n.on("data",(o)=>i.push(o)),n.on("end",()=>t(qi.from(qi.concat(i)))),n.on("error",r),n.write(e),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let e={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let t=this.config.rotation.encrypt;return{...e,...t}}return e}async rotateLog(){if(gr())return;if(!this.shouldWriteToFile())return;let e=await Ps(this.currentLogFile).catch(()=>null);if(!e)return;let t=this.config.rotation;if(typeof t==="boolean")return;if(t.maxSize&&e.size>=t.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let i=await sc(this.config.logDirectory),o=i.filter((u)=>u.startsWith(this.name)&&/\.log\.\d+$/.test(u)).sort((u,a)=>{let f=Number.parseInt(u.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1]||"0")-f}),s=o.length>0?Number.parseInt(o[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await Ps(r).catch(()=>null))try{if(await yg(r,c),t.compress)try{let u=`${c}.gz`;await this.compressLogFile(c,u),await ac(c)}catch(u){console.error("Error compressing rotated file:",u)}if(o.length===0&&!i.some((u)=>u.endsWith(".log.1")))try{let u=`${r}.1`;await iu(u,"")}catch(u){console.error("Error creating backup file:",u)}}catch(u){console.error(`Error during rotation: ${u instanceof Error?u.message:String(u)}`)}}else{let i=new Date().toISOString().replace(/[:.]/g,"-"),o=r.replace(/\.log$/,`-${i}.log`);if(await Ps(r).catch(()=>null))await yg(r,o)}if(this.currentLogFile=n,t.maxFiles){let o=(await sc(this.config.logDirectory)).filter((s)=>s.startsWith(this.name)).sort((s,c)=>c.localeCompare(s));for(let s of o.slice(t.maxFiles))await ac(Ds(this.config.logDirectory,s))}}}async compressLogFile(e,t){let r=gg(e),n=GS(t),i=bg();await YS(r,i,n)}async handleFingersCrossedBuffer(e,t){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(e)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(n);console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(t);console.log(t)}}shouldLog(e){if(!this.enabled)return!1;let t={debug:0,info:1,success:2,warning:3,error:4};return t[e]>=t[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((e)=>{if(e instanceof Promise)return e.catch((t)=>{console.error("Error in pending write operation:",t)});return Promise.resolve()})),oc(this.currentLogFile))try{let e=fg(this.currentLogFile,"r+");mg(e),nu(e)}catch(e){console.error(`Error flushing file: ${e}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let e of this.pendingOperations)if(typeof e.cancel==="function")e.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(e){console.error("Error waiting for pending operations:",e)}if(!gr()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await sc(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of t)try{await ac(Ds(this.config.logDirectory,r))}catch(n){console.error(`Failed to delete temp file ${r}:`,n)}}catch(e){console.error("Error cleaning up temporary files:",e)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(e){if(!e)return"";return`${this.tagFormat.prefix}${e}${this.tagFormat.suffix}`}formatFileTimestamp(e){return`[${e.toISOString()}]`}formatConsoleTimestamp(e){return this.shouldStyleConsole()?ht.gray(e.toLocaleTimeString()):e.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||gr())return!1;let e=typeof It.env.NO_COLOR<"u",t=It.env.FORCE_COLOR==="0";if(e||t)return!1;return!!(typeof It.stderr<"u"&&It.stderr.isTTY||typeof It.stdout<"u"&&It.stdout.isTTY)}formatConsoleMessage(e){let{timestamp:t,icon:r="",tag:n="",message:i,level:o,showTimestamp:s=!0}=e,c=(D)=>D.replace(this.ANSI_PATTERN,"");if(!this.fancy){let D=[];if(s)D.push(t);if(o==="warning")D.push("WARN");else if(o==="error")D.push("ERROR");else if(r)D.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)D.push(n.replace(/[[\]]/g,""));return D.push(i),D.join(" ")}let u=It.stdout.columns||120,a="";if(o==="warning"||o==="error")a=`${r} ${i}`;else if(o==="info"||o==="success")a=`${r} ${n} ${i}`;else a=`${r} ${n} ${ht.cyan(i)}`;if(!s)return a.trim();let f=c(a).trim().length,C=c(t).length,k=Math.max(1,u-2-f-C);return`${a.trim()}${" ".repeat(k)}${t}`}formatMessage(e,t){if(t.length===1&&Array.isArray(t[0]))return e.replace(/\{(\d+)\}/g,(o,s)=>{let c=Number.parseInt(s,10);return c<t[0].length?String(t[0][c]):o});let r=/%([sdijfo%])/g,n=0,i=e.replace(r,(o,s)=>{if(s==="%")return"%";if(n>=t.length)return o;let c=t[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return o}});if(n<t.length)i+=` ${t.slice(n).map((o)=>typeof o==="object"?JSON.stringify(o,null,2):String(o)).join(" ")}`;return i}formatMarkdown(e){if(!e)return e;let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,n,i)=>{let o=ht.underline(ht.blue(n)),s=this.toAbsoluteFilePath(i);if(s&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let c=`file://${encodeURI(s)}`,u="\x1B]8;;",a="\x1B\\";return`\x1B]8;;${c}\x1B\\${o}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${i}\x1B\\${o}\x1B]8;;\x1B\\`;return o}),t=t.replace(/`([^`]+)`/g,(r,n)=>ht.bgGray(n)),t=t.replace(/\*\*([^*]+)\*\*/g,(r,n)=>ht.bold(n)),t=t.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,n)=>ht.italic(n)),t=t.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,n)=>ht.italic(n)),t=t.replace(/~([^~]+)~/g,(r,n)=>ht.strikethrough(n)),t}supportsHyperlinks(){if(gr())return!1;let e=It.env;if(!e)return!1;if(e.TERM_PROGRAM==="iTerm.app"||e.TERM_PROGRAM==="vscode"||e.TERM_PROGRAM==="WezTerm")return!0;if(e.WT_SESSION)return!0;if(e.TERM==="xterm-kitty")return!0;let t=e.VTE_VERSION?Number.parseInt(e.VTE_VERSION,10):0;if(!Number.isNaN(t)&&t>=5000)return!0;return!1}toAbsoluteFilePath(e){try{let t=e;if(t.startsWith("file://"))t=t.replace(/^file:\/\//,"");if(t.startsWith("~")){let r=It.env.HOME||"";if(r)t=t.replace(/^~(?=$|\/)/,r)}if(KS(t)||t.startsWith("./")||t.startsWith("../"))t=QS(t);else return null;return oc(t)?t:null}catch{return null}}buildOutputTexts(e){let t=this.shouldStyleConsole()?this.formatMarkdown(e):e,r=e.replace(this.ANSI_PATTERN,"");return{consoleText:t,fileText:r}}async log(e,t,...r){if(!this.shouldLog(e))return;let n=new Date,i=this.formatConsoleTimestamp(n),o=this.formatFileTimestamp(n),s,c;if(t instanceof Error)s=t.message,c=t.stack;else s=this.formatMessage(t,r);let{consoleText:u,fileText:a}=this.buildOutputTexts(s);if(this.shouldStyleConsole()){let C=this.options.showIcons===!1?"":uw[e],k=this.options.showTags!==!1&&this.name?ht.gray(this.formatTag(this.name)):"",D;switch(e){case"debug":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:ht.gray(u),level:e}),console.error(D);break;case"info":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"success":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:ht.green(u),level:e}),console.error(D);break;case"warning":D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.warn(D);break;case"error":if(D=this.formatConsoleMessage({timestamp:i,icon:C,tag:k,message:u,level:e}),console.error(D),c){let W=c.split(`
|
|
50
|
+
`);for(let Y of W)if(Y.trim()&&!Y.includes(s))console.error(this.formatConsoleMessage({timestamp:i,message:ht.gray(` ${Y}`),level:e,showTimestamp:!1}))}break}}else if(!gr()){if(console.error(`${o} ${this.environment}.${e.toUpperCase()}: ${s}`),c)console.error(c)}let f=`${o} ${this.environment}.${e.toUpperCase()}: ${a}
|
|
51
51
|
`;if(c)f+=`${c}
|
|
52
|
-
`;if(f=f.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(f)}progress(e,t=""){let r={update:(c,u)=>{},finish:(c)=>{},interrupt:(c,u)=>{}};if(!this.enabled)return r;let n=30;if(this.activeProgressBar={total:Math.max(1,e||1),current:0,message:t||"",barLength:n,lastRenderedLine:""},this.shouldStyleConsole()&&!
|
|
53
|
-
`);if(this[u==="warning"?"warn":u](c),this.activeProgressBar&&this.shouldStyleConsole()&&!
|
|
54
|
-
`,a=a.replace(this.ANSI_PATTERN,""),this.shouldStyleConsole()){let f=this.options.showTags!==!1&&this.name?ht.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:c,icon:this.options.showIcons===!1?"":ht.green("✓"),tag:f,message:`${o}${r?` ${JSON.stringify(r)}`:""}`}))}else if(!
|
|
55
|
-
`),u=Math.max(...c.map((k)=>k.length))+2,a=`┌${"─".repeat(u)}┐`,f=`└${"─".repeat(u)}┘`,C=c.map((k)=>this.formatConsoleMessage({timestamp:r,message:ht.cyan(k),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:r,message:ht.cyan(a),showTimestamp:!1})),C.forEach((k)=>console.error(k)),console.error(this.formatConsoleMessage({timestamp:r,message:ht.cyan(f),showTimestamp:!1}))}else if(!
|
|
56
|
-
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(s)}async prompt(e){if(
|
|
52
|
+
`;if(f=f.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(f)}progress(e,t=""){let r={update:(c,u)=>{},finish:(c)=>{},interrupt:(c,u)=>{}};if(!this.enabled)return r;let n=30;if(this.activeProgressBar={total:Math.max(1,e||1),current:0,message:t||"",barLength:n,lastRenderedLine:""},this.shouldStyleConsole()&&!gr()&&It.stdout.isTTY)this.renderProgressBar(this.activeProgressBar);return{update:(c,u)=>{if(!this.enabled||!this.activeProgressBar)return;if(this.activeProgressBar.current=Math.min(Math.max(0,c),this.activeProgressBar.total),u!==void 0)this.activeProgressBar.message=u;if(this.shouldStyleConsole()&&!gr()&&It.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)},finish:(c)=>{if(!this.activeProgressBar)return;this.finishProgressBar(this.activeProgressBar,c)},interrupt:(c,u="info")=>{if(!gr()&&It.stdout.isTTY)It.stdout.write(`
|
|
53
|
+
`);if(this[u==="warning"?"warn":u](c),this.activeProgressBar&&this.shouldStyleConsole()&&!gr()&&It.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)}}}time(e){let t=performance.now();if(this.shouldStyleConsole()){let r=this.options.showTags!==!1&&this.name?ht.gray(this.formatTag(this.name)):"",n=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:n,icon:this.options.showIcons===!1?"":ht.blue("◐"),tag:r,message:`${ht.cyan(e)}...`}))}return async(r)=>{if(!this.enabled)return;let n=performance.now(),i=Math.round(n-t),o=`${e} completed in ${i}ms`,s=new Date,c=this.formatConsoleTimestamp(s),a=`${this.formatFileTimestamp(s)} ${this.environment}.INFO: ${o}`;if(r)a+=` ${JSON.stringify(r)}`;if(a+=`
|
|
54
|
+
`,a=a.replace(this.ANSI_PATTERN,""),this.shouldStyleConsole()){let f=this.options.showTags!==!1&&this.name?ht.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:c,icon:this.options.showIcons===!1?"":ht.green("✓"),tag:f,message:`${o}${r?` ${JSON.stringify(r)}`:""}`}))}else if(!gr())console.error(a.trim());if(this.shouldWriteToFile())await this.writeToFile(a)}}async debug(e,...t){await this.log("debug",e,...t)}async info(e,...t){await this.log("info",e,...t)}async success(e,...t){await this.log("success",e,...t)}async warn(e,...t){await this.log("warning",e,...t)}async error(e,...t){await this.log("error",e,...t)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let e=this.config.rotation,{encrypt:t}=e;return!!t}async only(e){if(!this.enabled)return;return await e()}isEnabled(){return this.enabled}setEnabled(e){this.enabled=e}extend(e){let t=`${this.name}:${e}`,r=new jc(t,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(r),r}createReadStream(){if(gr())throw Error("createReadStream is not supported in browser environments");if(!oc(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return gg(this.currentLogFile,{encoding:"utf8"})}async decrypt(e){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let t=this.config.rotation;if(!t.encrypt||typeof t.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let r=this.keys.get(this.currentKeyId);try{let n=qi.isBuffer(e)?e:qi.from(e,"base64"),i=n.subarray(0,16),o=n.subarray(n.length-16),s=n.subarray(16,n.length-16),c=qS("aes-256-gcm",r,i);c.setAuthTag(o);let u=c.update(s),a=c.final(),f=u.length+a.length,C=qi.allocUnsafe(f);return u.copy(C,0),a.copy(C,u.length),C.toString("utf8")}catch(n){throw Error(`Decryption failed: ${n instanceof Error?n.message:String(n)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return gr()}isServerMode(){return!gr()}setTestEncryptionKey(e,t){this.currentKeyId=e,this.keys.set(e,t)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(e){if(!this.enabled)return;let t=new Date,r=this.formatConsoleTimestamp(t),n=this.formatFileTimestamp(t),{consoleText:i,fileText:o}=this.buildOutputTexts(e);if(this.shouldStyleConsole()){let c=i.split(`
|
|
55
|
+
`),u=Math.max(...c.map((k)=>k.length))+2,a=`┌${"─".repeat(u)}┐`,f=`└${"─".repeat(u)}┘`,C=c.map((k)=>this.formatConsoleMessage({timestamp:r,message:ht.cyan(k),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:r,message:ht.cyan(a),showTimestamp:!1})),C.forEach((k)=>console.error(k)),console.error(this.formatConsoleMessage({timestamp:r,message:ht.cyan(f),showTimestamp:!1}))}else if(!gr())console.error(`${n} ${this.environment}.INFO: [BOX] ${o}`);let s=`${n} ${this.environment}.INFO: [BOX] ${o}
|
|
56
|
+
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(s)}async prompt(e){if(gr())return Promise.resolve(!0);return new Promise((t)=>{console.error(`${ht.cyan("?")} ${e} (y/n) `);let r=(n)=>{let i=n.toString().trim().toLowerCase();It.stdin.removeListener("data",r);try{if(typeof It.stdin.setRawMode==="function")It.stdin.setRawMode(!1)}catch{}It.stdin.pause(),console.error(""),t(i==="y"||i==="yes")};try{if(typeof It.stdin.setRawMode==="function")It.stdin.setRawMode(!0)}catch{}It.stdin.resume(),It.stdin.once("data",r)})}setFancy(e){this.fancy=e}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(e,...t){if(!this.enabled)return;let r=e;if(t&&t.length>0){let u=/%([sdijfo%])/g,a=0;if(r=e.replace(u,(f,C)=>{if(C==="%")return"%";if(a>=t.length)return f;let k=t[a++];switch(C){case"s":return String(k);case"d":case"i":return Number(k).toString();case"j":case"o":return JSON.stringify(k,null,2);default:return f}}),a<t.length)r+=` ${t.slice(a).map((f)=>typeof f==="object"?JSON.stringify(f,null,2):String(f)).join(" ")}`}let{consoleText:n,fileText:i}=this.buildOutputTexts(r);if(this.shouldStyleConsole()){let u=this.options.showTags!==!1&&this.name?ht.gray(this.formatTag(this.name)):"",a=this.options.showIcons===!1?"":`${ht.blue("◐")} `;console.error(`${a}${u} ${ht.cyan(n)}`)}let c=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${i}
|
|
57
57
|
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(c)}renderProgressBar(e,t=!1){if(!this.enabled||!this.shouldStyleConsole()||!It.stdout.isTTY)return;let r=Math.min(100,Math.max(0,Math.round(e.current/e.total*100))),n=Math.round(e.barLength*r/100),i=e.barLength-n,o=ht.green("━".repeat(n)),s=ht.gray("━".repeat(i)),c=`[${o}${s}]`,u=`${r}%`.padStart(4),a=e.message?` ${e.message}`:"",f=this.options.showIcons===!1?"":t||r===100?ht.green("✓"):ht.blue("▶"),C=this.options.showTags!==!1&&this.name?` ${ht.gray(this.formatTag(this.name))}`:"",k=`\r${f}${C} ${c} ${u}${a}`,D=It.stdout.columns||80,W=" ".repeat(Math.max(0,D-k.replace(this.ANSI_PATTERN,"").length));if(e.lastRenderedLine=`${k}${W}`,It.stdout.write(e.lastRenderedLine),t)It.stdout.write(`
|
|
58
|
-
`)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||
|
|
58
|
+
`)}finishProgressBar(e,t){if(!this.enabled||!this.fancy||gr()||!It.stdout.isTTY){this.activeProgressBar=null;return}if(e.current<e.total)e.current=e.total;if(t)e.message=t;this.renderProgressBar(e,!0),this.activeProgressBar=null}async clear(e={}){if(gr()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let t=await sc(this.config.logDirectory),r=[];for(let n of t){if(!(e.name?new RegExp(e.name.replace("*",".*")).test(n):n.startsWith(this.name))||!n.endsWith(".log"))continue;let o=Ds(this.config.logDirectory,n);if(e.before)try{if((await Ps(o)).mtime>=e.before)continue}catch(s){console.error(`Failed to get stats for file ${o}:`,s);continue}r.push(o)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let n of r)try{await ac(n),console.warn(`Deleted log file: ${n}`)}catch(i){console.error(`Failed to delete log file ${n}:`,i)}console.warn("Log clearing process finished.")}catch(t){console.error("Error during log clearing process:",t)}}}var kR=new jc("stacks");class mi extends Error{timestamp;context;constructor(e,t={}){super(e);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=t,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let e=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([t,r])=>`${t}: ${r}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${e}`}}class im extends mi{code="CONFIG_NOT_FOUND";constructor(e,t,r){let n=r===void 0?[]:Array.isArray(r)?r.filter(Boolean):[r],i="";if(n.length===1)i=` or alias "${n[0]}"`;else if(n.length>1)i=` or aliases ${n.map((o)=>`"${o}"`).join(", ")}`;super(`Configuration "${e}"${i} not found`,{configName:e,alias:r,searchPaths:t,searchPathCount:t.length})}}class Mc extends mi{code="CONFIG_LOAD_ERROR";constructor(e,t,r){super(`Failed to load configuration from "${e}": ${t.message}`,{configPath:e,configName:r,originalError:t.name,originalMessage:t.message});this.cause=t}}class om extends mi{code="CONFIG_VALIDATION_ERROR";constructor(e,t,r){super(`Configuration validation failed for "${e}"`,{configPath:e,configName:r,validationErrors:t,errorCount:t.length})}}class sm extends mi{code="CONFIG_MERGE_ERROR";constructor(e,t,r,n){super(`Failed to merge configuration from "${e}" with "${t}": ${r.message}`,{sourcePath:e,targetPath:t,configName:n,originalError:r.name,originalMessage:r.message});this.cause=r}}class Du extends mi{code="ENV_VAR_ERROR";constructor(e,t,r,n){super(`Failed to parse environment variable "${e}" with value "${t}" as ${r}`,{envKey:e,envValue:t,expectedType:r,configName:n})}}class am extends mi{code="FILE_SYSTEM_ERROR";constructor(e,t,r){super(`File system ${e} failed for "${t}": ${r.message}`,{operation:e,path:t,originalError:r.name,originalMessage:r.message});this.cause=r}}class cm extends mi{code="TYPE_GENERATION_ERROR";constructor(e,t,r){super(`Failed to generate types from "${e}" to "${t}": ${r.message}`,{configDir:e,outputPath:t,originalError:r.name,originalMessage:r.message});this.cause=r}}class $c extends mi{code="SCHEMA_VALIDATION_ERROR";constructor(e,t,r){super(`Schema validation failed${r?` for config "${r}"`:""}`,{schemaPath:e,configName:r,validationErrors:t,errorCount:t.length})}}class dm extends mi{code="BROWSER_CONFIG_ERROR";constructor(e,t,r,n){super(`Failed to fetch configuration from "${e}": ${t} ${r}`,{endpoint:e,status:t,statusText:r,configName:n})}}class um extends mi{code="PLUGIN_ERROR";constructor(e,t,r){super(`Plugin "${e}" failed during ${t}: ${r.message}`,{pluginName:e,operation:t,originalError:r.name,originalMessage:r.message});this.cause=r}}var Vo={configNotFound(e,t,r){return new im(e,t,r)},configLoad(e,t,r){return new Mc(e,t,r)},configValidation(e,t,r){return new om(e,t,r)},configMerge(e,t,r,n){return new sm(e,t,r,n)},envVar(e,t,r,n){return new Du(e,t,r,n)},fileSystem(e,t,r){return new am(e,t,r)},typeGeneration(e,t,r){return new cm(e,t,r)},schemaValidation(e,t,r){return new $c(e,t,r)},browserConfig(e,t,r,n){return new dm(e,t,r,n)},plugin(e,t,r){return new um(e,t,r)}};async function lw(e,t={}){let{maxRetries:r=3,retryDelay:n=1000,isRetryable:i=()=>!0,fallback:o}=t,s=Error("Unknown error occurred");for(let c=0;c<=r;c++)try{return await e()}catch(u){if(s=u instanceof Error?u:Error(String(u)),c===r||!i(s))break;if(n>0)await new Promise((a)=>setTimeout(a,n))}if(o!==void 0)return o;throw s instanceof Error?s:Error(`Unknown error: ${String(s)}`)}class Ou{defaultParsers;constructor(){this.defaultParsers=[{name:"boolean",canParse:(e,t)=>t==="boolean"||["true","false","1","0","yes","no"].includes(e.toLowerCase()),parse:(e)=>{let t=e.toLowerCase();return["true","1","yes"].includes(t)}},{name:"number",canParse:(e,t)=>t==="number"||!Number.isNaN(Number(e))&&!Number.isNaN(Number.parseFloat(e)),parse:(e)=>{let t=Number(e);if(Number.isNaN(t))throw TypeError(`Cannot parse "${e}" as number`);return t}},{name:"array",canParse:(e,t)=>t==="array"||e.startsWith("[")||e.includes(","),parse:(e)=>{try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.split(",").map((t)=>t.trim())}},{name:"json",canParse:(e,t)=>t==="object"||(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]")),parse:(e)=>{try{return JSON.parse(e)}catch(t){throw Error(`Cannot parse "${e}" as JSON: ${t}`)}}}]}async applyEnvironmentVariables(e,t,r={}){let{prefix:n,useCamelCase:i=!0,useBackwardCompatibility:o=!0,customParsers:s={},verbose:c=!1,trackPerformance:u=!0}=r,a=async()=>{if(!e)return{config:t,source:{type:"environment",priority:50,timestamp:new Date}};let f=n||this.generateEnvPrefix(e),C={...t};return this.processObject(C,[],f,{useCamelCase:i,useBackwardCompatibility:o,customParsers:s,verbose:c,configName:e}),{config:C,source:{type:"environment",priority:50,timestamp:new Date}}};if(u)return Cu.track("applyEnvironmentVariables",a,{configName:e});return a()}generateEnvPrefix(e){return e.toUpperCase().replace(/-/g,"_")}formatEnvKey(e,t){if(!t)return e.toUpperCase();return e.replace(/([A-Z])/g,"_$1").toUpperCase()}processObject(e,t,r,n){for(let[i,o]of Object.entries(e)){let s=[...t,i],c=s.map((f)=>this.formatEnvKey(f,n.useCamelCase)),u=`${r}_${c.join("_")}`,a=n.useBackwardCompatibility?`${r}_${s.map((f)=>f.toUpperCase()).join("_")}`:null;if(n.verbose);if(typeof o==="object"&&o!==null&&!Array.isArray(o))this.processObject(o,s,r,n);else{let f=pc.env[u]||(a?pc.env[a]:void 0);if(f!==void 0){if(n.verbose){let C=pc.env[u]?u:a}try{e[i]=this.parseEnvironmentValue(f,typeof o,u,n.customParsers,n.configName)}catch(C){if(C instanceof Du)throw C;throw Vo.envVar(u,f,typeof o,n.configName)}}}}}parseEnvironmentValue(e,t,r,n,i){for(let[o,s]of Object.entries(n))try{return s(e)}catch{continue}for(let o of this.defaultParsers)if(o.canParse(e,t))try{return o.parse(e)}catch{throw Vo.envVar(r,e,`${t} (via ${o.name} parser)`,i)}return e}getEnvironmentVariables(e){let t={},r=e.toUpperCase();for(let[n,i]of Object.entries(pc.env))if(n.startsWith(r)&&i!==void 0)t[n]=i;return t}validateEnvironmentVariable(e,t,r){let n=[];if(!/^[A-Z_][A-Z0-9_]*$/.test(e))n.push(`Environment variable key "${e}" should only contain uppercase letters, numbers, and underscores`);if(r)try{this.parseEnvironmentValue(e,t,r,{})}catch(i){n.push(`Cannot parse value "${t}" as ${r}: ${i}`)}return{isValid:n.length===0,errors:n}}generateEnvVarDocs(e,t,r={}){let{prefix:n,format:i="text"}=r,o=n||this.generateEnvPrefix(e),s=[];switch(this.extractEnvVarInfo(t,[],o,s),i){case"markdown":return this.formatAsMarkdown(s,e);case"json":return JSON.stringify(s,null,2);default:return this.formatAsText(s,e)}}extractEnvVarInfo(e,t,r,n){for(let[i,o]of Object.entries(e)){let s=[...t,i],c=`${r}_${s.map((u)=>this.formatEnvKey(u,!0)).join("_")}`;if(typeof o==="object"&&o!==null&&!Array.isArray(o))this.extractEnvVarInfo(o,s,r,n);else n.push({key:c,type:Array.isArray(o)?"array":typeof o,description:`Configuration for ${s.join(".")}`,example:this.generateExample(o)})}}generateExample(e){if(Array.isArray(e))return JSON.stringify(e);if(typeof e==="object"&&e!==null)return JSON.stringify(e);return String(e)}formatAsText(e,t){let r=`Environment Variables for ${t}:
|
|
59
59
|
|
|
60
60
|
`;for(let n of e)r+=`${n.key}
|
|
61
61
|
`,r+=` Type: ${n.type}
|
|
@@ -89,7 +89,7 @@ ${t.map(([r,n])=>` '${Co(r)}': '${Co(n)}',`).join(`
|
|
|
89
89
|
`)o=!1;continue}if(s){if(u==="*"&&a==="/")s=!1,c++;continue}if(n){if(i){i=!1;continue}if(u==="\\"){i=!0;continue}if(u===n)n=void 0;continue}if(u==="/"&&a==="/"){o=!0,c++;continue}if(u==="/"&&a==="*"){s=!0,c++;continue}if(u==='"'||u==="'"||u==="`"){n=u;continue}if(u==="{")r++;if(u==="}"){if(r--,r===0)return c}}throw Error("Could not find the closing brace for sites: { ... } in cloud.config.ts")}var Rw=new Set(["singlestore","vitess"]);function qc(e){return Rw.has(e)}var Vc={mysql:"/var/lib/pantry/mysql/mysqld.sock",mariadb:"/var/lib/pantry/mariadb/mariadbd.sock"};function Yi(e){return/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(e)}function Pw(e){if(e==="postgres"||e==="pgsql")return"postgres";if(e==="mariadb")return"mariadb";if(e==="singlestore")return"singlestore";if(e==="vitess")return"vitess";return"mysql"}function Ho(e){let t=e.infrastructure?.compute,r=A(e)?.engine;if(r)return Pw(r);let n=t?.managedServices??{};if(n.postgres)return"postgres";if(n.mariadb)return"mariadb";return"mysql"}var $u=(e)=>e.replace(/`/g,"``"),Oi=(e)=>e.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),Jo=(e)=>`"${e.replace(/"/g,'""')}"`,zc=(e)=>`'${e.replace(/'/g,"''")}'`;function Lu(e,t){return[`mysql --socket=${e==="mariadb"?Vc.mariadb:Vc.mysql} -u root <<'TS_CLOUD_SQL_EOF'`,...t,"TS_CLOUD_SQL_EOF"]}function Bu(e,t){return[`${Nr(t)} -tA <<'TS_CLOUD_PG_EOF'`,...e,"TS_CLOUD_PG_EOF"]}function xw(e,t){if(e==="vitess")return Dw(t);if(e==="postgres")return Bu(["SELECT 'DB=' || datname FROM pg_database WHERE datistemplate = false;","SELECT 'USER=' || usename FROM pg_user;"],t);return Lu(e,["SELECT CONCAT('DB=', schema_name) FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');","SELECT DISTINCT CONCAT('USER=', User) FROM mysql.user WHERE User NOT IN ('root', 'mysql.sys', 'mysql.session', 'mysql.infoschema', 'debian-sys-maint');"])}function $s(e,t,r){let n=t?.host??"127.0.0.1",i=t?.username??"root",o=t?.password??"",s=t?.ssl===!1?"":" --ssl-mode=PREFERRED",c=(a)=>`'${String(a).replace(/'/g,"'\\''")}'`;return[`${o?`MYSQL_PWD=${c(o)} `:""}mysql -h ${c(n)} -P ${t?.port??r} -u ${c(i)}${s} --batch --skip-column-names <<'TS_CLOUD_SQL_EOF'`,...e,"TS_CLOUD_SQL_EOF"]}var Ls=15306;function Dw(e){let t=$s(["SHOW KEYSPACES;"],e,Ls);return t[0]=`${t[0]} | sed 's/^/DB=/'`,t}function Ow(e){return $s(["SHOW KEYSPACES;","SHOW VITESS_SHARDS;","SHOW VITESS_TABLETS;"],e,Ls)}function _w(e){let t=[],r=[],n=[];for(let i of e.split(`
|
|
90
90
|
`)){let o=i.trim();if(!o)continue;let s=o.split("\t").map((c)=>c.trim()).filter(Boolean);if(s.length>=6){let[c,u,a,f,C,k,D]=s;n.push({cell:c??"",keyspace:u??"",shard:a??"",type:f??"",state:C??"",alias:k??"",hostname:D??""});continue}if(s.length===1){let c=s[0];if(c.includes("/")){let[u,a]=c.split("/");if(u&&a)r.push({keyspace:u,shard:a})}else t.push(c)}}return{keyspaces:[...new Set(t)].filter(Boolean).sort(),shards:r,tablets:n}}function Nw(e,t,r){if(e==="postgres")return Bu([`SELECT 'CREATE DATABASE ${Jo(t)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${zc(t)})\\gexec`],r);return Lu(e,[`CREATE DATABASE IF NOT EXISTS \`${$u(t)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`])}function Mw(e,t,r){let{username:n,password:i,database:o,access:s}=t;if(e==="postgres"){let a=["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${zc(n)}) THEN CREATE ROLE ${Jo(n)} LOGIN PASSWORD ${zc(i)};`,` ELSE ALTER ROLE ${Jo(n)} LOGIN PASSWORD ${zc(i)}; END IF;`,"END $$;"];if(o)a.push(s==="readonly"?`GRANT CONNECT ON DATABASE ${Jo(o)} TO ${Jo(n)};`:`GRANT ALL PRIVILEGES ON DATABASE ${Jo(o)} TO ${Jo(n)};`);return Bu(a,r)}let c=s==="readonly"?"SELECT":"ALL PRIVILEGES",u=[`CREATE USER IF NOT EXISTS '${Oi(n)}'@'%' IDENTIFIED BY '${Oi(i)}';`,`CREATE USER IF NOT EXISTS '${Oi(n)}'@'localhost' IDENTIFIED BY '${Oi(i)}';`,`ALTER USER '${Oi(n)}'@'%' IDENTIFIED BY '${Oi(i)}';`,`ALTER USER '${Oi(n)}'@'localhost' IDENTIFIED BY '${Oi(i)}';`];if(o)u.push(`GRANT ${c} ON \`${$u(o)}\`.* TO '${Oi(n)}'@'%';`,`GRANT ${c} ON \`${$u(o)}\`.* TO '${Oi(n)}'@'localhost';`);return u.push("FLUSH PRIVILEGES;"),Lu(e,u)}function $w(e){let t=[],r=[];for(let n of e.split(`
|
|
91
91
|
`)){let i=n.trim();if(i.startsWith("DB="))t.push(i.slice(3));else if(i.startsWith("USER="))r.push(i.slice(5))}return{databases:[...new Set(t)].filter(Boolean).sort(),users:[...new Set(r)].filter(Boolean).sort()}}async function Vr(e,t,r,n){let i;try{i=_({config:e})}catch(u){return{ok:!1,error:`Could not initialize the cloud driver: ${u?.message??u}`}}let o=e.project.slug,s=await i.findComputeTargets({slug:o,environment:t,role:"app"});if(!s.length)return{ok:!1,error:"No app server target was found for this environment."};let c=await i.runRemoteDeploy({targets:[s[0]],commands:["set -uo pipefail",...r],comment:n,tags:{Project:o,Environment:t,Role:"app"}});return{ok:c.success,stdout:c.perInstance?.[0]?.output??"",stderr:c.perInstance?.[0]?.error??c.error??""}}function Gc(e,t){return{ok:!1,error:`${t} is not available for ${e}: it is an external cluster, so this box has no engine to administer. ${e==="vitess"?"Create a keyspace with `vtctldclient CreateKeyspace`, and manage vtgate credentials on the cluster.":"Use the provider console or the cluster's own admin connection."}`}}async function Rm(e,t){let r=Ho(e);if(qc(r)&&r!=="vitess")return{...Gc(r,"Listing databases"),engine:r,databases:[],users:[]};let n=await Vr(e,t,xw(r,A(e)),"ts-cloud db:list"),i=n.ok&&n.stdout?$w(n.stdout):{databases:[],users:[]};return{...n,engine:r,...i}}async function Pm(e,t,r){let n=Ho(e);if(qc(n))return Gc(n,"Creating a database");return Vr(e,t,Nw(n,r,A(e)),`ts-cloud db:create ${r}`)}async function xm(e,t,r){let n=Ho(e);if(qc(n))return Gc(n,"Creating a database user");return Vr(e,t,Mw(n,r,A(e)),`ts-cloud db:user ${r.username}`)}var Fu="/var/backups/ts-cloud/databases";function ss(e,t,r=Fu,n){let o=`${r}/${t}-$TS_CLOUD_BACKUP_STAMP.sql.gz`,s=`mkdir -p ${r}`;if(e==="postgres")return[s,'TS_CLOUD_BACKUP_STAMP="$(date +%Y%m%d-%H%M%S)"',`${Nr(n,"pg_dump")} ${t} | gzip > "${o}"`,`echo "BACKUP=${o}"`,`ls -l "${o}"`];let c=e==="mariadb"?Vc.mariadb:Vc.mysql;return[s,'TS_CLOUD_BACKUP_STAMP="$(date +%Y%m%d-%H%M%S)"',`mysqldump --socket=${c} -u root ${t} | gzip > "${o}"`,`echo "BACKUP=${o}"`,`ls -l "${o}"`]}function Lw(e=Fu){return[`ls -1t ${e}/*.sql.gz 2>/dev/null | head -50 | sed 's|^|BACKUP=|' || true`]}function Bw(e){let t=[];for(let r of e.split(`
|
|
92
|
-
`)){let n=r.trim();if(!n.startsWith("BACKUP="))continue;let i=n.slice(7),s=(i.split("/").pop()??i).replace(/-\d{8}-\d{6}\.sql\.gz$/,"");if(i)t.push({file:i,database:s})}return t}async function Dm(e,t,r){if(!Yi(r))return{ok:!1,error:"Database name must be a valid identifier.",database:r};let n=Ho(e);if(qc(n))return{...Gc(n,"Backing up"),database:r};return{...await Vr(e,t,ss(n,r,Fu,A(e)),`ts-cloud db:backup ${r}`),database:r}}async function Om(e,t){let r=await Vr(e,t,Lw(),"ts-cloud db:backups"),n=r.ok&&r.stdout?Bw(r.stdout):[];return{...r,backups:n}}async function _m(e,t){let r=Ho(e),n={keyspaces:[],shards:[],tablets:[]};if(r!=="vitess")return{ok:!1,error:"The configured database engine is not Vitess.",engine:r,...n};let i=await Vr(e,t,Ow(A(e)),"ts-cloud vitess:topology"),o=i.ok&&i.stdout?_w(i.stdout):n;return{...i,engine:r,...o}}function Nm(e){return e.filter((t)=>t.state.toUpperCase()!=="SERVING")}function Mm(e){let t=new Set(e.tablets.filter((r)=>r.type.toUpperCase()==="PRIMARY"&&r.state.toUpperCase()==="SERVING").map((r)=>`${r.keyspace}/${r.shard}`));return e.shards.filter((r)=>!t.has(`${r.keyspace}/${r.shard}`))}var Fw=async(e)=>{let t=Bun.spawn(e,{stdout:"pipe",stderr:"pipe"}),[r,n,i]=await Promise.all([t.exited,new Response(t.stdout).text(),new Response(t.stderr).text()]);return{code:r,stdout:n,stderr:i}};class Hr{async scan(e,t){return no(e,t)}async exec(e,t){if(e.trustState!=="pinned")throw Error("SSH host key must be pinned before remote execution.");return Fw(["ssh","-p",String(e.sshPort),"-o","BatchMode=yes","-o","StrictHostKeyChecking=yes","-o","ConnectTimeout=10",`${e.sshUser}@${e.endpoint}`,t])}}var jw=gr,Uw=`set -eu; printf '{'; printf '"os":"%s",' "$(. /etc/os-release 2>/dev/null; printf %s "\${PRETTY_NAME:-Linux}")"; printf '"arch":"%s",' "$(uname -m)"; printf '"cpuCores":%s,' "$(getconf _NPROCESSORS_ONLN)"; printf '"memoryBytes":%s,' "$(awk '/MemTotal/{print $2*1024}' /proc/meminfo)"; printf '"diskBytes":%s,' "$(df -B1 / | awk 'NR==2{print $2}')"; printf '"diskFreeBytes":%s,' "$(df -B1 / | awk 'NR==2{print $4}')"; printf '"dnsOk":'; getent hosts example.com >/dev/null && printf true || printf false; printf ',"timeSkewSeconds":0,"tools":{"curl":"'; command -v curl >/dev/null && printf installed; printf '","tar":"'; command -v tar >/dev/null && printf installed; printf '"},"privilege":"'; sudo -n true >/dev/null 2>&1 && printf sudo || printf user; printf '"}'`;class at{provider;transport;discoverer;constructor(e,t=new Hr,r){this.provider=e;this.transport=t;this.discoverer=r}discover(e){return this.discoverer?.(e)??Promise.resolve([])}async test(e){try{let t=await this.transport.scan(e.endpoint,e.sshPort);return{reachable:!0,hostKeyAlgorithm:t.algorithm,hostKeyFingerprint:jw(t.key),latencyMs:0}}catch{return{reachable:!1,hostKeyAlgorithm:"unknown",hostKeyFingerprint:"",latencyMs:0}}}async validate(e){let t=await this.transport.exec(e,Uw);if(t.code!==0)throw Error(`Fleet validation failed: ${t.stderr.trim()||t.code}`);try{return JSON.parse(t.stdout)}catch{throw Error("Fleet validation returned malformed facts.")}}async bootstrap(e,t){let r=await this.transport.exec(e,`sudo -n ts-cloud-agent bootstrap --version 1 --steps ${t.length}`);if(r.code!==0)throw Error(`Fleet bootstrap failed: ${r.stderr.trim()||r.code}`);return{version:"1"}}capabilities(){return{document:{supported:!0,reason:"fleet-capabilities/v1; sha256:driver-contract"},validate:{supported:!0},bootstrap:{supported:!0},heartbeat:{supported:!0},drain:{supported:!0},archive:{supported:!0},terminate:{supported:!1,reason:"Inventory removal never terminates provider infrastructure."}}}}function $m(e,t){return{"fleet.bootstrap":async(r)=>{let n=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},i=e.get(String(n.serverId??""));if(!i)throw Error("Queued fleet server was not found.");let o=t.find((u)=>u.provider===i.provider);if(!o)throw Error(`No ${i.provider} fleet driver is configured.`);let s=Array.isArray(n.steps)?n.steps.map(String):[];if(r.checkpoint("preflight","Rechecking pinned trust and healthy validation."),i.trustState!=="pinned"||!i.validation?.valid)throw Error("Fleet bootstrap requires pinned trust and a healthy validation report.");r.checkpoint("bootstrap","Applying the reviewed idempotent bootstrap plan.");let c=await o.bootstrap(i,s);return e.update(i.id,{bootstrapVersion:c.version,status:"ready"}),r.checkpoint("verify","Bootstrap completed; heartbeat can now establish freshness."),{serverId:i.id,bootstrapVersion:c.version,steps:s.length}}}}var _i=(e)=>e==null?void 0:String(e),Wo=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},ju=(e)=>({id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),resourceId:String(e.resource_id),name:String(e.name),provider:String(e.provider),providerId:_i(e.provider_id),region:_i(e.region),zone:_i(e.zone),endpoint:String(e.endpoint),sshUser:String(e.ssh_user),sshPort:Number(e.ssh_port),credentialRef:String(e.credential_ref),hostKeyAlgorithm:_i(e.host_key_algorithm),hostKeyFingerprint:_i(e.host_key_fingerprint),pendingHostKey:_i(e.pending_host_key),roles:Wo(e.roles,[]),labels:Wo(e.labels,{}),taints:Wo(e.taints,[]),capacity:Wo(e.capacity,{}),usage:Wo(e.usage,{}),capabilities:Wo(e.capabilities,{}),status:String(e.status),trustState:String(e.trust_state),validation:Wo(e.validation,void 0),bootstrapVersion:_i(e.bootstrap_version),heartbeatAt:_i(e.heartbeat_at),lastSeenAt:_i(e.last_seen_at),archivedAt:_i(e.archived_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class xe{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}get(e){let t=this.control.database.query("SELECT * FROM fleet_servers WHERE id=?").get(e);return t?ju(t):void 0}list(e,t=!1){return this.control.database.query("SELECT * FROM fleet_servers WHERE project_id=? ORDER BY name").all(e).map(ju).filter((r)=>t||r.status!=="archived")}findProvider(e,t,r){let n=this.control.database.query("SELECT * FROM fleet_servers WHERE organization_id=? AND provider=? AND provider_id=? AND archived_at IS NULL").get(e,t,r);return n?ju(n):void 0}create(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO fleet_servers (id,organization_id,project_id,resource_id,name,provider,provider_id,region,zone,endpoint,ssh_user,ssh_port,credential_ref,host_key_algorithm,host_key_fingerprint,pending_host_key,roles,labels,taints,capacity,usage,capabilities,status,trust_state,validation,bootstrap_version,heartbeat_at,last_seen_at,archived_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.resourceId,e.name,e.provider,e.providerId??null,e.region??null,e.zone??null,e.endpoint,e.sshUser,e.sshPort,e.credentialRef,e.hostKeyAlgorithm??null,e.hostKeyFingerprint??null,e.pendingHostKey??null,JSON.stringify(e.roles),JSON.stringify(e.labels),JSON.stringify(e.taints),JSON.stringify(e.capacity),JSON.stringify(e.usage),JSON.stringify(e.capabilities),e.status,e.trustState,JSON.stringify(e.validation??{}),e.bootstrapVersion??null,e.heartbeatAt??null,e.lastSeenAt??null,e.archivedAt??null,r,r]),this.get(t)}update(e,t){let r=this.get(e);if(!r)throw Error("Server was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE fleet_servers SET name=?,provider_id=?,region=?,zone=?,endpoint=?,ssh_user=?,ssh_port=?,credential_ref=?,host_key_algorithm=?,host_key_fingerprint=?,pending_host_key=?,roles=?,labels=?,taints=?,capacity=?,usage=?,capabilities=?,status=?,trust_state=?,validation=?,bootstrap_version=?,heartbeat_at=?,last_seen_at=?,archived_at=?,version=version+1,updated_at=? WHERE id=?",[n.name,n.providerId??null,n.region??null,n.zone??null,n.endpoint,n.sshUser,n.sshPort,n.credentialRef,n.hostKeyAlgorithm??null,n.hostKeyFingerprint??null,n.pendingHostKey??null,JSON.stringify(n.roles),JSON.stringify(n.labels),JSON.stringify(n.taints),JSON.stringify(n.capacity),JSON.stringify(n.usage),JSON.stringify(n.capabilities),n.status,n.trustState,JSON.stringify(n.validation??{}),n.bootstrapVersion??null,n.heartbeatAt??null,n.lastSeenAt??null,n.archivedAt??null,i,e]),this.get(e)}}var zw=/^(?:[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?|\[[0-9a-fA-F:]+\])$/;class $n{store;drivers;now;queue;constructor(e,t,r,n=()=>new Date){this.store=e;this.drivers=t;this.now=n;this.queue=r??new S(e.control)}driver(e){let t=this.drivers.find((r)=>r.provider===e);if(!t)throw Error(`No ${e} fleet driver is configured.`);return t}enroll(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Server name is invalid.");if(!zw.test(e.endpoint)||e.sshUser==="root"||!e.credentialRef.startsWith("secret://"))throw Error("Enrollment requires a valid endpoint, non-root SSH user, and secret credential reference.");let t=e.providerId?this.store.findProvider(e.organizationId,e.provider,e.providerId):void 0;if(t)return this.store.update(t.id,{endpoint:e.endpoint,region:e.region,zone:e.zone});let r=this.store.control.createResource({projectId:e.projectId,kind:"server",slug:e.name,name:e.name,provider:e.provider,providerId:e.providerId}),n=this.driver(e.provider);return this.store.create({...e,resourceId:r.id,sshPort:e.sshPort??22,labels:e.labels??{},taints:[],capacity:{},usage:{},capabilities:n.capabilities(),status:"pending",trustState:"unverified"})}async test(e){let t=this.store.get(e);if(!t)throw Error("Server was not found.");let r=await this.driver(t.provider).test(t);if(!r.reachable)return this.store.update(e,{status:"unreachable"});if(t.hostKeyFingerprint&&t.hostKeyFingerprint!==r.hostKeyFingerprint)return this.store.update(e,{status:"degraded",trustState:"rotation_pending",pendingHostKey:r.hostKeyFingerprint});return this.store.update(e,{hostKeyAlgorithm:r.hostKeyAlgorithm,hostKeyFingerprint:r.hostKeyFingerprint,pendingHostKey:void 0,trustState:"pinned",status:"validating",lastSeenAt:this.now().toISOString()})}reviewHostKey(e,t){let r=this.store.get(e);if(!r||r.pendingHostKey!==t)throw Error("Pending host key does not match.");return this.store.update(e,{hostKeyFingerprint:t,pendingHostKey:void 0,trustState:"pinned",status:"validating"})}async validate(e){let t=this.store.get(e);if(!t||t.trustState!=="pinned")throw Error("Pin the SSH host key before validation.");let r=await this.driver(t.provider).validate(t),n=[];if(!["x64","arm64","x86_64","aarch64"].includes(r.arch??""))n.push({code:"arch.unsupported",severity:"error",message:"Unsupported architecture.",remediation:"Use x86_64 or arm64 Linux."});for(let s of["curl","tar"])if(!r.tools?.[s])n.push({code:`tool.${s}`,severity:"error",message:`${s} is missing.`,remediation:`Install ${s} before bootstrap.`});if(Math.abs(r.timeSkewSeconds??0)>60)n.push({code:"time.skew",severity:"error",message:"Clock skew exceeds 60 seconds.",remediation:"Enable NTP synchronization."});if(!r.dnsOk)n.push({code:"dns.failed",severity:"error",message:"DNS validation failed.",remediation:"Repair resolver configuration."});let i={valid:!n.some((s)=>s.severity==="error"),facts:r,findings:n,validatedAt:this.now().toISOString(),validatorVersion:"1"},o={cpu:r.cpuCores??0,memoryBytes:r.memoryBytes??0,diskBytes:r.diskBytes??0};return this.store.update(e,{validation:i,capacity:o,status:i.valid?"ready":"degraded"})}bootstrap(e,t=!1){let r=this.store.get(e);if(!r?.validation?.valid)throw Error("A healthy validation report is required.");let n=["install runtime dependencies","install ts-cloud agent","configure heartbeat","verify least-privilege access"];if(!t)return{preview:!0,steps:n};let i=this.queue.enqueue({projectId:r.projectId,resourceId:r.resourceId,kind:"fleet.bootstrap",input:{serverId:e,steps:n},lockKey:`server:${e}`,providerKey:r.provider}).operation;return{preview:!1,steps:n,operation:i}}heartbeat(e,t){let r=this.store.get(e);if(!r)throw Error("Server was not found.");let n=this.now().toISOString();return this.store.update(e,{usage:t.usage,capabilities:t.capabilities??r.capabilities,heartbeatAt:n,lastSeenAt:n,status:r.status==="draining"||r.status==="drained"?r.status:"ready"})}drain(e,t=!1){return this.store.update(e,{status:t?"drained":"draining"})}uncordon(e){return this.store.update(e,{status:"ready"})}archive(e,t){let r=this.store.get(e);if(!r||t!==r.name)throw Error("Exact server name confirmation is required.");return this.store.update(e,{status:"archived",archivedAt:this.now().toISOString()})}}var yi=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},un=(e)=>e==null?void 0:String(e),Fm=()=>({cpu:0,memoryBytes:0,diskBytes:0,gpu:0}),Bs=(e={})=>({...Fm(),...e});function Lm(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),name:String(e.name),purpose:String(e.purpose),backend:String(e.backend),region:un(e.region),architecture:un(e.architecture),labels:yi(e.labels,{}),requiredServerLabels:yi(e.required_server_labels,{}),toleratedTaints:yi(e.tolerated_taints,[]),capacity:Bs(yi(e.capacity,{})),reserved:yi(e.reserved,{}),maxWorkloads:Number(e.max_workloads),costWeight:Number(e.cost_weight),spreadKey:un(e.spread_key),concurrency:Number(e.concurrency),ephemeralWorkspaces:Number(e.ephemeral_workspaces)===1,allowProductionSecrets:Number(e.allow_production_secrets)===1,status:String(e.status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Bm(e){return{id:String(e.id),projectId:String(e.project_id),environmentId:un(e.environment_id),resourceId:String(e.resource_id),releaseId:un(e.release_id),poolId:String(e.pool_id),serverId:un(e.server_id),purpose:String(e.purpose),requirements:yi(e.requirements,{}),decision:yi(e.decision,{}),stateful:Number(e.stateful)===1,autoReschedule:Number(e.auto_reschedule)===1,status:String(e.status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Vw(e){return{id:String(e.id),projectId:String(e.project_id),resourceId:un(e.resource_id),poolId:String(e.pool_id),placementId:un(e.placement_id),operationId:un(e.operation_id),sourceSha:String(e.source_sha),buildSpec:yi(e.build_spec,{}),credentialPolicy:yi(e.credential_policy,{productionSecrets:!1,shortLivedTokenExpiresAt:""}),workspace:un(e.workspace),cacheKey:un(e.cache_key),artifactUri:un(e.artifact_uri),artifactDigest:un(e.artifact_digest),status:String(e.status),cleanupAt:un(e.cleanup_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class Ln{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}createPool(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO capacity_pools (id,organization_id,project_id,name,purpose,backend,region,architecture,labels,required_server_labels,tolerated_taints,capacity,reserved,max_workloads,cost_weight,spread_key,concurrency,ephemeral_workspaces,allow_production_secrets,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.name,e.purpose,e.backend,e.region??null,e.architecture??null,JSON.stringify(e.labels),JSON.stringify(e.requiredServerLabels),JSON.stringify(e.toleratedTaints),JSON.stringify(Bs(e.capacity)),"{}",e.maxWorkloads,e.costWeight,e.spreadKey??null,e.concurrency,e.ephemeralWorkspaces?1:0,e.allowProductionSecrets?1:0,e.status,r,r]),this.getPool(t)}getPool(e){let t=this.control.database.query("SELECT * FROM capacity_pools WHERE id=?").get(e);return t?Lm(t):void 0}listPools(e){return this.control.database.query("SELECT * FROM capacity_pools WHERE project_id=? ORDER BY name").all(e).map(Lm)}updatePool(e,t){let r=this.getPool(e);if(!r)throw Error("Capacity pool was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE capacity_pools SET status=?,reserved=?,capacity=?,concurrency=?,version=version+1,updated_at=? WHERE id=?",[n.status,JSON.stringify(n.reserved),JSON.stringify(n.capacity),n.concurrency,i,e]),this.getPool(e)}addMember(e,t,r={}){let n=this.now().toISOString();this.control.database.run("INSERT INTO capacity_pool_members (pool_id,server_id,capacity_override,status,created_at,updated_at) VALUES (?,?,?,'active',?,?) ON CONFLICT(pool_id,server_id) DO UPDATE SET capacity_override=excluded.capacity_override,status='active',updated_at=excluded.updated_at",[e,t,JSON.stringify(r),n,n])}members(e){return this.control.database.query("SELECT * FROM capacity_pool_members WHERE pool_id=? ORDER BY server_id").all(e).map((t)=>({serverId:String(t.server_id),status:String(t.status),capacityOverride:yi(t.capacity_override,{})}))}memberStatus(e,t,r){this.control.database.run("UPDATE capacity_pool_members SET status=?,updated_at=? WHERE pool_id=? AND server_id=?",[r,this.now().toISOString(),e,t])}listPlacements(e,t){let r=this.control.database.query("SELECT * FROM workload_placements WHERE project_id=? ORDER BY created_at,id").all(e).map(Bm);return t?.length?r.filter((n)=>t.includes(n.status)):r}getPlacement(e){let t=this.control.database.query("SELECT * FROM workload_placements WHERE id=?").get(e);return t?Bm(t):void 0}activeUsage(e,t){let r=this.control.database.query("SELECT l.resources,l.server_id FROM capacity_leases l WHERE l.pool_id=? AND l.state='active' AND l.expires_at>?").all(e,this.now().toISOString()),n=t?r.filter((i)=>String(i.server_id)===t):r;return{resources:n.reduce((i,o)=>{let s=Bs(yi(o.resources,{}));for(let c of Object.keys(i))i[c]+=s[c];return i},Fm()),count:n.length}}expireLeases(){return this.control.database.run("UPDATE capacity_leases SET state='expired',updated_at=? WHERE state='active' AND expires_at<=?",[this.now().toISOString(),this.now().toISOString()]).changes}reserve(e){return this.control.transaction(()=>{this.expireLeases();let t=this.id(),r=this.id(),n=this.now().toISOString(),i=new Date(this.now().getTime()+(e.requirements.leaseSeconds??300)*1000).toISOString();return this.control.database.run("INSERT INTO workload_placements (id,project_id,environment_id,resource_id,release_id,pool_id,server_id,purpose,requirements,decision,stateful,auto_reschedule,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,'reserved',?,?)",[t,e.projectId,e.environmentId??null,e.resourceId,e.releaseId??null,e.decision.poolId,e.decision.serverId??null,e.requirements.purpose,JSON.stringify(e.requirements),JSON.stringify(e.decision),e.requirements.stateful?1:0,e.requirements.autoReschedule&&!e.requirements.stateful?1:0,n,n]),this.control.database.run("INSERT INTO capacity_leases (id,placement_id,pool_id,server_id,resources,state,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,'active',?,?,?)",[r,t,e.decision.poolId,e.decision.serverId??null,JSON.stringify(Bs(e.requirements.resources)),i,n,n]),this.getPlacement(t)})}transitionPlacement(e,t){if(!this.getPlacement(e))throw Error("Placement was not found.");let n=this.now().toISOString();if(this.control.database.run("UPDATE workload_placements SET status=?,version=version+1,updated_at=? WHERE id=?",[t,n,e]),["released","failed","blocked"].includes(t))this.control.database.run("UPDATE capacity_leases SET state='released',updated_at=? WHERE placement_id=? AND state='active'",[n,e]);return this.getPlacement(e)}createBuild(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO remote_builds (id,project_id,resource_id,pool_id,placement_id,operation_id,source_sha,build_spec,credential_policy,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'queued',?,?)",[t,e.projectId,e.resourceId??null,e.poolId,e.placementId??null,e.operationId??null,e.sourceSha,JSON.stringify(e.buildSpec),JSON.stringify({productionSecrets:!1,shortLivedTokenExpiresAt:e.tokenExpiresAt}),r,r]),this.getBuild(t)}getBuild(e){let t=this.control.database.query("SELECT * FROM remote_builds WHERE id=?").get(e);return t?Vw(t):void 0}updateBuild(e,t){let r=this.getBuild(e);if(!r)throw Error("Remote build was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE remote_builds SET operation_id=?,workspace=?,cache_key=?,artifact_uri=?,artifact_digest=?,status=?,cleanup_at=?,updated_at=? WHERE id=?",[n.operationId??null,n.workspace??null,n.cacheKey??null,n.artifactUri??null,n.artifactDigest??null,n.status,n.cleanupAt??null,i,e]),this.getBuild(e)}}var Jc=["cpu","memoryBytes","diskBytes","gpu"],jm=(e,t={})=>Object.entries(t).every(([r,n])=>e[r]===n),qw=(e,t,r)=>Object.fromEntries(Jc.map((n)=>[n,Math.max(0,e[n]-t[n]-(r[n]??0))])),Gw=(e,t)=>Jc.every((r)=>e[r]>=(t[r]??0)),Jw=(e,t)=>Jc.reduce((r,n)=>r+(t[n]??0)/(e[n]||1),0);class Mn{store;fleet;constructor(e,t){this.store=e;this.fleet=t}poolCandidates(e,t,r){let n=[];for(let i of this.store.listPools(e)){if(i.id===r)continue;let o=[];if(i.status!=="active")o.push(`pool is ${i.status}`);if(i.purpose!==t.purpose)o.push(`purpose is ${i.purpose}`);if(t.region&&i.region!==t.region)o.push(`region is ${i.region??"unset"}`);if(t.architecture&&i.architecture!==t.architecture)o.push(`architecture is ${i.architecture??"unset"}`);if(!jm(i.labels,t.labels))o.push("pool labels do not match");if(i.backend==="server"){let s=this.store.members(i.id);if(!s.length)n.push(this.decision(i,void 0,t,[...o,"pool has no servers"]));for(let c of s){let u=this.fleet.get(c.serverId),a=[...o];if(!u)a.push("server is missing");else this.serverReasons(i,u,c.status,t,a);n.push(this.decision(i,u,t,a,c.capacityOverride))}}else n.push(this.decision(i,void 0,t,o))}return n.sort((i,o)=>Number(o.eligible)-Number(i.eligible)||i.score.cost-o.score.cost||i.score.spread-o.score.spread||i.score.fit-o.score.fit||i.poolName.localeCompare(o.poolName)||(i.serverId??"").localeCompare(o.serverId??""))}serverReasons(e,t,r,n,i){if(r!=="active")i.push(`member is ${r}`);if(t.status!=="ready")i.push(`server is ${t.status}`);if(!t.roles.includes(n.purpose==="build"?"build":n.purpose))i.push(`server lacks ${n.purpose} role`);if(!jm(t.labels,e.requiredServerLabels))i.push("server labels do not match pool selector");for(let o of t.taints)if(!e.toleratedTaints.includes(o))i.push(`taint ${o} is not tolerated`)}decision(e,t,r,n,i={}){let o=Bs({...t?.capacity,...i}),s=t?Object.fromEntries(Jc.map((a)=>[a,Math.min(e.capacity[a],o[a])])):e.capacity,c=this.store.activeUsage(e.id,t?.id),u=qw(s,c.resources,e.reserved);if(c.count>=e.maxWorkloads)n.push("workload limit reached");if(r.purpose==="build"&&c.count>=e.concurrency)n.push("build concurrency reached");if(!Gw(u,r.resources))n.push("insufficient capacity");return{poolId:e.id,poolName:e.name,serverId:t?.id,eligible:n.length===0,reasons:n,available:u,score:{fit:Jw(u,r.resources),spread:c.count,cost:e.costWeight}}}explain(e,t){return this.poolCandidates(e,t)}place(e){return this.store.control.transaction(()=>{let t=this.poolCandidates(e.projectId,e.requirements).find((r)=>r.eligible);if(!t)throw Error(`No eligible capacity: ${this.explain(e.projectId,e.requirements).flatMap((r)=>r.reasons).join("; ")}`);return this.store.reserve({...e,decision:t})})}activate(e){return this.store.transitionPlacement(e,"active")}release(e){return this.store.transitionPlacement(e,"released")}drainPool(e){let t=this.store.updatePool(e,{status:"draining"}),r=[],n=[];for(let i of this.store.listPlacements(t.projectId,["reserved","active"]).filter((o)=>o.poolId===e)){if(i.stateful){n.push(this.store.transitionPlacement(i.id,"blocked"));continue}this.store.transitionPlacement(i.id,"moving");let o=this.place({projectId:i.projectId,environmentId:i.environmentId,resourceId:i.resourceId,releaseId:i.releaseId,requirements:i.requirements});r.push(this.activate(o.id)),this.store.transitionPlacement(i.id,"released")}return{pool:t,moved:r,blocked:n}}drainServer(e,t){this.store.memberStatus(e,t,"draining");let r=this.store.getPool(e);if(!r)throw Error("Capacity pool was not found.");let n=[],i=[];for(let o of this.store.listPlacements(r.projectId,["reserved","active"]).filter((s)=>s.poolId===e&&s.serverId===t)){if(o.stateful){i.push(this.store.transitionPlacement(o.id,"blocked"));continue}this.store.transitionPlacement(o.id,"moving");let s=this.poolCandidates(o.projectId,o.requirements).find((u)=>u.eligible);if(!s){i.push(this.store.transitionPlacement(o.id,"blocked"));continue}let c=this.store.reserve({projectId:o.projectId,environmentId:o.environmentId,resourceId:o.resourceId,releaseId:o.releaseId,requirements:o.requirements,decision:s});n.push(this.activate(c.id)),this.store.transitionPlacement(o.id,"released")}return{moved:n,blocked:i}}reconcileFailure(e){let t=this.fleet.get(e);if(!t)throw Error("Server was not found.");let r=[],n=[];for(let i of this.store.listPlacements(t.projectId,["active"]).filter((o)=>o.serverId===e)){if(i.stateful||!i.autoReschedule){n.push(this.store.transitionPlacement(i.id,"blocked"));continue}this.store.transitionPlacement(i.id,"failed");let o=this.place({projectId:i.projectId,environmentId:i.environmentId,resourceId:i.resourceId,releaseId:i.releaseId,requirements:i.requirements});r.push(this.activate(o.id))}return{rescheduled:r,blocked:n}}}var Zi=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},Rn=(e)=>e==null?void 0:String(e),Um=(e)=>({id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:Rn(e.environment_id),name:String(e.name),hostname:String(e.hostname),homeRegion:String(e.home_region),regions:Zi(e.regions,[]),trafficPolicy:String(e.traffic_policy),dataPolicy:Zi(e.data_policy,{replicate:[],maxLagSeconds:60,retainOnDestroy:!0}),status:String(e.status),activeRegion:String(e.active_region),revision:Rn(e.revision),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Uu=(e)=>({id:String(e.id),topologyId:String(e.topology_id),region:String(e.region),role:String(e.role),provider:String(e.provider),stackId:Rn(e.stack_id),stackRevision:Rn(e.stack_revision),status:String(e.status),health:Zi(e.health,{}),lastHealthyAt:Rn(e.last_healthy_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),zu=(e)=>({id:String(e.id),topologyId:String(e.topology_id),kind:String(e.kind),sourceRegion:String(e.source_region),targetRegion:String(e.target_region),config:Zi(e.config,{}),status:String(e.status),checkpoint:Rn(e.checkpoint),lagSeconds:e.lag_seconds==null?void 0:Number(e.lag_seconds),lastVerifiedAt:Rn(e.last_verified_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Vu=(e)=>({id:String(e.id),topologyId:String(e.topology_id),hostname:String(e.hostname),dnsProvider:String(e.dns_provider),cdnEnabled:Number(e.cdn_enabled)===1,wafEnabled:Number(e.waf_enabled)===1,weights:Zi(e.weights,{}),desiredWeights:Zi(e.desired_weights,{}),status:String(e.status),providerState:Zi(e.provider_state,{}),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),zm=(e)=>({id:String(e.id),topologyId:String(e.topology_id),operationId:Rn(e.operation_id),kind:String(e.kind),requestedRegion:Rn(e.requested_region),revision:Rn(e.revision),plan:Zi(e.plan,[]),currentStep:Rn(e.current_step),completedSteps:Zi(e.completed_steps,[]),status:String(e.status),error:Rn(e.error),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class Un{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}create(e){return this.control.transaction(()=>{if(e.regions.length<2||new Set(e.regions.map((o)=>o.region)).size!==e.regions.length||e.regions.filter((o)=>o.role==="primary").length!==1)throw Error("A topology requires unique regions and exactly one primary.");let t=e.regions.find((o)=>o.role==="primary"),r=this.id(),n=this.now().toISOString();this.control.database.run("INSERT INTO regional_topologies (id,organization_id,project_id,environment_id,name,hostname,home_region,regions,traffic_policy,data_policy,status,active_region,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,'draft',?,?,?)",[r,e.organizationId,e.projectId,e.environmentId??null,e.name,e.hostname,t.region,JSON.stringify(e.regions),e.trafficPolicy,JSON.stringify(e.dataPolicy),t.region,n,n]);for(let o of e.regions)this.control.database.run("INSERT INTO regional_targets (id,topology_id,region,role,provider,status,created_at,updated_at) VALUES (?,?,?,?,?,'pending',?,?)",[this.id(),r,o.region,o.role,o.provider,n,n]);for(let o of e.dataPolicy.replicate)for(let s of e.regions)for(let c of e.regions.filter((u)=>u.region!==s.region))this.control.database.run("INSERT INTO regional_replication_channels (id,topology_id,kind,source_region,target_region,config,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,o,s.region,c.region,"{}",n,n]);let i=Object.fromEntries(e.regions.map((o)=>[o.region,o.region===t.region?100:0]));return this.control.database.run("INSERT INTO regional_traffic_routes (id,topology_id,hostname,dns_provider,cdn_enabled,waf_enabled,weights,desired_weights,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'pending',?,?)",[this.id(),r,e.hostname,e.dnsProvider??"route53",e.cdnEnabled?1:0,e.wafEnabled?1:0,JSON.stringify(i),JSON.stringify(i),n,n]),this.get(r)})}get(e){let t=this.control.database.query("SELECT * FROM regional_topologies WHERE id=?").get(e);return t?Um(t):void 0}list(e){return this.control.database.query("SELECT * FROM regional_topologies WHERE project_id=? ORDER BY name").all(e).map(Um)}targets(e){return this.control.database.query("SELECT * FROM regional_targets WHERE topology_id=? ORDER BY role,region").all(e).map(Uu)}channels(e){return this.control.database.query("SELECT * FROM regional_replication_channels WHERE topology_id=? ORDER BY kind,target_region").all(e).map(zu)}route(e){let t=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE topology_id=?").get(e);return t?Vu(t):void 0}updateTopology(e,t){let r=this.get(e);if(!r)throw Error("Regional topology was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE regional_topologies SET status=?,active_region=?,revision=?,regions=?,version=version+1,updated_at=? WHERE id=?",[n.status,n.activeRegion,n.revision??null,JSON.stringify(n.regions),i,e]),this.get(e)}updateTarget(e,t){let r=this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(e);if(!r)throw Error("Regional target was not found.");let n=Uu(r),i={...n,...t},o=this.now().toISOString();return this.control.database.run("UPDATE regional_targets SET role=?,stack_id=?,stack_revision=?,status=?,health=?,last_healthy_at=?,version=version+1,updated_at=? WHERE id=?",[i.role,i.stackId??null,i.stackRevision??null,i.status,JSON.stringify(i.health),i.lastHealthyAt??null,o,e]),Uu(this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(e))}updateChannel(e,t){let r=this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(e);if(!r)throw Error("Replication channel was not found.");let n=zu(r),i={...n,...t},o=this.now().toISOString();return this.control.database.run("UPDATE regional_replication_channels SET status=?,checkpoint=?,lag_seconds=?,last_verified_at=?,version=version+1,updated_at=? WHERE id=?",[i.status,i.checkpoint??null,i.lagSeconds??null,i.lastVerifiedAt??null,o,e]),zu(this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(e))}updateRoute(e,t){let r=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(e);if(!r)throw Error("Traffic route was not found.");let n=Vu(r),i={...n,...t},o=this.now().toISOString();return this.control.database.run("UPDATE regional_traffic_routes SET weights=?,desired_weights=?,status=?,provider_state=?,version=version+1,updated_at=? WHERE id=?",[JSON.stringify(i.weights),JSON.stringify(i.desiredWeights),i.status,JSON.stringify(i.providerState),o,e]),Vu(this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(e))}createExecution(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO regional_executions (id,topology_id,operation_id,kind,requested_region,revision,plan,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'queued',?,?)",[t,e.topologyId,e.operationId??null,e.kind,e.requestedRegion??null,e.revision??null,JSON.stringify(e.plan),r,r]),this.execution(t)}execution(e){let t=this.control.database.query("SELECT * FROM regional_executions WHERE id=?").get(e);return t?zm(t):void 0}executions(e){return this.control.database.query("SELECT * FROM regional_executions WHERE topology_id=? ORDER BY created_at DESC").all(e).map(zm)}updateExecution(e,t){let r=this.execution(e);if(!r)throw Error("Regional execution was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE regional_executions SET operation_id=?,current_step=?,completed_steps=?,status=?,error=?,updated_at=? WHERE id=?",[n.operationId??null,n.currentStep??null,JSON.stringify(n.completedSteps),n.status,n.error??null,i,e]),this.execution(e)}}class Bn{store;queue;constructor(e,t){this.store=e;this.queue=t??new S(e.control)}create(e){return this.store.create(e)}plan(e,t,r){if(!this.store.get(e))throw Error("Regional topology was not found.");let i=this.store.targets(e),o=this.store.channels(e);if(t==="rollout")return[...i.filter((s)=>s.role==="secondary").map((s)=>`apply:${s.region}`),...i.filter((s)=>s.role==="primary").map((s)=>`apply:${s.region}`),...o.map((s)=>`replicate:${s.kind}:${s.targetRegion}`),"traffic:activate"];if(t==="failover"||t==="failback")return[`health:${r}`,`replication:${r}`,`traffic:${r}`,`roles:${r}`];if(t==="destroy")return["traffic:drain",...i.filter((s)=>s.role==="secondary").map((s)=>`delete:${s.region}`),...i.filter((s)=>s.role==="primary").map((s)=>`delete:${s.region}`),"complete"];return["observe","repair"]}enqueue(e){let t=this.store.get(e.topologyId);if(!t)throw Error("Regional topology was not found.");if(["failover","failback"].includes(e.kind)&&(!e.targetRegion||!t.regions.some((o)=>o.region===e.targetRegion)))throw Error("A topology target region is required.");if(e.kind==="failover"&&e.targetRegion===t.activeRegion)throw Error("Target region is already active.");if((e.kind==="destroy"||e.deleteData)&&e.confirmation!==t.name)throw Error("Exact topology name confirmation is required.");if(e.deleteData&&t.dataPolicy.retainOnDestroy)throw Error("Topology policy requires regional data retention.");if(e.kind==="rollout"&&!/^[A-Za-z0-9._:@/-]{7,200}$/.test(e.revision??""))throw Error("An immutable revision is required.");let r=this.plan(t.id,e.kind,e.targetRegion),n=this.store.createExecution({topologyId:t.id,kind:e.kind,requestedRegion:e.targetRegion,revision:e.revision,plan:r}),i=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,kind:`region.${e.kind}`,input:{executionId:n.id,manifest:e.manifest??{},deleteData:e.deleteData===!0},lockKey:`regional-topology:${t.id}`,providerKey:"multi-region",timeoutSeconds:7200,cancellationMode:"provider_non_cancellable",resumePolicy:"requeue",maxAttempts:3}).operation;return this.store.updateExecution(n.id,{operationId:i.id}),{execution:this.store.execution(n.id),operation:i}}}var Hw=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{};function Vm(e,t){let r=(a)=>{let f=t.find((C)=>C.provider===a.provider);if(!f)throw Error(`No ${a.provider} regional driver is configured.`);return f},n=(a,f,C)=>{a.throwIfCancellationRequested(),a.checkpoint(C,C),e.updateExecution(f.id,{status:"running",currentStep:C,completedSteps:[...e.execution(f.id).completedSteps,C]})},i=async(a,f)=>{let C=e.route(a.id);if(!C)throw Error("Regional traffic route was not found.");let k=e.targets(a.id).find((W)=>W.region===a.activeRegion)??e.targets(a.id)[0];if(!k)throw Error("Regional traffic target was not found.");e.updateRoute(C.id,{status:"applying",desiredWeights:f});let D=await r(k).applyTraffic({route:e.route(a.id),topology:a,weights:f});e.updateRoute(C.id,{status:Object.values(f).every((W)=>W===0)?"drained":"in_sync",weights:f,providerState:D.providerState})},o=async(a,f,C,k)=>{e.updateTopology(C.id,{status:"provisioning"});let D=f.revision,W=k.manifest??{},Y=e.targets(C.id).sort((ne,he)=>Number(ne.role==="primary")-Number(he.role==="primary"));for(let ne of Y){n(a,f,`apply:${ne.region}`),e.updateTarget(ne.id,{status:"provisioning"});let he=await r(ne).applyStack({target:ne,revision:D,manifest:W,signal:a.signal}),te=await r(ne).health({target:e.updateTarget(ne.id,{stackId:he.stackId,stackRevision:D})});if(!te.healthy)throw Error(`Regional health gate failed in ${ne.region}.`);e.updateTarget(ne.id,{status:"ready",health:te.evidence,lastHealthyAt:new Date().toISOString()})}for(let ne of e.channels(C.id)){n(a,f,`replicate:${ne.kind}:${ne.targetRegion}`),e.updateChannel(ne.id,{status:"configuring"});let he=Y.find((Xe)=>Xe.region===ne.sourceRegion),te=await r(he).configureReplication({channel:ne,topology:C}),Pe=await r(he).verifyReplication({channel:e.updateChannel(ne.id,{checkpoint:te.checkpoint,lagSeconds:te.lagSeconds}),topology:C});if(!Pe.healthy||Pe.lagSeconds>C.dataPolicy.maxLagSeconds)throw Error(`${ne.kind} replication to ${ne.targetRegion} exceeds the RPO.`);e.updateChannel(ne.id,{status:"in_sync",checkpoint:Pe.checkpoint,lagSeconds:Pe.lagSeconds,lastVerifiedAt:new Date().toISOString()})}n(a,f,"traffic:activate");let ee=Object.fromEntries(C.regions.map((ne)=>[ne.region,ne.region===C.activeRegion?100:0]));return await i(C,ee),e.updateTopology(C.id,{status:"ready",revision:D}),{revision:D,activeRegion:C.activeRegion}},s=async(a,f,C)=>{let k=f.requestedRegion,D=e.targets(C.id).find((ee)=>ee.region===k);if(!D)throw Error("Requested regional target was not found.");e.updateTopology(C.id,{status:f.kind==="failover"?"failing_over":"failing_back"}),n(a,f,`health:${k}`);let W=await r(D).health({target:D});if(!W.healthy)throw Error(`Target region ${k} is unhealthy.`);e.updateTarget(D.id,{status:"ready",health:W.evidence,lastHealthyAt:new Date().toISOString()}),n(a,f,`replication:${k}`);for(let ee of e.channels(C.id).filter((ne)=>ne.targetRegion===k)){let ne=await r(D).verifyReplication({channel:ee,topology:C});if(!ne.healthy||ne.lagSeconds>C.dataPolicy.maxLagSeconds)throw Error(`${ee.kind} replication is outside the failover RPO.`);e.updateChannel(ee.id,{status:"in_sync",checkpoint:ne.checkpoint,lagSeconds:ne.lagSeconds,lastVerifiedAt:new Date().toISOString()})}n(a,f,`traffic:${k}`),await i(C,Object.fromEntries(C.regions.map((ee)=>[ee.region,ee.region===k?100:0]))),n(a,f,`roles:${k}`);let Y=C.regions.map((ee)=>({...ee,role:ee.region===k?"primary":"secondary"}));for(let ee of e.targets(C.id))e.updateTarget(ee.id,{role:ee.region===k?"primary":"secondary"});return e.updateTopology(C.id,{status:f.kind==="failover"?"failed_over":"ready",activeRegion:k,regions:Y}),{activeRegion:k}},c=async(a,f,C,k)=>{e.updateTopology(C.id,{status:"destroying"}),n(a,f,"traffic:drain"),await i(C,Object.fromEntries(C.regions.map((W)=>[W.region,0])));let D=k.deleteData!==!0;for(let W of e.targets(C.id).sort((Y,ee)=>Number(Y.role==="primary")-Number(ee.role==="primary")))n(a,f,`delete:${W.region}`),e.updateTarget(W.id,{status:"deleting"}),await r(W).deleteStack({target:W,retainData:D,signal:a.signal}),e.updateTarget(W.id,{status:"deleted"});return n(a,f,"complete"),e.updateTopology(C.id,{status:"destroyed"}),{destroyed:!0,dataRetained:D}},u=async(a)=>{let f=Hw(a.operation.input),C=e.execution(String(f.executionId??""));if(!C)throw Error("Regional execution was not found.");let k=e.get(C.topologyId);if(!k)throw Error("Regional topology was not found.");try{let D;if(C.kind==="rollout")D=await o(a,C,k,f);else if(C.kind==="failover"||C.kind==="failback")D=await s(a,C,k);else if(C.kind==="destroy")D=await c(a,C,k,f);else throw Error("Regional reconciliation is not configured.");return e.updateExecution(C.id,{status:"succeeded",currentStep:void 0}),{executionId:C.id,...D}}catch(D){if(e.updateExecution(C.id,{status:a.cancellationRequested()?"cancelled":"failed",error:D instanceof Error?D.message:String(D)}),e.get(k.id)?.status!=="destroyed")e.updateTopology(k.id,{status:"failed"});throw D}};return{"region.rollout":u,"region.failover":u,"region.failback":u,"region.destroy":u,"region.reconcile":u}}class qu{provider;reason;constructor(e,t="Configure a regional provider transport before executing this operation."){this.provider=e;this.reason=t}fail(){throw Error(this.reason)}async applyStack(){return this.fail()}async deleteStack(){this.fail()}async health(){return this.fail()}async configureReplication(){return this.fail()}async verifyReplication(){return this.fail()}async applyTraffic(){return this.fail()}}import{createHash as Gu,createPublicKey as Jm,verify as Ww}from"node:crypto";function wa(e){if(e===null||typeof e!=="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(wa).join(",")}]`;return`{${Object.keys(e).sort().map((t)=>`${JSON.stringify(t)}:${wa(e[t])}`).join(",")}}`}var Hm=(e)=>Gu("sha256").update(wa(e)).digest("hex"),Hc=(e)=>Gu("sha256").update(wa(e)).digest("hex"),Wm=(e)=>Gu("sha256").update(Jm(e).export({type:"spki",format:"der"})).digest("hex");function Km(e,t,r){try{return Ww(null,Buffer.from(wa(e)),Jm(r),Buffer.from(t,"base64"))}catch{return!1}}var qm=(e)=>e.replace(/^v/,"").split(/[.-]/).slice(0,3).map((t)=>Number(t)||0),Gm=(e,t)=>{let r=qm(e),n=qm(t);for(let i=0;i<3;i++){let o=(r[i]??0)-(n[i]??0);if(o)return o}return 0};function Qm(e,t){let r=[];if(t.schemaVersion<e.minimumSchema)r.push(`schema ${t.schemaVersion} is below ${e.minimumSchema}`);if(t.schemaVersion>e.maximumSchema)r.push(`schema ${t.schemaVersion} is above ${e.maximumSchema}`);if(e.minimumVersion&&Gm(t.currentVersion,e.minimumVersion)<0)r.push(`platform ${t.currentVersion} is below ${e.minimumVersion}`);if(Gm(e.version,t.currentVersion)<=0)r.push(`version ${e.version} is not newer than ${t.currentVersion}`);if(!e.artifacts.some((n)=>n.platform===t.platform&&n.architecture===t.architecture))r.push(`no artifact for ${t.platform}/${t.architecture}`);return{compatible:r.length===0,reasons:r}}var eo=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},Tr=(e)=>e==null?void 0:String(e),Kw=(e)=>({id:String(e.id),organizationId:String(e.organization_id),name:String(e.name),algorithm:"ed25519",publicKeyPem:String(e.public_key_pem),fingerprint:String(e.fingerprint),revokedAt:Tr(e.revoked_at),createdAt:String(e.created_at)}),Ym=(e)=>({id:String(e.id),organizationId:String(e.organization_id),version:String(e.version),channel:String(e.channel),publishedAt:String(e.published_at),keyId:String(e.key_id),digest:String(e.digest),document:eo(e.document,{}),signature:String(e.signature),verificationStatus:String(e.verification_status),compatibility:eo(e.compatibility,{compatible:!1,reasons:[]}),createdAt:String(e.created_at)}),Xm=(e)=>({id:String(e.id),projectId:String(e.project_id),name:String(e.name),schedule:String(e.schedule),timezone:String(e.timezone),durationMinutes:Number(e.duration_minutes),allowedOperations:eo(e.allowed_operations,[]),requireApproval:Number(e.require_approval)===1,enabled:Number(e.enabled)===1,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Zm=(e)=>({id:String(e.id),projectId:String(e.project_id),manifestId:String(e.manifest_id),windowId:Tr(e.window_id),fromVersion:String(e.from_version),strategy:String(e.strategy),batchSize:Number(e.batch_size),healthGate:eo(e.health_gate,{}),status:String(e.status),currentStage:Tr(e.current_stage),backupId:Tr(e.backup_id),approvedBy:Tr(e.approved_by),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Ju=(e)=>({id:String(e.id),campaignId:String(e.campaign_id),serverId:Tr(e.server_id),target:String(e.target),cohort:Number(e.cohort),previousVersion:String(e.previous_version),status:String(e.status),evidence:eo(e.evidence,{}),error:Tr(e.error),startedAt:Tr(e.started_at),finishedAt:Tr(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),ef=(e)=>({id:String(e.id),projectId:String(e.project_id),kind:String(e.kind),criteria:eo(e.criteria,{}),candidates:eo(e.candidates,[]),candidateDigest:String(e.candidate_digest),estimatedBytes:Number(e.estimated_bytes),status:String(e.status),confirmation:Tr(e.confirmation),expiresAt:String(e.expires_at),result:eo(e.result,{}),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),tf=(e)=>({id:String(e.id),projectId:String(e.project_id),backupPolicyId:Tr(e.backup_policy_id),recoveryPointId:Tr(e.recovery_point_id),topologyId:Tr(e.topology_id),scenario:String(e.scenario),isolatedTarget:String(e.isolated_target),expectedRpoMinutes:Number(e.expected_rpo_minutes),expectedRtoMinutes:Number(e.expected_rto_minutes),status:String(e.status),operationId:Tr(e.operation_id),evidence:eo(e.evidence,{}),measuredRpoMinutes:e.measured_rpo_minutes==null?void 0:Number(e.measured_rpo_minutes),measuredRtoMinutes:e.measured_rto_minutes==null?void 0:Number(e.measured_rto_minutes),cleanupVerified:Number(e.cleanup_verified)===1,error:Tr(e.error),startedAt:Tr(e.started_at),finishedAt:Tr(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class jn{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}addTrustedKey(e){let t=this.id(),r=this.now().toISOString(),n=Wm(e.publicKeyPem);return this.control.database.run("INSERT INTO platform_trusted_keys (id,organization_id,name,algorithm,public_key_pem,fingerprint,created_at) VALUES (?,?,?,'ed25519',?,?,?)",[t,e.organizationId,e.name,e.publicKeyPem,n,r]),this.key(t)}key(e){let t=this.control.database.query("SELECT * FROM platform_trusted_keys WHERE id=?").get(e);return t?Kw(t):void 0}revokeKey(e){return this.control.database.run("UPDATE platform_trusted_keys SET revoked_at=? WHERE id=?",[this.now().toISOString(),e]),this.key(e)}importManifest(e){let t=this.key(e.keyId);if(!t||t.organizationId!==e.organizationId)throw Error("Trusted update key was not found.");if(t.revokedAt)throw Error("Update signing key is revoked.");if(!Km(e.document,e.signature,t.publicKeyPem))throw Error("Update manifest signature is invalid.");let r=Qm(e.document,e.current),n=Hm(e.document),i=this.id(),o=this.now().toISOString();return this.control.database.run("INSERT INTO platform_update_manifests (id,organization_id,version,channel,published_at,key_id,digest,document,signature,verification_status,compatibility,created_at) VALUES (?,?,?,?,?,?,?,?,?,'verified',?,?)",[i,e.organizationId,e.document.version,e.document.channel,new Date(e.document.publishedAt).toISOString(),e.keyId,n,JSON.stringify(e.document),e.signature,JSON.stringify(r),o]),this.manifest(i)}manifest(e){let t=this.control.database.query("SELECT * FROM platform_update_manifests WHERE id=?").get(e);return t?Ym(t):void 0}manifests(e){return this.control.database.query("SELECT * FROM platform_update_manifests WHERE organization_id=? ORDER BY published_at DESC").all(e).map(Ym)}createWindow(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO maintenance_windows (id,project_id,name,schedule,timezone,duration_minutes,allowed_operations,require_approval,enabled,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,1,?,?)",[t,e.projectId,e.name,e.schedule,e.timezone,e.durationMinutes,JSON.stringify(e.allowedOperations),e.requireApproval===!1?0:1,r,r]),this.window(t)}window(e){let t=this.control.database.query("SELECT * FROM maintenance_windows WHERE id=?").get(e);return t?Xm(t):void 0}windows(e){return this.control.database.query("SELECT * FROM maintenance_windows WHERE project_id=? ORDER BY name").all(e).map(Xm)}createCampaign(e){return this.control.transaction(()=>{let t=this.manifest(e.manifestId);if(!t?.compatibility.compatible||t.verificationStatus!=="verified")throw Error("A verified compatible update manifest is required.");if(!e.backupId)throw Error("A verified pre-upgrade backup is required.");let r=this.id(),n=this.now().toISOString();return this.control.database.run("INSERT INTO platform_upgrade_campaigns (id,project_id,manifest_id,window_id,from_version,strategy,batch_size,health_gate,status,backup_id,approved_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'planned',?,?,?,?)",[r,e.projectId,e.manifestId,e.windowId??null,e.fromVersion,e.strategy,e.batchSize,JSON.stringify(e.healthGate),e.backupId,e.approvedBy??null,n,n]),e.targets.forEach((i,o)=>this.control.database.run("INSERT INTO platform_upgrade_targets (id,campaign_id,server_id,target,cohort,previous_version,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,i.serverId??null,i.target,e.strategy==="canary"?o===0?0:1+Math.floor((o-1)/e.batchSize):Math.floor(o/e.batchSize),i.previousVersion,n,n])),this.campaign(r)})}campaign(e){let t=this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE id=?").get(e);return t?Zm(t):void 0}campaigns(e){return this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE project_id=? ORDER BY created_at DESC").all(e).map(Zm)}targets(e){return this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE campaign_id=? ORDER BY cohort,target").all(e).map(Ju)}updateCampaign(e,t){let r=this.campaign(e);if(!r)throw Error("Upgrade campaign was not found.");let n={...r,...t};return this.control.database.run("UPDATE platform_upgrade_campaigns SET status=?,current_stage=?,updated_at=? WHERE id=?",[n.status,n.currentStage??null,this.now().toISOString(),e]),this.campaign(e)}updateTarget(e,t){let r=this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(e);if(!r)throw Error("Upgrade target was not found.");let n={...Ju(r),...t};return this.control.database.run("UPDATE platform_upgrade_targets SET status=?,evidence=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[n.status,JSON.stringify(n.evidence),n.error??null,n.startedAt??null,n.finishedAt??null,this.now().toISOString(),e]),Ju(this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(e))}createCleanup(e){let t=[...e.candidates].sort((s,c)=>s.id.localeCompare(c.id)),r=Hc(t),n=this.id(),i=this.now().toISOString(),o=new Date(this.now().getTime()+(e.ttlMinutes??60)*60000).toISOString();return this.control.database.run("INSERT INTO cleanup_plans (id,project_id,kind,criteria,candidates,candidate_digest,estimated_bytes,status,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'preview',?,?,?)",[n,e.projectId,e.kind,JSON.stringify(e.criteria),JSON.stringify(t),r,t.reduce((s,c)=>s+c.bytes,0),o,i,i]),this.cleanup(n)}cleanup(e){let t=this.control.database.query("SELECT * FROM cleanup_plans WHERE id=?").get(e);return t?ef(t):void 0}cleanups(e){return this.control.database.query("SELECT * FROM cleanup_plans WHERE project_id=? ORDER BY created_at DESC").all(e).map(ef)}updateCleanup(e,t){let r=this.cleanup(e);if(!r)throw Error("Cleanup plan was not found.");let n={...r,...t};return this.control.database.run("UPDATE cleanup_plans SET status=?,confirmation=?,result=?,updated_at=? WHERE id=?",[n.status,n.confirmation??null,JSON.stringify(n.result),this.now().toISOString(),e]),this.cleanup(e)}createDrill(e){if(!/^isolated:\/\//.test(e.isolatedTarget))throw Error("DR drills require an isolated target.");let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO disaster_recovery_drills (id,project_id,backup_policy_id,recovery_point_id,topology_id,scenario,isolated_target,expected_rpo_minutes,expected_rto_minutes,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'planned',?,?)",[t,e.projectId,e.backupPolicyId??null,e.recoveryPointId??null,e.topologyId??null,e.scenario,e.isolatedTarget,e.expectedRpoMinutes,e.expectedRtoMinutes,r,r]),this.drill(t)}drill(e){let t=this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE id=?").get(e);return t?tf(t):void 0}drills(e){return this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE project_id=? ORDER BY created_at DESC").all(e).map(tf)}updateDrill(e,t){let r=this.drill(e);if(!r)throw Error("DR drill was not found.");let n={...r,...t};return this.control.database.run("UPDATE disaster_recovery_drills SET status=?,operation_id=?,evidence=?,measured_rpo_minutes=?,measured_rto_minutes=?,cleanup_verified=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[n.status,n.operationId??null,JSON.stringify(n.evidence),n.measuredRpoMinutes??null,n.measuredRtoMinutes??null,n.cleanupVerified?1:0,n.error??null,n.startedAt??null,n.finishedAt??null,this.now().toISOString(),e]),this.drill(e)}}function Qw(e,t=new Date){if(!e.enabled)return!1;let r=new Date(e.schedule);if(!Number.isNaN(r.getTime()))return t>=r&&t.getTime()<=r.getTime()+e.durationMinutes*60000;let n=/^(\d{2}):(\d{2})$/.exec(e.schedule);if(!n)return!1;let i=new Intl.DateTimeFormat("en-US",{timeZone:e.timezone,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).formatToParts(t),o=Number(i.find((c)=>c.type==="hour")?.value)*60+Number(i.find((c)=>c.type==="minute")?.value),s=Number(n[1])*60+Number(n[2]);return o>=s&&o<s+e.durationMinutes}class Vn{store;now;queue;constructor(e,t,r=()=>new Date){this.store=e;this.now=r;this.queue=t??new S(e.control)}enqueueCampaign(e,t={}){let r=this.store.campaign(e);if(!r)throw Error("Upgrade campaign was not found.");let n=r.windowId?this.store.window(r.windowId):void 0;if(n&&!n.allowedOperations.includes("platform.upgrade"))throw Error("Maintenance window does not permit platform upgrades.");if(n&&!t.overrideWindow&&!Qw(n,this.now()))throw Error("Upgrade is outside its maintenance window.");if(n?.requireApproval&&!t.approvedBy&&!r.approvedBy)throw Error("Maintenance approval is required.");let i=this.queue.enqueue({projectId:r.projectId,actorId:t.approvedBy,kind:"maintenance.upgrade",input:{campaignId:e},lockKey:"platform-upgrade",providerKey:"platform",timeoutSeconds:7200,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return{campaign:this.store.updateCampaign(e,{status:"queued"}),operation:i}}async previewCleanup(e,t){let r=t.find((n)=>n.kind===e.kind);if(!r)throw Error(`No ${e.kind} cleanup driver is configured.`);return this.store.createCleanup({...e,candidates:await r.discover(e.criteria)})}enqueueCleanup(e,t){let r=this.store.cleanup(e);if(!r||r.status!=="preview")throw Error("A current cleanup preview is required.");if(new Date(r.expiresAt)<=this.now())throw Error("Cleanup preview expired; generate it again.");let n=`DELETE ${r.candidates.length} ${r.kind}`;if(t!==n)throw Error(`Exact confirmation ${n} is required.`);let i=this.queue.enqueue({projectId:r.projectId,kind:"maintenance.cleanup",input:{planId:e},lockKey:`cleanup:${r.kind}`,providerKey:"cleanup",timeoutSeconds:3600,cancellationMode:"cooperative"}).operation;return{plan:this.store.updateCleanup(e,{status:"approved",confirmation:t}),operation:i}}enqueueDrill(e){let t=this.store.drill(e);if(!t||t.status!=="planned")throw Error("A planned DR drill is required.");let r=this.queue.enqueue({projectId:t.projectId,kind:"maintenance.drill",input:{drillId:e},lockKey:`drill:${t.scenario}:${t.id}`,providerKey:"recovery",timeoutSeconds:7200,cancellationMode:"cooperative"}).operation;return{drill:this.store.updateDrill(e,{status:"queued",operationId:r.id}),operation:r}}}var Hu=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{};function rf(e){return{"maintenance.upgrade":async(i)=>{let o=e.store.campaign(String(Hu(i.operation.input).campaignId??""));if(!o||!e.platform)throw Error("Upgrade campaign or platform maintenance driver is unavailable.");let s=e.store.manifest(o.manifestId);if(!s?.compatibility.compatible||s.verificationStatus!=="verified")throw Error("Update manifest is no longer verified and compatible.");let c=s.document.artifacts.find((a)=>a.platform===process.platform&&a.architecture===process.arch)??s.document.artifacts[0];if(!c)throw Error("No update artifact matches this platform.");e.store.updateCampaign(o.id,{status:"running",currentStage:"preflight"});let u=[];try{for(let a of[...new Set(e.store.targets(o.id).map((f)=>f.cohort))].sort((f,C)=>f-C)){e.store.updateCampaign(o.id,{currentStage:`cohort:${a}`});for(let f of e.store.targets(o.id).filter((C)=>C.cohort===a)){i.throwIfCancellationRequested(),i.checkpoint(`download:${f.target}`,"Downloading signed platform artifact."),e.store.updateTarget(f.id,{status:"downloading",startedAt:new Date().toISOString()});let C=await e.platform.download({target:f,artifact:c,signal:i.signal});if(C.sha256!==c.sha256)throw Error(`Artifact checksum mismatch for ${f.target}.`);i.checkpoint(`install:${f.target}`,"Installing verified artifact."),e.store.updateTarget(f.id,{status:"installing"}),await e.platform.install({target:f,path:C.path,version:s.version,signal:i.signal}),u.push(f);let k=await e.platform.health({target:f,gate:o.healthGate});if(!k.healthy)throw Error(`Upgrade health gate failed for ${f.target}.`);e.store.updateTarget(f.id,{status:"healthy",evidence:k.evidence,finishedAt:new Date().toISOString()})}}return e.store.updateCampaign(o.id,{status:"succeeded",currentStage:void 0}),{campaignId:o.id,version:s.version,targets:u.length}}catch(a){e.store.updateCampaign(o.id,{status:"rolling_back",currentStage:"rollback"});for(let f of u.reverse())e.store.updateTarget(f.id,{status:"rolling_back"}),await e.platform.rollback({target:f,version:f.previousVersion,signal:i.signal}),e.store.updateTarget(f.id,{status:"rolled_back",finishedAt:new Date().toISOString()});throw e.store.updateCampaign(o.id,{status:"rolled_back",currentStage:void 0}),a}},"maintenance.cleanup":async(i)=>{let o=e.store.cleanup(String(Hu(i.operation.input).planId??""));if(!o||o.status!=="approved")throw Error("Approved cleanup plan was not found.");if(Hc([...o.candidates].sort((f,C)=>f.id.localeCompare(C.id)))!==o.candidateDigest)throw Error("Cleanup candidate set changed after preview.");let s=e.cleanup?.find((f)=>f.kind===o.kind);if(!s)throw Error(`No ${o.kind} cleanup driver is configured.`);e.store.updateCleanup(o.id,{status:"running"});let c=[],u=[];for(let f of o.candidates){i.throwIfCancellationRequested();try{await s.remove(f),c.push(f.id)}catch(C){u.push({id:f.id,error:C instanceof Error?C.message:String(C)})}}let a=u.length?c.length?"partial":"failed":"succeeded";if(e.store.updateCleanup(o.id,{status:a,result:{removed:c,failed:u,reclaimedBytes:o.candidates.filter((f)=>c.includes(f.id)).reduce((f,C)=>f+C.bytes,0)}}),u.length)throw Error(`Cleanup failed for ${u.length} candidate(s).`);return{planId:o.id,removed:c.length,reclaimedBytes:o.estimatedBytes}},"maintenance.drill":async(i)=>{let o=e.store.drill(String(Hu(i.operation.input).drillId??""));if(!o)throw Error("DR drill was not found.");let s=e.recovery?.find((C)=>C.scenario===o.scenario);if(!s)throw Error(`No ${o.scenario} recovery driver is configured.`);let c=new Date;e.store.updateDrill(o.id,{status:"restoring",startedAt:c.toISOString()});let u=o.isolatedTarget,a={},f={};try{i.checkpoint("restore","Restoring into isolated drill target.");let C=await s.restore({drill:o,signal:i.signal});if(!C.target.startsWith("isolated://"))throw Error("Recovery driver attempted a non-isolated target.");u=C.target,a=C.evidence;let k=(c.getTime()-new Date(C.recoveryPointAt).getTime())/60000;e.store.updateDrill(o.id,{status:"verifying",measuredRpoMinutes:k,evidence:{restore:a}}),i.checkpoint("verify","Running recovery health checks without production traffic.");let D=await s.verify({drill:o,target:u});f=D.evidence;let W=(Date.now()-c.getTime())/60000;if(!D.healthy||k>o.expectedRpoMinutes||W>o.expectedRtoMinutes)throw Error("DR drill failed its health, RPO, or RTO objective.");e.store.updateDrill(o.id,{measuredRpoMinutes:k,measuredRtoMinutes:W,evidence:{restore:a,verify:f}})}catch(C){throw e.store.updateDrill(o.id,{status:"failed",error:C instanceof Error?C.message:String(C),evidence:{restore:a,verify:f}}),C}finally{e.store.updateDrill(o.id,{status:"cleaning"});try{await s.cleanup({drill:o,target:u});let C=e.store.drill(o.id);e.store.updateDrill(o.id,{status:C.error?"failed":"passed",cleanupVerified:!0,finishedAt:new Date().toISOString()})}catch(C){e.store.updateDrill(o.id,{status:"cleanup_required",cleanupVerified:!1,error:C instanceof Error?C.message:String(C),finishedAt:new Date().toISOString()})}}return{drillId:o.id,status:e.store.drill(o.id).status}}}}var nf={releases:{select:"SELECT id,created_at,0 bytes FROM releases WHERE project_id=? AND pinned=0 AND status IN ('failed','rolled_back','superseded') AND created_at<?",remove:"DELETE FROM releases WHERE id=?"},artifacts:{select:"SELECT a.id,a.created_at,a.size bytes FROM release_artifacts a WHERE a.organization_id=? AND NOT EXISTS(SELECT 1 FROM releases r WHERE r.artifact_id=a.id) AND a.created_at<?",remove:"DELETE FROM release_artifacts WHERE id=?"},operations:{select:"SELECT id,created_at,0 bytes FROM operations WHERE project_id=? AND state IN ('succeeded','failed','cancelled','timed_out') AND updated_at<?",remove:"DELETE FROM operations WHERE id=?"},logs:{select:"SELECT l.id,l.created_at,length(l.message) bytes FROM operation_logs l JOIN operations o ON o.id=l.operation_id WHERE o.project_id=? AND o.state IN ('succeeded','failed','cancelled','timed_out') AND l.created_at<?",remove:"DELETE FROM operation_logs WHERE id=?"},previews:{select:"SELECT id,created_at,0 bytes FROM preview_instances WHERE project_id=? AND status IN ('destroyed','failed') AND updated_at<?",remove:"DELETE FROM preview_instances WHERE id=?"},snapshots:{select:"SELECT id,created_at,size_bytes bytes FROM recovery_points WHERE project_id=? AND pinned=0 AND held=0 AND status IN ('failed','deleted') AND created_at<?",remove:"DELETE FROM recovery_points WHERE id=?"},orphaned_resources:{select:"SELECT id,created_at,COALESCE(capacity_bytes,0) bytes FROM persistent_volumes WHERE project_id=? AND status='orphaned' AND orphaned_at<?",remove:"UPDATE persistent_volumes SET status='deleted',deleted_at=datetime('now'),updated_at=datetime('now') WHERE id=? AND status='orphaned'"}};class zn{kind;control;projectId;organizationId;constructor(e,t,r,n){this.kind=e;this.control=t;this.projectId=r;this.organizationId=n}async discover(e){let t=Math.max(1,Math.min(3650,Number(e.olderThanDays??30))),r=new Date(Date.now()-t*86400000).toISOString(),n=nf[this.kind],i=this.kind==="artifacts"?this.organizationId:this.projectId;return this.control.database.query(n.select).all(i,r).map((s)=>({id:String(s.id),kind:this.kind,label:`${this.kind}:${String(s.id)}`,bytes:Number(s.bytes??0),metadata:{createdAt:String(s.created_at)}}))}async remove(e){if(this.control.database.run(nf[this.kind].remove,[e.id]).changes!==1)throw Error(`${e.label} changed or is no longer removable.`)}}var Yw=new qt({ignoreAttributes:!0,parseTagValue:!1,trimValues:!0});function sf(e){if(e===void 0||e===null||e==="")return;let t=Number(e);return Number.isFinite(t)?t:void 0}function af(e){if(!e?.Address)return;return{Address:String(e.Address),Port:sf(e.Port)??0}}function of(e){return{CacheClusterId:String(e?.CacheClusterId??""),CacheClusterStatus:String(e?.CacheClusterStatus??""),Engine:String(e?.Engine??""),EngineVersion:String(e?.EngineVersion??""),CacheNodeType:String(e?.CacheNodeType??""),NumCacheNodes:sf(e?.NumCacheNodes)??0,PreferredAvailabilityZone:e?.PreferredAvailabilityZone||void 0,CacheClusterCreateTime:String(e?.CacheClusterCreateTime??""),CacheNodes:N(e?.CacheNodes?.CacheNode).map((t)=>({CacheNodeId:String(t.CacheNodeId??""),CacheNodeStatus:String(t.CacheNodeStatus??""),Endpoint:af(t.Endpoint)}))}}function Xw(e){return{ReplicationGroupId:String(e?.ReplicationGroupId??""),Status:String(e?.Status??""),Description:e?.Description||void 0,MemberClusters:N(e?.MemberClusters?.ClusterId).map(String),NodeGroups:N(e?.NodeGroups?.NodeGroup).map((t)=>({NodeGroupId:String(t.NodeGroupId??""),Status:String(t.Status??""),PrimaryEndpoint:af(t.PrimaryEndpoint)}))}}class oe{client;region;profile;constructor(e="us-east-1",t){this.region=e,this.profile=t,this.client=new p(void 0,{profile:t})}async query(e){let t=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString(),rawResponse:!0});if(typeof t!=="string"||!t.trim())return;return O(Yw.parse(t),e.Action)}async describeCacheClusters(e){let t={Action:"DescribeCacheClusters",Version:"2015-02-02",ShowCacheNodeInfo:"true"};if(e)t.CacheClusterId=e;let r=await this.query(t);return{CacheClusters:N(r?.CacheClusters?.CacheCluster).map(of)}}async describeReplicationGroups(e){let t={Action:"DescribeReplicationGroups",Version:"2015-02-02"};if(e)t.ReplicationGroupId=e;let r=await this.query(t);return{ReplicationGroups:N(r?.ReplicationGroups?.ReplicationGroup).map(Xw)}}async createCacheCluster(e){let t={Action:"CreateCacheCluster",Version:"2015-02-02",CacheClusterId:e.cacheClusterId,Engine:e.engine,CacheNodeType:e.cacheNodeType};if(e.numCacheNodes)t.NumCacheNodes=e.numCacheNodes;if(e.engineVersion)t.EngineVersion=e.engineVersion;if(e.port)t.Port=e.port;if(e.securityGroupIds&&e.securityGroupIds.length>0)e.securityGroupIds.forEach((n,i)=>{t[`SecurityGroupIds.member.${i+1}`]=n});if(e.subnetGroupName)t.CacheSubnetGroupName=e.subnetGroupName;if(e.tags&&e.tags.length>0)e.tags.forEach((n,i)=>{t[`Tags.member.${i+1}.Key`]=n.Key,t[`Tags.member.${i+1}.Value`]=n.Value});let r=await this.query(t);return{CacheCluster:of(r?.CacheCluster)}}async deleteCacheCluster(e,t){let r={Action:"DeleteCacheCluster",Version:"2015-02-02",CacheClusterId:e};if(t)r.FinalSnapshotIdentifier=t;await this.query(r)}async rebootCacheCluster(e,t){let r={Action:"RebootCacheCluster",Version:"2015-02-02",CacheClusterId:e};t.forEach((n,i)=>{r[`CacheNodeIdsToReboot.member.${i+1}`]=n}),await this.query(r)}async describeCacheEngineVersions(e){let t={Action:"DescribeCacheEngineVersions",Version:"2015-02-02"};if(e)t.Engine=e;let r=[],n;do{let i=await this.query(n?{...t,Marker:n}:t);for(let o of N(i?.CacheEngineVersions?.CacheEngineVersion))r.push({Engine:String(o.Engine??""),EngineVersion:String(o.EngineVersion??""),CacheParameterGroupFamily:String(o.CacheParameterGroupFamily??"")});n=i?.Marker||void 0}while(n);return{CacheEngineVersions:r}}async getCacheStatistics(e){let r=(await this.describeCacheClusters(e)).CacheClusters[0];if(!r)throw Error(`Cache cluster ${e} not found`);let n=r.Engine==="memcached",i=new G(this.region,this.profile),o=new Date,s=new Date(o.getTime()-600000),c=async(D,W)=>[...await i.getMetricStatistics({Namespace:"AWS/ElastiCache",MetricName:D,Dimensions:[{Name:"CacheClusterId",Value:e}],StartTime:s,EndTime:o,Period:300,Statistics:[W]})].sort((ne,he)=>new Date(he.Timestamp??0).getTime()-new Date(ne.Timestamp??0).getTime())[0]?.[W],[u,a,f,C,k]=await Promise.all([c("CPUUtilization","Average"),c("Evictions","Sum"),c(n?"GetHits":"CacheHits","Sum"),c(n?"GetMisses":"CacheMisses","Sum"),c("CurrConnections","Average")]);return{cpuUtilization:u,evictions:a,hits:f,misses:C,connections:k}}}var Br=(e,t="none",r=!1)=>({supported:!0,downtime:t,destructive:r,explanation:e}),Ar=(e)=>({supported:!1,downtime:"none",destructive:!1,explanation:e});function tr(e,t){let r=["aws_rds","aws_aurora","aws_elasticache"].includes(t),n=["server","container"].includes(t),i=["postgres","mysql","mariadb"].includes(e),o=e==="redis",s={};return s.create=t==="external"?Ar("External services can be adopted as read-only inventory."):Br(r?"Provision through the provider API.":"Provision through the owning runtime driver.","possible"),s.observe=t==="external"?Ar("External observation requires a configured provider adapter."):Br("Provider/runtime health and endpoint metadata are observable."),s.connect=Br("Connection guidance uses secret references and never returns a password by default."),s.backup=i&&(r||n)?Br(r?"Create a provider snapshot.":"Create a consistent engine-native dump.","possible"):Ar("This cache path is not a durable backup source."),s.restore=r&&i?Br("Restore creates a reviewed provider target.","required",!0):Ar("Restore requires a configured provider restore runner."),s.restart=t==="external"?Ar("External restart requires a configured provider adapter."):Br(r?"Provider restart/failover semantics apply.":"Restart the owning service unit.","required"),s.resize=t==="aws_elasticache"?Ar("ElastiCache resizing requires a replication-group migration runner."):r?Br("Provider plan/storage modification may enter a maintenance window.","possible"):n?Br("Edit host/container resources and reconcile.","required"):Ar("External resize requires a configured provider adapter."),s.version=n?Ar("Runtime version upgrades require an explicit image migration runner."):r&&t!=="aws_elasticache"?Br(i?"Major versions require compatibility preflight and backup.":"Engine upgrades require a maintenance window.","required"):Ar("External upgrades require a configured provider adapter."),s.rotate=t==="aws_elasticache"||t==="external"||n&&!i&&!o?Ar("Credential rotation is not available for this provider/engine path."):Br("Rotate through the secret backend, update the engine, then flag dependent releases."),s.expose=n?Ar("Direct container publishing is refused; use a reviewed firewall and proxy policy."):t==="aws_rds"?Br("Exposure is reconciled through security groups; public access defaults off."):Ar("Exposure changes require a provider-specific network runner."),s.delete=t==="external"?Ar("External deletion requires a configured provider adapter."):Br(r?"Final snapshot is supported where the provider allows it.":"A final engine backup is required unless explicitly retained.","required",!0),s.logs=n?Br("Read bounded service logs from the runtime."):Ar("Provider log export is not configured for this adapter."),s.slow_queries=n&&i?Br("Read bounded runtime logs after engine slow-query logging is enabled."):Ar("A slow-query log runner is not configured for this provider."),s.users=n&&i?Br("Logical users can be listed; creation requires a referenced secondary credential."):Ar("User management requires an engine connection runner."),s.databases=n&&i?Br("Logical databases can be listed, created, and confirmation-gated for deletion."):Ar("Logical database management requires an engine connection runner."),{actions:s,endpointTypes:r?["internal","external","tunnel"]:["internal","tunnel"],metrics:o?["connections","memory","evictions","hit_rate","latency"]:["connections","cpu","storage","read_latency","write_latency","iops"]}}var js=(e)=>e==null?void 0:String(e),Kc=(e)=>Number(e)===1,Wc=(e)=>{try{return JSON.parse(String(e))}catch{return{}}};function cf(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:js(e.environment_id),resourceId:js(e.resource_id),name:String(e.name),engine:String(e.engine),provider:String(e.provider),placement:String(e.placement),engineVersion:js(e.engine_version),plan:String(e.plan),storageGb:e.storage_gb==null?void 0:Number(e.storage_gb),highAvailability:Kc(e.high_availability),publicExposure:Kc(e.public_exposure),allowedCidrs:Wc(e.allowed_cidrs),desiredState:Wc(e.desired_state),observedState:Wc(e.observed_state),capabilities:Wc(e.capabilities),credentialRef:js(e.credential_ref),status:String(e.status),origin:String(e.origin),managementEnabled:Kc(e.management_enabled),ownerActorId:js(e.owner_actor_id),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class rr{controlPlane;now;constructor(e,t=()=>new Date){this.controlPlane=e;this.now=t}create(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Data service names must be 2-63 lowercase letters, numbers, or dashes.");if(e.publicExposure&&(!e.allowedCidrs.length||e.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");let t=crypto.randomUUID(),r=this.now().toISOString(),n=tr(e.engine,e.provider);return this.controlPlane.database.run("INSERT INTO data_services (id,organization_id,project_id,environment_id,resource_id,name,engine,provider,placement,engine_version,plan,storage_gb,high_availability,public_exposure,allowed_cidrs,desired_state,observed_state,capabilities,credential_ref,status,origin,management_enabled,owner_actor_id,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name,e.engine,e.provider,e.placement,e.engineVersion??null,e.plan,e.storageGb??null,e.highAvailability?1:0,e.publicExposure?1:0,JSON.stringify(e.allowedCidrs),JSON.stringify(e.desiredState),JSON.stringify(e.observedState),JSON.stringify(n),e.credentialRef??null,e.status,e.origin,e.managementEnabled?1:0,e.ownerActorId??null,1,r,r]),this.get(t)}get(e){let t=this.controlPlane.database.query("SELECT * FROM data_services WHERE id=?").get(e);return t?cf(t):void 0}list(e,t){return this.controlPlane.database.query(`SELECT * FROM data_services WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(cf)}update(e,t,r){let n=this.get(e);if(!n)throw Error("Data service was not found.");if(n.version!==t)throw Error("Data service changed; refresh before retrying.");let i={...n,...r};if(i.publicExposure&&(!i.allowedCidrs.length||i.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");if(this.controlPlane.database.run("UPDATE data_services SET plan=?,storage_gb=?,engine_version=?,high_availability=?,public_exposure=?,allowed_cidrs=?,desired_state=?,observed_state=?,status=?,management_enabled=?,credential_ref=?,version=version+1,updated_at=? WHERE id=? AND version=?",[i.plan,i.storageGb??null,i.engineVersion??null,i.highAvailability?1:0,i.publicExposure?1:0,JSON.stringify(i.allowedCidrs),JSON.stringify(i.desiredState),JSON.stringify(i.observedState),i.status,i.managementEnabled?1:0,i.credentialRef??null,this.now().toISOString(),e,t]).changes!==1)throw Error("Data service changed; refresh before retrying.");return this.get(e)}credential(e){let t=this.controlPlane.database.query("SELECT * FROM data_service_credentials WHERE service_id=? ORDER BY version DESC LIMIT 1").get(e);return t?{id:String(t.id),serviceId:String(t.service_id),username:String(t.username),secretRef:String(t.secret_ref),version:Number(t.version),createdAt:String(t.created_at),rotatedAt:js(t.rotated_at)}:void 0}saveCredential(e,t,r){let n=this.credential(e),i=n?.id??crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_credentials (id,service_id,username,secret_ref,version,created_at,rotated_at) VALUES (?,?,?,?,?,?,?) ON CONFLICT(service_id,username) DO UPDATE SET secret_ref=excluded.secret_ref,version=data_service_credentials.version+1,rotated_at=excluded.rotated_at",[i,e,t,r,n?.version??1,n?.createdAt??o,n?o:null]),this.credential(e)}addDependency(e){let t=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_dependencies (service_id,resource_id,secret_ref,requires_redeploy,created_at) VALUES (?,?,?,?,?) ON CONFLICT(service_id,resource_id) DO UPDATE SET secret_ref=excluded.secret_ref,requires_redeploy=excluded.requires_redeploy",[e.serviceId,e.resourceId,e.secretRef,e.requiresRedeploy?1:0,t]),{...e,createdAt:t}}dependencies(e){return this.controlPlane.database.query("SELECT * FROM data_service_dependencies WHERE service_id=? ORDER BY resource_id").all(e).map((t)=>({serviceId:String(t.service_id),resourceId:String(t.resource_id),secretRef:String(t.secret_ref),requiresRedeploy:Kc(t.requires_redeploy),createdAt:String(t.created_at)}))}removeDependency(e,t){return this.controlPlane.database.run("DELETE FROM data_service_dependencies WHERE service_id=? AND resource_id=?",[e,t]).changes===1}remove(e){this.controlPlane.database.run("DELETE FROM data_services WHERE id=?",[e])}}function df(){let t=crypto.getRandomValues(new Uint8Array(40));return Array.from(t,(r)=>"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*_-+="[r%69]).join("")}function Hn(e,t){return t.map((r)=>{let n=r.type==="tunnel"?"127.0.0.1":r.host,i=e.engine==="redis"?`redis-cli -h ${n} -p ${r.port}${r.tls?" --tls":""}`:e.engine==="postgres"?`psql "host=${n} port=${r.port} dbname=${r.database??"postgres"} sslmode=${r.tls?"require":"disable"}"`:e.engine==="mongodb"?`mongosh "mongodb://${n}:${r.port}/${r.database??"admin"}${r.tls?"?tls=true":""}"`:e.engine==="libsql"?`turso db shell ${r.tls?"https":"http"}://${n}:${r.port}`:`mysql --host=${n} --port=${r.port} --database=${r.database??"mysql"} --ssl-mode=${r.tls?"REQUIRED":"DISABLED"}`;return{type:r.type,command:i,secretRef:e.credentialRef}})}class qr{store;queue;secrets;constructor(e,t,r){this.store=e;this.queue=t;this.secrets=r}async create(e){let t,r;if(e.provider!=="aws_elasticache"){let n=e.username??"app",i=df();r=`secret://data-services/${e.projectId}/${e.name}/${n}`,await this.secrets.put(r,i),t={username:n,password:i,secretRef:r}}try{let n=this.store.create({...e,credentialRef:r,status:"planning"});if(t)this.store.saveCredential(n.id,t.username,t.secretRef);let i=this.enqueue(n,"create",{});return{service:n,credential:t,operationId:i}}catch(n){if(r)await this.secrets.remove(r);throw n}}plan(e,t,r={}){let n=e.capabilities.actions[t],i=t==="version"&&String(r.engineVersion??"").split(".")[0]!==String(e.engineVersion??"").split(".")[0];return{service:e,action:t,capability:n,changes:r,preflight:{backupRequired:["delete","restore"].includes(t)||i,compatibilityRequired:i,typedConfirmation:n.destructive?e.name:void 0,retentionChoiceRequired:t==="delete"},warnings:[...n.downtime!=="none"?[`Downtime is ${n.downtime}.`]:[],...e.origin==="adopted"&&!e.managementEnabled?["Adopted resource is read-only until management is explicitly enabled."]:[]]}}enqueue(e,t,r,n){let i=this.plan(e,t,r);if(!i.capability.supported)throw Error(i.capability.explanation);if(e.origin==="adopted"&&!e.managementEnabled&&t!=="observe")throw Error("Adopted resources remain read-only until management is explicitly enabled.");if(i.preflight.typedConfirmation&&r.confirm!==i.preflight.typedConfirmation)throw Error(`Type ${i.preflight.typedConfirmation} to confirm ${t}.`);if(i.preflight.retentionChoiceRequired&&!["final_backup","retain"].includes(String(r.retention??"")))throw Error("Deletion requires retention final_backup or retain.");if(i.preflight.compatibilityRequired&&(r.compatibilityReviewed!==!0||!r.backupId))throw Error("Major version changes require compatibilityReviewed=true and a backupId.");if(t==="restore"){let o=String(r.backupId??""),s=String(r.targetId??"");if(!o||!s)throw Error("Restore requires both backupId and targetId.");if(s===e.placement)throw Error("Restore targetId must differ from the source placement.");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(s))throw Error("Restore targetId must be 2-63 lowercase letters, numbers, or dashes.")}return this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:n,kind:"data_service.action",input:{serviceId:e.id,action:t,...r},lockKey:`data-service:${e.id}`,providerKey:e.provider,maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"}).operation.id}async rotate(e,t,r){let n=this.store.credential(e.id);if(!n)throw Error("Data service credential metadata was not found.");let i=df(),o=`${n.secretRef}/v${n.version+1}`;await this.secrets.put(o,i);try{return await t.action(e,"rotate",{username:n.username,secretRef:o},i,r),this.store.saveCredential(e.id,n.username,o),this.store.update(e.id,e.version,{credentialRef:o}),{credential:{username:n.username,password:i,secretRef:o},dependencies:this.store.dependencies(e.id).filter((s)=>s.requiresRedeploy).map((s)=>s.resourceId)}}catch(s){throw await this.secrets.remove(o),s}}}function uf(e){return{"data_service.action":async(t)=>{let r=t.operation.input,n=e.store.get(String(r.serviceId??"")),i=String(r.action??"");if(!n)throw Error("Data service was not found.");let o=e.resolveAdapter(n);if(!o||o.provider!==n.provider||!o.engines.includes(n.engine))throw Error(`No ${n.provider}/${n.engine} adapter is configured.`);if(i==="rotate"){let c=await new qr(e.store,new S(e.store.controlPlane),e.secrets).rotate(n,o,t);return{serviceId:n.id,action:i,username:c.credential.username,secretRef:c.credential.secretRef,dependencies:c.dependencies}}let s=n.credentialRef?await e.secrets.resolve(n.credentialRef):void 0;try{let c=i==="observe"?await o.observe(n):i==="create"?await o.apply(n,s,t):await o.action(n,i,r,s,t),u=e.store.get(n.id);return e.store.update(n.id,u.version,{observedState:c,status:i==="delete"?r.retention==="retain"?"retained":"deleting":"available"}),{serviceId:n.id,action:i,observed:c}}catch(c){let u=e.store.get(n.id);if(e.store.update(n.id,u.version,{status:"failed",observedState:{...u.observedState,error:c instanceof Error?c.message:String(c)}}),/temporar|timeout|unavailable|throttl/i.test(c instanceof Error?c.message:String(c)))throw new Ue(c instanceof Error?c.message:String(c),"provider_transient");throw c}}}}class zs{transport;constructor(e){this.transport=e}observe(e){return this.transport.observe(e.placement)}apply(e,t){return this.transport.apply({id:e.placement,name:e.name,engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,storageGb:e.storageGb??null,highAvailability:e.highAvailability,publicExposure:e.publicExposure,allowedCidrs:e.allowedCidrs,username:e.desiredState.username??"app",desiredState:e.desiredState},t)}action(e,t,r,n,i){return this.transport.execute(e.placement,t,{engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,desiredState:e.desiredState,...r},n,i)}}class qn extends zs{provider="aws_rds";engines=["postgres","mysql","mariadb"]}class Gn extends zs{provider="aws_aurora";engines=["postgres","mysql"]}class Wn extends zs{provider="aws_elasticache";engines=["redis"]}class Kn extends zs{provider="server";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}class Jn extends zs{provider="container";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}var Xc=(e,t)=>{let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)},jt=(e,t,r)=>{let n=Xc(e,t);return n==null?r:String(n)},pn=(e,t)=>{let r=Xc(e,t);return r==null?void 0:Number(r)},Eo=(e,t)=>{let r=Xc(e,t);return r==null?void 0:r===!0||r==="true"},Vs=(e,t)=>{let r=Xc(e,t);return Array.isArray(r)?r.map(String):[]},Yc=(e,t)=>jt(t,"snapshotId")??`${e}-final-${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}`;function Qc(e){if(!e)throw Error("RDS instance was not found.");return{providerId:e.DBInstanceIdentifier??null,status:e.DBInstanceStatus??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,plan:e.DBInstanceClass??null,storageGb:e.AllocatedStorage??null,highAvailability:e.MultiAZ??!1,publicExposure:e.PubliclyAccessible??!1,endpoint:e.Endpoint?.Address??null,port:e.Endpoint?.Port??null,username:e.MasterUsername??null,database:e.DBName??null,encrypted:e.StorageEncrypted??!1}}class Xn{client;constructor(e=new fe){this.client=e}async observe(e){return Qc(await this.client.describeDBInstance(e))}async apply(e,t){let r=String(e.id),n=await this.client.createDBInstance({DBInstanceIdentifier:r,DBInstanceClass:String(e.plan),Engine:String(e.engine),MasterUsername:jt(e,"username","app"),MasterUserPassword:t,DBName:jt(e,"database"),AllocatedStorage:pn(e,"storageGb"),VpcSecurityGroupIds:Vs(e,"securityGroupIds"),DBSubnetGroupName:jt(e,"subnetGroup"),BackupRetentionPeriod:pn(e,"backupRetentionDays")??7,MultiAZ:Eo(e,"highAvailability"),EngineVersion:jt(e,"engineVersion"),PubliclyAccessible:Eo(e,"publicExposure")??!1,StorageType:jt(e,"storageType","gp3"),StorageEncrypted:!0,KmsKeyId:jt(e,"kmsKeyId"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return Qc(n.DBInstance)}async execute(e,t,r,n,i){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBInstance({DBInstanceIdentifier:e}),{status:"rebooting"};if(t==="backup"){let o=Yc(e,r);return await this.client.createDBSnapshot({DBInstanceIdentifier:e,DBSnapshotIdentifier:o}),{status:"snapshotting",snapshotId:o}}if(t==="restore"){let o=String(r.targetId),s=await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:o,DBSnapshotIdentifier:String(r.backupId),DBInstanceClass:jt(r,"plan"),DBSubnetGroupName:jt(r,"subnetGroup"),MultiAZ:Eo(r,"highAvailability"),PubliclyAccessible:!1,StorageType:jt(r,"storageType"),VpcSecurityGroupIds:Vs(r,"securityGroupIds"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{...Qc(s.DBInstance),sourceId:e,restoreTargetId:o}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let o=Yc(e,r);return await this.client.modifyDBInstance({DBInstanceIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:e,SkipFinalSnapshot:!1,FinalDBSnapshotIdentifier:o,DeleteAutomatedBackups:!1}),{status:"deleting",finalSnapshotId:o}}if(["resize","version","rotate","expose"].includes(t)){let o=await this.client.modifyDBInstance({DBInstanceIdentifier:e,DBInstanceClass:jt(r,"plan"),AllocatedStorage:pn(r,"storageGb"),MasterUserPassword:t==="rotate"?n:void 0,EngineVersion:jt(r,"engineVersion"),MultiAZ:Eo(r,"highAvailability"),PubliclyAccessible:Eo(r,"publicExposure"),VpcSecurityGroupIds:Vs(r,"securityGroupIds"),ApplyImmediately:Eo(r,"applyImmediately")??!0});return Qc(o.DBInstance)}throw Error(`RDS action ${t} requires an engine connection runner.`)}}function Wu(e){if(!e)throw Error("Aurora cluster was not found.");return{providerId:e.DBClusterIdentifier??null,status:e.Status??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,endpoint:e.Endpoint??null,readerEndpoint:e.ReaderEndpoint??null,port:e.Port??null,username:e.MasterUsername??null,database:e.DatabaseName??null,encrypted:e.StorageEncrypted??!1,highAvailability:e.MultiAZ??!0}}class Qn{client;constructor(e=new fe){this.client=e}async observe(e){let t=await this.client.describeDBClusters({DBClusterIdentifier:e});return Wu(t.DBClusters?.[0])}async apply(e,t){let r=String(e.id),n=String(e.engine)==="postgres"?"aurora-postgresql":"aurora-mysql";return await this.client.createDBCluster({DBClusterIdentifier:r,Engine:n,EngineVersion:jt(e,"engineVersion"),MasterUsername:jt(e,"username","app"),MasterUserPassword:t,DatabaseName:jt(e,"database"),DBSubnetGroupName:jt(e,"subnetGroup"),VpcSecurityGroupIds:Vs(e,"securityGroupIds"),BackupRetentionPeriod:pn(e,"backupRetentionDays")??7,StorageEncrypted:!0,KmsKeyId:jt(e,"kmsKeyId"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:pn(e,"minCapacity")??0.5,MaxCapacity:pn(e,"maxCapacity")??4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${r}-writer-1`,DBClusterIdentifier:r,DBInstanceClass:String(e.plan||"db.serverless"),Engine:n,PubliclyAccessible:Eo(e,"publicExposure")??!1}),{status:"creating",providerId:r}}async execute(e,t,r,n){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBCluster(e),{status:"rebooting"};if(t==="backup"){let i=Yc(e,r);return await this.client.createDBClusterSnapshot(e,i),{status:"snapshotting",snapshotId:i}}if(t==="restore"){let i=String(r.targetId),o=String(r.engine)==="postgres"?"aurora-postgresql":"aurora-mysql",s=await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:i,SnapshotIdentifier:String(r.backupId),Engine:o,EngineVersion:jt(r,"engineVersion"),DBSubnetGroupName:jt(r,"subnetGroup"),VpcSecurityGroupIds:Vs(r,"securityGroupIds"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:pn(r,"minCapacity")??0.5,MaxCapacity:pn(r,"maxCapacity")??4}});return await this.client.createDBInstance({DBInstanceIdentifier:`${i}-writer-1`,DBClusterIdentifier:i,DBInstanceClass:jt(r,"plan","db.serverless"),Engine:o,PubliclyAccessible:!1}),{...Wu(s.DBCluster),sourceId:e,restoreTargetId:i}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let i=Yc(e,r);return await this.client.modifyDBCluster({DBClusterIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(e,i),{status:"deleting",finalSnapshotId:i}}if(["resize","version","rotate"].includes(t)){let i=await this.client.modifyDBCluster({DBClusterIdentifier:e,ServerlessV2ScalingConfiguration:pn(r,"minCapacity")==null&&pn(r,"maxCapacity")==null?void 0:{MinCapacity:pn(r,"minCapacity")??0.5,MaxCapacity:pn(r,"maxCapacity")??4},EngineVersion:jt(r,"engineVersion"),MasterUserPassword:t==="rotate"?n:void 0,ApplyImmediately:Eo(r,"applyImmediately")??!0});return Wu(i.DBCluster)}throw Error(`Aurora action ${t} requires an engine connection runner.`)}}class Yn{client;constructor(e=new oe){this.client=e}async observe(e){let t=(await this.client.describeCacheClusters(e)).CacheClusters[0];if(!t)throw Error("ElastiCache cluster was not found.");let r=t.CacheNodes?.[0]?.Endpoint;return{providerId:t.CacheClusterId,status:t.CacheClusterStatus,engine:t.Engine,engineVersion:t.EngineVersion,plan:t.CacheNodeType,nodes:t.NumCacheNodes,endpoint:r?.Address??null,port:r?.Port??null}}async apply(e){let t=await this.client.createCacheCluster({cacheClusterId:String(e.id),engine:"redis",cacheNodeType:String(e.plan),numCacheNodes:pn(e,"nodes")??1,engineVersion:jt(e,"engineVersion"),port:pn(e,"port"),securityGroupIds:Vs(e,"securityGroupIds"),subnetGroupName:jt(e,"subnetGroup"),tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{providerId:t.CacheCluster.CacheClusterId,status:t.CacheCluster.CacheClusterStatus}}async execute(e,t,r){if(t==="observe")return this.observe(e);if(t==="restart"){let n=(await this.client.describeCacheClusters(e)).CacheClusters[0];return await this.client.rebootCacheCluster(e,n?.CacheNodes?.map((i)=>i.CacheNodeId)??["0001"]),{status:"rebooting"}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};return await this.client.deleteCacheCluster(e),{status:"deleting"}}throw Error(`ElastiCache action ${t} is not supported by this cluster mode.`)}}import{mkdir as Zw,writeFile as eI}from"node:fs/promises";import{join as tI}from"node:path";async function wn(e,t,r=!1){let n=Bun.spawn(["docker",...e],{stdin:t==null?"ignore":"pipe",stdout:"pipe",stderr:"pipe"}),i=new Response(n.stdout).text(),o=new Response(n.stderr).text();if(t!=null)n.stdin.write(t),n.stdin.end();let[s,c,u]=await Promise.all([n.exited,i,o]);if(s!==0&&!r)throw Error(`Docker command failed (${s}): ${u.trim()||c.trim()}`);return{code:s,stdout:c,stderr:u}}class lf{async ensureNetwork(e){if((await wn(["network","inspect",e],void 0,!0)).code!==0)await wn(["network","create","--internal",e])}async seedSecret(e,t){await wn(["volume","create",e]),await wn(["run","--rm","-i","-v",`${e}:/run/target`,"alpine:3.21","sh","-c","umask 077; cat > /run/target/credential"],t)}async removeVolume(e){await wn(["volume","rm",e],void 0,!0)}async inspect(e){let t=await wn(["inspect",e],void 0,!0);if(t.code!==0)return;return JSON.parse(t.stdout)[0]}async run(e){await wn(["run",...e])}async exec(e,t,r){return(await wn(["exec","-i",e,...t],r)).stdout}async update(e,t){await wn(["update",...t,e])}async restart(e){await wn(["restart",e])}async remove(e){await wn(["rm","--force",e],void 0,!0)}async logs(e,t){let r=await wn(["logs","--tail",String(Math.min(2000,Math.max(1,t))),e],void 0,!0);return`${r.stdout}${r.stderr}`.slice(-262144)}async stats(e){let t=await wn(["stats","--no-stream","--format","{{json .}}",e],void 0,!0);if(t.code!==0||!t.stdout.trim())return{};let r=JSON.parse(t.stdout.trim());return{cpuPercent:String(r.CPUPerc??""),memoryUsage:String(r.MemUsage??""),memoryPercent:String(r.MemPerc??""),networkIo:String(r.NetIO??""),blockIo:String(r.BlockIO??""),pids:Number(r.PIDs??0)}}}var rI={postgres:{image:"postgres:17-alpine",port:5432,dataPath:"/var/lib/postgresql/data"},mysql:{image:"mysql:8.4",port:3306,dataPath:"/var/lib/mysql"},mariadb:{image:"mariadb:11.7",port:3306,dataPath:"/var/lib/mysql"},redis:{image:"redis:7.4-alpine",port:6379,dataPath:"/data"},mongodb:{image:"mongo:8.0",port:27017,dataPath:"/data/db"}};function to(e,t="app"){let r=String(e??t);if(!/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(r))throw Error("Database identifiers must be letters, numbers, or underscores.");return r}function Ko(e){if(!/^[a-z0-9][a-z0-9_.-]{1,62}$/i.test(e))throw Error("Runtime placement must be a valid container identifier.");return`tscloud-data-${e.toLowerCase()}`}function nI(e,t){let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)}function Ia(e){return e.Config?.Labels??{}}class ct{runtime;backupRoot;constructor(e=new lf,t=R(process.cwd(),"backups","data")){this.runtime=e;this.backupRoot=t}async observe(e){let t=Ko(e),r=await this.runtime.inspect(t);if(!r)throw Error(`Data container ${t} was not found.`);let n=Ia(r),i=await this.runtime.stats(t),o=r.NetworkSettings?.Ports??{},s=Object.values(o).flat().find(Boolean);return{providerId:t,status:r.State?.Status??"unknown",healthy:r.State?.Health?.Status??null,engine:n["ts-cloud.engine"]??null,engineVersion:n["ts-cloud.engine-version"]??null,username:n["ts-cloud.username"]??null,database:n["ts-cloud.database"]??null,endpoint:s?.HostIp||"127.0.0.1",port:s?.HostPort?Number(s.HostPort):null,image:r.Config?.Image??null,startedAt:r.State?.StartedAt??null,metrics:i}}async apply(e,t){let r=String(e.id),n=Ko(r),i=String(e.engine);if(i==="libsql")throw Error("libSQL requires an explicitly configured runtime image.");let o=rI[i];if(!o)throw Error(`Unsupported runtime data engine ${i}.`);if(!t)throw Error(`${i} requires a managed credential.`);if(e.publicExposure===!0)throw Error("Container public exposure requires an external reviewed firewall policy; direct publishing is refused.");let s=to(e.username),c=to(nI(e,"database")),u=`${n}-secret`,a=`${n}-data`,f=i==="redis"?`appendonly yes
|
|
92
|
+
`)){let n=r.trim();if(!n.startsWith("BACKUP="))continue;let i=n.slice(7),s=(i.split("/").pop()??i).replace(/-\d{8}-\d{6}\.sql\.gz$/,"");if(i)t.push({file:i,database:s})}return t}async function Dm(e,t,r){if(!Yi(r))return{ok:!1,error:"Database name must be a valid identifier.",database:r};let n=Ho(e);if(qc(n))return{...Gc(n,"Backing up"),database:r};return{...await Vr(e,t,ss(n,r,Fu,A(e)),`ts-cloud db:backup ${r}`),database:r}}async function Om(e,t){let r=await Vr(e,t,Lw(),"ts-cloud db:backups"),n=r.ok&&r.stdout?Bw(r.stdout):[];return{...r,backups:n}}async function _m(e,t){let r=Ho(e),n={keyspaces:[],shards:[],tablets:[]};if(r!=="vitess")return{ok:!1,error:"The configured database engine is not Vitess.",engine:r,...n};let i=await Vr(e,t,Ow(A(e)),"ts-cloud vitess:topology"),o=i.ok&&i.stdout?_w(i.stdout):n;return{...i,engine:r,...o}}function Nm(e){return e.filter((t)=>t.state.toUpperCase()!=="SERVING")}function Mm(e){let t=new Set(e.tablets.filter((r)=>r.type.toUpperCase()==="PRIMARY"&&r.state.toUpperCase()==="SERVING").map((r)=>`${r.keyspace}/${r.shard}`));return e.shards.filter((r)=>!t.has(`${r.keyspace}/${r.shard}`))}var Fw=async(e)=>{let t=Bun.spawn(e,{stdout:"pipe",stderr:"pipe"}),[r,n,i]=await Promise.all([t.exited,new Response(t.stdout).text(),new Response(t.stderr).text()]);return{code:r,stdout:n,stderr:i}};class Hr{async scan(e,t){return no(e,t)}async exec(e,t){if(e.trustState!=="pinned")throw Error("SSH host key must be pinned before remote execution.");return Fw(["ssh","-p",String(e.sshPort),"-o","BatchMode=yes","-o","StrictHostKeyChecking=yes","-o","ConnectTimeout=10",`${e.sshUser}@${e.endpoint}`,t])}}var jw=fr,Uw=`set -eu; printf '{'; printf '"os":"%s",' "$(. /etc/os-release 2>/dev/null; printf %s "\${PRETTY_NAME:-Linux}")"; printf '"arch":"%s",' "$(uname -m)"; printf '"cpuCores":%s,' "$(getconf _NPROCESSORS_ONLN)"; printf '"memoryBytes":%s,' "$(awk '/MemTotal/{print $2*1024}' /proc/meminfo)"; printf '"diskBytes":%s,' "$(df -B1 / | awk 'NR==2{print $2}')"; printf '"diskFreeBytes":%s,' "$(df -B1 / | awk 'NR==2{print $4}')"; printf '"dnsOk":'; getent hosts example.com >/dev/null && printf true || printf false; printf ',"timeSkewSeconds":0,"tools":{"curl":"'; command -v curl >/dev/null && printf installed; printf '","tar":"'; command -v tar >/dev/null && printf installed; printf '"},"privilege":"'; sudo -n true >/dev/null 2>&1 && printf sudo || printf user; printf '"}'`;class at{provider;transport;discoverer;constructor(e,t=new Hr,r){this.provider=e;this.transport=t;this.discoverer=r}discover(e){return this.discoverer?.(e)??Promise.resolve([])}async test(e){try{let t=await this.transport.scan(e.endpoint,e.sshPort);return{reachable:!0,hostKeyAlgorithm:t.algorithm,hostKeyFingerprint:jw(t.key),latencyMs:0}}catch{return{reachable:!1,hostKeyAlgorithm:"unknown",hostKeyFingerprint:"",latencyMs:0}}}async validate(e){let t=await this.transport.exec(e,Uw);if(t.code!==0)throw Error(`Fleet validation failed: ${t.stderr.trim()||t.code}`);try{return JSON.parse(t.stdout)}catch{throw Error("Fleet validation returned malformed facts.")}}async bootstrap(e,t){let r=await this.transport.exec(e,`sudo -n ts-cloud-agent bootstrap --version 1 --steps ${t.length}`);if(r.code!==0)throw Error(`Fleet bootstrap failed: ${r.stderr.trim()||r.code}`);return{version:"1"}}capabilities(){return{document:{supported:!0,reason:"fleet-capabilities/v1; sha256:driver-contract"},validate:{supported:!0},bootstrap:{supported:!0},heartbeat:{supported:!0},drain:{supported:!0},archive:{supported:!0},terminate:{supported:!1,reason:"Inventory removal never terminates provider infrastructure."}}}}function $m(e,t){return{"fleet.bootstrap":async(r)=>{let n=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},i=e.get(String(n.serverId??""));if(!i)throw Error("Queued fleet server was not found.");let o=t.find((u)=>u.provider===i.provider);if(!o)throw Error(`No ${i.provider} fleet driver is configured.`);let s=Array.isArray(n.steps)?n.steps.map(String):[];if(r.checkpoint("preflight","Rechecking pinned trust and healthy validation."),i.trustState!=="pinned"||!i.validation?.valid)throw Error("Fleet bootstrap requires pinned trust and a healthy validation report.");r.checkpoint("bootstrap","Applying the reviewed idempotent bootstrap plan.");let c=await o.bootstrap(i,s);return e.update(i.id,{bootstrapVersion:c.version,status:"ready"}),r.checkpoint("verify","Bootstrap completed; heartbeat can now establish freshness."),{serverId:i.id,bootstrapVersion:c.version,steps:s.length}}}}var _i=(e)=>e==null?void 0:String(e),Wo=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},ju=(e)=>({id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),resourceId:String(e.resource_id),name:String(e.name),provider:String(e.provider),providerId:_i(e.provider_id),region:_i(e.region),zone:_i(e.zone),endpoint:String(e.endpoint),sshUser:String(e.ssh_user),sshPort:Number(e.ssh_port),credentialRef:String(e.credential_ref),hostKeyAlgorithm:_i(e.host_key_algorithm),hostKeyFingerprint:_i(e.host_key_fingerprint),pendingHostKey:_i(e.pending_host_key),roles:Wo(e.roles,[]),labels:Wo(e.labels,{}),taints:Wo(e.taints,[]),capacity:Wo(e.capacity,{}),usage:Wo(e.usage,{}),capabilities:Wo(e.capabilities,{}),status:String(e.status),trustState:String(e.trust_state),validation:Wo(e.validation,void 0),bootstrapVersion:_i(e.bootstrap_version),heartbeatAt:_i(e.heartbeat_at),lastSeenAt:_i(e.last_seen_at),archivedAt:_i(e.archived_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class xe{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}get(e){let t=this.control.database.query("SELECT * FROM fleet_servers WHERE id=?").get(e);return t?ju(t):void 0}list(e,t=!1){return this.control.database.query("SELECT * FROM fleet_servers WHERE project_id=? ORDER BY name").all(e).map(ju).filter((r)=>t||r.status!=="archived")}findProvider(e,t,r){let n=this.control.database.query("SELECT * FROM fleet_servers WHERE organization_id=? AND provider=? AND provider_id=? AND archived_at IS NULL").get(e,t,r);return n?ju(n):void 0}create(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO fleet_servers (id,organization_id,project_id,resource_id,name,provider,provider_id,region,zone,endpoint,ssh_user,ssh_port,credential_ref,host_key_algorithm,host_key_fingerprint,pending_host_key,roles,labels,taints,capacity,usage,capabilities,status,trust_state,validation,bootstrap_version,heartbeat_at,last_seen_at,archived_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.resourceId,e.name,e.provider,e.providerId??null,e.region??null,e.zone??null,e.endpoint,e.sshUser,e.sshPort,e.credentialRef,e.hostKeyAlgorithm??null,e.hostKeyFingerprint??null,e.pendingHostKey??null,JSON.stringify(e.roles),JSON.stringify(e.labels),JSON.stringify(e.taints),JSON.stringify(e.capacity),JSON.stringify(e.usage),JSON.stringify(e.capabilities),e.status,e.trustState,JSON.stringify(e.validation??{}),e.bootstrapVersion??null,e.heartbeatAt??null,e.lastSeenAt??null,e.archivedAt??null,r,r]),this.get(t)}update(e,t){let r=this.get(e);if(!r)throw Error("Server was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE fleet_servers SET name=?,provider_id=?,region=?,zone=?,endpoint=?,ssh_user=?,ssh_port=?,credential_ref=?,host_key_algorithm=?,host_key_fingerprint=?,pending_host_key=?,roles=?,labels=?,taints=?,capacity=?,usage=?,capabilities=?,status=?,trust_state=?,validation=?,bootstrap_version=?,heartbeat_at=?,last_seen_at=?,archived_at=?,version=version+1,updated_at=? WHERE id=?",[n.name,n.providerId??null,n.region??null,n.zone??null,n.endpoint,n.sshUser,n.sshPort,n.credentialRef,n.hostKeyAlgorithm??null,n.hostKeyFingerprint??null,n.pendingHostKey??null,JSON.stringify(n.roles),JSON.stringify(n.labels),JSON.stringify(n.taints),JSON.stringify(n.capacity),JSON.stringify(n.usage),JSON.stringify(n.capabilities),n.status,n.trustState,JSON.stringify(n.validation??{}),n.bootstrapVersion??null,n.heartbeatAt??null,n.lastSeenAt??null,n.archivedAt??null,i,e]),this.get(e)}}var zw=/^(?:[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?|\[[0-9a-fA-F:]+\])$/;class $n{store;drivers;now;queue;constructor(e,t,r,n=()=>new Date){this.store=e;this.drivers=t;this.now=n;this.queue=r??new S(e.control)}driver(e){let t=this.drivers.find((r)=>r.provider===e);if(!t)throw Error(`No ${e} fleet driver is configured.`);return t}enroll(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Server name is invalid.");if(!zw.test(e.endpoint)||e.sshUser==="root"||!e.credentialRef.startsWith("secret://"))throw Error("Enrollment requires a valid endpoint, non-root SSH user, and secret credential reference.");let t=e.providerId?this.store.findProvider(e.organizationId,e.provider,e.providerId):void 0;if(t)return this.store.update(t.id,{endpoint:e.endpoint,region:e.region,zone:e.zone});let r=this.store.control.createResource({projectId:e.projectId,kind:"server",slug:e.name,name:e.name,provider:e.provider,providerId:e.providerId}),n=this.driver(e.provider);return this.store.create({...e,resourceId:r.id,sshPort:e.sshPort??22,labels:e.labels??{},taints:[],capacity:{},usage:{},capabilities:n.capabilities(),status:"pending",trustState:"unverified"})}async test(e){let t=this.store.get(e);if(!t)throw Error("Server was not found.");let r=await this.driver(t.provider).test(t);if(!r.reachable)return this.store.update(e,{status:"unreachable"});if(t.hostKeyFingerprint&&t.hostKeyFingerprint!==r.hostKeyFingerprint)return this.store.update(e,{status:"degraded",trustState:"rotation_pending",pendingHostKey:r.hostKeyFingerprint});return this.store.update(e,{hostKeyAlgorithm:r.hostKeyAlgorithm,hostKeyFingerprint:r.hostKeyFingerprint,pendingHostKey:void 0,trustState:"pinned",status:"validating",lastSeenAt:this.now().toISOString()})}reviewHostKey(e,t){let r=this.store.get(e);if(!r||r.pendingHostKey!==t)throw Error("Pending host key does not match.");return this.store.update(e,{hostKeyFingerprint:t,pendingHostKey:void 0,trustState:"pinned",status:"validating"})}async validate(e){let t=this.store.get(e);if(!t||t.trustState!=="pinned")throw Error("Pin the SSH host key before validation.");let r=await this.driver(t.provider).validate(t),n=[];if(!["x64","arm64","x86_64","aarch64"].includes(r.arch??""))n.push({code:"arch.unsupported",severity:"error",message:"Unsupported architecture.",remediation:"Use x86_64 or arm64 Linux."});for(let s of["curl","tar"])if(!r.tools?.[s])n.push({code:`tool.${s}`,severity:"error",message:`${s} is missing.`,remediation:`Install ${s} before bootstrap.`});if(Math.abs(r.timeSkewSeconds??0)>60)n.push({code:"time.skew",severity:"error",message:"Clock skew exceeds 60 seconds.",remediation:"Enable NTP synchronization."});if(!r.dnsOk)n.push({code:"dns.failed",severity:"error",message:"DNS validation failed.",remediation:"Repair resolver configuration."});let i={valid:!n.some((s)=>s.severity==="error"),facts:r,findings:n,validatedAt:this.now().toISOString(),validatorVersion:"1"},o={cpu:r.cpuCores??0,memoryBytes:r.memoryBytes??0,diskBytes:r.diskBytes??0};return this.store.update(e,{validation:i,capacity:o,status:i.valid?"ready":"degraded"})}bootstrap(e,t=!1){let r=this.store.get(e);if(!r?.validation?.valid)throw Error("A healthy validation report is required.");let n=["install runtime dependencies","install ts-cloud agent","configure heartbeat","verify least-privilege access"];if(!t)return{preview:!0,steps:n};let i=this.queue.enqueue({projectId:r.projectId,resourceId:r.resourceId,kind:"fleet.bootstrap",input:{serverId:e,steps:n},lockKey:`server:${e}`,providerKey:r.provider}).operation;return{preview:!1,steps:n,operation:i}}heartbeat(e,t){let r=this.store.get(e);if(!r)throw Error("Server was not found.");let n=this.now().toISOString();return this.store.update(e,{usage:t.usage,capabilities:t.capabilities??r.capabilities,heartbeatAt:n,lastSeenAt:n,status:r.status==="draining"||r.status==="drained"?r.status:"ready"})}drain(e,t=!1){return this.store.update(e,{status:t?"drained":"draining"})}uncordon(e){return this.store.update(e,{status:"ready"})}archive(e,t){let r=this.store.get(e);if(!r||t!==r.name)throw Error("Exact server name confirmation is required.");return this.store.update(e,{status:"archived",archivedAt:this.now().toISOString()})}}var yi=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},un=(e)=>e==null?void 0:String(e),Fm=()=>({cpu:0,memoryBytes:0,diskBytes:0,gpu:0}),Bs=(e={})=>({...Fm(),...e});function Lm(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),name:String(e.name),purpose:String(e.purpose),backend:String(e.backend),region:un(e.region),architecture:un(e.architecture),labels:yi(e.labels,{}),requiredServerLabels:yi(e.required_server_labels,{}),toleratedTaints:yi(e.tolerated_taints,[]),capacity:Bs(yi(e.capacity,{})),reserved:yi(e.reserved,{}),maxWorkloads:Number(e.max_workloads),costWeight:Number(e.cost_weight),spreadKey:un(e.spread_key),concurrency:Number(e.concurrency),ephemeralWorkspaces:Number(e.ephemeral_workspaces)===1,allowProductionSecrets:Number(e.allow_production_secrets)===1,status:String(e.status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Bm(e){return{id:String(e.id),projectId:String(e.project_id),environmentId:un(e.environment_id),resourceId:String(e.resource_id),releaseId:un(e.release_id),poolId:String(e.pool_id),serverId:un(e.server_id),purpose:String(e.purpose),requirements:yi(e.requirements,{}),decision:yi(e.decision,{}),stateful:Number(e.stateful)===1,autoReschedule:Number(e.auto_reschedule)===1,status:String(e.status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Vw(e){return{id:String(e.id),projectId:String(e.project_id),resourceId:un(e.resource_id),poolId:String(e.pool_id),placementId:un(e.placement_id),operationId:un(e.operation_id),sourceSha:String(e.source_sha),buildSpec:yi(e.build_spec,{}),credentialPolicy:yi(e.credential_policy,{productionSecrets:!1,shortLivedTokenExpiresAt:""}),workspace:un(e.workspace),cacheKey:un(e.cache_key),artifactUri:un(e.artifact_uri),artifactDigest:un(e.artifact_digest),status:String(e.status),cleanupAt:un(e.cleanup_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class Ln{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}createPool(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO capacity_pools (id,organization_id,project_id,name,purpose,backend,region,architecture,labels,required_server_labels,tolerated_taints,capacity,reserved,max_workloads,cost_weight,spread_key,concurrency,ephemeral_workspaces,allow_production_secrets,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.name,e.purpose,e.backend,e.region??null,e.architecture??null,JSON.stringify(e.labels),JSON.stringify(e.requiredServerLabels),JSON.stringify(e.toleratedTaints),JSON.stringify(Bs(e.capacity)),"{}",e.maxWorkloads,e.costWeight,e.spreadKey??null,e.concurrency,e.ephemeralWorkspaces?1:0,e.allowProductionSecrets?1:0,e.status,r,r]),this.getPool(t)}getPool(e){let t=this.control.database.query("SELECT * FROM capacity_pools WHERE id=?").get(e);return t?Lm(t):void 0}listPools(e){return this.control.database.query("SELECT * FROM capacity_pools WHERE project_id=? ORDER BY name").all(e).map(Lm)}updatePool(e,t){let r=this.getPool(e);if(!r)throw Error("Capacity pool was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE capacity_pools SET status=?,reserved=?,capacity=?,concurrency=?,version=version+1,updated_at=? WHERE id=?",[n.status,JSON.stringify(n.reserved),JSON.stringify(n.capacity),n.concurrency,i,e]),this.getPool(e)}addMember(e,t,r={}){let n=this.now().toISOString();this.control.database.run("INSERT INTO capacity_pool_members (pool_id,server_id,capacity_override,status,created_at,updated_at) VALUES (?,?,?,'active',?,?) ON CONFLICT(pool_id,server_id) DO UPDATE SET capacity_override=excluded.capacity_override,status='active',updated_at=excluded.updated_at",[e,t,JSON.stringify(r),n,n])}members(e){return this.control.database.query("SELECT * FROM capacity_pool_members WHERE pool_id=? ORDER BY server_id").all(e).map((t)=>({serverId:String(t.server_id),status:String(t.status),capacityOverride:yi(t.capacity_override,{})}))}memberStatus(e,t,r){this.control.database.run("UPDATE capacity_pool_members SET status=?,updated_at=? WHERE pool_id=? AND server_id=?",[r,this.now().toISOString(),e,t])}listPlacements(e,t){let r=this.control.database.query("SELECT * FROM workload_placements WHERE project_id=? ORDER BY created_at,id").all(e).map(Bm);return t?.length?r.filter((n)=>t.includes(n.status)):r}getPlacement(e){let t=this.control.database.query("SELECT * FROM workload_placements WHERE id=?").get(e);return t?Bm(t):void 0}activeUsage(e,t){let r=this.control.database.query("SELECT l.resources,l.server_id FROM capacity_leases l WHERE l.pool_id=? AND l.state='active' AND l.expires_at>?").all(e,this.now().toISOString()),n=t?r.filter((i)=>String(i.server_id)===t):r;return{resources:n.reduce((i,o)=>{let s=Bs(yi(o.resources,{}));for(let c of Object.keys(i))i[c]+=s[c];return i},Fm()),count:n.length}}expireLeases(){return this.control.database.run("UPDATE capacity_leases SET state='expired',updated_at=? WHERE state='active' AND expires_at<=?",[this.now().toISOString(),this.now().toISOString()]).changes}reserve(e){return this.control.transaction(()=>{this.expireLeases();let t=this.id(),r=this.id(),n=this.now().toISOString(),i=new Date(this.now().getTime()+(e.requirements.leaseSeconds??300)*1000).toISOString();return this.control.database.run("INSERT INTO workload_placements (id,project_id,environment_id,resource_id,release_id,pool_id,server_id,purpose,requirements,decision,stateful,auto_reschedule,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,'reserved',?,?)",[t,e.projectId,e.environmentId??null,e.resourceId,e.releaseId??null,e.decision.poolId,e.decision.serverId??null,e.requirements.purpose,JSON.stringify(e.requirements),JSON.stringify(e.decision),e.requirements.stateful?1:0,e.requirements.autoReschedule&&!e.requirements.stateful?1:0,n,n]),this.control.database.run("INSERT INTO capacity_leases (id,placement_id,pool_id,server_id,resources,state,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,'active',?,?,?)",[r,t,e.decision.poolId,e.decision.serverId??null,JSON.stringify(Bs(e.requirements.resources)),i,n,n]),this.getPlacement(t)})}transitionPlacement(e,t){if(!this.getPlacement(e))throw Error("Placement was not found.");let n=this.now().toISOString();if(this.control.database.run("UPDATE workload_placements SET status=?,version=version+1,updated_at=? WHERE id=?",[t,n,e]),["released","failed","blocked"].includes(t))this.control.database.run("UPDATE capacity_leases SET state='released',updated_at=? WHERE placement_id=? AND state='active'",[n,e]);return this.getPlacement(e)}createBuild(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO remote_builds (id,project_id,resource_id,pool_id,placement_id,operation_id,source_sha,build_spec,credential_policy,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'queued',?,?)",[t,e.projectId,e.resourceId??null,e.poolId,e.placementId??null,e.operationId??null,e.sourceSha,JSON.stringify(e.buildSpec),JSON.stringify({productionSecrets:!1,shortLivedTokenExpiresAt:e.tokenExpiresAt}),r,r]),this.getBuild(t)}getBuild(e){let t=this.control.database.query("SELECT * FROM remote_builds WHERE id=?").get(e);return t?Vw(t):void 0}updateBuild(e,t){let r=this.getBuild(e);if(!r)throw Error("Remote build was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE remote_builds SET operation_id=?,workspace=?,cache_key=?,artifact_uri=?,artifact_digest=?,status=?,cleanup_at=?,updated_at=? WHERE id=?",[n.operationId??null,n.workspace??null,n.cacheKey??null,n.artifactUri??null,n.artifactDigest??null,n.status,n.cleanupAt??null,i,e]),this.getBuild(e)}}var Jc=["cpu","memoryBytes","diskBytes","gpu"],jm=(e,t={})=>Object.entries(t).every(([r,n])=>e[r]===n),qw=(e,t,r)=>Object.fromEntries(Jc.map((n)=>[n,Math.max(0,e[n]-t[n]-(r[n]??0))])),Gw=(e,t)=>Jc.every((r)=>e[r]>=(t[r]??0)),Jw=(e,t)=>Jc.reduce((r,n)=>r+(t[n]??0)/(e[n]||1),0);class Mn{store;fleet;constructor(e,t){this.store=e;this.fleet=t}poolCandidates(e,t,r){let n=[];for(let i of this.store.listPools(e)){if(i.id===r)continue;let o=[];if(i.status!=="active")o.push(`pool is ${i.status}`);if(i.purpose!==t.purpose)o.push(`purpose is ${i.purpose}`);if(t.region&&i.region!==t.region)o.push(`region is ${i.region??"unset"}`);if(t.architecture&&i.architecture!==t.architecture)o.push(`architecture is ${i.architecture??"unset"}`);if(!jm(i.labels,t.labels))o.push("pool labels do not match");if(i.backend==="server"){let s=this.store.members(i.id);if(!s.length)n.push(this.decision(i,void 0,t,[...o,"pool has no servers"]));for(let c of s){let u=this.fleet.get(c.serverId),a=[...o];if(!u)a.push("server is missing");else this.serverReasons(i,u,c.status,t,a);n.push(this.decision(i,u,t,a,c.capacityOverride))}}else n.push(this.decision(i,void 0,t,o))}return n.sort((i,o)=>Number(o.eligible)-Number(i.eligible)||i.score.cost-o.score.cost||i.score.spread-o.score.spread||i.score.fit-o.score.fit||i.poolName.localeCompare(o.poolName)||(i.serverId??"").localeCompare(o.serverId??""))}serverReasons(e,t,r,n,i){if(r!=="active")i.push(`member is ${r}`);if(t.status!=="ready")i.push(`server is ${t.status}`);if(!t.roles.includes(n.purpose==="build"?"build":n.purpose))i.push(`server lacks ${n.purpose} role`);if(!jm(t.labels,e.requiredServerLabels))i.push("server labels do not match pool selector");for(let o of t.taints)if(!e.toleratedTaints.includes(o))i.push(`taint ${o} is not tolerated`)}decision(e,t,r,n,i={}){let o=Bs({...t?.capacity,...i}),s=t?Object.fromEntries(Jc.map((a)=>[a,Math.min(e.capacity[a],o[a])])):e.capacity,c=this.store.activeUsage(e.id,t?.id),u=qw(s,c.resources,e.reserved);if(c.count>=e.maxWorkloads)n.push("workload limit reached");if(r.purpose==="build"&&c.count>=e.concurrency)n.push("build concurrency reached");if(!Gw(u,r.resources))n.push("insufficient capacity");return{poolId:e.id,poolName:e.name,serverId:t?.id,eligible:n.length===0,reasons:n,available:u,score:{fit:Jw(u,r.resources),spread:c.count,cost:e.costWeight}}}explain(e,t){return this.poolCandidates(e,t)}place(e){return this.store.control.transaction(()=>{let t=this.poolCandidates(e.projectId,e.requirements).find((r)=>r.eligible);if(!t)throw Error(`No eligible capacity: ${this.explain(e.projectId,e.requirements).flatMap((r)=>r.reasons).join("; ")}`);return this.store.reserve({...e,decision:t})})}activate(e){return this.store.transitionPlacement(e,"active")}release(e){return this.store.transitionPlacement(e,"released")}drainPool(e){let t=this.store.updatePool(e,{status:"draining"}),r=[],n=[];for(let i of this.store.listPlacements(t.projectId,["reserved","active"]).filter((o)=>o.poolId===e)){if(i.stateful){n.push(this.store.transitionPlacement(i.id,"blocked"));continue}this.store.transitionPlacement(i.id,"moving");let o=this.place({projectId:i.projectId,environmentId:i.environmentId,resourceId:i.resourceId,releaseId:i.releaseId,requirements:i.requirements});r.push(this.activate(o.id)),this.store.transitionPlacement(i.id,"released")}return{pool:t,moved:r,blocked:n}}drainServer(e,t){this.store.memberStatus(e,t,"draining");let r=this.store.getPool(e);if(!r)throw Error("Capacity pool was not found.");let n=[],i=[];for(let o of this.store.listPlacements(r.projectId,["reserved","active"]).filter((s)=>s.poolId===e&&s.serverId===t)){if(o.stateful){i.push(this.store.transitionPlacement(o.id,"blocked"));continue}this.store.transitionPlacement(o.id,"moving");let s=this.poolCandidates(o.projectId,o.requirements).find((u)=>u.eligible);if(!s){i.push(this.store.transitionPlacement(o.id,"blocked"));continue}let c=this.store.reserve({projectId:o.projectId,environmentId:o.environmentId,resourceId:o.resourceId,releaseId:o.releaseId,requirements:o.requirements,decision:s});n.push(this.activate(c.id)),this.store.transitionPlacement(o.id,"released")}return{moved:n,blocked:i}}reconcileFailure(e){let t=this.fleet.get(e);if(!t)throw Error("Server was not found.");let r=[],n=[];for(let i of this.store.listPlacements(t.projectId,["active"]).filter((o)=>o.serverId===e)){if(i.stateful||!i.autoReschedule){n.push(this.store.transitionPlacement(i.id,"blocked"));continue}this.store.transitionPlacement(i.id,"failed");let o=this.place({projectId:i.projectId,environmentId:i.environmentId,resourceId:i.resourceId,releaseId:i.releaseId,requirements:i.requirements});r.push(this.activate(o.id))}return{rescheduled:r,blocked:n}}}var Zi=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},Rn=(e)=>e==null?void 0:String(e),Um=(e)=>({id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:Rn(e.environment_id),name:String(e.name),hostname:String(e.hostname),homeRegion:String(e.home_region),regions:Zi(e.regions,[]),trafficPolicy:String(e.traffic_policy),dataPolicy:Zi(e.data_policy,{replicate:[],maxLagSeconds:60,retainOnDestroy:!0}),status:String(e.status),activeRegion:String(e.active_region),revision:Rn(e.revision),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Uu=(e)=>({id:String(e.id),topologyId:String(e.topology_id),region:String(e.region),role:String(e.role),provider:String(e.provider),stackId:Rn(e.stack_id),stackRevision:Rn(e.stack_revision),status:String(e.status),health:Zi(e.health,{}),lastHealthyAt:Rn(e.last_healthy_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),zu=(e)=>({id:String(e.id),topologyId:String(e.topology_id),kind:String(e.kind),sourceRegion:String(e.source_region),targetRegion:String(e.target_region),config:Zi(e.config,{}),status:String(e.status),checkpoint:Rn(e.checkpoint),lagSeconds:e.lag_seconds==null?void 0:Number(e.lag_seconds),lastVerifiedAt:Rn(e.last_verified_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Vu=(e)=>({id:String(e.id),topologyId:String(e.topology_id),hostname:String(e.hostname),dnsProvider:String(e.dns_provider),cdnEnabled:Number(e.cdn_enabled)===1,wafEnabled:Number(e.waf_enabled)===1,weights:Zi(e.weights,{}),desiredWeights:Zi(e.desired_weights,{}),status:String(e.status),providerState:Zi(e.provider_state,{}),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),zm=(e)=>({id:String(e.id),topologyId:String(e.topology_id),operationId:Rn(e.operation_id),kind:String(e.kind),requestedRegion:Rn(e.requested_region),revision:Rn(e.revision),plan:Zi(e.plan,[]),currentStep:Rn(e.current_step),completedSteps:Zi(e.completed_steps,[]),status:String(e.status),error:Rn(e.error),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class Un{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}create(e){return this.control.transaction(()=>{if(e.regions.length<2||new Set(e.regions.map((o)=>o.region)).size!==e.regions.length||e.regions.filter((o)=>o.role==="primary").length!==1)throw Error("A topology requires unique regions and exactly one primary.");let t=e.regions.find((o)=>o.role==="primary"),r=this.id(),n=this.now().toISOString();this.control.database.run("INSERT INTO regional_topologies (id,organization_id,project_id,environment_id,name,hostname,home_region,regions,traffic_policy,data_policy,status,active_region,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,'draft',?,?,?)",[r,e.organizationId,e.projectId,e.environmentId??null,e.name,e.hostname,t.region,JSON.stringify(e.regions),e.trafficPolicy,JSON.stringify(e.dataPolicy),t.region,n,n]);for(let o of e.regions)this.control.database.run("INSERT INTO regional_targets (id,topology_id,region,role,provider,status,created_at,updated_at) VALUES (?,?,?,?,?,'pending',?,?)",[this.id(),r,o.region,o.role,o.provider,n,n]);for(let o of e.dataPolicy.replicate)for(let s of e.regions)for(let c of e.regions.filter((u)=>u.region!==s.region))this.control.database.run("INSERT INTO regional_replication_channels (id,topology_id,kind,source_region,target_region,config,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,o,s.region,c.region,"{}",n,n]);let i=Object.fromEntries(e.regions.map((o)=>[o.region,o.region===t.region?100:0]));return this.control.database.run("INSERT INTO regional_traffic_routes (id,topology_id,hostname,dns_provider,cdn_enabled,waf_enabled,weights,desired_weights,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'pending',?,?)",[this.id(),r,e.hostname,e.dnsProvider??"route53",e.cdnEnabled?1:0,e.wafEnabled?1:0,JSON.stringify(i),JSON.stringify(i),n,n]),this.get(r)})}get(e){let t=this.control.database.query("SELECT * FROM regional_topologies WHERE id=?").get(e);return t?Um(t):void 0}list(e){return this.control.database.query("SELECT * FROM regional_topologies WHERE project_id=? ORDER BY name").all(e).map(Um)}targets(e){return this.control.database.query("SELECT * FROM regional_targets WHERE topology_id=? ORDER BY role,region").all(e).map(Uu)}channels(e){return this.control.database.query("SELECT * FROM regional_replication_channels WHERE topology_id=? ORDER BY kind,target_region").all(e).map(zu)}route(e){let t=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE topology_id=?").get(e);return t?Vu(t):void 0}updateTopology(e,t){let r=this.get(e);if(!r)throw Error("Regional topology was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE regional_topologies SET status=?,active_region=?,revision=?,regions=?,version=version+1,updated_at=? WHERE id=?",[n.status,n.activeRegion,n.revision??null,JSON.stringify(n.regions),i,e]),this.get(e)}updateTarget(e,t){let r=this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(e);if(!r)throw Error("Regional target was not found.");let n=Uu(r),i={...n,...t},o=this.now().toISOString();return this.control.database.run("UPDATE regional_targets SET role=?,stack_id=?,stack_revision=?,status=?,health=?,last_healthy_at=?,version=version+1,updated_at=? WHERE id=?",[i.role,i.stackId??null,i.stackRevision??null,i.status,JSON.stringify(i.health),i.lastHealthyAt??null,o,e]),Uu(this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(e))}updateChannel(e,t){let r=this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(e);if(!r)throw Error("Replication channel was not found.");let n=zu(r),i={...n,...t},o=this.now().toISOString();return this.control.database.run("UPDATE regional_replication_channels SET status=?,checkpoint=?,lag_seconds=?,last_verified_at=?,version=version+1,updated_at=? WHERE id=?",[i.status,i.checkpoint??null,i.lagSeconds??null,i.lastVerifiedAt??null,o,e]),zu(this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(e))}updateRoute(e,t){let r=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(e);if(!r)throw Error("Traffic route was not found.");let n=Vu(r),i={...n,...t},o=this.now().toISOString();return this.control.database.run("UPDATE regional_traffic_routes SET weights=?,desired_weights=?,status=?,provider_state=?,version=version+1,updated_at=? WHERE id=?",[JSON.stringify(i.weights),JSON.stringify(i.desiredWeights),i.status,JSON.stringify(i.providerState),o,e]),Vu(this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(e))}createExecution(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO regional_executions (id,topology_id,operation_id,kind,requested_region,revision,plan,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'queued',?,?)",[t,e.topologyId,e.operationId??null,e.kind,e.requestedRegion??null,e.revision??null,JSON.stringify(e.plan),r,r]),this.execution(t)}execution(e){let t=this.control.database.query("SELECT * FROM regional_executions WHERE id=?").get(e);return t?zm(t):void 0}executions(e){return this.control.database.query("SELECT * FROM regional_executions WHERE topology_id=? ORDER BY created_at DESC").all(e).map(zm)}updateExecution(e,t){let r=this.execution(e);if(!r)throw Error("Regional execution was not found.");let n={...r,...t},i=this.now().toISOString();return this.control.database.run("UPDATE regional_executions SET operation_id=?,current_step=?,completed_steps=?,status=?,error=?,updated_at=? WHERE id=?",[n.operationId??null,n.currentStep??null,JSON.stringify(n.completedSteps),n.status,n.error??null,i,e]),this.execution(e)}}class Bn{store;queue;constructor(e,t){this.store=e;this.queue=t??new S(e.control)}create(e){return this.store.create(e)}plan(e,t,r){if(!this.store.get(e))throw Error("Regional topology was not found.");let i=this.store.targets(e),o=this.store.channels(e);if(t==="rollout")return[...i.filter((s)=>s.role==="secondary").map((s)=>`apply:${s.region}`),...i.filter((s)=>s.role==="primary").map((s)=>`apply:${s.region}`),...o.map((s)=>`replicate:${s.kind}:${s.targetRegion}`),"traffic:activate"];if(t==="failover"||t==="failback")return[`health:${r}`,`replication:${r}`,`traffic:${r}`,`roles:${r}`];if(t==="destroy")return["traffic:drain",...i.filter((s)=>s.role==="secondary").map((s)=>`delete:${s.region}`),...i.filter((s)=>s.role==="primary").map((s)=>`delete:${s.region}`),"complete"];return["observe","repair"]}enqueue(e){let t=this.store.get(e.topologyId);if(!t)throw Error("Regional topology was not found.");if(["failover","failback"].includes(e.kind)&&(!e.targetRegion||!t.regions.some((o)=>o.region===e.targetRegion)))throw Error("A topology target region is required.");if(e.kind==="failover"&&e.targetRegion===t.activeRegion)throw Error("Target region is already active.");if((e.kind==="destroy"||e.deleteData)&&e.confirmation!==t.name)throw Error("Exact topology name confirmation is required.");if(e.deleteData&&t.dataPolicy.retainOnDestroy)throw Error("Topology policy requires regional data retention.");if(e.kind==="rollout"&&!/^[A-Za-z0-9._:@/-]{7,200}$/.test(e.revision??""))throw Error("An immutable revision is required.");let r=this.plan(t.id,e.kind,e.targetRegion),n=this.store.createExecution({topologyId:t.id,kind:e.kind,requestedRegion:e.targetRegion,revision:e.revision,plan:r}),i=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,kind:`region.${e.kind}`,input:{executionId:n.id,manifest:e.manifest??{},deleteData:e.deleteData===!0},lockKey:`regional-topology:${t.id}`,providerKey:"multi-region",timeoutSeconds:7200,cancellationMode:"provider_non_cancellable",resumePolicy:"requeue",maxAttempts:3}).operation;return this.store.updateExecution(n.id,{operationId:i.id}),{execution:this.store.execution(n.id),operation:i}}}var Hw=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{};function Vm(e,t){let r=(a)=>{let f=t.find((C)=>C.provider===a.provider);if(!f)throw Error(`No ${a.provider} regional driver is configured.`);return f},n=(a,f,C)=>{a.throwIfCancellationRequested(),a.checkpoint(C,C),e.updateExecution(f.id,{status:"running",currentStep:C,completedSteps:[...e.execution(f.id).completedSteps,C]})},i=async(a,f)=>{let C=e.route(a.id);if(!C)throw Error("Regional traffic route was not found.");let k=e.targets(a.id).find((W)=>W.region===a.activeRegion)??e.targets(a.id)[0];if(!k)throw Error("Regional traffic target was not found.");e.updateRoute(C.id,{status:"applying",desiredWeights:f});let D=await r(k).applyTraffic({route:e.route(a.id),topology:a,weights:f});e.updateRoute(C.id,{status:Object.values(f).every((W)=>W===0)?"drained":"in_sync",weights:f,providerState:D.providerState})},o=async(a,f,C,k)=>{e.updateTopology(C.id,{status:"provisioning"});let D=f.revision,W=k.manifest??{},Y=e.targets(C.id).sort((ne,he)=>Number(ne.role==="primary")-Number(he.role==="primary"));for(let ne of Y){n(a,f,`apply:${ne.region}`),e.updateTarget(ne.id,{status:"provisioning"});let he=await r(ne).applyStack({target:ne,revision:D,manifest:W,signal:a.signal}),te=await r(ne).health({target:e.updateTarget(ne.id,{stackId:he.stackId,stackRevision:D})});if(!te.healthy)throw Error(`Regional health gate failed in ${ne.region}.`);e.updateTarget(ne.id,{status:"ready",health:te.evidence,lastHealthyAt:new Date().toISOString()})}for(let ne of e.channels(C.id)){n(a,f,`replicate:${ne.kind}:${ne.targetRegion}`),e.updateChannel(ne.id,{status:"configuring"});let he=Y.find((Xe)=>Xe.region===ne.sourceRegion),te=await r(he).configureReplication({channel:ne,topology:C}),Pe=await r(he).verifyReplication({channel:e.updateChannel(ne.id,{checkpoint:te.checkpoint,lagSeconds:te.lagSeconds}),topology:C});if(!Pe.healthy||Pe.lagSeconds>C.dataPolicy.maxLagSeconds)throw Error(`${ne.kind} replication to ${ne.targetRegion} exceeds the RPO.`);e.updateChannel(ne.id,{status:"in_sync",checkpoint:Pe.checkpoint,lagSeconds:Pe.lagSeconds,lastVerifiedAt:new Date().toISOString()})}n(a,f,"traffic:activate");let ee=Object.fromEntries(C.regions.map((ne)=>[ne.region,ne.region===C.activeRegion?100:0]));return await i(C,ee),e.updateTopology(C.id,{status:"ready",revision:D}),{revision:D,activeRegion:C.activeRegion}},s=async(a,f,C)=>{let k=f.requestedRegion,D=e.targets(C.id).find((ee)=>ee.region===k);if(!D)throw Error("Requested regional target was not found.");e.updateTopology(C.id,{status:f.kind==="failover"?"failing_over":"failing_back"}),n(a,f,`health:${k}`);let W=await r(D).health({target:D});if(!W.healthy)throw Error(`Target region ${k} is unhealthy.`);e.updateTarget(D.id,{status:"ready",health:W.evidence,lastHealthyAt:new Date().toISOString()}),n(a,f,`replication:${k}`);for(let ee of e.channels(C.id).filter((ne)=>ne.targetRegion===k)){let ne=await r(D).verifyReplication({channel:ee,topology:C});if(!ne.healthy||ne.lagSeconds>C.dataPolicy.maxLagSeconds)throw Error(`${ee.kind} replication is outside the failover RPO.`);e.updateChannel(ee.id,{status:"in_sync",checkpoint:ne.checkpoint,lagSeconds:ne.lagSeconds,lastVerifiedAt:new Date().toISOString()})}n(a,f,`traffic:${k}`),await i(C,Object.fromEntries(C.regions.map((ee)=>[ee.region,ee.region===k?100:0]))),n(a,f,`roles:${k}`);let Y=C.regions.map((ee)=>({...ee,role:ee.region===k?"primary":"secondary"}));for(let ee of e.targets(C.id))e.updateTarget(ee.id,{role:ee.region===k?"primary":"secondary"});return e.updateTopology(C.id,{status:f.kind==="failover"?"failed_over":"ready",activeRegion:k,regions:Y}),{activeRegion:k}},c=async(a,f,C,k)=>{e.updateTopology(C.id,{status:"destroying"}),n(a,f,"traffic:drain"),await i(C,Object.fromEntries(C.regions.map((W)=>[W.region,0])));let D=k.deleteData!==!0;for(let W of e.targets(C.id).sort((Y,ee)=>Number(Y.role==="primary")-Number(ee.role==="primary")))n(a,f,`delete:${W.region}`),e.updateTarget(W.id,{status:"deleting"}),await r(W).deleteStack({target:W,retainData:D,signal:a.signal}),e.updateTarget(W.id,{status:"deleted"});return n(a,f,"complete"),e.updateTopology(C.id,{status:"destroyed"}),{destroyed:!0,dataRetained:D}},u=async(a)=>{let f=Hw(a.operation.input),C=e.execution(String(f.executionId??""));if(!C)throw Error("Regional execution was not found.");let k=e.get(C.topologyId);if(!k)throw Error("Regional topology was not found.");try{let D;if(C.kind==="rollout")D=await o(a,C,k,f);else if(C.kind==="failover"||C.kind==="failback")D=await s(a,C,k);else if(C.kind==="destroy")D=await c(a,C,k,f);else throw Error("Regional reconciliation is not configured.");return e.updateExecution(C.id,{status:"succeeded",currentStep:void 0}),{executionId:C.id,...D}}catch(D){if(e.updateExecution(C.id,{status:a.cancellationRequested()?"cancelled":"failed",error:D instanceof Error?D.message:String(D)}),e.get(k.id)?.status!=="destroyed")e.updateTopology(k.id,{status:"failed"});throw D}};return{"region.rollout":u,"region.failover":u,"region.failback":u,"region.destroy":u,"region.reconcile":u}}class qu{provider;reason;constructor(e,t="Configure a regional provider transport before executing this operation."){this.provider=e;this.reason=t}fail(){throw Error(this.reason)}async applyStack(){return this.fail()}async deleteStack(){this.fail()}async health(){return this.fail()}async configureReplication(){return this.fail()}async verifyReplication(){return this.fail()}async applyTraffic(){return this.fail()}}import{createHash as Gu,createPublicKey as Jm,verify as Ww}from"node:crypto";function wa(e){if(e===null||typeof e!=="object")return JSON.stringify(e);if(Array.isArray(e))return`[${e.map(wa).join(",")}]`;return`{${Object.keys(e).sort().map((t)=>`${JSON.stringify(t)}:${wa(e[t])}`).join(",")}}`}var Hm=(e)=>Gu("sha256").update(wa(e)).digest("hex"),Hc=(e)=>Gu("sha256").update(wa(e)).digest("hex"),Wm=(e)=>Gu("sha256").update(Jm(e).export({type:"spki",format:"der"})).digest("hex");function Km(e,t,r){try{return Ww(null,Buffer.from(wa(e)),Jm(r),Buffer.from(t,"base64"))}catch{return!1}}var qm=(e)=>e.replace(/^v/,"").split(/[.-]/).slice(0,3).map((t)=>Number(t)||0),Gm=(e,t)=>{let r=qm(e),n=qm(t);for(let i=0;i<3;i++){let o=(r[i]??0)-(n[i]??0);if(o)return o}return 0};function Qm(e,t){let r=[];if(t.schemaVersion<e.minimumSchema)r.push(`schema ${t.schemaVersion} is below ${e.minimumSchema}`);if(t.schemaVersion>e.maximumSchema)r.push(`schema ${t.schemaVersion} is above ${e.maximumSchema}`);if(e.minimumVersion&&Gm(t.currentVersion,e.minimumVersion)<0)r.push(`platform ${t.currentVersion} is below ${e.minimumVersion}`);if(Gm(e.version,t.currentVersion)<=0)r.push(`version ${e.version} is not newer than ${t.currentVersion}`);if(!e.artifacts.some((n)=>n.platform===t.platform&&n.architecture===t.architecture))r.push(`no artifact for ${t.platform}/${t.architecture}`);return{compatible:r.length===0,reasons:r}}var eo=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},Ar=(e)=>e==null?void 0:String(e),Kw=(e)=>({id:String(e.id),organizationId:String(e.organization_id),name:String(e.name),algorithm:"ed25519",publicKeyPem:String(e.public_key_pem),fingerprint:String(e.fingerprint),revokedAt:Ar(e.revoked_at),createdAt:String(e.created_at)}),Ym=(e)=>({id:String(e.id),organizationId:String(e.organization_id),version:String(e.version),channel:String(e.channel),publishedAt:String(e.published_at),keyId:String(e.key_id),digest:String(e.digest),document:eo(e.document,{}),signature:String(e.signature),verificationStatus:String(e.verification_status),compatibility:eo(e.compatibility,{compatible:!1,reasons:[]}),createdAt:String(e.created_at)}),Xm=(e)=>({id:String(e.id),projectId:String(e.project_id),name:String(e.name),schedule:String(e.schedule),timezone:String(e.timezone),durationMinutes:Number(e.duration_minutes),allowedOperations:eo(e.allowed_operations,[]),requireApproval:Number(e.require_approval)===1,enabled:Number(e.enabled)===1,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Zm=(e)=>({id:String(e.id),projectId:String(e.project_id),manifestId:String(e.manifest_id),windowId:Ar(e.window_id),fromVersion:String(e.from_version),strategy:String(e.strategy),batchSize:Number(e.batch_size),healthGate:eo(e.health_gate,{}),status:String(e.status),currentStage:Ar(e.current_stage),backupId:Ar(e.backup_id),approvedBy:Ar(e.approved_by),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),Ju=(e)=>({id:String(e.id),campaignId:String(e.campaign_id),serverId:Ar(e.server_id),target:String(e.target),cohort:Number(e.cohort),previousVersion:String(e.previous_version),status:String(e.status),evidence:eo(e.evidence,{}),error:Ar(e.error),startedAt:Ar(e.started_at),finishedAt:Ar(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),ef=(e)=>({id:String(e.id),projectId:String(e.project_id),kind:String(e.kind),criteria:eo(e.criteria,{}),candidates:eo(e.candidates,[]),candidateDigest:String(e.candidate_digest),estimatedBytes:Number(e.estimated_bytes),status:String(e.status),confirmation:Ar(e.confirmation),expiresAt:String(e.expires_at),result:eo(e.result,{}),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}),tf=(e)=>({id:String(e.id),projectId:String(e.project_id),backupPolicyId:Ar(e.backup_policy_id),recoveryPointId:Ar(e.recovery_point_id),topologyId:Ar(e.topology_id),scenario:String(e.scenario),isolatedTarget:String(e.isolated_target),expectedRpoMinutes:Number(e.expected_rpo_minutes),expectedRtoMinutes:Number(e.expected_rto_minutes),status:String(e.status),operationId:Ar(e.operation_id),evidence:eo(e.evidence,{}),measuredRpoMinutes:e.measured_rpo_minutes==null?void 0:Number(e.measured_rpo_minutes),measuredRtoMinutes:e.measured_rto_minutes==null?void 0:Number(e.measured_rto_minutes),cleanupVerified:Number(e.cleanup_verified)===1,error:Ar(e.error),startedAt:Ar(e.started_at),finishedAt:Ar(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)});class jn{control;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.control=e;this.now=t;this.id=r}addTrustedKey(e){let t=this.id(),r=this.now().toISOString(),n=Wm(e.publicKeyPem);return this.control.database.run("INSERT INTO platform_trusted_keys (id,organization_id,name,algorithm,public_key_pem,fingerprint,created_at) VALUES (?,?,?,'ed25519',?,?,?)",[t,e.organizationId,e.name,e.publicKeyPem,n,r]),this.key(t)}key(e){let t=this.control.database.query("SELECT * FROM platform_trusted_keys WHERE id=?").get(e);return t?Kw(t):void 0}revokeKey(e){return this.control.database.run("UPDATE platform_trusted_keys SET revoked_at=? WHERE id=?",[this.now().toISOString(),e]),this.key(e)}importManifest(e){let t=this.key(e.keyId);if(!t||t.organizationId!==e.organizationId)throw Error("Trusted update key was not found.");if(t.revokedAt)throw Error("Update signing key is revoked.");if(!Km(e.document,e.signature,t.publicKeyPem))throw Error("Update manifest signature is invalid.");let r=Qm(e.document,e.current),n=Hm(e.document),i=this.id(),o=this.now().toISOString();return this.control.database.run("INSERT INTO platform_update_manifests (id,organization_id,version,channel,published_at,key_id,digest,document,signature,verification_status,compatibility,created_at) VALUES (?,?,?,?,?,?,?,?,?,'verified',?,?)",[i,e.organizationId,e.document.version,e.document.channel,new Date(e.document.publishedAt).toISOString(),e.keyId,n,JSON.stringify(e.document),e.signature,JSON.stringify(r),o]),this.manifest(i)}manifest(e){let t=this.control.database.query("SELECT * FROM platform_update_manifests WHERE id=?").get(e);return t?Ym(t):void 0}manifests(e){return this.control.database.query("SELECT * FROM platform_update_manifests WHERE organization_id=? ORDER BY published_at DESC").all(e).map(Ym)}createWindow(e){let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO maintenance_windows (id,project_id,name,schedule,timezone,duration_minutes,allowed_operations,require_approval,enabled,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,1,?,?)",[t,e.projectId,e.name,e.schedule,e.timezone,e.durationMinutes,JSON.stringify(e.allowedOperations),e.requireApproval===!1?0:1,r,r]),this.window(t)}window(e){let t=this.control.database.query("SELECT * FROM maintenance_windows WHERE id=?").get(e);return t?Xm(t):void 0}windows(e){return this.control.database.query("SELECT * FROM maintenance_windows WHERE project_id=? ORDER BY name").all(e).map(Xm)}createCampaign(e){return this.control.transaction(()=>{let t=this.manifest(e.manifestId);if(!t?.compatibility.compatible||t.verificationStatus!=="verified")throw Error("A verified compatible update manifest is required.");if(!e.backupId)throw Error("A verified pre-upgrade backup is required.");let r=this.id(),n=this.now().toISOString();return this.control.database.run("INSERT INTO platform_upgrade_campaigns (id,project_id,manifest_id,window_id,from_version,strategy,batch_size,health_gate,status,backup_id,approved_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'planned',?,?,?,?)",[r,e.projectId,e.manifestId,e.windowId??null,e.fromVersion,e.strategy,e.batchSize,JSON.stringify(e.healthGate),e.backupId,e.approvedBy??null,n,n]),e.targets.forEach((i,o)=>this.control.database.run("INSERT INTO platform_upgrade_targets (id,campaign_id,server_id,target,cohort,previous_version,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,i.serverId??null,i.target,e.strategy==="canary"?o===0?0:1+Math.floor((o-1)/e.batchSize):Math.floor(o/e.batchSize),i.previousVersion,n,n])),this.campaign(r)})}campaign(e){let t=this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE id=?").get(e);return t?Zm(t):void 0}campaigns(e){return this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE project_id=? ORDER BY created_at DESC").all(e).map(Zm)}targets(e){return this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE campaign_id=? ORDER BY cohort,target").all(e).map(Ju)}updateCampaign(e,t){let r=this.campaign(e);if(!r)throw Error("Upgrade campaign was not found.");let n={...r,...t};return this.control.database.run("UPDATE platform_upgrade_campaigns SET status=?,current_stage=?,updated_at=? WHERE id=?",[n.status,n.currentStage??null,this.now().toISOString(),e]),this.campaign(e)}updateTarget(e,t){let r=this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(e);if(!r)throw Error("Upgrade target was not found.");let n={...Ju(r),...t};return this.control.database.run("UPDATE platform_upgrade_targets SET status=?,evidence=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[n.status,JSON.stringify(n.evidence),n.error??null,n.startedAt??null,n.finishedAt??null,this.now().toISOString(),e]),Ju(this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(e))}createCleanup(e){let t=[...e.candidates].sort((s,c)=>s.id.localeCompare(c.id)),r=Hc(t),n=this.id(),i=this.now().toISOString(),o=new Date(this.now().getTime()+(e.ttlMinutes??60)*60000).toISOString();return this.control.database.run("INSERT INTO cleanup_plans (id,project_id,kind,criteria,candidates,candidate_digest,estimated_bytes,status,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'preview',?,?,?)",[n,e.projectId,e.kind,JSON.stringify(e.criteria),JSON.stringify(t),r,t.reduce((s,c)=>s+c.bytes,0),o,i,i]),this.cleanup(n)}cleanup(e){let t=this.control.database.query("SELECT * FROM cleanup_plans WHERE id=?").get(e);return t?ef(t):void 0}cleanups(e){return this.control.database.query("SELECT * FROM cleanup_plans WHERE project_id=? ORDER BY created_at DESC").all(e).map(ef)}updateCleanup(e,t){let r=this.cleanup(e);if(!r)throw Error("Cleanup plan was not found.");let n={...r,...t};return this.control.database.run("UPDATE cleanup_plans SET status=?,confirmation=?,result=?,updated_at=? WHERE id=?",[n.status,n.confirmation??null,JSON.stringify(n.result),this.now().toISOString(),e]),this.cleanup(e)}createDrill(e){if(!/^isolated:\/\//.test(e.isolatedTarget))throw Error("DR drills require an isolated target.");let t=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO disaster_recovery_drills (id,project_id,backup_policy_id,recovery_point_id,topology_id,scenario,isolated_target,expected_rpo_minutes,expected_rto_minutes,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'planned',?,?)",[t,e.projectId,e.backupPolicyId??null,e.recoveryPointId??null,e.topologyId??null,e.scenario,e.isolatedTarget,e.expectedRpoMinutes,e.expectedRtoMinutes,r,r]),this.drill(t)}drill(e){let t=this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE id=?").get(e);return t?tf(t):void 0}drills(e){return this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE project_id=? ORDER BY created_at DESC").all(e).map(tf)}updateDrill(e,t){let r=this.drill(e);if(!r)throw Error("DR drill was not found.");let n={...r,...t};return this.control.database.run("UPDATE disaster_recovery_drills SET status=?,operation_id=?,evidence=?,measured_rpo_minutes=?,measured_rto_minutes=?,cleanup_verified=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[n.status,n.operationId??null,JSON.stringify(n.evidence),n.measuredRpoMinutes??null,n.measuredRtoMinutes??null,n.cleanupVerified?1:0,n.error??null,n.startedAt??null,n.finishedAt??null,this.now().toISOString(),e]),this.drill(e)}}function Qw(e,t=new Date){if(!e.enabled)return!1;let r=new Date(e.schedule);if(!Number.isNaN(r.getTime()))return t>=r&&t.getTime()<=r.getTime()+e.durationMinutes*60000;let n=/^(\d{2}):(\d{2})$/.exec(e.schedule);if(!n)return!1;let i=new Intl.DateTimeFormat("en-US",{timeZone:e.timezone,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).formatToParts(t),o=Number(i.find((c)=>c.type==="hour")?.value)*60+Number(i.find((c)=>c.type==="minute")?.value),s=Number(n[1])*60+Number(n[2]);return o>=s&&o<s+e.durationMinutes}class Vn{store;now;queue;constructor(e,t,r=()=>new Date){this.store=e;this.now=r;this.queue=t??new S(e.control)}enqueueCampaign(e,t={}){let r=this.store.campaign(e);if(!r)throw Error("Upgrade campaign was not found.");let n=r.windowId?this.store.window(r.windowId):void 0;if(n&&!n.allowedOperations.includes("platform.upgrade"))throw Error("Maintenance window does not permit platform upgrades.");if(n&&!t.overrideWindow&&!Qw(n,this.now()))throw Error("Upgrade is outside its maintenance window.");if(n?.requireApproval&&!t.approvedBy&&!r.approvedBy)throw Error("Maintenance approval is required.");let i=this.queue.enqueue({projectId:r.projectId,actorId:t.approvedBy,kind:"maintenance.upgrade",input:{campaignId:e},lockKey:"platform-upgrade",providerKey:"platform",timeoutSeconds:7200,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return{campaign:this.store.updateCampaign(e,{status:"queued"}),operation:i}}async previewCleanup(e,t){let r=t.find((n)=>n.kind===e.kind);if(!r)throw Error(`No ${e.kind} cleanup driver is configured.`);return this.store.createCleanup({...e,candidates:await r.discover(e.criteria)})}enqueueCleanup(e,t){let r=this.store.cleanup(e);if(!r||r.status!=="preview")throw Error("A current cleanup preview is required.");if(new Date(r.expiresAt)<=this.now())throw Error("Cleanup preview expired; generate it again.");let n=`DELETE ${r.candidates.length} ${r.kind}`;if(t!==n)throw Error(`Exact confirmation ${n} is required.`);let i=this.queue.enqueue({projectId:r.projectId,kind:"maintenance.cleanup",input:{planId:e},lockKey:`cleanup:${r.kind}`,providerKey:"cleanup",timeoutSeconds:3600,cancellationMode:"cooperative"}).operation;return{plan:this.store.updateCleanup(e,{status:"approved",confirmation:t}),operation:i}}enqueueDrill(e){let t=this.store.drill(e);if(!t||t.status!=="planned")throw Error("A planned DR drill is required.");let r=this.queue.enqueue({projectId:t.projectId,kind:"maintenance.drill",input:{drillId:e},lockKey:`drill:${t.scenario}:${t.id}`,providerKey:"recovery",timeoutSeconds:7200,cancellationMode:"cooperative"}).operation;return{drill:this.store.updateDrill(e,{status:"queued",operationId:r.id}),operation:r}}}var Hu=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{};function rf(e){return{"maintenance.upgrade":async(i)=>{let o=e.store.campaign(String(Hu(i.operation.input).campaignId??""));if(!o||!e.platform)throw Error("Upgrade campaign or platform maintenance driver is unavailable.");let s=e.store.manifest(o.manifestId);if(!s?.compatibility.compatible||s.verificationStatus!=="verified")throw Error("Update manifest is no longer verified and compatible.");let c=s.document.artifacts.find((a)=>a.platform===process.platform&&a.architecture===process.arch)??s.document.artifacts[0];if(!c)throw Error("No update artifact matches this platform.");e.store.updateCampaign(o.id,{status:"running",currentStage:"preflight"});let u=[];try{for(let a of[...new Set(e.store.targets(o.id).map((f)=>f.cohort))].sort((f,C)=>f-C)){e.store.updateCampaign(o.id,{currentStage:`cohort:${a}`});for(let f of e.store.targets(o.id).filter((C)=>C.cohort===a)){i.throwIfCancellationRequested(),i.checkpoint(`download:${f.target}`,"Downloading signed platform artifact."),e.store.updateTarget(f.id,{status:"downloading",startedAt:new Date().toISOString()});let C=await e.platform.download({target:f,artifact:c,signal:i.signal});if(C.sha256!==c.sha256)throw Error(`Artifact checksum mismatch for ${f.target}.`);i.checkpoint(`install:${f.target}`,"Installing verified artifact."),e.store.updateTarget(f.id,{status:"installing"}),await e.platform.install({target:f,path:C.path,version:s.version,signal:i.signal}),u.push(f);let k=await e.platform.health({target:f,gate:o.healthGate});if(!k.healthy)throw Error(`Upgrade health gate failed for ${f.target}.`);e.store.updateTarget(f.id,{status:"healthy",evidence:k.evidence,finishedAt:new Date().toISOString()})}}return e.store.updateCampaign(o.id,{status:"succeeded",currentStage:void 0}),{campaignId:o.id,version:s.version,targets:u.length}}catch(a){e.store.updateCampaign(o.id,{status:"rolling_back",currentStage:"rollback"});for(let f of u.reverse())e.store.updateTarget(f.id,{status:"rolling_back"}),await e.platform.rollback({target:f,version:f.previousVersion,signal:i.signal}),e.store.updateTarget(f.id,{status:"rolled_back",finishedAt:new Date().toISOString()});throw e.store.updateCampaign(o.id,{status:"rolled_back",currentStage:void 0}),a}},"maintenance.cleanup":async(i)=>{let o=e.store.cleanup(String(Hu(i.operation.input).planId??""));if(!o||o.status!=="approved")throw Error("Approved cleanup plan was not found.");if(Hc([...o.candidates].sort((f,C)=>f.id.localeCompare(C.id)))!==o.candidateDigest)throw Error("Cleanup candidate set changed after preview.");let s=e.cleanup?.find((f)=>f.kind===o.kind);if(!s)throw Error(`No ${o.kind} cleanup driver is configured.`);e.store.updateCleanup(o.id,{status:"running"});let c=[],u=[];for(let f of o.candidates){i.throwIfCancellationRequested();try{await s.remove(f),c.push(f.id)}catch(C){u.push({id:f.id,error:C instanceof Error?C.message:String(C)})}}let a=u.length?c.length?"partial":"failed":"succeeded";if(e.store.updateCleanup(o.id,{status:a,result:{removed:c,failed:u,reclaimedBytes:o.candidates.filter((f)=>c.includes(f.id)).reduce((f,C)=>f+C.bytes,0)}}),u.length)throw Error(`Cleanup failed for ${u.length} candidate(s).`);return{planId:o.id,removed:c.length,reclaimedBytes:o.estimatedBytes}},"maintenance.drill":async(i)=>{let o=e.store.drill(String(Hu(i.operation.input).drillId??""));if(!o)throw Error("DR drill was not found.");let s=e.recovery?.find((C)=>C.scenario===o.scenario);if(!s)throw Error(`No ${o.scenario} recovery driver is configured.`);let c=new Date;e.store.updateDrill(o.id,{status:"restoring",startedAt:c.toISOString()});let u=o.isolatedTarget,a={},f={};try{i.checkpoint("restore","Restoring into isolated drill target.");let C=await s.restore({drill:o,signal:i.signal});if(!C.target.startsWith("isolated://"))throw Error("Recovery driver attempted a non-isolated target.");u=C.target,a=C.evidence;let k=(c.getTime()-new Date(C.recoveryPointAt).getTime())/60000;e.store.updateDrill(o.id,{status:"verifying",measuredRpoMinutes:k,evidence:{restore:a}}),i.checkpoint("verify","Running recovery health checks without production traffic.");let D=await s.verify({drill:o,target:u});f=D.evidence;let W=(Date.now()-c.getTime())/60000;if(!D.healthy||k>o.expectedRpoMinutes||W>o.expectedRtoMinutes)throw Error("DR drill failed its health, RPO, or RTO objective.");e.store.updateDrill(o.id,{measuredRpoMinutes:k,measuredRtoMinutes:W,evidence:{restore:a,verify:f}})}catch(C){throw e.store.updateDrill(o.id,{status:"failed",error:C instanceof Error?C.message:String(C),evidence:{restore:a,verify:f}}),C}finally{e.store.updateDrill(o.id,{status:"cleaning"});try{await s.cleanup({drill:o,target:u});let C=e.store.drill(o.id);e.store.updateDrill(o.id,{status:C.error?"failed":"passed",cleanupVerified:!0,finishedAt:new Date().toISOString()})}catch(C){e.store.updateDrill(o.id,{status:"cleanup_required",cleanupVerified:!1,error:C instanceof Error?C.message:String(C),finishedAt:new Date().toISOString()})}}return{drillId:o.id,status:e.store.drill(o.id).status}}}}var nf={releases:{select:"SELECT id,created_at,0 bytes FROM releases WHERE project_id=? AND pinned=0 AND status IN ('failed','rolled_back','superseded') AND created_at<?",remove:"DELETE FROM releases WHERE id=?"},artifacts:{select:"SELECT a.id,a.created_at,a.size bytes FROM release_artifacts a WHERE a.organization_id=? AND NOT EXISTS(SELECT 1 FROM releases r WHERE r.artifact_id=a.id) AND a.created_at<?",remove:"DELETE FROM release_artifacts WHERE id=?"},operations:{select:"SELECT id,created_at,0 bytes FROM operations WHERE project_id=? AND state IN ('succeeded','failed','cancelled','timed_out') AND updated_at<?",remove:"DELETE FROM operations WHERE id=?"},logs:{select:"SELECT l.id,l.created_at,length(l.message) bytes FROM operation_logs l JOIN operations o ON o.id=l.operation_id WHERE o.project_id=? AND o.state IN ('succeeded','failed','cancelled','timed_out') AND l.created_at<?",remove:"DELETE FROM operation_logs WHERE id=?"},previews:{select:"SELECT id,created_at,0 bytes FROM preview_instances WHERE project_id=? AND status IN ('destroyed','failed') AND updated_at<?",remove:"DELETE FROM preview_instances WHERE id=?"},snapshots:{select:"SELECT id,created_at,size_bytes bytes FROM recovery_points WHERE project_id=? AND pinned=0 AND held=0 AND status IN ('failed','deleted') AND created_at<?",remove:"DELETE FROM recovery_points WHERE id=?"},orphaned_resources:{select:"SELECT id,created_at,COALESCE(capacity_bytes,0) bytes FROM persistent_volumes WHERE project_id=? AND status='orphaned' AND orphaned_at<?",remove:"UPDATE persistent_volumes SET status='deleted',deleted_at=datetime('now'),updated_at=datetime('now') WHERE id=? AND status='orphaned'"}};class zn{kind;control;projectId;organizationId;constructor(e,t,r,n){this.kind=e;this.control=t;this.projectId=r;this.organizationId=n}async discover(e){let t=Math.max(1,Math.min(3650,Number(e.olderThanDays??30))),r=new Date(Date.now()-t*86400000).toISOString(),n=nf[this.kind],i=this.kind==="artifacts"?this.organizationId:this.projectId;return this.control.database.query(n.select).all(i,r).map((s)=>({id:String(s.id),kind:this.kind,label:`${this.kind}:${String(s.id)}`,bytes:Number(s.bytes??0),metadata:{createdAt:String(s.created_at)}}))}async remove(e){if(this.control.database.run(nf[this.kind].remove,[e.id]).changes!==1)throw Error(`${e.label} changed or is no longer removable.`)}}var Yw=new qt({ignoreAttributes:!0,parseTagValue:!1,trimValues:!0});function sf(e){if(e===void 0||e===null||e==="")return;let t=Number(e);return Number.isFinite(t)?t:void 0}function af(e){if(!e?.Address)return;return{Address:String(e.Address),Port:sf(e.Port)??0}}function of(e){return{CacheClusterId:String(e?.CacheClusterId??""),CacheClusterStatus:String(e?.CacheClusterStatus??""),Engine:String(e?.Engine??""),EngineVersion:String(e?.EngineVersion??""),CacheNodeType:String(e?.CacheNodeType??""),NumCacheNodes:sf(e?.NumCacheNodes)??0,PreferredAvailabilityZone:e?.PreferredAvailabilityZone||void 0,CacheClusterCreateTime:String(e?.CacheClusterCreateTime??""),CacheNodes:N(e?.CacheNodes?.CacheNode).map((t)=>({CacheNodeId:String(t.CacheNodeId??""),CacheNodeStatus:String(t.CacheNodeStatus??""),Endpoint:af(t.Endpoint)}))}}function Xw(e){return{ReplicationGroupId:String(e?.ReplicationGroupId??""),Status:String(e?.Status??""),Description:e?.Description||void 0,MemberClusters:N(e?.MemberClusters?.ClusterId).map(String),NodeGroups:N(e?.NodeGroups?.NodeGroup).map((t)=>({NodeGroupId:String(t.NodeGroupId??""),Status:String(t.Status??""),PrimaryEndpoint:af(t.PrimaryEndpoint)}))}}class oe{client;region;profile;constructor(e="us-east-1",t){this.region=e,this.profile=t,this.client=new p(void 0,{profile:t})}async query(e){let t=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString(),rawResponse:!0});if(typeof t!=="string"||!t.trim())return;return O(Yw.parse(t),e.Action)}async describeCacheClusters(e){let t={Action:"DescribeCacheClusters",Version:"2015-02-02",ShowCacheNodeInfo:"true"};if(e)t.CacheClusterId=e;let r=await this.query(t);return{CacheClusters:N(r?.CacheClusters?.CacheCluster).map(of)}}async describeReplicationGroups(e){let t={Action:"DescribeReplicationGroups",Version:"2015-02-02"};if(e)t.ReplicationGroupId=e;let r=await this.query(t);return{ReplicationGroups:N(r?.ReplicationGroups?.ReplicationGroup).map(Xw)}}async createCacheCluster(e){let t={Action:"CreateCacheCluster",Version:"2015-02-02",CacheClusterId:e.cacheClusterId,Engine:e.engine,CacheNodeType:e.cacheNodeType};if(e.numCacheNodes)t.NumCacheNodes=e.numCacheNodes;if(e.engineVersion)t.EngineVersion=e.engineVersion;if(e.port)t.Port=e.port;if(e.securityGroupIds&&e.securityGroupIds.length>0)e.securityGroupIds.forEach((n,i)=>{t[`SecurityGroupIds.member.${i+1}`]=n});if(e.subnetGroupName)t.CacheSubnetGroupName=e.subnetGroupName;if(e.tags&&e.tags.length>0)e.tags.forEach((n,i)=>{t[`Tags.member.${i+1}.Key`]=n.Key,t[`Tags.member.${i+1}.Value`]=n.Value});let r=await this.query(t);return{CacheCluster:of(r?.CacheCluster)}}async deleteCacheCluster(e,t){let r={Action:"DeleteCacheCluster",Version:"2015-02-02",CacheClusterId:e};if(t)r.FinalSnapshotIdentifier=t;await this.query(r)}async rebootCacheCluster(e,t){let r={Action:"RebootCacheCluster",Version:"2015-02-02",CacheClusterId:e};t.forEach((n,i)=>{r[`CacheNodeIdsToReboot.member.${i+1}`]=n}),await this.query(r)}async describeCacheEngineVersions(e){let t={Action:"DescribeCacheEngineVersions",Version:"2015-02-02"};if(e)t.Engine=e;let r=[],n;do{let i=await this.query(n?{...t,Marker:n}:t);for(let o of N(i?.CacheEngineVersions?.CacheEngineVersion))r.push({Engine:String(o.Engine??""),EngineVersion:String(o.EngineVersion??""),CacheParameterGroupFamily:String(o.CacheParameterGroupFamily??"")});n=i?.Marker||void 0}while(n);return{CacheEngineVersions:r}}async getCacheStatistics(e){let r=(await this.describeCacheClusters(e)).CacheClusters[0];if(!r)throw Error(`Cache cluster ${e} not found`);let n=r.Engine==="memcached",i=new q(this.region,this.profile),o=new Date,s=new Date(o.getTime()-600000),c=async(D,W)=>[...await i.getMetricStatistics({Namespace:"AWS/ElastiCache",MetricName:D,Dimensions:[{Name:"CacheClusterId",Value:e}],StartTime:s,EndTime:o,Period:300,Statistics:[W]})].sort((ne,he)=>new Date(he.Timestamp??0).getTime()-new Date(ne.Timestamp??0).getTime())[0]?.[W],[u,a,f,C,k]=await Promise.all([c("CPUUtilization","Average"),c("Evictions","Sum"),c(n?"GetHits":"CacheHits","Sum"),c(n?"GetMisses":"CacheMisses","Sum"),c("CurrConnections","Average")]);return{cpuUtilization:u,evictions:a,hits:f,misses:C,connections:k}}}var Br=(e,t="none",r=!1)=>({supported:!0,downtime:t,destructive:r,explanation:e}),kr=(e)=>({supported:!1,downtime:"none",destructive:!1,explanation:e});function rr(e,t){let r=["aws_rds","aws_aurora","aws_elasticache"].includes(t),n=["server","container"].includes(t),i=["postgres","mysql","mariadb"].includes(e),o=e==="redis",s={};return s.create=t==="external"?kr("External services can be adopted as read-only inventory."):Br(r?"Provision through the provider API.":"Provision through the owning runtime driver.","possible"),s.observe=t==="external"?kr("External observation requires a configured provider adapter."):Br("Provider/runtime health and endpoint metadata are observable."),s.connect=Br("Connection guidance uses secret references and never returns a password by default."),s.backup=i&&(r||n)?Br(r?"Create a provider snapshot.":"Create a consistent engine-native dump.","possible"):kr("This cache path is not a durable backup source."),s.restore=r&&i?Br("Restore creates a reviewed provider target.","required",!0):kr("Restore requires a configured provider restore runner."),s.restart=t==="external"?kr("External restart requires a configured provider adapter."):Br(r?"Provider restart/failover semantics apply.":"Restart the owning service unit.","required"),s.resize=t==="aws_elasticache"?kr("ElastiCache resizing requires a replication-group migration runner."):r?Br("Provider plan/storage modification may enter a maintenance window.","possible"):n?Br("Edit host/container resources and reconcile.","required"):kr("External resize requires a configured provider adapter."),s.version=n?kr("Runtime version upgrades require an explicit image migration runner."):r&&t!=="aws_elasticache"?Br(i?"Major versions require compatibility preflight and backup.":"Engine upgrades require a maintenance window.","required"):kr("External upgrades require a configured provider adapter."),s.rotate=t==="aws_elasticache"||t==="external"||n&&!i&&!o?kr("Credential rotation is not available for this provider/engine path."):Br("Rotate through the secret backend, update the engine, then flag dependent releases."),s.expose=n?kr("Direct container publishing is refused; use a reviewed firewall and proxy policy."):t==="aws_rds"?Br("Exposure is reconciled through security groups; public access defaults off."):kr("Exposure changes require a provider-specific network runner."),s.delete=t==="external"?kr("External deletion requires a configured provider adapter."):Br(r?"Final snapshot is supported where the provider allows it.":"A final engine backup is required unless explicitly retained.","required",!0),s.logs=n?Br("Read bounded service logs from the runtime."):kr("Provider log export is not configured for this adapter."),s.slow_queries=n&&i?Br("Read bounded runtime logs after engine slow-query logging is enabled."):kr("A slow-query log runner is not configured for this provider."),s.users=n&&i?Br("Logical users can be listed; creation requires a referenced secondary credential."):kr("User management requires an engine connection runner."),s.databases=n&&i?Br("Logical databases can be listed, created, and confirmation-gated for deletion."):kr("Logical database management requires an engine connection runner."),{actions:s,endpointTypes:r?["internal","external","tunnel"]:["internal","tunnel"],metrics:o?["connections","memory","evictions","hit_rate","latency"]:["connections","cpu","storage","read_latency","write_latency","iops"]}}var js=(e)=>e==null?void 0:String(e),Kc=(e)=>Number(e)===1,Wc=(e)=>{try{return JSON.parse(String(e))}catch{return{}}};function cf(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:js(e.environment_id),resourceId:js(e.resource_id),name:String(e.name),engine:String(e.engine),provider:String(e.provider),placement:String(e.placement),engineVersion:js(e.engine_version),plan:String(e.plan),storageGb:e.storage_gb==null?void 0:Number(e.storage_gb),highAvailability:Kc(e.high_availability),publicExposure:Kc(e.public_exposure),allowedCidrs:Wc(e.allowed_cidrs),desiredState:Wc(e.desired_state),observedState:Wc(e.observed_state),capabilities:Wc(e.capabilities),credentialRef:js(e.credential_ref),status:String(e.status),origin:String(e.origin),managementEnabled:Kc(e.management_enabled),ownerActorId:js(e.owner_actor_id),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class nr{controlPlane;now;constructor(e,t=()=>new Date){this.controlPlane=e;this.now=t}create(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Data service names must be 2-63 lowercase letters, numbers, or dashes.");if(e.publicExposure&&(!e.allowedCidrs.length||e.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");let t=crypto.randomUUID(),r=this.now().toISOString(),n=rr(e.engine,e.provider);return this.controlPlane.database.run("INSERT INTO data_services (id,organization_id,project_id,environment_id,resource_id,name,engine,provider,placement,engine_version,plan,storage_gb,high_availability,public_exposure,allowed_cidrs,desired_state,observed_state,capabilities,credential_ref,status,origin,management_enabled,owner_actor_id,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name,e.engine,e.provider,e.placement,e.engineVersion??null,e.plan,e.storageGb??null,e.highAvailability?1:0,e.publicExposure?1:0,JSON.stringify(e.allowedCidrs),JSON.stringify(e.desiredState),JSON.stringify(e.observedState),JSON.stringify(n),e.credentialRef??null,e.status,e.origin,e.managementEnabled?1:0,e.ownerActorId??null,1,r,r]),this.get(t)}get(e){let t=this.controlPlane.database.query("SELECT * FROM data_services WHERE id=?").get(e);return t?cf(t):void 0}list(e,t){return this.controlPlane.database.query(`SELECT * FROM data_services WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(cf)}update(e,t,r){let n=this.get(e);if(!n)throw Error("Data service was not found.");if(n.version!==t)throw Error("Data service changed; refresh before retrying.");let i={...n,...r};if(i.publicExposure&&(!i.allowedCidrs.length||i.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");if(this.controlPlane.database.run("UPDATE data_services SET plan=?,storage_gb=?,engine_version=?,high_availability=?,public_exposure=?,allowed_cidrs=?,desired_state=?,observed_state=?,status=?,management_enabled=?,credential_ref=?,version=version+1,updated_at=? WHERE id=? AND version=?",[i.plan,i.storageGb??null,i.engineVersion??null,i.highAvailability?1:0,i.publicExposure?1:0,JSON.stringify(i.allowedCidrs),JSON.stringify(i.desiredState),JSON.stringify(i.observedState),i.status,i.managementEnabled?1:0,i.credentialRef??null,this.now().toISOString(),e,t]).changes!==1)throw Error("Data service changed; refresh before retrying.");return this.get(e)}credential(e){let t=this.controlPlane.database.query("SELECT * FROM data_service_credentials WHERE service_id=? ORDER BY version DESC LIMIT 1").get(e);return t?{id:String(t.id),serviceId:String(t.service_id),username:String(t.username),secretRef:String(t.secret_ref),version:Number(t.version),createdAt:String(t.created_at),rotatedAt:js(t.rotated_at)}:void 0}saveCredential(e,t,r){let n=this.credential(e),i=n?.id??crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_credentials (id,service_id,username,secret_ref,version,created_at,rotated_at) VALUES (?,?,?,?,?,?,?) ON CONFLICT(service_id,username) DO UPDATE SET secret_ref=excluded.secret_ref,version=data_service_credentials.version+1,rotated_at=excluded.rotated_at",[i,e,t,r,n?.version??1,n?.createdAt??o,n?o:null]),this.credential(e)}addDependency(e){let t=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_dependencies (service_id,resource_id,secret_ref,requires_redeploy,created_at) VALUES (?,?,?,?,?) ON CONFLICT(service_id,resource_id) DO UPDATE SET secret_ref=excluded.secret_ref,requires_redeploy=excluded.requires_redeploy",[e.serviceId,e.resourceId,e.secretRef,e.requiresRedeploy?1:0,t]),{...e,createdAt:t}}dependencies(e){return this.controlPlane.database.query("SELECT * FROM data_service_dependencies WHERE service_id=? ORDER BY resource_id").all(e).map((t)=>({serviceId:String(t.service_id),resourceId:String(t.resource_id),secretRef:String(t.secret_ref),requiresRedeploy:Kc(t.requires_redeploy),createdAt:String(t.created_at)}))}removeDependency(e,t){return this.controlPlane.database.run("DELETE FROM data_service_dependencies WHERE service_id=? AND resource_id=?",[e,t]).changes===1}remove(e){this.controlPlane.database.run("DELETE FROM data_services WHERE id=?",[e])}}function df(){let t=crypto.getRandomValues(new Uint8Array(40));return Array.from(t,(r)=>"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*_-+="[r%69]).join("")}function Hn(e,t){return t.map((r)=>{let n=r.type==="tunnel"?"127.0.0.1":r.host,i=e.engine==="redis"?`redis-cli -h ${n} -p ${r.port}${r.tls?" --tls":""}`:e.engine==="postgres"?`psql "host=${n} port=${r.port} dbname=${r.database??"postgres"} sslmode=${r.tls?"require":"disable"}"`:e.engine==="mongodb"?`mongosh "mongodb://${n}:${r.port}/${r.database??"admin"}${r.tls?"?tls=true":""}"`:e.engine==="libsql"?`turso db shell ${r.tls?"https":"http"}://${n}:${r.port}`:`mysql --host=${n} --port=${r.port} --database=${r.database??"mysql"} --ssl-mode=${r.tls?"REQUIRED":"DISABLED"}`;return{type:r.type,command:i,secretRef:e.credentialRef}})}class Gr{store;queue;secrets;constructor(e,t,r){this.store=e;this.queue=t;this.secrets=r}async create(e){let t,r;if(e.provider!=="aws_elasticache"){let n=e.username??"app",i=df();r=`secret://data-services/${e.projectId}/${e.name}/${n}`,await this.secrets.put(r,i),t={username:n,password:i,secretRef:r}}try{let n=this.store.create({...e,credentialRef:r,status:"planning"});if(t)this.store.saveCredential(n.id,t.username,t.secretRef);let i=this.enqueue(n,"create",{});return{service:n,credential:t,operationId:i}}catch(n){if(r)await this.secrets.remove(r);throw n}}plan(e,t,r={}){let n=e.capabilities.actions[t],i=t==="version"&&String(r.engineVersion??"").split(".")[0]!==String(e.engineVersion??"").split(".")[0];return{service:e,action:t,capability:n,changes:r,preflight:{backupRequired:["delete","restore"].includes(t)||i,compatibilityRequired:i,typedConfirmation:n.destructive?e.name:void 0,retentionChoiceRequired:t==="delete"},warnings:[...n.downtime!=="none"?[`Downtime is ${n.downtime}.`]:[],...e.origin==="adopted"&&!e.managementEnabled?["Adopted resource is read-only until management is explicitly enabled."]:[]]}}enqueue(e,t,r,n){let i=this.plan(e,t,r);if(!i.capability.supported)throw Error(i.capability.explanation);if(e.origin==="adopted"&&!e.managementEnabled&&t!=="observe")throw Error("Adopted resources remain read-only until management is explicitly enabled.");if(i.preflight.typedConfirmation&&r.confirm!==i.preflight.typedConfirmation)throw Error(`Type ${i.preflight.typedConfirmation} to confirm ${t}.`);if(i.preflight.retentionChoiceRequired&&!["final_backup","retain"].includes(String(r.retention??"")))throw Error("Deletion requires retention final_backup or retain.");if(i.preflight.compatibilityRequired&&(r.compatibilityReviewed!==!0||!r.backupId))throw Error("Major version changes require compatibilityReviewed=true and a backupId.");if(t==="restore"){let o=String(r.backupId??""),s=String(r.targetId??"");if(!o||!s)throw Error("Restore requires both backupId and targetId.");if(s===e.placement)throw Error("Restore targetId must differ from the source placement.");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(s))throw Error("Restore targetId must be 2-63 lowercase letters, numbers, or dashes.")}return this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:n,kind:"data_service.action",input:{serviceId:e.id,action:t,...r},lockKey:`data-service:${e.id}`,providerKey:e.provider,maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"}).operation.id}async rotate(e,t,r){let n=this.store.credential(e.id);if(!n)throw Error("Data service credential metadata was not found.");let i=df(),o=`${n.secretRef}/v${n.version+1}`;await this.secrets.put(o,i);try{return await t.action(e,"rotate",{username:n.username,secretRef:o},i,r),this.store.saveCredential(e.id,n.username,o),this.store.update(e.id,e.version,{credentialRef:o}),{credential:{username:n.username,password:i,secretRef:o},dependencies:this.store.dependencies(e.id).filter((s)=>s.requiresRedeploy).map((s)=>s.resourceId)}}catch(s){throw await this.secrets.remove(o),s}}}function uf(e){return{"data_service.action":async(t)=>{let r=t.operation.input,n=e.store.get(String(r.serviceId??"")),i=String(r.action??"");if(!n)throw Error("Data service was not found.");let o=e.resolveAdapter(n);if(!o||o.provider!==n.provider||!o.engines.includes(n.engine))throw Error(`No ${n.provider}/${n.engine} adapter is configured.`);if(i==="rotate"){let c=await new Gr(e.store,new S(e.store.controlPlane),e.secrets).rotate(n,o,t);return{serviceId:n.id,action:i,username:c.credential.username,secretRef:c.credential.secretRef,dependencies:c.dependencies}}let s=n.credentialRef?await e.secrets.resolve(n.credentialRef):void 0;try{let c=i==="observe"?await o.observe(n):i==="create"?await o.apply(n,s,t):await o.action(n,i,r,s,t),u=e.store.get(n.id);return e.store.update(n.id,u.version,{observedState:c,status:i==="delete"?r.retention==="retain"?"retained":"deleting":"available"}),{serviceId:n.id,action:i,observed:c}}catch(c){let u=e.store.get(n.id);if(e.store.update(n.id,u.version,{status:"failed",observedState:{...u.observedState,error:c instanceof Error?c.message:String(c)}}),/temporar|timeout|unavailable|throttl/i.test(c instanceof Error?c.message:String(c)))throw new Ue(c instanceof Error?c.message:String(c),"provider_transient");throw c}}}}class zs{transport;constructor(e){this.transport=e}observe(e){return this.transport.observe(e.placement)}apply(e,t){return this.transport.apply({id:e.placement,name:e.name,engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,storageGb:e.storageGb??null,highAvailability:e.highAvailability,publicExposure:e.publicExposure,allowedCidrs:e.allowedCidrs,username:e.desiredState.username??"app",desiredState:e.desiredState},t)}action(e,t,r,n,i){return this.transport.execute(e.placement,t,{engine:e.engine,engineVersion:e.engineVersion??null,plan:e.plan,desiredState:e.desiredState,...r},n,i)}}class Gn extends zs{provider="aws_rds";engines=["postgres","mysql","mariadb"]}class qn extends zs{provider="aws_aurora";engines=["postgres","mysql"]}class Wn extends zs{provider="aws_elasticache";engines=["redis"]}class Kn extends zs{provider="server";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}class Jn extends zs{provider="container";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}var Xc=(e,t)=>{let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)},jt=(e,t,r)=>{let n=Xc(e,t);return n==null?r:String(n)},pn=(e,t)=>{let r=Xc(e,t);return r==null?void 0:Number(r)},Eo=(e,t)=>{let r=Xc(e,t);return r==null?void 0:r===!0||r==="true"},Vs=(e,t)=>{let r=Xc(e,t);return Array.isArray(r)?r.map(String):[]},Yc=(e,t)=>jt(t,"snapshotId")??`${e}-final-${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}`;function Qc(e){if(!e)throw Error("RDS instance was not found.");return{providerId:e.DBInstanceIdentifier??null,status:e.DBInstanceStatus??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,plan:e.DBInstanceClass??null,storageGb:e.AllocatedStorage??null,highAvailability:e.MultiAZ??!1,publicExposure:e.PubliclyAccessible??!1,endpoint:e.Endpoint?.Address??null,port:e.Endpoint?.Port??null,username:e.MasterUsername??null,database:e.DBName??null,encrypted:e.StorageEncrypted??!1}}class Xn{client;constructor(e=new fe){this.client=e}async observe(e){return Qc(await this.client.describeDBInstance(e))}async apply(e,t){let r=String(e.id),n=await this.client.createDBInstance({DBInstanceIdentifier:r,DBInstanceClass:String(e.plan),Engine:String(e.engine),MasterUsername:jt(e,"username","app"),MasterUserPassword:t,DBName:jt(e,"database"),AllocatedStorage:pn(e,"storageGb"),VpcSecurityGroupIds:Vs(e,"securityGroupIds"),DBSubnetGroupName:jt(e,"subnetGroup"),BackupRetentionPeriod:pn(e,"backupRetentionDays")??7,MultiAZ:Eo(e,"highAvailability"),EngineVersion:jt(e,"engineVersion"),PubliclyAccessible:Eo(e,"publicExposure")??!1,StorageType:jt(e,"storageType","gp3"),StorageEncrypted:!0,KmsKeyId:jt(e,"kmsKeyId"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return Qc(n.DBInstance)}async execute(e,t,r,n,i){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBInstance({DBInstanceIdentifier:e}),{status:"rebooting"};if(t==="backup"){let o=Yc(e,r);return await this.client.createDBSnapshot({DBInstanceIdentifier:e,DBSnapshotIdentifier:o}),{status:"snapshotting",snapshotId:o}}if(t==="restore"){let o=String(r.targetId),s=await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:o,DBSnapshotIdentifier:String(r.backupId),DBInstanceClass:jt(r,"plan"),DBSubnetGroupName:jt(r,"subnetGroup"),MultiAZ:Eo(r,"highAvailability"),PubliclyAccessible:!1,StorageType:jt(r,"storageType"),VpcSecurityGroupIds:Vs(r,"securityGroupIds"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{...Qc(s.DBInstance),sourceId:e,restoreTargetId:o}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let o=Yc(e,r);return await this.client.modifyDBInstance({DBInstanceIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:e,SkipFinalSnapshot:!1,FinalDBSnapshotIdentifier:o,DeleteAutomatedBackups:!1}),{status:"deleting",finalSnapshotId:o}}if(["resize","version","rotate","expose"].includes(t)){let o=await this.client.modifyDBInstance({DBInstanceIdentifier:e,DBInstanceClass:jt(r,"plan"),AllocatedStorage:pn(r,"storageGb"),MasterUserPassword:t==="rotate"?n:void 0,EngineVersion:jt(r,"engineVersion"),MultiAZ:Eo(r,"highAvailability"),PubliclyAccessible:Eo(r,"publicExposure"),VpcSecurityGroupIds:Vs(r,"securityGroupIds"),ApplyImmediately:Eo(r,"applyImmediately")??!0});return Qc(o.DBInstance)}throw Error(`RDS action ${t} requires an engine connection runner.`)}}function Wu(e){if(!e)throw Error("Aurora cluster was not found.");return{providerId:e.DBClusterIdentifier??null,status:e.Status??"unknown",engine:e.Engine??null,engineVersion:e.EngineVersion??null,endpoint:e.Endpoint??null,readerEndpoint:e.ReaderEndpoint??null,port:e.Port??null,username:e.MasterUsername??null,database:e.DatabaseName??null,encrypted:e.StorageEncrypted??!1,highAvailability:e.MultiAZ??!0}}class Qn{client;constructor(e=new fe){this.client=e}async observe(e){let t=await this.client.describeDBClusters({DBClusterIdentifier:e});return Wu(t.DBClusters?.[0])}async apply(e,t){let r=String(e.id),n=String(e.engine)==="postgres"?"aurora-postgresql":"aurora-mysql";return await this.client.createDBCluster({DBClusterIdentifier:r,Engine:n,EngineVersion:jt(e,"engineVersion"),MasterUsername:jt(e,"username","app"),MasterUserPassword:t,DatabaseName:jt(e,"database"),DBSubnetGroupName:jt(e,"subnetGroup"),VpcSecurityGroupIds:Vs(e,"securityGroupIds"),BackupRetentionPeriod:pn(e,"backupRetentionDays")??7,StorageEncrypted:!0,KmsKeyId:jt(e,"kmsKeyId"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:pn(e,"minCapacity")??0.5,MaxCapacity:pn(e,"maxCapacity")??4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${r}-writer-1`,DBClusterIdentifier:r,DBInstanceClass:String(e.plan||"db.serverless"),Engine:n,PubliclyAccessible:Eo(e,"publicExposure")??!1}),{status:"creating",providerId:r}}async execute(e,t,r,n){if(t==="observe")return this.observe(e);if(t==="restart")return await this.client.rebootDBCluster(e),{status:"rebooting"};if(t==="backup"){let i=Yc(e,r);return await this.client.createDBClusterSnapshot(e,i),{status:"snapshotting",snapshotId:i}}if(t==="restore"){let i=String(r.targetId),o=String(r.engine)==="postgres"?"aurora-postgresql":"aurora-mysql",s=await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:i,SnapshotIdentifier:String(r.backupId),Engine:o,EngineVersion:jt(r,"engineVersion"),DBSubnetGroupName:jt(r,"subnetGroup"),VpcSecurityGroupIds:Vs(r,"securityGroupIds"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:pn(r,"minCapacity")??0.5,MaxCapacity:pn(r,"maxCapacity")??4}});return await this.client.createDBInstance({DBInstanceIdentifier:`${i}-writer-1`,DBClusterIdentifier:i,DBInstanceClass:jt(r,"plan","db.serverless"),Engine:o,PubliclyAccessible:!1}),{...Wu(s.DBCluster),sourceId:e,restoreTargetId:i}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let i=Yc(e,r);return await this.client.modifyDBCluster({DBClusterIdentifier:e,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(e,i),{status:"deleting",finalSnapshotId:i}}if(["resize","version","rotate"].includes(t)){let i=await this.client.modifyDBCluster({DBClusterIdentifier:e,ServerlessV2ScalingConfiguration:pn(r,"minCapacity")==null&&pn(r,"maxCapacity")==null?void 0:{MinCapacity:pn(r,"minCapacity")??0.5,MaxCapacity:pn(r,"maxCapacity")??4},EngineVersion:jt(r,"engineVersion"),MasterUserPassword:t==="rotate"?n:void 0,ApplyImmediately:Eo(r,"applyImmediately")??!0});return Wu(i.DBCluster)}throw Error(`Aurora action ${t} requires an engine connection runner.`)}}class Yn{client;constructor(e=new oe){this.client=e}async observe(e){let t=(await this.client.describeCacheClusters(e)).CacheClusters[0];if(!t)throw Error("ElastiCache cluster was not found.");let r=t.CacheNodes?.[0]?.Endpoint;return{providerId:t.CacheClusterId,status:t.CacheClusterStatus,engine:t.Engine,engineVersion:t.EngineVersion,plan:t.CacheNodeType,nodes:t.NumCacheNodes,endpoint:r?.Address??null,port:r?.Port??null}}async apply(e){let t=await this.client.createCacheCluster({cacheClusterId:String(e.id),engine:"redis",cacheNodeType:String(e.plan),numCacheNodes:pn(e,"nodes")??1,engineVersion:jt(e,"engineVersion"),port:pn(e,"port"),securityGroupIds:Vs(e,"securityGroupIds"),subnetGroupName:jt(e,"subnetGroup"),tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{providerId:t.CacheCluster.CacheClusterId,status:t.CacheCluster.CacheClusterStatus}}async execute(e,t,r){if(t==="observe")return this.observe(e);if(t==="restart"){let n=(await this.client.describeCacheClusters(e)).CacheClusters[0];return await this.client.rebootCacheCluster(e,n?.CacheNodes?.map((i)=>i.CacheNodeId)??["0001"]),{status:"rebooting"}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};return await this.client.deleteCacheCluster(e),{status:"deleting"}}throw Error(`ElastiCache action ${t} is not supported by this cluster mode.`)}}import{mkdir as Zw,writeFile as eI}from"node:fs/promises";import{join as tI}from"node:path";async function wn(e,t,r=!1){let n=Bun.spawn(["docker",...e],{stdin:t==null?"ignore":"pipe",stdout:"pipe",stderr:"pipe"}),i=new Response(n.stdout).text(),o=new Response(n.stderr).text();if(t!=null)n.stdin.write(t),n.stdin.end();let[s,c,u]=await Promise.all([n.exited,i,o]);if(s!==0&&!r)throw Error(`Docker command failed (${s}): ${u.trim()||c.trim()}`);return{code:s,stdout:c,stderr:u}}class lf{async ensureNetwork(e){if((await wn(["network","inspect",e],void 0,!0)).code!==0)await wn(["network","create","--internal",e])}async seedSecret(e,t){await wn(["volume","create",e]),await wn(["run","--rm","-i","-v",`${e}:/run/target`,"alpine:3.21","sh","-c","umask 077; cat > /run/target/credential"],t)}async removeVolume(e){await wn(["volume","rm",e],void 0,!0)}async inspect(e){let t=await wn(["inspect",e],void 0,!0);if(t.code!==0)return;return JSON.parse(t.stdout)[0]}async run(e){await wn(["run",...e])}async exec(e,t,r){return(await wn(["exec","-i",e,...t],r)).stdout}async update(e,t){await wn(["update",...t,e])}async restart(e){await wn(["restart",e])}async remove(e){await wn(["rm","--force",e],void 0,!0)}async logs(e,t){let r=await wn(["logs","--tail",String(Math.min(2000,Math.max(1,t))),e],void 0,!0);return`${r.stdout}${r.stderr}`.slice(-262144)}async stats(e){let t=await wn(["stats","--no-stream","--format","{{json .}}",e],void 0,!0);if(t.code!==0||!t.stdout.trim())return{};let r=JSON.parse(t.stdout.trim());return{cpuPercent:String(r.CPUPerc??""),memoryUsage:String(r.MemUsage??""),memoryPercent:String(r.MemPerc??""),networkIo:String(r.NetIO??""),blockIo:String(r.BlockIO??""),pids:Number(r.PIDs??0)}}}var rI={postgres:{image:"postgres:17-alpine",port:5432,dataPath:"/var/lib/postgresql/data"},mysql:{image:"mysql:8.4",port:3306,dataPath:"/var/lib/mysql"},mariadb:{image:"mariadb:11.7",port:3306,dataPath:"/var/lib/mysql"},redis:{image:"redis:7.4-alpine",port:6379,dataPath:"/data"},mongodb:{image:"mongo:8.0",port:27017,dataPath:"/data/db"}};function to(e,t="app"){let r=String(e??t);if(!/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(r))throw Error("Database identifiers must be letters, numbers, or underscores.");return r}function Ko(e){if(!/^[a-z0-9][a-z0-9_.-]{1,62}$/i.test(e))throw Error("Runtime placement must be a valid container identifier.");return`tscloud-data-${e.toLowerCase()}`}function nI(e,t){let r=e.desiredState;return e[t]??(r&&typeof r==="object"&&!Array.isArray(r)?r[t]:void 0)}function Ia(e){return e.Config?.Labels??{}}class ct{runtime;backupRoot;constructor(e=new lf,t=R(process.cwd(),"backups","data")){this.runtime=e;this.backupRoot=t}async observe(e){let t=Ko(e),r=await this.runtime.inspect(t);if(!r)throw Error(`Data container ${t} was not found.`);let n=Ia(r),i=await this.runtime.stats(t),o=r.NetworkSettings?.Ports??{},s=Object.values(o).flat().find(Boolean);return{providerId:t,status:r.State?.Status??"unknown",healthy:r.State?.Health?.Status??null,engine:n["ts-cloud.engine"]??null,engineVersion:n["ts-cloud.engine-version"]??null,username:n["ts-cloud.username"]??null,database:n["ts-cloud.database"]??null,endpoint:s?.HostIp||"127.0.0.1",port:s?.HostPort?Number(s.HostPort):null,image:r.Config?.Image??null,startedAt:r.State?.StartedAt??null,metrics:i}}async apply(e,t){let r=String(e.id),n=Ko(r),i=String(e.engine);if(i==="libsql")throw Error("libSQL requires an explicitly configured runtime image.");let o=rI[i];if(!o)throw Error(`Unsupported runtime data engine ${i}.`);if(!t)throw Error(`${i} requires a managed credential.`);if(e.publicExposure===!0)throw Error("Container public exposure requires an external reviewed firewall policy; direct publishing is refused.");let s=to(e.username),c=to(nI(e,"database")),u=`${n}-secret`,a=`${n}-data`,f=i==="redis"?`appendonly yes
|
|
93
93
|
protected-mode yes
|
|
94
94
|
requirepass ${t.replaceAll("\\","\\\\").replaceAll(`
|
|
95
95
|
`,"")}
|
|
@@ -103,15 +103,15 @@ requirepass ${t.replaceAll("\\","\\\\").replaceAll(`
|
|
|
103
103
|
protected-mode yes
|
|
104
104
|
requirepass ${n.replaceAll("\\","\\\\").replaceAll(`
|
|
105
105
|
`,"")}
|
|
106
|
-
`:n;if(await this.runtime.seedSecret(`${i}-secret`,f),c==="redis")await this.runtime.restart(i);return{status:c==="redis"?"restarting":"running",username:u}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let o=await this.backup(e,r);return await this.runtime.remove(i),await this.runtime.removeVolume(`${i}-secret`),await this.runtime.removeVolume(`${i}-data`),{status:"deleted",finalBackupId:o.backupId??null,backupPath:o.path??null}}if(t==="expose")throw Error("Direct container exposure is refused; use a reviewed firewall and proxy policy.");throw Error(`${t} requires a configured engine lifecycle runner.`)}}import{createCipheriv as iI,createDecipheriv as oI,createHash as pf,randomBytes as sI}from"node:crypto";class
|
|
106
|
+
`:n;if(await this.runtime.seedSecret(`${i}-secret`,f),c==="redis")await this.runtime.restart(i);return{status:c==="redis"?"restarting":"running",username:u}}if(t==="delete"){if(r.retention==="retain")return{status:"retained"};let o=await this.backup(e,r);return await this.runtime.remove(i),await this.runtime.removeVolume(`${i}-secret`),await this.runtime.removeVolume(`${i}-data`),{status:"deleted",finalBackupId:o.backupId??null,backupPath:o.path??null}}if(t==="expose")throw Error("Direct container exposure is refused; use a reviewed firewall and proxy policy.");throw Error(`${t} requires a configured engine lifecycle runner.`)}}import{createCipheriv as iI,createDecipheriv as oI,createHash as pf,randomBytes as sI}from"node:crypto";class ir{controlPlane;now;key;constructor(e,t,r=()=>new Date){this.controlPlane=e;this.now=r;if(!t)throw Error("Data-service encryption key is required.");this.key=pf("sha256").update(`ts-cloud:data-services:${t}`).digest()}encrypt(e){let t=sI(12),r=iI("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("Encrypted data-service secret is unavailable.");try{let o=oI("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")}catch{throw Error("Encrypted data-service secret could not be decrypted.")}}async put(e,t){if(!/^secret:\/\/data-services\/[A-Za-z0-9._/-]+$/.test(e))throw Error("Invalid data-service secret reference.");if(!t)throw Error("Data-service secret cannot be empty.");let r=this.now().toISOString();this.controlPlane.database.run("INSERT INTO data_service_secrets (reference,ciphertext,fingerprint,created_at,updated_at) VALUES (?,?,?,?,?) ON CONFLICT(reference) DO UPDATE SET ciphertext=excluded.ciphertext,fingerprint=excluded.fingerprint,updated_at=excluded.updated_at",[e,this.encrypt(t),pf("sha256").update(t).digest("hex"),r,r])}async resolve(e){let t=this.controlPlane.database.query("SELECT ciphertext FROM data_service_secrets WHERE reference = ?").get(e);if(!t)throw Error("Data-service secret was not found.");return this.decrypt(t.ciphertext)}async remove(e){this.controlPlane.database.run("DELETE FROM data_service_secrets WHERE reference = ?",[e])}}import{createCipheriv as aI,createDecipheriv as cI,createHash as yf,randomBytes as Ku}from"node:crypto";var bf={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 kt(e){return typeof e==="string"&&e?e:void 0}function Yo(e,t){try{return typeof e==="string"?JSON.parse(e):t}catch{return t}}function Ni(e){return JSON.stringify(h(e))}function Qo(e){return yf("sha256").update(e).digest("hex")}function gf(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 mf(e){let t=e.trim();if(t.length<2||t.length>80)throw Error("Connection name must contain 2-80 characters");return t}function Qu(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 ff(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 Zc(e){return[...new Set((e??[]).map((t)=>t.trim()).filter(Boolean))].slice(0,100)}function dI(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 uI(e){return{id:String(e.id),organizationId:String(e.organization_id),provider:String(e.provider),name:String(e.name),host:String(e.host),owner:kt(e.owner),authKind:String(e.auth_kind),credentialConfigured:!!e.credential_ciphertext,credentialFingerprint:kt(e.credential_fingerprint),grantedScopes:Yo(e.granted_scopes,[]),capabilities:Yo(e.capabilities,bf[String(e.provider)]),status:String(e.status),healthMessage:kt(e.health_message),lastTestedAt:kt(e.last_tested_at),lastSyncedAt:kt(e.last_synced_at),credentialExpiresAt:kt(e.credential_expires_at),version:Number(e.version),createdByActorId:kt(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Yu(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:Yo(e.metadata,{}),syncedAt:String(e.synced_at)}}function hf(e){return{id:String(e.id),projectId:String(e.project_id),environmentId:kt(e.environment_id),resourceId:kt(e.resource_id),connectionId:String(e.connection_id),repositoryId:kt(e.repository_id),repositoryFullName:String(e.repository_full_name),defaultBranch:String(e.default_branch),branchRule:kt(e.branch_rule),tagRule:kt(e.tag_rule),monorepoRoot:String(e.monorepo_root),includePaths:Yo(e.include_paths,[]),excludePaths:Yo(e.exclude_paths,[]),submodules:Number(e.submodules)===1,cloneDepth:e.clone_depth==null?void 0:Number(e.clone_depth),deployKeyId:kt(e.deploy_key_id),autoDeploy:Number(e.auto_deploy)===1,pullRequestPreviews:Number(e.pull_request_previews)===1,status:String(e.status),disabledReason:kt(e.disabled_reason),version:Number(e.version),createdByActorId:kt(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Xu(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:kt(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Zu(e){return{id:String(e.id),connectionId:String(e.connection_id),repositoryId:kt(e.repository_id),repositoryFullName:String(e.repository_full_name),providerWebhookId:kt(e.provider_webhook_id),events:Yo(e.events,[]),status:String(e.status),healthMessage:kt(e.health_message),lastDeliveryAt:kt(e.last_delivery_at),lastReconciledAt:kt(e.last_reconciled_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function el(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:kt(e.action),commitSha:kt(e.commit_sha),signatureStatus:String(e.signature_status),status:String(e.status),payloadSummary:Yo(e.payload_summary,{}),operationId:kt(e.operation_id),error:kt(e.error),receivedAt:String(e.received_at),processedAt:kt(e.processed_at)}}class or{controlPlane;key;nowFn;idFn;constructor(e,t={}){this.controlPlane=e;this.key=t.encryptionKey?yf("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=Ku(12),r=aI("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=cI("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)
|
|
107
107
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?)`,[r,e.organizationId,e.provider,mf(e.name),gf(e.host),e.owner?.trim()||null,e.authKind??(n?"access_token":"none"),n?this.encrypt(n):null,n?Qo(n).slice(0,16):null,Ni([...new Set(e.grantedScopes??[])].sort()),Ni(bf[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:gf(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=uI(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),Qo(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:Qo(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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
108
108
|
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,Qu(e.fullName),dI(e.cloneUrl),e.defaultBranch.trim()||"main",e.visibility,e.archived?1:0,Ni(e.metadata),r]),Yu(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(Yu)}getRepository(e){let t=this.controlPlane.database.query("SELECT * FROM source_repositories WHERE id = ?").get(e);return t?Yu(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:${Qo(e.publicKey.trim())}`,o=`sha256:${Qo(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,mf(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}}),Xu(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?Xu(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(Xu)}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)
|
|
109
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?)`,[r,e.projectId,e.environmentId??null,e.resourceId??null,e.connectionId,e.repositoryId??null,Qu(e.repositoryFullName),e.defaultBranch?.trim()||"main",e.branchRule?.trim()||null,e.tagRule?.trim()||null,ff(e.monorepoRoot??"."),Ni(Zc(e.includePaths)),Ni(Zc(e.excludePaths)),e.submodules?1:0,e.cloneDepth??null,e.deployKeyId??null,e.autoDeploy===!1?0:1,e.pullRequestPreviews===!1?0:1,e.actorId??null,n,n]),this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:e.projectId,actorId:e.actorId,type:"source.binding.created",payload:{bindingId:r,connectionId:e.connectionId,repository:e.repositoryFullName,branch:e.defaultBranch??"main"}}),this.getBinding(r)}getBinding(e){let t=this.controlPlane.database.query("SELECT * FROM source_bindings WHERE id = ?").get(e);return t?hf(t):void 0}listBindings(e={}){return this.controlPlane.database.query("SELECT * FROM source_bindings ORDER BY created_at DESC").all().map(hf).filter((r)=>(!e.connectionId||r.connectionId===e.connectionId)&&(!e.projectId||r.projectId===e.projectId)&&(!e.status||r.status===e.status))}updateBinding(e,t,r){let n=this.getBinding(e);if(!n||n.version!==t)throw Error(`Source binding ${e} changed since version ${t}`);let i=this.getConnection(n.connectionId);if((!i||["disconnected","expired"].includes(i.status))&&(r.status==="active"||r.autoDeploy===!0))throw Error("Rotate or reconnect the source credential before enabling this binding");if(r.deployKeyId&&this.getDeployKey(r.deployKeyId)?.connectionId!==n.connectionId)throw Error("Deploy key does not belong to this connection");let o=this.now();if(this.controlPlane.database.run("UPDATE source_bindings SET default_branch=?, branch_rule=?, tag_rule=?, monorepo_root=?, include_paths=?, exclude_paths=?, submodules=?, clone_depth=?, deploy_key_id=?, auto_deploy=?, pull_request_previews=?, status=?, disabled_reason=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.defaultBranch?.trim()||n.defaultBranch,r.branchRule===void 0?n.branchRule??null:r.branchRule.trim()||null,r.tagRule===void 0?n.tagRule??null:r.tagRule.trim()||null,r.monorepoRoot===void 0?n.monorepoRoot:ff(r.monorepoRoot),Ni(r.includePaths===void 0?n.includePaths:Zc(r.includePaths)),Ni(r.excludePaths===void 0?n.excludePaths:Zc(r.excludePaths)),r.submodules??n.submodules?1:0,r.cloneDepth===void 0?n.cloneDepth??null:r.cloneDepth,r.deployKeyId===void 0?n.deployKeyId??null:r.deployKeyId,r.autoDeploy??n.autoDeploy?1:0,r.pullRequestPreviews??n.pullRequestPreviews?1:0,r.status??n.status,r.disabledReason===void 0?n.disabledReason??null:r.disabledReason.slice(0,1000),o,e,t]).changes!==1)throw Error(`Source binding ${e} changed since version ${t}`);let c=this.getConnection(n.connectionId);return this.controlPlane.appendEvent({organizationId:c.organizationId,projectId:n.projectId,actorId:r.actorId,type:"source.binding.updated",payload:{bindingId:e,fromVersion:t,toVersion:t+1,status:r.status??n.status}}),this.getBinding(e)}createWebhook(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");let r=this.idFn(),n=this.now(),i=e.endpointToken??Ku(24).toString("base64url"),o=e.secret??Ku(32).toString("base64url"),s=[...new Set(e.events??["push","pull_request"])].filter((c)=>["push","pull_request"].includes(c));if(!s.length)throw Error("At least one supported webhook event is required");return this.run("INSERT INTO source_webhooks (id, connection_id, repository_id, repository_full_name, endpoint_token_hash, endpoint_token_ciphertext, secret_ciphertext, events, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?)",[r,e.connectionId,e.repositoryId??null,Qu(e.repositoryFullName),Qo(i),this.encrypt(i),this.encrypt(o),Ni(s),n,n]),this.controlPlane.appendEvent({organizationId:t.organizationId,type:"source.webhook.created",payload:{webhookId:r,connectionId:t.id,repository:e.repositoryFullName,events:s}}),{webhook:{...this.getWebhook(r),endpointToken:i},secret:o}}getWebhook(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE id = ?").get(e);return t?Zu(t):void 0}getWebhookByEndpointToken(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE endpoint_token_hash = ?").get(Qo(e));return t?Zu(t):void 0}getWebhookSecret(e){let t=this.controlPlane.database.query("SELECT secret_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t)throw Error("Source webhook was not found");return this.decrypt(String(t.secret_ciphertext))}getWebhookEndpointToken(e){let t=this.controlPlane.database.query("SELECT endpoint_token_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t?.endpoint_token_ciphertext)throw Error("Source webhook endpoint token is unavailable");return this.decrypt(String(t.endpoint_token_ciphertext))}listWebhooks(e){return this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE connection_id = ? ORDER BY repository_full_name").all(e).map(Zu)}updateWebhookState(e,t){let r=this.getWebhook(e);if(!r)throw Error("Source webhook was not found");let n=this.now();this.run("UPDATE source_webhooks SET provider_webhook_id=COALESCE(?, provider_webhook_id), status=?, health_message=?, last_reconciled_at=COALESCE(?, last_reconciled_at), updated_at=? WHERE id=?",[t.providerWebhookId??null,t.status,t.healthMessage?.slice(0,1000)??null,t.reconciled?n:null,n,e]);let i=this.getConnection(r.connectionId);if(i)this.controlPlane.appendEvent({organizationId:i.organizationId,type:"source.webhook.updated",payload:{webhookId:e,connectionId:i.id,repository:r.repositoryFullName,status:t.status,reconciled:t.reconciled??!1,providerWebhookId:t.providerWebhookId??r.providerWebhookId??null}});return this.getWebhook(e)}getDeliveryByProviderId(e,t){let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE connection_id = ? AND provider_delivery_id = ?").get(e,t);return r?el(r):void 0}recordDelivery(e){let t=this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId);if(t)return{delivery:t,duplicate:!0};let r=this.idFn(),n=this.now();return this.controlPlane.database.transaction(()=>{this.run("INSERT INTO source_webhook_deliveries (id, connection_id, webhook_id, provider_delivery_id, event, action, commit_sha, signature_status, status, payload_summary, operation_id, error, received_at, processed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.connectionId,e.webhookId,e.providerDeliveryId,e.event.slice(0,100),e.action?.slice(0,100)??null,e.commitSha?.slice(0,128)??null,e.signatureStatus,e.status,Ni(e.payloadSummary??{}),e.operationId??null,e.error?.slice(0,2000)??null,n,["enqueued","ignored","rejected","failed"].includes(e.status)?n:null]),this.run("UPDATE source_webhooks SET last_delivery_at=?, updated_at=? WHERE id=?",[n,n,e.webhookId])})(),{delivery:this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId),duplicate:!1}}updateDelivery(e,t){this.run("UPDATE source_webhook_deliveries SET status=?, operation_id=?, error=?, processed_at=? WHERE id=?",[t.status,t.operationId??null,t.error?.slice(0,2000)??null,this.now(),e]);let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE id = ?").get(e);if(!r)throw Error("Source webhook delivery was not found");return el(r)}listDeliveries(e,t=100){return this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE webhook_id = ? ORDER BY received_at DESC LIMIT ?").all(e,Math.min(500,Math.max(1,t))).map(el)}disconnectConnection(e,t){let r=this.getConnection(e);if(!r)throw Error("Source connection was not found");let n=this.listBindings({connectionId:e,status:"active"}),i=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_connections SET status='disconnected', credential_ciphertext=NULL, health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[i,e]),this.run("UPDATE source_bindings SET status='disabled', auto_deploy=0, disabled_reason='Source connection was disconnected', version=version+1, updated_at=? WHERE connection_id=? AND status='active'",[i,e]),this.run("UPDATE source_webhooks SET status='disabled', health_message='Source connection was disconnected', updated_at=? WHERE connection_id=?",[i,e])})(),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"source.connection.disconnected",level:"warning",payload:{connectionId:e,affectedBindingIds:n.map((o)=>o.id),affectedRepositories:n.map((o)=>o.repositoryFullName)}}),{connection:this.getConnection(e),affectedBindings:n}}}import{createSign as lI}from"node:crypto";class Gs extends Error{status;retryAfterSeconds;constructor(e,t,r){super(e);this.status=t;this.retryAfterSeconds=r;this.name="SourceProviderError"}}var vf={repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0};function To(e){let t=Number(e??"1");return Number.isInteger(t)&&t>0?t:1}function Ao(e){return Math.max(1,Math.min(100,e??50))}function Pn(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 Ca(e){let t=new URL(e);if(t.username||t.password||t.protocol!=="https:")throw Error("Webhook endpoint must be credential-free HTTPS");return t.href}function Sf(e){return Buffer.from(e).toString("base64url")}function pI(e,t){if(!e.appId||!e.privateKey)throw Error("GitHub App credentials require appId and privateKey");let r=Sf(JSON.stringify({alg:"RS256",typ:"JWT"})),n=Math.floor(t.getTime()/1000)-30,i=Sf(JSON.stringify({iat:n,exp:n+540,iss:e.appId})),o=lI("RSA-SHA256");return o.update(`${r}.${i}`),o.end(),`${r}.${i}.${o.sign(e.privateKey).toString("base64url")}`}class Ea{connection;credential;capabilities=vf;fetchFn;timeoutMs;nowFn;constructor(e,t,r={}){this.connection=e;this.credential=t;this.fetchFn=r.fetch??((n,i)=>globalThis.fetch(n,i)),this.timeoutMs=Math.max(100,r.timeoutMs??20000),this.nowFn=r.now??(()=>new Date)}async request(e,t={}){let r=new URL(`${this.apiRoot().replace(/\/$/,"")}/`),n=new URL(e.replace(/^\//,""),r);if(n.origin!==r.origin)throw Error("Provider pagination cannot leave the configured host");let i=new AbortController,o=setTimeout(()=>i.abort(),this.timeoutMs);try{let s=await this.fetchFn(n,{...t,redirect:"error",signal:i.signal,headers:{Accept:"application/json","User-Agent":"ts-cloud-source/1",...await this.authorization(),...t.headers}});if(!s.ok){let c=Number(s.headers.get("retry-after")??""),u=s.headers.get("x-request-id")??s.headers.get("x-github-request-id");throw new Gs(`Source provider request failed (${s.status})${u?` [request ${u}]`:""}`,s.status,Number.isFinite(c)?c:void 0)}if(s.status===204)return{data:void 0,headers:s.headers};return{data:await s.json(),headers:s.headers}}catch(s){if(s instanceof Gs)throw s;if(i.signal.aborted)throw new Gs(`Source provider request exceeded ${this.timeoutMs}ms`);throw new Gs(s instanceof Error?s.message.replace(/(?:token|password|secret)=[^\s&]+/gi,"$1=[REDACTED]"):"Source provider request failed")}finally{clearTimeout(o)}}async deleteWebhook(e,t){await this.request(this.webhookPath(e,t),{method:"DELETE"})}}class wf extends Ea{provider="github";installationToken;apiRoot(){return this.connection.host==="https://github.com"?"https://api.github.com":`${this.connection.host}/api/v3`}async authorization(){if(this.credential?.token)return{Authorization:`Bearer ${this.credential.token}`,"X-GitHub-Api-Version":"2022-11-28"};if(!this.credential?.installationId)return{};if(!this.installationToken||this.installationToken.expiresAt<this.nowFn().getTime()+60000){let e=pI(this.credential,this.nowFn()),t=this.apiRoot().replace(/\/$/,""),r=new AbortController,n=setTimeout(()=>r.abort(),this.timeoutMs);try{let i=await this.fetchFn(`${t}/app/installations/${encodeURIComponent(this.credential.installationId)}/access_tokens`,{method:"POST",signal:r.signal,redirect:"error",headers:{Accept:"application/vnd.github+json",Authorization:`Bearer ${e}`,"X-GitHub-Api-Version":"2022-11-28","User-Agent":"ts-cloud-source/1"}});if(!i.ok)throw new Gs(`GitHub App token refresh failed (${i.status})`,i.status);let o=await i.json();this.installationToken={value:o.token,expiresAt:new Date(o.expires_at).getTime()}}finally{clearTimeout(n)}}return{Authorization:`Bearer ${this.installationToken.value}`,"X-GitHub-Api-Version":"2022-11-28"}}async testConnection(){let e=this.credential?.installationId?"/installation/repositories?per_page=1":"/user",{data:t,headers:r}=await this.request(e);return{ok:!0,account:t.login??this.connection.owner,scopes:(r.get("x-oauth-scopes")??this.connection.grantedScopes.join(",")).split(",").map((n)=>n.trim()).filter(Boolean),message:"GitHub connection is healthy"}}async listRepositories(e={}){let t=Ao(e.limit),r=To(e.cursor),n=this.credential?.installationId?`/installation/repositories?per_page=${t}&page=${r}`:`/user/repos?per_page=${t}&page=${r}&sort=updated`,{data:i}=await this.request(n),o=Array.isArray(i)?i:i.repositories;return{repositories:(e.search?o.filter((c)=>c.full_name.toLowerCase().includes(e.search.toLowerCase())):o).map((c)=>({providerRepositoryId:String(c.id),fullName:c.full_name,cloneUrl:c.clone_url,defaultBranch:c.default_branch||"main",visibility:c.visibility??(c.private?"private":"public"),archived:!!c.archived,metadata:{}})),nextCursor:o.length===t?String(r+1):void 0}}async refs(e,t,r={}){let n=Ao(r.limit),i=To(r.cursor),{data:o}=await this.request(`/repos/${Pn(e)}/${t}?per_page=${n}&page=${i}`);return{refs:o.map((s)=>({name:s.name,commitSha:s.commit.sha,protected:s.protected})),nextCursor:o.length===n?String(i+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Pn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events,url:e.config.url??""}}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:JSON.stringify({name:"web",active:!0,events:t.events,config:{url:Ca(t.url),content_type:"json",secret:t.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:JSON.stringify({active:!0,events:r.events,config:{url:Ca(r.url),content_type:"json",secret:r.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){await this.request(`/repos/${Pn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}class If extends Ea{provider="gitlab";apiRoot(){return`${this.connection.host}/api/v4`}async authorization(){return this.credential?.token?{"PRIVATE-TOKEN":this.credential.token}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username,scopes:this.connection.grantedScopes,message:"GitLab connection is healthy"}}async listRepositories(e={}){let t=Ao(e.limit),r=To(e.cursor),n=e.search?`&search=${encodeURIComponent(e.search)}`:"",{data:i,headers:o}=await this.request(`/projects?membership=true&simple=true&order_by=last_activity_at&per_page=${t}&page=${r}${n}`);return{repositories:i.map((s)=>({providerRepositoryId:String(s.id),fullName:s.path_with_namespace,cloneUrl:s.http_url_to_repo,defaultBranch:s.default_branch??"main",visibility:s.visibility??"unknown",archived:!!s.archived,metadata:{}})),nextCursor:o.get("x-next-page")||void 0}}async refs(e,t,r={}){let n=Ao(r.limit),i=To(r.cursor),{data:o,headers:s}=await this.request(`/projects/${encodeURIComponent(Pn(e))}/repository/${t}?per_page=${n}&page=${i}`);return{refs:o.map((c)=>({name:c.name,commitSha:c.commit.id,protected:c.protected})),nextCursor:s.get("x-next-page")||void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/projects/${encodeURIComponent(Pn(e))}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:!0,events:[...e.push_events?["push"]:[],...e.merge_requests_events?["pull_request"]:[]],url:e.url}}body(e){return JSON.stringify({url:Ca(e.url),token:e.secret,enable_ssl_verification:!0,push_events:e.events.includes("push"),merge_requests_events:e.events.includes("pull_request")})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){let n=r.state==="failure"||r.state==="error"?"failed":r.state;await this.request(`/projects/${encodeURIComponent(Pn(e))}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n,target_url:r.url,description:r.description.slice(0,255),name:r.context??"ts-cloud/preview"})})}}class Cf extends Ea{provider="bitbucket";apiRoot(){return this.connection.host==="https://bitbucket.org"?"https://api.bitbucket.org/2.0":`${this.connection.host}/2.0`}async authorization(){return this.credential?.token?{Authorization:`Bearer ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username??e.display_name,scopes:this.connection.grantedScopes,message:"Bitbucket connection is healthy"}}async listRepositories(e={}){if(!this.connection.owner)throw Error("Bitbucket repository discovery requires an owner/workspace");let t=To(e.cursor),r=Ao(e.limit),n=e.search?`&q=name~%22${encodeURIComponent(e.search)}%22`:"",{data:i}=await this.request(`/repositories/${encodeURIComponent(this.connection.owner)}?pagelen=${r}&page=${t}${n}`);return{repositories:i.values.map((o)=>({providerRepositoryId:o.uuid,fullName:o.full_name,cloneUrl:o.links.clone.find((s)=>s.name==="https")?.href??o.links.clone[0]?.href??"",defaultBranch:o.mainbranch?.name??"main",visibility:o.is_private?"private":"public",archived:!1,metadata:{}})),nextCursor:i.next?String(t+1):void 0}}async refs(e,t,r={}){let n=To(r.cursor),i=Ao(r.limit),{data:o}=await this.request(`/repositories/${Pn(e)}/refs/${t}?pagelen=${i}&page=${n}`);return{refs:o.values.map((s)=>({name:s.name,commitSha:s.target.hash})),nextCursor:o.next?String(n+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repositories/${Pn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:e.uuid,active:e.active,events:e.events.map((t)=>t.replace("repo:push","push").replace("pullrequest:","pull_request:")),url:e.url}}body(e){return JSON.stringify({description:"ts-cloud deploy",url:Ca(e.url),active:!0,events:e.events.map((t)=>t==="push"?"repo:push":t.replace("pull_request:","pullrequest:"))})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.values.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){let n=r.state==="success"?"SUCCESSFUL":r.state==="pending"?"INPROGRESS":"FAILED";await this.request(`/repositories/${Pn(e)}/commit/${encodeURIComponent(t)}/statuses/build/ts-cloud-preview`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n,key:"ts-cloud-preview",name:r.context??"ts-cloud/preview",url:r.url,description:r.description.slice(0,255)})})}}class Ef extends Ea{provider="gitea";capabilities={...vf,tokenRefresh:!1};apiRoot(){return`${this.connection.host}/api/v1`}async authorization(){return this.credential?.token?{Authorization:`token ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.login,scopes:this.connection.grantedScopes,message:"Gitea connection is healthy"}}async listRepositories(e={}){let t=To(e.cursor),r=Ao(e.limit),n=e.search?`/repos/search?q=${encodeURIComponent(e.search)}&limit=${r}&page=${t}`:`/user/repos?limit=${r}&page=${t}`,{data:i,headers:o}=await this.request(n),s=Array.isArray(i)?i:i.data;return{repositories:s.map((c)=>({providerRepositoryId:String(c.id),fullName:c.full_name,cloneUrl:c.clone_url,defaultBranch:c.default_branch??"main",visibility:c.private?"private":"public",archived:!!c.archived,metadata:{}})),nextCursor:o.get("x-hasmore")==="true"||s.length===r?String(t+1):void 0}}async refs(e,t,r={}){let n=To(r.cursor),i=Ao(r.limit),{data:o}=await this.request(`/repos/${Pn(e)}/${t}?limit=${i}&page=${n}`);return{refs:o.map((s)=>({name:s.name,commitSha:s.commit.id})),nextCursor:o.length===i?String(n+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Pn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events??[],url:e.config.url??""}}body(e){return JSON.stringify({type:"gitea",active:!0,events:e.events,config:{url:Ca(e.url),content_type:"json",secret:e.secret,insecure_ssl:"0"}})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){await this.request(`/repos/${Pn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}function ko(e,t,r={}){switch(e.provider){case"github":return new wf(e,t,r);case"gitlab":return new If(e,t,r);case"bitbucket":return new Cf(e,t,r);case"gitea":return new Ef(e,t,r);default:throw Error(`${e.provider} uses bounded Git discovery instead of a hosted provider API`)}}import{createHmac as gI,timingSafeEqual as mI}from"node:crypto";function en(e,t){if(e instanceof Headers)return e.get(t)??void 0;return Object.entries(e).find(([n])=>n.toLowerCase()===t.toLowerCase())?.[1]}function Tf(e,t){let r=Buffer.from(e),n=Buffer.from(t);return r.length===n.length&&mI(r,n)}function fI(e,t){return gI("sha256",e).update(t).digest("hex")}function hI(e,t,r,n,i){if(e==="gitlab")return Tf(en(r,"x-gitlab-token")??"",t);let o=e==="github"?en(r,"x-hub-signature-256"):e==="gitea"?en(r,"x-gitea-signature"):en(r,"x-hub-signature")??en(r,"x-ts-cloud-signature");if(!o)return!1;if(e==="generic_https"||e==="generic_ssh"){let s=Number(en(r,"x-ts-cloud-timestamp"));if(!Number.isFinite(s)||Math.abs(i.getTime()-s*1000)>300000)return!1}return Tf(o.replace(/^sha256=/,""),fI(t,n))}function yI(e,t){return{github:["x-github-delivery"],gitlab:["x-gitlab-event-uuid","x-request-id"],bitbucket:["x-request-uuid"],gitea:["x-gitea-delivery"],generic_https:["x-ts-cloud-delivery"],generic_ssh:["x-ts-cloud-delivery"]}[e].map((n)=>en(t,n)?.trim()).find(Boolean)}function Ro(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");return/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t)?t:""}function tl(e){return[...new Set(e.flatMap((t)=>{if(!t||typeof t!=="object")return[];let r=t;return[...r.added??[],...r.modified??[],...r.removed??[]].map(String)}).filter((t)=>t&&!t.includes("\x00")).slice(0,500))]}function bI(e,t,r){let n=e,i=t,o=r;if(n==="github"){let s=en(i,"x-github-event"),c=Ro(o.repository?.full_name);if(s==="push")return{event:"push",repository:c,ref:String(o.ref??""),branch:String(o.ref??"").replace(/^refs\/heads\//,""),tag:String(o.ref??"").startsWith("refs/tags/")?String(o.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(o.after??o.head_commit?.id??""),changedPaths:tl(o.commits??[]),deleted:o.deleted===!0||/^0{40,64}$/.test(String(o.after??""))};if(s==="pull_request")return{event:"pull_request",action:String(o.action??""),repository:c,branch:String(o.pull_request?.head?.ref??""),commitSha:String(o.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(o.number)||void 0,fork:Ro(o.pull_request?.head?.repo?.full_name)!==c}}if(n==="gitlab"){let s=String(o.object_kind??"").toLowerCase(),c=Ro(o.project?.path_with_namespace);if(s==="push"||s==="tag_push")return{event:"push",repository:c,ref:String(o.ref??""),branch:String(o.ref??"").replace(/^refs\/heads\//,""),tag:s==="tag_push"?String(o.ref??"").replace(/^refs\/tags\//,""):void 0,commitSha:String(o.checkout_sha??o.after??""),changedPaths:tl(o.commits??[]),deleted:/^0{40,64}$/.test(String(o.after??""))};if(s==="merge_request")return{event:"pull_request",action:String(o.object_attributes?.action??o.object_attributes?.state??""),repository:c,branch:String(o.object_attributes?.source_branch??""),commitSha:String(o.object_attributes?.last_commit?.id??""),changedPaths:[],pullRequestNumber:Number(o.object_attributes?.iid)||void 0,fork:o.object_attributes?.source_project_id!==o.object_attributes?.target_project_id}}if(n==="bitbucket"){let s=en(i,"x-event-key")??"",c=Ro(o.repository?.full_name);if(s==="repo:push"){let u=o.push?.changes?.[0]??{},a=u.new??u.old??{},f=u.new?.target??u.old?.target;return{event:"push",repository:c,ref:String(a.name??""),branch:a.type==="branch"?String(a.name):void 0,tag:a.type==="tag"?String(a.name):void 0,commitSha:String(f?.hash??""),changedPaths:[],deleted:u.closed===!0||u.new==null}}if(s.startsWith("pullrequest:"))return{event:"pull_request",action:s.replace("pullrequest:",""),repository:c,branch:String(o.pullrequest?.source?.branch?.name??""),commitSha:String(o.pullrequest?.source?.commit?.hash??""),changedPaths:[],pullRequestNumber:Number(o.pullrequest?.id)||void 0,fork:Ro(o.pullrequest?.source?.repository?.full_name)!==c}}if(n==="gitea"){let s=en(i,"x-gitea-event"),c=Ro(o.repository?.full_name);if(s==="push")return{event:"push",repository:c,ref:String(o.ref??""),branch:String(o.ref??"").replace(/^refs\/heads\//,""),tag:String(o.ref??"").startsWith("refs/tags/")?String(o.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(o.after??""),changedPaths:tl(o.commits??[]),deleted:o.deleted===!0||/^0{40,64}$/.test(String(o.after??""))};if(s==="pull_request")return{event:"pull_request",action:String(o.action??""),repository:c,branch:String(o.pull_request?.head?.ref??""),commitSha:String(o.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(o.number)||void 0,fork:Ro(o.pull_request?.head?.repo?.full_name)!==c}}if(n==="generic_https"||n==="generic_ssh"){if(o.event!=="push"&&o.event!=="pull_request")return;return{event:o.event,action:typeof o.action==="string"?o.action:void 0,repository:Ro(o.repository),ref:typeof o.ref==="string"?o.ref:void 0,branch:typeof o.branch==="string"?o.branch:void 0,tag:typeof o.tag==="string"?o.tag:void 0,commitSha:String(o.commitSha??""),changedPaths:Array.isArray(o.changedPaths)?o.changedPaths.map(String).slice(0,500):[],pullRequestNumber:Number(o.pullRequestNumber)||void 0,fork:o.fork===!0,deleted:o.deleted===!0}}return}function Js(e,t){let r="^";for(let n=0;n<t.length;n++){let i=t[n];if(i==="*"&&t[n+1]==="*")r+=".*",n++;else if(i==="*")r+="[^/]*";else if(i==="?")r+="[^/]";else r+=i.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")}return new RegExp(`${r}$`).test(e)}function SI(e,t){if(t.event==="pull_request")return e.pullRequestPreviews;if(!e.autoDeploy)return!1;if(t.tag)return!!e.tagRule&&Js(t.tag,e.tagRule);return Js(t.branch??"",e.branchRule??e.defaultBranch)}function vI(e,t){if(!t.length)return!0;return t.filter((n)=>!e.excludePaths.some((i)=>Js(n,i))).some((n)=>!e.includePaths.length||e.includePaths.some((i)=>Js(n,i)))}function Af(e,t){return en(t,e==="github"?"x-github-event":e==="gitlab"?"x-gitlab-event":e==="bitbucket"?"x-event-key":e==="gitea"?"x-gitea-event":"x-ts-cloud-event")??"unknown"}function Xo(){return{accepted:!1,duplicate:!1,status:"rejected",operations:[],message:"Webhook unavailable"}}async function kf(e){if(e.rawBody.byteLength>2097152)return Xo();let t=e.sources.getWebhookByEndpointToken(e.endpointToken);if(!t||t.status==="disabled")return Xo();let r=e.sources.getConnection(t.connectionId);if(!r||r.status==="disconnected"||r.status==="expired")return Xo();let n=yI(r.provider,e.headers);if(!n||n.length>200)return Xo();if(!hI(r.provider,e.sources.getWebhookSecret(t.id),e.headers,e.rawBody,e.now??new Date))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:n,event:Af(r.provider,e.headers),signatureStatus:en(e.headers,"x-hub-signature-256")||en(e.headers,"x-gitlab-token")||en(e.headers,"x-hub-signature")||en(e.headers,"x-gitea-signature")?"invalid":"missing",status:"rejected",error:"Webhook signature verification failed"}),Xo();let o;try{o=JSON.parse(new TextDecoder().decode(e.rawBody))}catch{return Xo()}let s=bI(r.provider,e.headers,o);if(!s||!s.repository||!/^[a-f0-9]{7,64}$/i.test(s.commitSha))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:n,event:Af(r.provider,e.headers),signatureStatus:"verified",status:"rejected",error:"Unsupported or malformed source event"}),Xo();let c=e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:n,event:s.event,action:s.action,commitSha:s.commitSha,signatureStatus:"verified",status:"accepted",payloadSummary:{repository:s.repository,ref:s.ref??null,branch:s.branch??null,tag:s.tag??null,commitSha:s.commitSha,pullRequestNumber:s.pullRequestNumber??null,changedPathCount:s.changedPaths.length}});if(c.duplicate&&c.delivery.status!=="accepted")return{accepted:!0,duplicate:!0,status:"duplicate",operations:[],message:"Delivery already processed"};let u=new Fe(e.controlPlane),a=e.sources.listBindings({connectionId:r.id,status:"active"}).filter((D)=>{if(D.repositoryFullName.toLowerCase()!==s.repository.toLowerCase()||!vI(D,s.changedPaths))return!1;let W=D.resourceId?u.getDefinitionForResource(D.resourceId):void 0,Y=s.event==="push"&&!!W?.branchRule&&!!s.branch&&Js(s.branch,W.branchRule);return SI(D,s)||Y});if(!a.length)return e.sources.updateDelivery(c.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:c.duplicate,status:"ignored",operations:[],message:"Verified event did not match an active deployment rule"};let f=new S(e.controlPlane),C=new Set(["closed","merged","declined"]),k=a.flatMap((D)=>{if(s.event==="push"&&D.resourceId&&s.branch){let Y=u.getDefinitionForResource(D.resourceId);if(Y?.branchRule&&Js(s.branch,Y.branchRule)){let ee=u.findForBranch(Y.id,s.repository,s.branch);if(s.deleted){if(!Y.cleanupOnClose||!ee||ee.status==="destroyed")return[];let Pe=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${ee.id}:branch-delete:${n}`,correlationId:`preview:${ee.id}`,input:{previewId:ee.id,reason:"branch_deleted",source:{repository:s.repository,commitSha:s.commitSha,branch:s.branch}},lockKey:`preview:${ee.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(ee.id,"queued",{operationId:Pe.id}),[Pe]}let ne=u.upsert({definitionId:Y.id,sourceProvider:r.provider,repository:s.repository,branch:s.branch,commitSha:s.commitSha});if(!ne.changed)return[];let he=ne.created?"preview.create":"preview.update",te=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:he,idempotencyKey:`preview:${ne.preview.id}:${s.commitSha}`,correlationId:`preview:${ne.preview.id}`,input:{previewId:ne.preview.id,source:{connectionId:r.id,bindingId:D.id,repository:s.repository,commitSha:s.commitSha,branch:s.branch,monorepoRoot:D.monorepoRoot,submodules:D.submodules,cloneDepth:D.cloneDepth??null}},lockKey:`preview:${ne.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(ne.preview.id,"queued",{operationId:te.id}),[te]}}if(s.event==="pull_request"&&D.resourceId&&s.pullRequestNumber){let Y=u.getDefinitionForResource(D.resourceId);if(Y){let ee=C.has(String(s.action??"").toLowerCase()),ne=u.findForPullRequest(Y.id,s.repository,s.pullRequestNumber);if(ee){if(!Y.cleanupOnClose||!ne||ne.status==="destroyed")return[];let he=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${ne.id}:destroy:${n}`,correlationId:`preview:${ne.id}`,input:{previewId:ne.id,reason:"pull_request_closed",source:{repository:s.repository,commitSha:s.commitSha,branch:s.branch??null,pullRequestNumber:s.pullRequestNumber}},lockKey:`preview:${ne.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(ne.id,"queued",{operationId:he.id}),[he]}try{let he=u.upsert({definitionId:Y.id,sourceProvider:r.provider,repository:s.repository,branch:s.branch??`pr-${s.pullRequestNumber}`,pullRequestNumber:s.pullRequestNumber,fork:s.fork,commitSha:s.commitSha});if(!he.changed)return[];let te=he.created?"preview.create":"preview.update",Pe=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:te,idempotencyKey:`preview:${he.preview.id}:${s.commitSha}`,correlationId:`preview:${he.preview.id}`,input:{previewId:he.preview.id,source:{connectionId:r.id,bindingId:D.id,repository:s.repository,commitSha:s.commitSha,branch:s.branch??null,pullRequestNumber:s.pullRequestNumber,fork:!!s.fork,monorepoRoot:D.monorepoRoot,submodules:D.submodules,cloneDepth:D.cloneDepth??null},inheritedSecretNames:he.inheritedSecrets},lockKey:`preview:${he.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(he.preview.id,"queued",{operationId:Pe.id}),[Pe]}catch(he){return e.controlPlane.appendEvent({projectId:D.projectId,resourceId:D.resourceId,type:"preview.rejected",level:"warning",payload:{repository:s.repository,pullRequestNumber:s.pullRequestNumber,fork:!!s.fork,reason:he instanceof Error?he.message:String(he)}}),[]}}}let W=s.event==="pull_request"?"deploy.preview":"deploy.source";return[f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:W,idempotencyKey:`source:${r.id}:${n}:${D.id}:${s.commitSha}`,correlationId:`source:${n}`,input:{source:{connectionId:r.id,bindingId:D.id,repository:s.repository,commitSha:s.commitSha,branch:s.branch??null,tag:s.tag??null,monorepoRoot:D.monorepoRoot,submodules:D.submodules,cloneDepth:D.cloneDepth??null},preview:s.event==="pull_request"?{number:s.pullRequestNumber??null,action:s.action??null}:null},lockKey:D.resourceId?`resource:${D.resourceId}`:`environment:${D.environmentId??D.projectId}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:s.event==="pull_request"?14:90}).operation]});if(!k.length)return e.sources.updateDelivery(c.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:c.duplicate,status:"ignored",operations:[],message:"Verified event required no preview lifecycle change"};return e.sources.updateDelivery(c.delivery.id,{status:"enqueued",operationId:k[0]?.id}),e.controlPlane.appendEvent({organizationId:r.organizationId,projectId:a[0]?.projectId,operationId:k[0]?.id,type:"source.webhook.enqueued",payload:{webhookId:t.id,deliveryId:c.delivery.id,repository:s.repository,commitSha:s.commitSha,operationIds:k.map((D)=>D.id)}}),{accepted:!0,duplicate:c.duplicate,status:"enqueued",operations:k,message:`${k.length} deployment operation${k.length===1?"":"s"} enqueued`}}function Nt(e,t){if(!t.endpointToken)throw Error("The webhook endpoint token is only available at creation time");let r=new URL(e);if(r.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(r.hostname))throw Error("Webhook base URL must use HTTPS");return new URL(`/api/source/webhooks/${encodeURIComponent(t.endpointToken)}`,r).href}import{chmodSync as Rf,mkdtempSync as wI,rmSync as II,writeFileSync as Pf}from"node:fs";import{tmpdir as CI}from"node:os";import{join as ed,resolve as EI}from"node:path";function Df(e,t){let r=e.trim();if(/\r|\n|\0/.test(r))throw Error("Git remote contains control characters");if(r.startsWith("https://")){let i=new URL(r);if(i.username||i.password||i.search||i.hash)throw Error("HTTPS Git remotes cannot contain credentials, queries, or fragments");return i.href}let n=r.startsWith("ssh://")?new URL(r).hostname:r.match(/^git@([A-Za-z0-9.-]+):/)?.[1];if(!n)throw Error("Git remote must use credential-free HTTPS or SSH");if(!t||t.host.toLowerCase()!==n.toLowerCase())throw Error("SSH Git remote requires a deploy key with a pinned key for the same host");return r}function TI(e,t,r){let n=e.replaceAll(t,"[REMOTE]").slice(0,4000);for(let i of[r?.token,r?.privateKey])if(i)n=n.replaceAll(i,"[REDACTED]");return n}function AI(e){let t={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_NOSYSTEM:"1",GIT_OPTIONAL_LOCKS:"0"},r;if(e.credential?.token){let n=e.credential.username??"oauth2";t.GIT_CONFIG_COUNT="1",t.GIT_CONFIG_KEY_0="http.extraHeader",t.GIT_CONFIG_VALUE_0=`Authorization: Basic ${Buffer.from(`${n}:${e.credential.token}`).toString("base64")}`}if(e.deployKey){r=wI(ed(CI(),"ts-cloud-git-transport-"));let n=ed(r,"key"),i=ed(r,"known_hosts");Pf(n,e.deployKey.privateKey,{mode:384}),Pf(i,`${e.deployKey.host} ${e.deployKey.hostKey}
|
|
109
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?)`,[r,e.projectId,e.environmentId??null,e.resourceId??null,e.connectionId,e.repositoryId??null,Qu(e.repositoryFullName),e.defaultBranch?.trim()||"main",e.branchRule?.trim()||null,e.tagRule?.trim()||null,ff(e.monorepoRoot??"."),Ni(Zc(e.includePaths)),Ni(Zc(e.excludePaths)),e.submodules?1:0,e.cloneDepth??null,e.deployKeyId??null,e.autoDeploy===!1?0:1,e.pullRequestPreviews===!1?0:1,e.actorId??null,n,n]),this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:e.projectId,actorId:e.actorId,type:"source.binding.created",payload:{bindingId:r,connectionId:e.connectionId,repository:e.repositoryFullName,branch:e.defaultBranch??"main"}}),this.getBinding(r)}getBinding(e){let t=this.controlPlane.database.query("SELECT * FROM source_bindings WHERE id = ?").get(e);return t?hf(t):void 0}listBindings(e={}){return this.controlPlane.database.query("SELECT * FROM source_bindings ORDER BY created_at DESC").all().map(hf).filter((r)=>(!e.connectionId||r.connectionId===e.connectionId)&&(!e.projectId||r.projectId===e.projectId)&&(!e.status||r.status===e.status))}updateBinding(e,t,r){let n=this.getBinding(e);if(!n||n.version!==t)throw Error(`Source binding ${e} changed since version ${t}`);let i=this.getConnection(n.connectionId);if((!i||["disconnected","expired"].includes(i.status))&&(r.status==="active"||r.autoDeploy===!0))throw Error("Rotate or reconnect the source credential before enabling this binding");if(r.deployKeyId&&this.getDeployKey(r.deployKeyId)?.connectionId!==n.connectionId)throw Error("Deploy key does not belong to this connection");let o=this.now();if(this.controlPlane.database.run("UPDATE source_bindings SET default_branch=?, branch_rule=?, tag_rule=?, monorepo_root=?, include_paths=?, exclude_paths=?, submodules=?, clone_depth=?, deploy_key_id=?, auto_deploy=?, pull_request_previews=?, status=?, disabled_reason=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.defaultBranch?.trim()||n.defaultBranch,r.branchRule===void 0?n.branchRule??null:r.branchRule.trim()||null,r.tagRule===void 0?n.tagRule??null:r.tagRule.trim()||null,r.monorepoRoot===void 0?n.monorepoRoot:ff(r.monorepoRoot),Ni(r.includePaths===void 0?n.includePaths:Zc(r.includePaths)),Ni(r.excludePaths===void 0?n.excludePaths:Zc(r.excludePaths)),r.submodules??n.submodules?1:0,r.cloneDepth===void 0?n.cloneDepth??null:r.cloneDepth,r.deployKeyId===void 0?n.deployKeyId??null:r.deployKeyId,r.autoDeploy??n.autoDeploy?1:0,r.pullRequestPreviews??n.pullRequestPreviews?1:0,r.status??n.status,r.disabledReason===void 0?n.disabledReason??null:r.disabledReason.slice(0,1000),o,e,t]).changes!==1)throw Error(`Source binding ${e} changed since version ${t}`);let c=this.getConnection(n.connectionId);return this.controlPlane.appendEvent({organizationId:c.organizationId,projectId:n.projectId,actorId:r.actorId,type:"source.binding.updated",payload:{bindingId:e,fromVersion:t,toVersion:t+1,status:r.status??n.status}}),this.getBinding(e)}createWebhook(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");let r=this.idFn(),n=this.now(),i=e.endpointToken??Ku(24).toString("base64url"),o=e.secret??Ku(32).toString("base64url"),s=[...new Set(e.events??["push","pull_request"])].filter((c)=>["push","pull_request"].includes(c));if(!s.length)throw Error("At least one supported webhook event is required");return this.run("INSERT INTO source_webhooks (id, connection_id, repository_id, repository_full_name, endpoint_token_hash, endpoint_token_ciphertext, secret_ciphertext, events, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?)",[r,e.connectionId,e.repositoryId??null,Qu(e.repositoryFullName),Qo(i),this.encrypt(i),this.encrypt(o),Ni(s),n,n]),this.controlPlane.appendEvent({organizationId:t.organizationId,type:"source.webhook.created",payload:{webhookId:r,connectionId:t.id,repository:e.repositoryFullName,events:s}}),{webhook:{...this.getWebhook(r),endpointToken:i},secret:o}}getWebhook(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE id = ?").get(e);return t?Zu(t):void 0}getWebhookByEndpointToken(e){let t=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE endpoint_token_hash = ?").get(Qo(e));return t?Zu(t):void 0}getWebhookSecret(e){let t=this.controlPlane.database.query("SELECT secret_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t)throw Error("Source webhook was not found");return this.decrypt(String(t.secret_ciphertext))}getWebhookEndpointToken(e){let t=this.controlPlane.database.query("SELECT endpoint_token_ciphertext FROM source_webhooks WHERE id = ?").get(e);if(!t?.endpoint_token_ciphertext)throw Error("Source webhook endpoint token is unavailable");return this.decrypt(String(t.endpoint_token_ciphertext))}listWebhooks(e){return this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE connection_id = ? ORDER BY repository_full_name").all(e).map(Zu)}updateWebhookState(e,t){let r=this.getWebhook(e);if(!r)throw Error("Source webhook was not found");let n=this.now();this.run("UPDATE source_webhooks SET provider_webhook_id=COALESCE(?, provider_webhook_id), status=?, health_message=?, last_reconciled_at=COALESCE(?, last_reconciled_at), updated_at=? WHERE id=?",[t.providerWebhookId??null,t.status,t.healthMessage?.slice(0,1000)??null,t.reconciled?n:null,n,e]);let i=this.getConnection(r.connectionId);if(i)this.controlPlane.appendEvent({organizationId:i.organizationId,type:"source.webhook.updated",payload:{webhookId:e,connectionId:i.id,repository:r.repositoryFullName,status:t.status,reconciled:t.reconciled??!1,providerWebhookId:t.providerWebhookId??r.providerWebhookId??null}});return this.getWebhook(e)}getDeliveryByProviderId(e,t){let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE connection_id = ? AND provider_delivery_id = ?").get(e,t);return r?el(r):void 0}recordDelivery(e){let t=this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId);if(t)return{delivery:t,duplicate:!0};let r=this.idFn(),n=this.now();return this.controlPlane.database.transaction(()=>{this.run("INSERT INTO source_webhook_deliveries (id, connection_id, webhook_id, provider_delivery_id, event, action, commit_sha, signature_status, status, payload_summary, operation_id, error, received_at, processed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,e.connectionId,e.webhookId,e.providerDeliveryId,e.event.slice(0,100),e.action?.slice(0,100)??null,e.commitSha?.slice(0,128)??null,e.signatureStatus,e.status,Ni(e.payloadSummary??{}),e.operationId??null,e.error?.slice(0,2000)??null,n,["enqueued","ignored","rejected","failed"].includes(e.status)?n:null]),this.run("UPDATE source_webhooks SET last_delivery_at=?, updated_at=? WHERE id=?",[n,n,e.webhookId])})(),{delivery:this.getDeliveryByProviderId(e.connectionId,e.providerDeliveryId),duplicate:!1}}updateDelivery(e,t){this.run("UPDATE source_webhook_deliveries SET status=?, operation_id=?, error=?, processed_at=? WHERE id=?",[t.status,t.operationId??null,t.error?.slice(0,2000)??null,this.now(),e]);let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE id = ?").get(e);if(!r)throw Error("Source webhook delivery was not found");return el(r)}listDeliveries(e,t=100){return this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE webhook_id = ? ORDER BY received_at DESC LIMIT ?").all(e,Math.min(500,Math.max(1,t))).map(el)}disconnectConnection(e,t){let r=this.getConnection(e);if(!r)throw Error("Source connection was not found");let n=this.listBindings({connectionId:e,status:"active"}),i=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_connections SET status='disconnected', credential_ciphertext=NULL, health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[i,e]),this.run("UPDATE source_bindings SET status='disabled', auto_deploy=0, disabled_reason='Source connection was disconnected', version=version+1, updated_at=? WHERE connection_id=? AND status='active'",[i,e]),this.run("UPDATE source_webhooks SET status='disabled', health_message='Source connection was disconnected', updated_at=? WHERE connection_id=?",[i,e])})(),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:t,type:"source.connection.disconnected",level:"warning",payload:{connectionId:e,affectedBindingIds:n.map((o)=>o.id),affectedRepositories:n.map((o)=>o.repositoryFullName)}}),{connection:this.getConnection(e),affectedBindings:n}}}import{createSign as lI}from"node:crypto";class qs extends Error{status;retryAfterSeconds;constructor(e,t,r){super(e);this.status=t;this.retryAfterSeconds=r;this.name="SourceProviderError"}}var vf={repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0};function To(e){let t=Number(e??"1");return Number.isInteger(t)&&t>0?t:1}function Ao(e){return Math.max(1,Math.min(100,e??50))}function Pn(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 Ca(e){let t=new URL(e);if(t.username||t.password||t.protocol!=="https:")throw Error("Webhook endpoint must be credential-free HTTPS");return t.href}function Sf(e){return Buffer.from(e).toString("base64url")}function pI(e,t){if(!e.appId||!e.privateKey)throw Error("GitHub App credentials require appId and privateKey");let r=Sf(JSON.stringify({alg:"RS256",typ:"JWT"})),n=Math.floor(t.getTime()/1000)-30,i=Sf(JSON.stringify({iat:n,exp:n+540,iss:e.appId})),o=lI("RSA-SHA256");return o.update(`${r}.${i}`),o.end(),`${r}.${i}.${o.sign(e.privateKey).toString("base64url")}`}class Ea{connection;credential;capabilities=vf;fetchFn;timeoutMs;nowFn;constructor(e,t,r={}){this.connection=e;this.credential=t;this.fetchFn=r.fetch??((n,i)=>globalThis.fetch(n,i)),this.timeoutMs=Math.max(100,r.timeoutMs??20000),this.nowFn=r.now??(()=>new Date)}async request(e,t={}){let r=new URL(`${this.apiRoot().replace(/\/$/,"")}/`),n=new URL(e.replace(/^\//,""),r);if(n.origin!==r.origin)throw Error("Provider pagination cannot leave the configured host");let i=new AbortController,o=setTimeout(()=>i.abort(),this.timeoutMs);try{let s=await this.fetchFn(n,{...t,redirect:"error",signal:i.signal,headers:{Accept:"application/json","User-Agent":"ts-cloud-source/1",...await this.authorization(),...t.headers}});if(!s.ok){let c=Number(s.headers.get("retry-after")??""),u=s.headers.get("x-request-id")??s.headers.get("x-github-request-id");throw new qs(`Source provider request failed (${s.status})${u?` [request ${u}]`:""}`,s.status,Number.isFinite(c)?c:void 0)}if(s.status===204)return{data:void 0,headers:s.headers};return{data:await s.json(),headers:s.headers}}catch(s){if(s instanceof qs)throw s;if(i.signal.aborted)throw new qs(`Source provider request exceeded ${this.timeoutMs}ms`);throw new qs(s instanceof Error?s.message.replace(/(?:token|password|secret)=[^\s&]+/gi,"$1=[REDACTED]"):"Source provider request failed")}finally{clearTimeout(o)}}async deleteWebhook(e,t){await this.request(this.webhookPath(e,t),{method:"DELETE"})}}class wf extends Ea{provider="github";installationToken;apiRoot(){return this.connection.host==="https://github.com"?"https://api.github.com":`${this.connection.host}/api/v3`}async authorization(){if(this.credential?.token)return{Authorization:`Bearer ${this.credential.token}`,"X-GitHub-Api-Version":"2022-11-28"};if(!this.credential?.installationId)return{};if(!this.installationToken||this.installationToken.expiresAt<this.nowFn().getTime()+60000){let e=pI(this.credential,this.nowFn()),t=this.apiRoot().replace(/\/$/,""),r=new AbortController,n=setTimeout(()=>r.abort(),this.timeoutMs);try{let i=await this.fetchFn(`${t}/app/installations/${encodeURIComponent(this.credential.installationId)}/access_tokens`,{method:"POST",signal:r.signal,redirect:"error",headers:{Accept:"application/vnd.github+json",Authorization:`Bearer ${e}`,"X-GitHub-Api-Version":"2022-11-28","User-Agent":"ts-cloud-source/1"}});if(!i.ok)throw new qs(`GitHub App token refresh failed (${i.status})`,i.status);let o=await i.json();this.installationToken={value:o.token,expiresAt:new Date(o.expires_at).getTime()}}finally{clearTimeout(n)}}return{Authorization:`Bearer ${this.installationToken.value}`,"X-GitHub-Api-Version":"2022-11-28"}}async testConnection(){let e=this.credential?.installationId?"/installation/repositories?per_page=1":"/user",{data:t,headers:r}=await this.request(e);return{ok:!0,account:t.login??this.connection.owner,scopes:(r.get("x-oauth-scopes")??this.connection.grantedScopes.join(",")).split(",").map((n)=>n.trim()).filter(Boolean),message:"GitHub connection is healthy"}}async listRepositories(e={}){let t=Ao(e.limit),r=To(e.cursor),n=this.credential?.installationId?`/installation/repositories?per_page=${t}&page=${r}`:`/user/repos?per_page=${t}&page=${r}&sort=updated`,{data:i}=await this.request(n),o=Array.isArray(i)?i:i.repositories;return{repositories:(e.search?o.filter((c)=>c.full_name.toLowerCase().includes(e.search.toLowerCase())):o).map((c)=>({providerRepositoryId:String(c.id),fullName:c.full_name,cloneUrl:c.clone_url,defaultBranch:c.default_branch||"main",visibility:c.visibility??(c.private?"private":"public"),archived:!!c.archived,metadata:{}})),nextCursor:o.length===t?String(r+1):void 0}}async refs(e,t,r={}){let n=Ao(r.limit),i=To(r.cursor),{data:o}=await this.request(`/repos/${Pn(e)}/${t}?per_page=${n}&page=${i}`);return{refs:o.map((s)=>({name:s.name,commitSha:s.commit.sha,protected:s.protected})),nextCursor:o.length===n?String(i+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Pn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events,url:e.config.url??""}}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:JSON.stringify({name:"web",active:!0,events:t.events,config:{url:Ca(t.url),content_type:"json",secret:t.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:JSON.stringify({active:!0,events:r.events,config:{url:Ca(r.url),content_type:"json",secret:r.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){await this.request(`/repos/${Pn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}class If extends Ea{provider="gitlab";apiRoot(){return`${this.connection.host}/api/v4`}async authorization(){return this.credential?.token?{"PRIVATE-TOKEN":this.credential.token}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username,scopes:this.connection.grantedScopes,message:"GitLab connection is healthy"}}async listRepositories(e={}){let t=Ao(e.limit),r=To(e.cursor),n=e.search?`&search=${encodeURIComponent(e.search)}`:"",{data:i,headers:o}=await this.request(`/projects?membership=true&simple=true&order_by=last_activity_at&per_page=${t}&page=${r}${n}`);return{repositories:i.map((s)=>({providerRepositoryId:String(s.id),fullName:s.path_with_namespace,cloneUrl:s.http_url_to_repo,defaultBranch:s.default_branch??"main",visibility:s.visibility??"unknown",archived:!!s.archived,metadata:{}})),nextCursor:o.get("x-next-page")||void 0}}async refs(e,t,r={}){let n=Ao(r.limit),i=To(r.cursor),{data:o,headers:s}=await this.request(`/projects/${encodeURIComponent(Pn(e))}/repository/${t}?per_page=${n}&page=${i}`);return{refs:o.map((c)=>({name:c.name,commitSha:c.commit.id,protected:c.protected})),nextCursor:s.get("x-next-page")||void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/projects/${encodeURIComponent(Pn(e))}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:!0,events:[...e.push_events?["push"]:[],...e.merge_requests_events?["pull_request"]:[]],url:e.url}}body(e){return JSON.stringify({url:Ca(e.url),token:e.secret,enable_ssl_verification:!0,push_events:e.events.includes("push"),merge_requests_events:e.events.includes("pull_request")})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){let n=r.state==="failure"||r.state==="error"?"failed":r.state;await this.request(`/projects/${encodeURIComponent(Pn(e))}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n,target_url:r.url,description:r.description.slice(0,255),name:r.context??"ts-cloud/preview"})})}}class Cf extends Ea{provider="bitbucket";apiRoot(){return this.connection.host==="https://bitbucket.org"?"https://api.bitbucket.org/2.0":`${this.connection.host}/2.0`}async authorization(){return this.credential?.token?{Authorization:`Bearer ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.username??e.display_name,scopes:this.connection.grantedScopes,message:"Bitbucket connection is healthy"}}async listRepositories(e={}){if(!this.connection.owner)throw Error("Bitbucket repository discovery requires an owner/workspace");let t=To(e.cursor),r=Ao(e.limit),n=e.search?`&q=name~%22${encodeURIComponent(e.search)}%22`:"",{data:i}=await this.request(`/repositories/${encodeURIComponent(this.connection.owner)}?pagelen=${r}&page=${t}${n}`);return{repositories:i.values.map((o)=>({providerRepositoryId:o.uuid,fullName:o.full_name,cloneUrl:o.links.clone.find((s)=>s.name==="https")?.href??o.links.clone[0]?.href??"",defaultBranch:o.mainbranch?.name??"main",visibility:o.is_private?"private":"public",archived:!1,metadata:{}})),nextCursor:i.next?String(t+1):void 0}}async refs(e,t,r={}){let n=To(r.cursor),i=Ao(r.limit),{data:o}=await this.request(`/repositories/${Pn(e)}/refs/${t}?pagelen=${i}&page=${n}`);return{refs:o.values.map((s)=>({name:s.name,commitSha:s.target.hash})),nextCursor:o.next?String(n+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repositories/${Pn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:e.uuid,active:e.active,events:e.events.map((t)=>t.replace("repo:push","push").replace("pullrequest:","pull_request:")),url:e.url}}body(e){return JSON.stringify({description:"ts-cloud deploy",url:Ca(e.url),active:!0,events:e.events.map((t)=>t==="push"?"repo:push":t.replace("pull_request:","pullrequest:"))})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.values.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){let n=r.state==="success"?"SUCCESSFUL":r.state==="pending"?"INPROGRESS":"FAILED";await this.request(`/repositories/${Pn(e)}/commit/${encodeURIComponent(t)}/statuses/build/ts-cloud-preview`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n,key:"ts-cloud-preview",name:r.context??"ts-cloud/preview",url:r.url,description:r.description.slice(0,255)})})}}class Ef extends Ea{provider="gitea";capabilities={...vf,tokenRefresh:!1};apiRoot(){return`${this.connection.host}/api/v1`}async authorization(){return this.credential?.token?{Authorization:`token ${this.credential.token}`}:{}}async testConnection(){let{data:e}=await this.request("/user");return{ok:!0,account:e.login,scopes:this.connection.grantedScopes,message:"Gitea connection is healthy"}}async listRepositories(e={}){let t=To(e.cursor),r=Ao(e.limit),n=e.search?`/repos/search?q=${encodeURIComponent(e.search)}&limit=${r}&page=${t}`:`/user/repos?limit=${r}&page=${t}`,{data:i,headers:o}=await this.request(n),s=Array.isArray(i)?i:i.data;return{repositories:s.map((c)=>({providerRepositoryId:String(c.id),fullName:c.full_name,cloneUrl:c.clone_url,defaultBranch:c.default_branch??"main",visibility:c.private?"private":"public",archived:!!c.archived,metadata:{}})),nextCursor:o.get("x-hasmore")==="true"||s.length===r?String(t+1):void 0}}async refs(e,t,r={}){let n=To(r.cursor),i=Ao(r.limit),{data:o}=await this.request(`/repos/${Pn(e)}/${t}?limit=${i}&page=${n}`);return{refs:o.map((s)=>({name:s.name,commitSha:s.commit.id})),nextCursor:o.length===i?String(n+1):void 0}}listBranches(e,t){return this.refs(e,"branches",t)}listTags(e,t){return this.refs(e,"tags",t)}webhookPath(e,t){return`/repos/${Pn(e)}/hooks${t?`/${encodeURIComponent(t)}`:""}`}hook(e){return{providerWebhookId:String(e.id),active:e.active,events:e.events??[],url:e.config.url??""}}body(e){return JSON.stringify({type:"gitea",active:!0,events:e.events,config:{url:Ca(e.url),content_type:"json",secret:e.secret,insecure_ssl:"0"}})}async createWebhook(e,t){let{data:r}=await this.request(this.webhookPath(e),{method:"POST",body:this.body(t),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(e){let{data:t}=await this.request(this.webhookPath(e));return t.map((r)=>this.hook(r))}async updateWebhook(e,t,r){let{data:n}=await this.request(this.webhookPath(e,t),{method:"PATCH",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(n)}async setCommitStatus(e,t,r){await this.request(`/repos/${Pn(e)}/statuses/${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}function ko(e,t,r={}){switch(e.provider){case"github":return new wf(e,t,r);case"gitlab":return new If(e,t,r);case"bitbucket":return new Cf(e,t,r);case"gitea":return new Ef(e,t,r);default:throw Error(`${e.provider} uses bounded Git discovery instead of a hosted provider API`)}}import{createHmac as gI,timingSafeEqual as mI}from"node:crypto";function en(e,t){if(e instanceof Headers)return e.get(t)??void 0;return Object.entries(e).find(([n])=>n.toLowerCase()===t.toLowerCase())?.[1]}function Tf(e,t){let r=Buffer.from(e),n=Buffer.from(t);return r.length===n.length&&mI(r,n)}function fI(e,t){return gI("sha256",e).update(t).digest("hex")}function hI(e,t,r,n,i){if(e==="gitlab")return Tf(en(r,"x-gitlab-token")??"",t);let o=e==="github"?en(r,"x-hub-signature-256"):e==="gitea"?en(r,"x-gitea-signature"):en(r,"x-hub-signature")??en(r,"x-ts-cloud-signature");if(!o)return!1;if(e==="generic_https"||e==="generic_ssh"){let s=Number(en(r,"x-ts-cloud-timestamp"));if(!Number.isFinite(s)||Math.abs(i.getTime()-s*1000)>300000)return!1}return Tf(o.replace(/^sha256=/,""),fI(t,n))}function yI(e,t){return{github:["x-github-delivery"],gitlab:["x-gitlab-event-uuid","x-request-id"],bitbucket:["x-request-uuid"],gitea:["x-gitea-delivery"],generic_https:["x-ts-cloud-delivery"],generic_ssh:["x-ts-cloud-delivery"]}[e].map((n)=>en(t,n)?.trim()).find(Boolean)}function Ro(e){let t=String(e??"").trim().replace(/^\/+|\/+$/g,"");return/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(t)?t:""}function tl(e){return[...new Set(e.flatMap((t)=>{if(!t||typeof t!=="object")return[];let r=t;return[...r.added??[],...r.modified??[],...r.removed??[]].map(String)}).filter((t)=>t&&!t.includes("\x00")).slice(0,500))]}function bI(e,t,r){let n=e,i=t,o=r;if(n==="github"){let s=en(i,"x-github-event"),c=Ro(o.repository?.full_name);if(s==="push")return{event:"push",repository:c,ref:String(o.ref??""),branch:String(o.ref??"").replace(/^refs\/heads\//,""),tag:String(o.ref??"").startsWith("refs/tags/")?String(o.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(o.after??o.head_commit?.id??""),changedPaths:tl(o.commits??[]),deleted:o.deleted===!0||/^0{40,64}$/.test(String(o.after??""))};if(s==="pull_request")return{event:"pull_request",action:String(o.action??""),repository:c,branch:String(o.pull_request?.head?.ref??""),commitSha:String(o.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(o.number)||void 0,fork:Ro(o.pull_request?.head?.repo?.full_name)!==c}}if(n==="gitlab"){let s=String(o.object_kind??"").toLowerCase(),c=Ro(o.project?.path_with_namespace);if(s==="push"||s==="tag_push")return{event:"push",repository:c,ref:String(o.ref??""),branch:String(o.ref??"").replace(/^refs\/heads\//,""),tag:s==="tag_push"?String(o.ref??"").replace(/^refs\/tags\//,""):void 0,commitSha:String(o.checkout_sha??o.after??""),changedPaths:tl(o.commits??[]),deleted:/^0{40,64}$/.test(String(o.after??""))};if(s==="merge_request")return{event:"pull_request",action:String(o.object_attributes?.action??o.object_attributes?.state??""),repository:c,branch:String(o.object_attributes?.source_branch??""),commitSha:String(o.object_attributes?.last_commit?.id??""),changedPaths:[],pullRequestNumber:Number(o.object_attributes?.iid)||void 0,fork:o.object_attributes?.source_project_id!==o.object_attributes?.target_project_id}}if(n==="bitbucket"){let s=en(i,"x-event-key")??"",c=Ro(o.repository?.full_name);if(s==="repo:push"){let u=o.push?.changes?.[0]??{},a=u.new??u.old??{},f=u.new?.target??u.old?.target;return{event:"push",repository:c,ref:String(a.name??""),branch:a.type==="branch"?String(a.name):void 0,tag:a.type==="tag"?String(a.name):void 0,commitSha:String(f?.hash??""),changedPaths:[],deleted:u.closed===!0||u.new==null}}if(s.startsWith("pullrequest:"))return{event:"pull_request",action:s.replace("pullrequest:",""),repository:c,branch:String(o.pullrequest?.source?.branch?.name??""),commitSha:String(o.pullrequest?.source?.commit?.hash??""),changedPaths:[],pullRequestNumber:Number(o.pullrequest?.id)||void 0,fork:Ro(o.pullrequest?.source?.repository?.full_name)!==c}}if(n==="gitea"){let s=en(i,"x-gitea-event"),c=Ro(o.repository?.full_name);if(s==="push")return{event:"push",repository:c,ref:String(o.ref??""),branch:String(o.ref??"").replace(/^refs\/heads\//,""),tag:String(o.ref??"").startsWith("refs/tags/")?String(o.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(o.after??""),changedPaths:tl(o.commits??[]),deleted:o.deleted===!0||/^0{40,64}$/.test(String(o.after??""))};if(s==="pull_request")return{event:"pull_request",action:String(o.action??""),repository:c,branch:String(o.pull_request?.head?.ref??""),commitSha:String(o.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(o.number)||void 0,fork:Ro(o.pull_request?.head?.repo?.full_name)!==c}}if(n==="generic_https"||n==="generic_ssh"){if(o.event!=="push"&&o.event!=="pull_request")return;return{event:o.event,action:typeof o.action==="string"?o.action:void 0,repository:Ro(o.repository),ref:typeof o.ref==="string"?o.ref:void 0,branch:typeof o.branch==="string"?o.branch:void 0,tag:typeof o.tag==="string"?o.tag:void 0,commitSha:String(o.commitSha??""),changedPaths:Array.isArray(o.changedPaths)?o.changedPaths.map(String).slice(0,500):[],pullRequestNumber:Number(o.pullRequestNumber)||void 0,fork:o.fork===!0,deleted:o.deleted===!0}}return}function Js(e,t){let r="^";for(let n=0;n<t.length;n++){let i=t[n];if(i==="*"&&t[n+1]==="*")r+=".*",n++;else if(i==="*")r+="[^/]*";else if(i==="?")r+="[^/]";else r+=i.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")}return new RegExp(`${r}$`).test(e)}function SI(e,t){if(t.event==="pull_request")return e.pullRequestPreviews;if(!e.autoDeploy)return!1;if(t.tag)return!!e.tagRule&&Js(t.tag,e.tagRule);return Js(t.branch??"",e.branchRule??e.defaultBranch)}function vI(e,t){if(!t.length)return!0;return t.filter((n)=>!e.excludePaths.some((i)=>Js(n,i))).some((n)=>!e.includePaths.length||e.includePaths.some((i)=>Js(n,i)))}function Af(e,t){return en(t,e==="github"?"x-github-event":e==="gitlab"?"x-gitlab-event":e==="bitbucket"?"x-event-key":e==="gitea"?"x-gitea-event":"x-ts-cloud-event")??"unknown"}function Xo(){return{accepted:!1,duplicate:!1,status:"rejected",operations:[],message:"Webhook unavailable"}}async function kf(e){if(e.rawBody.byteLength>2097152)return Xo();let t=e.sources.getWebhookByEndpointToken(e.endpointToken);if(!t||t.status==="disabled")return Xo();let r=e.sources.getConnection(t.connectionId);if(!r||r.status==="disconnected"||r.status==="expired")return Xo();let n=yI(r.provider,e.headers);if(!n||n.length>200)return Xo();if(!hI(r.provider,e.sources.getWebhookSecret(t.id),e.headers,e.rawBody,e.now??new Date))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:n,event:Af(r.provider,e.headers),signatureStatus:en(e.headers,"x-hub-signature-256")||en(e.headers,"x-gitlab-token")||en(e.headers,"x-hub-signature")||en(e.headers,"x-gitea-signature")?"invalid":"missing",status:"rejected",error:"Webhook signature verification failed"}),Xo();let o;try{o=JSON.parse(new TextDecoder().decode(e.rawBody))}catch{return Xo()}let s=bI(r.provider,e.headers,o);if(!s||!s.repository||!/^[a-f0-9]{7,64}$/i.test(s.commitSha))return e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:n,event:Af(r.provider,e.headers),signatureStatus:"verified",status:"rejected",error:"Unsupported or malformed source event"}),Xo();let c=e.sources.recordDelivery({connectionId:r.id,webhookId:t.id,providerDeliveryId:n,event:s.event,action:s.action,commitSha:s.commitSha,signatureStatus:"verified",status:"accepted",payloadSummary:{repository:s.repository,ref:s.ref??null,branch:s.branch??null,tag:s.tag??null,commitSha:s.commitSha,pullRequestNumber:s.pullRequestNumber??null,changedPathCount:s.changedPaths.length}});if(c.duplicate&&c.delivery.status!=="accepted")return{accepted:!0,duplicate:!0,status:"duplicate",operations:[],message:"Delivery already processed"};let u=new Fe(e.controlPlane),a=e.sources.listBindings({connectionId:r.id,status:"active"}).filter((D)=>{if(D.repositoryFullName.toLowerCase()!==s.repository.toLowerCase()||!vI(D,s.changedPaths))return!1;let W=D.resourceId?u.getDefinitionForResource(D.resourceId):void 0,Y=s.event==="push"&&!!W?.branchRule&&!!s.branch&&Js(s.branch,W.branchRule);return SI(D,s)||Y});if(!a.length)return e.sources.updateDelivery(c.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:c.duplicate,status:"ignored",operations:[],message:"Verified event did not match an active deployment rule"};let f=new S(e.controlPlane),C=new Set(["closed","merged","declined"]),k=a.flatMap((D)=>{if(s.event==="push"&&D.resourceId&&s.branch){let Y=u.getDefinitionForResource(D.resourceId);if(Y?.branchRule&&Js(s.branch,Y.branchRule)){let ee=u.findForBranch(Y.id,s.repository,s.branch);if(s.deleted){if(!Y.cleanupOnClose||!ee||ee.status==="destroyed")return[];let Pe=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${ee.id}:branch-delete:${n}`,correlationId:`preview:${ee.id}`,input:{previewId:ee.id,reason:"branch_deleted",source:{repository:s.repository,commitSha:s.commitSha,branch:s.branch}},lockKey:`preview:${ee.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(ee.id,"queued",{operationId:Pe.id}),[Pe]}let ne=u.upsert({definitionId:Y.id,sourceProvider:r.provider,repository:s.repository,branch:s.branch,commitSha:s.commitSha});if(!ne.changed)return[];let he=ne.created?"preview.create":"preview.update",te=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:he,idempotencyKey:`preview:${ne.preview.id}:${s.commitSha}`,correlationId:`preview:${ne.preview.id}`,input:{previewId:ne.preview.id,source:{connectionId:r.id,bindingId:D.id,repository:s.repository,commitSha:s.commitSha,branch:s.branch,monorepoRoot:D.monorepoRoot,submodules:D.submodules,cloneDepth:D.cloneDepth??null}},lockKey:`preview:${ne.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(ne.preview.id,"queued",{operationId:te.id}),[te]}}if(s.event==="pull_request"&&D.resourceId&&s.pullRequestNumber){let Y=u.getDefinitionForResource(D.resourceId);if(Y){let ee=C.has(String(s.action??"").toLowerCase()),ne=u.findForPullRequest(Y.id,s.repository,s.pullRequestNumber);if(ee){if(!Y.cleanupOnClose||!ne||ne.status==="destroyed")return[];let he=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${ne.id}:destroy:${n}`,correlationId:`preview:${ne.id}`,input:{previewId:ne.id,reason:"pull_request_closed",source:{repository:s.repository,commitSha:s.commitSha,branch:s.branch??null,pullRequestNumber:s.pullRequestNumber}},lockKey:`preview:${ne.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(ne.id,"queued",{operationId:he.id}),[he]}try{let he=u.upsert({definitionId:Y.id,sourceProvider:r.provider,repository:s.repository,branch:s.branch??`pr-${s.pullRequestNumber}`,pullRequestNumber:s.pullRequestNumber,fork:s.fork,commitSha:s.commitSha});if(!he.changed)return[];let te=he.created?"preview.create":"preview.update",Pe=f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:te,idempotencyKey:`preview:${he.preview.id}:${s.commitSha}`,correlationId:`preview:${he.preview.id}`,input:{previewId:he.preview.id,source:{connectionId:r.id,bindingId:D.id,repository:s.repository,commitSha:s.commitSha,branch:s.branch??null,pullRequestNumber:s.pullRequestNumber,fork:!!s.fork,monorepoRoot:D.monorepoRoot,submodules:D.submodules,cloneDepth:D.cloneDepth??null},inheritedSecretNames:he.inheritedSecrets},lockKey:`preview:${he.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return u.transition(he.preview.id,"queued",{operationId:Pe.id}),[Pe]}catch(he){return e.controlPlane.appendEvent({projectId:D.projectId,resourceId:D.resourceId,type:"preview.rejected",level:"warning",payload:{repository:s.repository,pullRequestNumber:s.pullRequestNumber,fork:!!s.fork,reason:he instanceof Error?he.message:String(he)}}),[]}}}let W=s.event==="pull_request"?"deploy.preview":"deploy.source";return[f.enqueue({projectId:D.projectId,environmentId:D.environmentId,resourceId:D.resourceId,kind:W,idempotencyKey:`source:${r.id}:${n}:${D.id}:${s.commitSha}`,correlationId:`source:${n}`,input:{source:{connectionId:r.id,bindingId:D.id,repository:s.repository,commitSha:s.commitSha,branch:s.branch??null,tag:s.tag??null,monorepoRoot:D.monorepoRoot,submodules:D.submodules,cloneDepth:D.cloneDepth??null},preview:s.event==="pull_request"?{number:s.pullRequestNumber??null,action:s.action??null}:null},lockKey:D.resourceId?`resource:${D.resourceId}`:`environment:${D.environmentId??D.projectId}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:s.event==="pull_request"?14:90}).operation]});if(!k.length)return e.sources.updateDelivery(c.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:c.duplicate,status:"ignored",operations:[],message:"Verified event required no preview lifecycle change"};return e.sources.updateDelivery(c.delivery.id,{status:"enqueued",operationId:k[0]?.id}),e.controlPlane.appendEvent({organizationId:r.organizationId,projectId:a[0]?.projectId,operationId:k[0]?.id,type:"source.webhook.enqueued",payload:{webhookId:t.id,deliveryId:c.delivery.id,repository:s.repository,commitSha:s.commitSha,operationIds:k.map((D)=>D.id)}}),{accepted:!0,duplicate:c.duplicate,status:"enqueued",operations:k,message:`${k.length} deployment operation${k.length===1?"":"s"} enqueued`}}function Nt(e,t){if(!t.endpointToken)throw Error("The webhook endpoint token is only available at creation time");let r=new URL(e);if(r.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(r.hostname))throw Error("Webhook base URL must use HTTPS");return new URL(`/api/source/webhooks/${encodeURIComponent(t.endpointToken)}`,r).href}import{chmodSync as Rf,mkdtempSync as wI,rmSync as II,writeFileSync as Pf}from"node:fs";import{tmpdir as CI}from"node:os";import{join as ed,resolve as EI}from"node:path";function Df(e,t){let r=e.trim();if(/\r|\n|\0/.test(r))throw Error("Git remote contains control characters");if(r.startsWith("https://")){let i=new URL(r);if(i.username||i.password||i.search||i.hash)throw Error("HTTPS Git remotes cannot contain credentials, queries, or fragments");return i.href}let n=r.startsWith("ssh://")?new URL(r).hostname:r.match(/^git@([A-Za-z0-9.-]+):/)?.[1];if(!n)throw Error("Git remote must use credential-free HTTPS or SSH");if(!t||t.host.toLowerCase()!==n.toLowerCase())throw Error("SSH Git remote requires a deploy key with a pinned key for the same host");return r}function TI(e,t,r){let n=e.replaceAll(t,"[REMOTE]").slice(0,4000);for(let i of[r?.token,r?.privateKey])if(i)n=n.replaceAll(i,"[REDACTED]");return n}function AI(e){let t={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_NOSYSTEM:"1",GIT_OPTIONAL_LOCKS:"0"},r;if(e.credential?.token){let n=e.credential.username??"oauth2";t.GIT_CONFIG_COUNT="1",t.GIT_CONFIG_KEY_0="http.extraHeader",t.GIT_CONFIG_VALUE_0=`Authorization: Basic ${Buffer.from(`${n}:${e.credential.token}`).toString("base64")}`}if(e.deployKey){r=wI(ed(CI(),"ts-cloud-git-transport-"));let n=ed(r,"key"),i=ed(r,"known_hosts");Pf(n,e.deployKey.privateKey,{mode:384}),Pf(i,`${e.deployKey.host} ${e.deployKey.hostKey}
|
|
110
110
|
`,{mode:384}),Rf(n,384),Rf(i,384),t.GIT_SSH_COMMAND=`ssh -i ${n} -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=${i} -o GlobalKnownHostsFile=/dev/null -o BatchMode=yes`}return{env:t,cleanup:()=>{if(r)II(r,{recursive:!0,force:!0})}}}async function Zo(e,t,r){let n=AI(r),i=Bun.spawn([r.executable??"git",...e],{stdout:"pipe",stderr:"pipe",env:n.env}),o=Math.max(100,r.timeoutMs??120000),s,c=new Promise((u,a)=>{s=setTimeout(()=>{i.kill(),a(Error(`Git operation exceeded ${o}ms`))},o)});try{let u=Promise.all([i.exited,new Response(i.stdout).text(),new Response(i.stderr).text()]),[a,f,C]=await Promise.race([u,c]);if(a!==0)throw Error(TI(C||`Git exited with ${a}`,t,r.credential));return f}finally{if(s)clearTimeout(s);n.cleanup()}}function xf(e,t){let r=new Map;for(let n of e.split(`
|
|
111
|
-
`)){let i=n.trim().match(/^([a-f0-9]{40,64})\s+(.+)$/i);if(!i||!i[2].startsWith(t)||i[2].endsWith("^{}"))continue;let o=i[2].slice(t.length);r.set(o,{name:o,commitSha:i[1]})}return[...r.values()].sort((n,i)=>n.name.localeCompare(i.name))}async function rl(e,t={}){let r=Df(e,t.deployKey),n=await Zo(["ls-remote","--heads","--tags","--",r],r,t);return{branches:xf(n,"refs/heads/"),tags:xf(n,"refs/tags/")}}async function nl(e,t={}){let r=Df(e.remote,t.deployKey),n=EI(e.destination),i=e.ref?.trim()||e.binding.defaultBranch;if(!/^[A-Za-z0-9._/-]{1,255}$/.test(i)||i.startsWith("-")||i.includes(".."))throw Error("Git ref contains unsupported characters");let o=["clone","--no-tags","--single-branch","--branch",i],s=[...new Set(e.sparsePaths??[])];if(s.some((u)=>!u||u.startsWith("/")||u.split("/").includes("..")||/[\0\r\n]/.test(u)))throw Error("Sparse checkout paths must stay inside the repository");if(s.length)o.push("--filter=blob:none","--no-checkout");if(e.binding.cloneDepth)o.push("--depth",String(e.binding.cloneDepth));if(e.binding.submodules)o.push("--recurse-submodules","--shallow-submodules");if(o.push("--",r,n),await Zo(o,r,t),s.length)await Zo(["-C",n,"sparse-checkout","set","--cone","--",...s],r,t),await Zo(["-C",n,"checkout","--force"],r,t);if(e.commitSha){if(!/^[a-f0-9]{40,64}$/i.test(e.commitSha))throw Error("Expected source commit must be an immutable 40-64 character SHA");await Zo(["-C",n,"fetch","--no-tags","--depth","1","origin",e.commitSha],r,t),await Zo(["-C",n,"checkout","--detach","--force",e.commitSha],r,t)}let c=(await Zo(["-C",n,"rev-parse","HEAD"],r,t)).trim();if(!/^[a-f0-9]{40,64}$/i.test(c))throw Error("Git clone did not produce a valid commit SHA");if(e.commitSha&&c.toLowerCase()!==e.commitSha.toLowerCase())throw Error(`Git checkout resolved ${c} instead of the requested immutable commit`);return{directory:e.binding.monorepoRoot==="."?n:ed(n,e.binding.monorepoRoot),commitSha:c}}function Ta(e){return["github","gitlab","bitbucket","gitea"].includes(e)}async function il(e,t,r){let n=e.getConnection(t);if(!n||["disconnected","expired"].includes(n.status))throw Error("Active source connection was not found");try{if(Ta(n.provider)){let s=await ko(n,e.getCredential(n.id)).testConnection();return e.updateHealth(n.id,{status:s.ok?"healthy":"degraded",message:s.message,tested:!0,grantedScopes:s.scopes})}let i=r?e.getRepository(r):e.listRepositories(n.id,void 0,1)[0];if(!i)return e.updateHealth(n.id,{status:"degraded",message:"Add a repository URL before testing this generic connection.",tested:!0});let o=n.provider==="generic_ssh"?e.listBindings({connectionId:n.id}).map((s)=>s.deployKeyId).filter(Boolean).map((s)=>e.getDeployKey(s)).find(Boolean):void 0;return await rl(i.cloneUrl,{credential:e.getCredential(n.id),deployKey:o?{...o,privateKey:e.getDeployPrivateKey(o.id)}:void 0}),e.updateHealth(n.id,{status:"healthy",message:"Git repository access is healthy.",tested:!0})}catch(i){return e.updateHealth(n.id,{status:"degraded",message:i instanceof Error?i.message:"Connection test failed",tested:!0})}}async function Gr(e,t,r={}){let n=e.getConnection(t);if(!n||!Ta(n.provider)||["disconnected","expired"].includes(n.status))throw Error("A hosted active source connection is required for repository discovery");let i=ko(n,e.getCredential(n.id)),o=[],s;for(let c=0;c<Math.min(20,Math.max(1,r.maxPages??10));c++){let u=await i.listRepositories({cursor:s,search:r.search,limit:100});for(let a of u.repositories)o.push(e.upsertRepository({connectionId:n.id,...a}));if(s=u.nextCursor,!s)break}return e.updateHealth(n.id,{status:"healthy",message:`${o.length} repositories synchronized.`,synced:!0}),o}async function or(e,t){let r=e.getConnection(t.connectionId);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active source connection was not found");if(Ta(r.provider)){let c=ko(r,e.getCredential(r.id));return t.type==="tags"?c.listTags(t.repository,t):c.listBranches(t.repository,t)}let n=t.repositoryId?e.getRepository(t.repositoryId):e.listRepositories(r.id).find((c)=>c.fullName===t.repository);if(!n||n.connectionId!==r.id)throw Error("Generic repository metadata was not found");let i=t.deployKeyId?e.getDeployKey(t.deployKeyId):void 0;if(i&&i.connectionId!==r.id)throw Error("Deploy key does not belong to this connection");let o=await rl(n.cloneUrl,{credential:e.getCredential(r.id),deployKey:i?{...i,privateKey:e.getDeployPrivateKey(i.id)}:void 0});return{refs:(t.type==="tags"?o.tags:o.branches).slice(0,Math.min(500,t.limit??100))}}async function sr(e,t,r){let n=e.getWebhook(t),i=n?e.getConnection(n.connectionId):void 0;if(!n||!i||["disconnected","expired"].includes(i.status))throw Error("Active source webhook was not found");let o=Nt(r,{...n,endpointToken:e.getWebhookEndpointToken(n.id)});if(!Ta(i.provider))return e.updateWebhookState(n.id,{status:"healthy",healthMessage:"Manual webhook endpoint is ready.",reconciled:!0});try{let s=ko(i,e.getCredential(i.id)),c=e.getWebhookSecret(n.id),u=n.providerWebhookId?await s.updateWebhook(n.repositoryFullName,n.providerWebhookId,{url:o,secret:c,events:n.events}):await s.createWebhook(n.repositoryFullName,{url:o,secret:c,events:n.events});return e.updateWebhookState(n.id,{providerWebhookId:u.providerWebhookId,status:u.active?"healthy":"degraded",healthMessage:u.active?"Provider webhook is synchronized.":"Provider webhook exists but is inactive.",reconciled:!0})}catch(s){return e.updateWebhookState(n.id,{status:"degraded",healthMessage:s instanceof Error?s.message:"Webhook reconciliation failed",reconciled:!0})}}async function Xi(e,t){let r=e.getWebhook(t),n=r?e.getConnection(r.connectionId):void 0;if(!r||!n)throw Error("Source webhook was not found");if(Ta(n.provider)&&r.providerWebhookId&&!["disconnected","expired"].includes(n.status))await ko(n,e.getCredential(n.id)).deleteWebhook(r.repositoryFullName,r.providerWebhookId);return e.updateWebhookState(r.id,{status:"disabled",healthMessage:"Webhook disabled."})}import{lstatSync as kI,readdirSync as RI,readFileSync as PI}from"node:fs";import{relative as xI,resolve as Of,sep as DI}from"node:path";function OI(e){return new Map(e.map((t)=>[t.path.replace(/^\.\//,"").replace(/\\/g,"/"),t]))}function es(e,t,r){return{path:e,reason:t,weight:r}}function _f(e){try{return e?.content?JSON.parse(e.content):{}}catch{return{}}}function Ws(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 xt(e){let t=OI(e.slice(0,1e4)),r=[];if(t.has("Dockerfile"))r.push(Ws("dockerfile","dockerfile",0.99,[es("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=_f(t.get("composer.json"));if(t.has("artisan")&&n.require?.["laravel/framework"])r.push(Ws("laravel","server",0.98,[es("artisan","Laravel Artisan entrypoint is present.",0.45),es("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(Ws("php","server",0.82,[es("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=_f(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",u=[es("package.json",`Defines ${i.scripts?.build?"build and ":""}${i.scripts?.start?"start ":""}scripts.`,0.55)];if(o)u.push(es(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,f=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(Ws(c,f.kind,Math.min(0.94,u.reduce((C,k)=>C+k.weight,0)),u,f,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(Ws("static","static",0.78,[es(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(Ws("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 Zn(e,t={}){let r=Of(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"]),u=(a)=>{for(let f of RI(a).sort()){if(c.has(f))continue;let C=Of(a,f),k=xI(r,C).split(DI).join("/");if(!k||k.startsWith("../"))throw Error("Detection path escaped the application root");let D=kI(C);if(D.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${k}`);if(D.isDirectory())u(C);else if(D.isFile()){if(o.length>=n)throw Error("Application file-count limit exceeded");let W={path:k,size:D.size};if(s.has(k)&&D.size<=i)W.content=PI(C,"utf8");o.push(W)}}};return u(r),o}function sl(e){if(Array.isArray(e))return`[${e.map(sl).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)}:${sl(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function Aa(e){return!!e&&!e.startsWith("/")&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function gn(e,t,r,n){return{path:e,code:t,message:r,alternatives:n}}function ol(e){return JSON.parse(JSON.stringify(e))}function _I(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 ol({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 ol({serverless:{apps:{[e.slug]:{source:e.source,build:e.build,architecture:e.runtime.architecture,environment:t,domain:e.domain}}}});return ol({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 de(e,t=[]){let r=[],n=(W)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(W),i=Object.fromEntries(Object.entries(e.environment??{}).map(([W,Y])=>{if(typeof Y==="string"&&n(W))return r.push(gn(`environment.${W}`,"write_only_secret_required",`${W} must be supplied through the write-only secrets boundary.`)),[W,{secretRef:W}];return[W,Y]})),o=e.build;if(e.build.kind==="dockerfile"&&e.build.buildArgs){let W=Object.fromEntries(Object.entries(e.build.buildArgs).map(([Y,ee])=>{if(n(Y))return r.push(gn(`build.buildArgs.${Y}`,"write_only_build_secret_required",`${Y} must be declared in secretNames instead of buildArgs.`)),[Y,"[REDACTED]"];return[Y,ee]}));o={...e.build,buildArgs:W}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.slug))r.push(gn("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!Aa((e.source.kind==="git"?e.source.monorepoRoot:e.source.kind==="local"?e.source.root:".")??"."))r.push(gn("source","unsafe_source_root","Source root must stay inside the source tree."));if(e.source.kind==="git"&&e.source.sparsePaths?.some((W)=>!Aa(W)))r.push(gn("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(e.build.kind==="dockerfile"&&(!Aa(e.build.context)||!Aa(e.build.dockerfile)))r.push(gn("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(e.build.kind==="static"&&!Aa(e.build.publishDirectory))r.push(gn("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(e.build.kind==="server"&&!e.build.startCommand.trim())r.push(gn("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(gn("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(gn("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(gn("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(gn("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(gn("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(gn("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let c=Object.values(i).flatMap((W)=>typeof W==="object"?[W.secretRef]:[]),u=[...new Set([...e.requiredSecretNames??[],...e.build.kind==="dockerfile"?e.build.secretNames??[]:[],...c])].sort(),a=new Set(t),f=u.filter((W)=>!a.has(W)),C={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}},k=[...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(),D=[...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&&f.length===0,issues:r,missingSecrets:f,manifest:C,configPatch:_I({...e,build:o,environment:i}),capabilityRequirements:k,costDrivers:D,serializedManifest:`${sl(C)}
|
|
111
|
+
`)){let i=n.trim().match(/^([a-f0-9]{40,64})\s+(.+)$/i);if(!i||!i[2].startsWith(t)||i[2].endsWith("^{}"))continue;let o=i[2].slice(t.length);r.set(o,{name:o,commitSha:i[1]})}return[...r.values()].sort((n,i)=>n.name.localeCompare(i.name))}async function rl(e,t={}){let r=Df(e,t.deployKey),n=await Zo(["ls-remote","--heads","--tags","--",r],r,t);return{branches:xf(n,"refs/heads/"),tags:xf(n,"refs/tags/")}}async function nl(e,t={}){let r=Df(e.remote,t.deployKey),n=EI(e.destination),i=e.ref?.trim()||e.binding.defaultBranch;if(!/^[A-Za-z0-9._/-]{1,255}$/.test(i)||i.startsWith("-")||i.includes(".."))throw Error("Git ref contains unsupported characters");let o=["clone","--no-tags","--single-branch","--branch",i],s=[...new Set(e.sparsePaths??[])];if(s.some((u)=>!u||u.startsWith("/")||u.split("/").includes("..")||/[\0\r\n]/.test(u)))throw Error("Sparse checkout paths must stay inside the repository");if(s.length)o.push("--filter=blob:none","--no-checkout");if(e.binding.cloneDepth)o.push("--depth",String(e.binding.cloneDepth));if(e.binding.submodules)o.push("--recurse-submodules","--shallow-submodules");if(o.push("--",r,n),await Zo(o,r,t),s.length)await Zo(["-C",n,"sparse-checkout","set","--cone","--",...s],r,t),await Zo(["-C",n,"checkout","--force"],r,t);if(e.commitSha){if(!/^[a-f0-9]{40,64}$/i.test(e.commitSha))throw Error("Expected source commit must be an immutable 40-64 character SHA");await Zo(["-C",n,"fetch","--no-tags","--depth","1","origin",e.commitSha],r,t),await Zo(["-C",n,"checkout","--detach","--force",e.commitSha],r,t)}let c=(await Zo(["-C",n,"rev-parse","HEAD"],r,t)).trim();if(!/^[a-f0-9]{40,64}$/i.test(c))throw Error("Git clone did not produce a valid commit SHA");if(e.commitSha&&c.toLowerCase()!==e.commitSha.toLowerCase())throw Error(`Git checkout resolved ${c} instead of the requested immutable commit`);return{directory:e.binding.monorepoRoot==="."?n:ed(n,e.binding.monorepoRoot),commitSha:c}}function Ta(e){return["github","gitlab","bitbucket","gitea"].includes(e)}async function il(e,t,r){let n=e.getConnection(t);if(!n||["disconnected","expired"].includes(n.status))throw Error("Active source connection was not found");try{if(Ta(n.provider)){let s=await ko(n,e.getCredential(n.id)).testConnection();return e.updateHealth(n.id,{status:s.ok?"healthy":"degraded",message:s.message,tested:!0,grantedScopes:s.scopes})}let i=r?e.getRepository(r):e.listRepositories(n.id,void 0,1)[0];if(!i)return e.updateHealth(n.id,{status:"degraded",message:"Add a repository URL before testing this generic connection.",tested:!0});let o=n.provider==="generic_ssh"?e.listBindings({connectionId:n.id}).map((s)=>s.deployKeyId).filter(Boolean).map((s)=>e.getDeployKey(s)).find(Boolean):void 0;return await rl(i.cloneUrl,{credential:e.getCredential(n.id),deployKey:o?{...o,privateKey:e.getDeployPrivateKey(o.id)}:void 0}),e.updateHealth(n.id,{status:"healthy",message:"Git repository access is healthy.",tested:!0})}catch(i){return e.updateHealth(n.id,{status:"degraded",message:i instanceof Error?i.message:"Connection test failed",tested:!0})}}async function qr(e,t,r={}){let n=e.getConnection(t);if(!n||!Ta(n.provider)||["disconnected","expired"].includes(n.status))throw Error("A hosted active source connection is required for repository discovery");let i=ko(n,e.getCredential(n.id)),o=[],s;for(let c=0;c<Math.min(20,Math.max(1,r.maxPages??10));c++){let u=await i.listRepositories({cursor:s,search:r.search,limit:100});for(let a of u.repositories)o.push(e.upsertRepository({connectionId:n.id,...a}));if(s=u.nextCursor,!s)break}return e.updateHealth(n.id,{status:"healthy",message:`${o.length} repositories synchronized.`,synced:!0}),o}async function sr(e,t){let r=e.getConnection(t.connectionId);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active source connection was not found");if(Ta(r.provider)){let c=ko(r,e.getCredential(r.id));return t.type==="tags"?c.listTags(t.repository,t):c.listBranches(t.repository,t)}let n=t.repositoryId?e.getRepository(t.repositoryId):e.listRepositories(r.id).find((c)=>c.fullName===t.repository);if(!n||n.connectionId!==r.id)throw Error("Generic repository metadata was not found");let i=t.deployKeyId?e.getDeployKey(t.deployKeyId):void 0;if(i&&i.connectionId!==r.id)throw Error("Deploy key does not belong to this connection");let o=await rl(n.cloneUrl,{credential:e.getCredential(r.id),deployKey:i?{...i,privateKey:e.getDeployPrivateKey(i.id)}:void 0});return{refs:(t.type==="tags"?o.tags:o.branches).slice(0,Math.min(500,t.limit??100))}}async function ar(e,t,r){let n=e.getWebhook(t),i=n?e.getConnection(n.connectionId):void 0;if(!n||!i||["disconnected","expired"].includes(i.status))throw Error("Active source webhook was not found");let o=Nt(r,{...n,endpointToken:e.getWebhookEndpointToken(n.id)});if(!Ta(i.provider))return e.updateWebhookState(n.id,{status:"healthy",healthMessage:"Manual webhook endpoint is ready.",reconciled:!0});try{let s=ko(i,e.getCredential(i.id)),c=e.getWebhookSecret(n.id),u=n.providerWebhookId?await s.updateWebhook(n.repositoryFullName,n.providerWebhookId,{url:o,secret:c,events:n.events}):await s.createWebhook(n.repositoryFullName,{url:o,secret:c,events:n.events});return e.updateWebhookState(n.id,{providerWebhookId:u.providerWebhookId,status:u.active?"healthy":"degraded",healthMessage:u.active?"Provider webhook is synchronized.":"Provider webhook exists but is inactive.",reconciled:!0})}catch(s){return e.updateWebhookState(n.id,{status:"degraded",healthMessage:s instanceof Error?s.message:"Webhook reconciliation failed",reconciled:!0})}}async function Xi(e,t){let r=e.getWebhook(t),n=r?e.getConnection(r.connectionId):void 0;if(!r||!n)throw Error("Source webhook was not found");if(Ta(n.provider)&&r.providerWebhookId&&!["disconnected","expired"].includes(n.status))await ko(n,e.getCredential(n.id)).deleteWebhook(r.repositoryFullName,r.providerWebhookId);return e.updateWebhookState(r.id,{status:"disabled",healthMessage:"Webhook disabled."})}import{lstatSync as kI,readdirSync as RI,readFileSync as PI}from"node:fs";import{relative as xI,resolve as Of,sep as DI}from"node:path";function OI(e){return new Map(e.map((t)=>[t.path.replace(/^\.\//,"").replace(/\\/g,"/"),t]))}function es(e,t,r){return{path:e,reason:t,weight:r}}function _f(e){try{return e?.content?JSON.parse(e.content):{}}catch{return{}}}function Ws(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 xt(e){let t=OI(e.slice(0,1e4)),r=[];if(t.has("Dockerfile"))r.push(Ws("dockerfile","dockerfile",0.99,[es("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=_f(t.get("composer.json"));if(t.has("artisan")&&n.require?.["laravel/framework"])r.push(Ws("laravel","server",0.98,[es("artisan","Laravel Artisan entrypoint is present.",0.45),es("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(Ws("php","server",0.82,[es("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=_f(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",u=[es("package.json",`Defines ${i.scripts?.build?"build and ":""}${i.scripts?.start?"start ":""}scripts.`,0.55)];if(o)u.push(es(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,f=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(Ws(c,f.kind,Math.min(0.94,u.reduce((C,k)=>C+k.weight,0)),u,f,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(Ws("static","static",0.78,[es(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(Ws("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 Zn(e,t={}){let r=Of(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"]),u=(a)=>{for(let f of RI(a).sort()){if(c.has(f))continue;let C=Of(a,f),k=xI(r,C).split(DI).join("/");if(!k||k.startsWith("../"))throw Error("Detection path escaped the application root");let D=kI(C);if(D.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${k}`);if(D.isDirectory())u(C);else if(D.isFile()){if(o.length>=n)throw Error("Application file-count limit exceeded");let W={path:k,size:D.size};if(s.has(k)&&D.size<=i)W.content=PI(C,"utf8");o.push(W)}}};return u(r),o}function sl(e){if(Array.isArray(e))return`[${e.map(sl).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)}:${sl(r)}`).join(",")}}`;return JSON.stringify(e)??"null"}function Aa(e){return!!e&&!e.startsWith("/")&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function gn(e,t,r,n){return{path:e,code:t,message:r,alternatives:n}}function ol(e){return JSON.parse(JSON.stringify(e))}function _I(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 ol({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 ol({serverless:{apps:{[e.slug]:{source:e.source,build:e.build,architecture:e.runtime.architecture,environment:t,domain:e.domain}}}});return ol({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 de(e,t=[]){let r=[],n=(W)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(W),i=Object.fromEntries(Object.entries(e.environment??{}).map(([W,Y])=>{if(typeof Y==="string"&&n(W))return r.push(gn(`environment.${W}`,"write_only_secret_required",`${W} must be supplied through the write-only secrets boundary.`)),[W,{secretRef:W}];return[W,Y]})),o=e.build;if(e.build.kind==="dockerfile"&&e.build.buildArgs){let W=Object.fromEntries(Object.entries(e.build.buildArgs).map(([Y,ee])=>{if(n(Y))return r.push(gn(`build.buildArgs.${Y}`,"write_only_build_secret_required",`${Y} must be declared in secretNames instead of buildArgs.`)),[Y,"[REDACTED]"];return[Y,ee]}));o={...e.build,buildArgs:W}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.slug))r.push(gn("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!Aa((e.source.kind==="git"?e.source.monorepoRoot:e.source.kind==="local"?e.source.root:".")??"."))r.push(gn("source","unsafe_source_root","Source root must stay inside the source tree."));if(e.source.kind==="git"&&e.source.sparsePaths?.some((W)=>!Aa(W)))r.push(gn("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(e.build.kind==="dockerfile"&&(!Aa(e.build.context)||!Aa(e.build.dockerfile)))r.push(gn("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(e.build.kind==="static"&&!Aa(e.build.publishDirectory))r.push(gn("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(e.build.kind==="server"&&!e.build.startCommand.trim())r.push(gn("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(gn("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(gn("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(gn("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(gn("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(gn("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(gn("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let c=Object.values(i).flatMap((W)=>typeof W==="object"?[W.secretRef]:[]),u=[...new Set([...e.requiredSecretNames??[],...e.build.kind==="dockerfile"?e.build.secretNames??[]:[],...c])].sort(),a=new Set(t),f=u.filter((W)=>!a.has(W)),C={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}},k=[...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(),D=[...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&&f.length===0,issues:r,missingSecrets:f,manifest:C,configPatch:_I({...e,build:o,environment:i}),capabilityRequirements:k,costDrivers:D,serializedManifest:`${sl(C)}
|
|
112
112
|
`}}function Nf(e){let t=e.replace(/\\/g,"/");return!!t&&!t.startsWith("/")&&!/^[A-Za-z]:\//.test(t)&&!t.split("/").includes("..")&&!/[\0\r\n]/.test(t)}function Mf(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=[],u=0;if(t.toLowerCase().endsWith(".zip")||e[0]===80&&e[1]===75){let f=0;while(f+30<=e.length){let C=s.getUint32(f,!0);if(C===33639248||C===101010256)break;if(C!==67324752)throw Error("Malformed ZIP local header");let k=s.getUint16(f+6,!0),D=s.getUint32(f+18,!0),W=s.getUint32(f+22,!0),Y=s.getUint16(f+26,!0),ee=s.getUint16(f+28,!0);if(k&8)throw Error("ZIP data descriptors are not accepted for uploaded artifacts");let ne=new TextDecoder().decode(e.subarray(f+30,f+30+Y));if(!Nf(ne))throw Error(`Unsafe archive path: ${ne}`);if(c.push(ne),u+=W,c.length>i||u>o)throw Error("Archive expansion limit exceeded");f+=30+Y+ee+D}return{format:"zip",entries:c.length,expandedBytes:u,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 f=e.subarray(a,a+512);if(f.every((Y)=>Y===0))break;let C=(Y,ee)=>new TextDecoder().decode(f.subarray(Y,Y+ee)).replace(/\0.*$/,""),k=`${C(345,155)}${C(345,155)?"/":""}${C(0,100)}`,D=Number.parseInt(C(124,12).trim()||"0",8),W=String.fromCharCode(f[156]??0);if(!Nf(k))throw Error(`Unsafe archive path: ${k}`);if(W==="1"||W==="2")throw Error(`Archive links are not accepted: ${k}`);if(!Number.isFinite(D)||D<0)throw Error("Malformed TAR entry size");if(c.push(k),u+=D,c.length>i||u>o)throw Error("Archive expansion limit exceeded");a+=512+Math.ceil(D/512)*512}return{format:"tar",entries:c.length,expandedBytes:u,paths:c}}var $f=new Set(["source","build","runtime","environment","domain","review"]);function Lf(e,t){try{return typeof e==="string"?JSON.parse(e):t}catch{return t}}function Bf(e){return/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(e)}function Ff(e){for(let[r,n]of Object.entries(e.environment??{}))if(typeof n==="string"&&Bf(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(Bf(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 jf(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:Lf(e.input,{}),suppliedSecretNames:Lf(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 ei{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(Ff(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(!$f.has(i))throw Error("Invalid draft step");let o=[...new Set(e.suppliedSecretNames??[])].sort(),s=de(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?jf(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(jf)}update(e,t,r){let n=this.get(e);if(!n||n.version!==t)throw Error(`Application draft ${e} changed since version ${t}`);if(!$f.has(r.step))throw Error("Invalid draft step");if(r.draft.projectId!==n.projectId)throw Error("Draft project cannot be changed");Ff(r.draft);let i=[...new Set(r.suppliedSecretNames??n.suppliedSecretNames)].sort(),o=de(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=de(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 NI,createDecipheriv as MI,createHash as Vf,randomBytes as $I}from"node:crypto";function ka(e){return typeof e==="string"&&e?e:void 0}function al(e){return Vf("sha256").update(e).digest("hex").slice(0,16)}function Uf(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 LI(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:ka(e.credential_fingerprint),credentialExpiresAt:ka(e.credential_expires_at),status:String(e.status),healthMessage:ka(e.health_message),lastTestedAt:ka(e.last_tested_at),version:Number(e.version),createdByActorId:ka(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class ti{controlPlane;key;nowFn;idFn;constructor(e,t){this.controlPlane=e;if(!t.encryptionKey)throw Error("Registry encryption key is required");this.key=Vf("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=$I(12),r=NI("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=MI("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=LI(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),Uf(e.host),t?this.encrypt(t):null,t?al(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:Uf(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),al(i),r.expiresAt??null,this.now(),e]),this.controlPlane.appendEvent({organizationId:n.organizationId,actorId:r.actorId,type:"registry.credential.rotated",payload:{connectionId:e,fingerprint:al(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 u=await i(`${r.host}/v2/`,{method:"GET",redirect:"error",signal:o.signal,headers:c?{Authorization:c}:void 0}),a=u.headers.get("www-authenticate")??"";if(u.status===401&&a.startsWith("Bearer ")&&n){let k=Object.fromEntries([...a.slice(7).matchAll(/(\w+)="([^"]+)"/g)].map((ne)=>[ne[1],ne[2]])),D=new URL(k.realm??"");if(D.protocol!=="https:")throw Error("Registry authentication realm must use HTTPS");if(k.service)D.searchParams.set("service",k.service);if(t.image)D.searchParams.set("scope",`repository:${qf(t.image).repository}:pull`);let W=await i(D,{signal:o.signal,redirect:"error",headers:c?{Authorization:c}:void 0});if(!W.ok)throw Error(`Registry authentication failed (${W.status})`);let Y=await W.json(),ee=Y.token??Y.access_token;if(!ee)throw Error("Registry did not return an access token");u=t.image?await zf(i,r.host,t.image,ee,o.signal):await i(`${r.host}/v2/`,{signal:o.signal,redirect:"error",headers:{Authorization:`Bearer ${ee}`}})}else if(u.ok&&t.image)u=await zf(i,r.host,t.image,n?.token,o.signal,c);let f=u.ok?"healthy":"degraded",C=u.ok?t.image?"Registry image is readable.":"Registry connection is healthy.":`Registry request failed (${u.status})`;return this.controlPlane.database.run("UPDATE registry_connections SET status=?, health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[f,C,this.now(),this.now(),e]),this.get(e)}catch(u){let a=o.signal.aborted?"Registry request timed out.":u instanceof Error?u.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 qf(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,u=s>=0?n.slice(s+1):"latest";if(!/^[A-Za-z0-9_.\/-]+$/.test(c)||!/^[A-Za-z0-9_.:+-]+$/.test(u))throw Error("Image reference is invalid");return{repository:c,reference:u}}async function zf(e,t,r,n,i,o){let s=qf(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 BI}from"node:crypto";import{chmodSync as Gf,existsSync as Jf,mkdirSync as FI,renameSync as jI,unlinkSync as Hf,writeFileSync as UI}from"node:fs";import{basename as zI,join as VI}from"node:path";function cl(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 ri{controlPlane;root;idFn;nowFn;constructor(e,t){this.controlPlane=e;this.root=R(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=zI(e.filename).slice(0,200);if(!r||r!==e.filename)throw Error("Artifact filename must not contain a path");let n=Mf(e.bytes,r),i=BI("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 cl(o);let s=this.idFn();FI(this.root,{recursive:!0,mode:448}),Gf(this.root,448);let c=VI(this.root,`${s}.archive`),u=`${c}.partial`;try{UI(u,e.bytes,{mode:384,flag:"wx"}),jI(u,c),Gf(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(Jf(u))Hf(u);if(Jf(c))Hf(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?cl(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(cl)}}function Wr(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=de(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}}),u=new S(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:u.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:u}}var qI=["restart","reload","start","stop","enable","disable"],Wf=65536;function Ks(e){return e.length<=Wf?e:`${e.slice(0,Wf)}
|
|
113
113
|
|
|
114
|
-
[output truncated]`}function GI(e){return/^[A-Za-z0-9_.@:-]+$/.test(e)}function dl(e){return/^[A-Za-z0-9_-]+$/.test(e)}function JI(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Kr(e,t){let r=[],n=t.servicesDetail??t.services??[];for(let s of n){let c=String(s?.name??"");if(!c||!GI(c))continue;for(let u of qI)r.push({id:`${u}:${c}`,label:`${JI(u)} ${c}`,group:"service",target:c,mutates:!0,confirm:c,danger:u==="stop"||u==="disable"})}for(let[s,c]of Object.entries(e.sites??{})){if(!c||!dl(s))continue;let u=w(c);if(u==="server-app"||u==="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&&dl(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||!dl(s))continue;if(c.scheduler||c.schedule){let u=sn(c)==="laravel";r.push({id:`scheduler:run:${s}`,label:`${u?"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"}),A(e))r.push({id:"backup:restore",label:"Restore latest DB backup",group:"backup",target:"database",mutates:!0,confirm:"restore",danger:!0})}return r}function ni(e,t,r){return Kr(t,r).find((n)=>n.id===e)}function HI(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 WI(){return`eval "$(cd ${U} && pantry env 2>/dev/null)"`}function Qf(e,t,r){let n=`${J(e,t)}/current`;return["set -uo pipefail",`[ -d ${n} ] || { echo "site ${t} has no current release" >&2; exit 1; }`,`cd ${n} && ${WI()} && php artisan ${r}`]}function KI(e,t,r){if(e==="laravel")return Qf(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 QI(e,t,r){if(e==="laravel")return Qf(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 YI(){return["set -uo pipefail",`[ -x ${fn} ] || { echo "scheduled backups are not provisioned on this server" >&2; exit 1; }`,fn]}function Kf(e,t,r){return{operation:e,command:t,ok:r.success,stdout:Ks(r.perInstance?.[0]?.output??""),stderr:Ks(r.perInstance?.[0]?.error??r.error??"")}}async function Jr(e,t,r,n={}){let i=e.project.slug,o;try{o=_({config:e})}catch(C){return{operation:r.id,ok:!1,error:`Could not initialize the cloud driver: ${C?.message??C}`}}let s={driver:o,slug:i,environment:t,role:"app"};if(r.group==="deploy"){let C=n.to&&/^[A-Za-z0-9._-]+$/.test(n.to)?n.to:void 0,k=await Hs(s,{siteName:r.target,to:C,site:e.sites?.[r.target]});return Kf(r.id,`rollback ${r.target}${C?` → ${C}`:""}`,k)}if(r.id==="backup:restore"){let C=await qs(s,{database:A(e)});return Kf(r.id,"db restore",C)}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 u,a;if(r.group==="service"){let[C,...k]=r.id.split(":");u=HI(C,k.join(":")),a=`systemctl ${C} ${r.target}`}else if(r.group==="worker"){let C=sn(e.sites?.[r.target]??{});u=KI(C,i,r.target),a=C==="laravel"?`queue:restart (${r.target})`:`restart queue units (${r.target})`}else if(r.group==="scheduler"){let C=sn(e.sites?.[r.target]??{});u=QI(C,i,r.target),a=C==="laravel"?`schedule:run (${r.target})`:`restart scheduler (${r.target})`}else if(r.id==="backup:run")u=YI(),a="ts-cloud backup";else return{operation:r.id,ok:!1,error:"Unknown operation."};let f=await o.runRemoteDeploy({targets:[c[0]],commands:u,comment:`ts-cloud dashboard:${r.id}`,tags:{Project:i,Environment:t,Role:"app"}});return{operation:r.id,command:a,ok:f.success,stdout:Ks(f.perInstance?.[0]?.output??""),stderr:Ks(f.perInstance?.[0]?.error??f.error??"")}}async function ar(e,t,r){let n=r.trim();if(!n)return{operation:"command",ok:!1,error:"A command is required."};let i;try{i=_({config:e})}catch(u){return{operation:"command",ok:!1,error:`Could not initialize the cloud driver: ${u?.message??u}`}}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:Ks(c.perInstance?.[0]?.output??""),stderr:Ks(c.perInstance?.[0]?.error??c.error??"")}}function cr(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 td(e,t){let r=cr(e).find((n)=>n.strategy===t);if(!r.supported)throw Error(`${t} is unavailable: ${r.explanation}`);return r}import{createHash as XI}from"node:crypto";var ZI=/^sha256:[a-f0-9]{64}$/,eC=/^[a-f0-9]{40,64}$/i;function Mi(e){return typeof e==="string"&&e?e:void 0}function ts(e,t){try{return JSON.parse(String(e))}catch{return t}}function Yf(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:ts(e.provenance,{}),attestation:ts(e.attestation,{}),verifiedAt:String(e.verified_at),createdAt:String(e.created_at)}}function Xf(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:Mi(e.source_sha),configHash:String(e.config_hash),manifest:ts(e.manifest,{}),provenance:ts(e.provenance,{}),strategy:String(e.strategy),status:String(e.status),healthGate:e.health_gate==null?void 0:ts(e.health_gate,void 0),hooks:ts(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:Mi(e.previous_release_id),promotedFromReleaseId:Mi(e.promoted_from_release_id),actorId:Mi(e.actor_id),trigger:String(e.trigger),pinned:Number(e.pinned)===1,pinReason:Mi(e.pin_reason),activatedAt:Mi(e.activated_at),failedAt:Mi(e.failed_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function tC(e){return{sequence:Number(e.sequence),id:String(e.id),releaseId:String(e.release_id),fromStatus:Mi(e.from_status),toStatus:String(e.to_status),trafficPercent:e.traffic_percent==null?void 0:Number(e.traffic_percent),health:ts(e.health,{}),message:String(e.message),operationId:Mi(e.operation_id),createdAt:String(e.created_at)}}function rC(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 ul{controlPlane;now;id;constructor(e,t={}){this.controlPlane=e;this.now=t.now??(()=>new Date),this.id=t.id??(()=>crypto.randomUUID())}registerArtifact(e){if(!ZI.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 Yf(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?Yf(t):void 0}create(e){let t=this.getArtifact(e.artifactId),r=this.controlPlane.getResource(e.resourceId),n=this.controlPlane.listEnvironments(e.projectId).find((C)=>C.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&&!eC.test(e.sourceSha))throw Error("Release source must be an immutable commit SHA");td({kind:e.kind,provider:r.provider,hasHealthGate:!!e.healthGate,replicas:e.replicas},e.strategy);let i=h(e.config),o=XI("sha256").update(JSON.stringify(i)).digest("hex"),s=this.active(e.resourceId),c=this.id(),u=this.now().toISOString(),a=e.approvalRequired?"awaiting_approval":"built",f=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(f),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",u,u]),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?Xf(t):void 0}list(e={}){return this.controlPlane.database.query("SELECT * FROM releases ORDER BY created_at DESC, rowid DESC").all().map(Xf).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(tC)}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:Mi(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:rC(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 lt{controlPlane;releases;queue;constructor(e){this.controlPlane=e;this.releases=new ul(e),this.queue=new S(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 nC(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 Zf(e,t){if(t.release.artifactId!==t.artifact.id)throw Error("Release activation artifact identity changed");td({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:nC(t.release)})}async function eh(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 iC=["release.activate","release.rollback"];function oC(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function th(e){let t=new lt(e.store),r=async(n)=>{let i=oC(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 u=typeof i.targetReleaseId==="string"&&i.targetReleaseId?i.targetReleaseId:s.previousReleaseId,a=u?t.releases.get(u):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 f=await e.resolveDriver(s);n.checkpoint("verify",`Verifying ${c.digest} and ${s.configHash} for ${f.name}.`),n.log(`Artifact ${c.digest}; source ${s.sourceSha??"not recorded"}; config ${s.configHash}.`,{stream:"system"}),n.throwIfCancellationRequested();let C;try{C=n.operation.kind==="release.rollback"?await eh(f,{release:s,artifact:c,previous:a}):await Zf(f,{release:s,artifact:c,previous:a})}catch(k){if(n.operation.kind==="release.activate"&&t.releases.get(s.id)?.status==="activating")t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,message:k instanceof Error?k.message:String(k)});throw k}for(let k of C.transitions)t.releases.progress(s.id,{message:`${n.operation.kind==="release.rollback"?"Rollback":"Activation"} traffic at ${k.trafficPercent}%.`,trafficPercent:k.trafficPercent,health:k.observed,operationId:n.operation.id}),n.log(`Traffic ${k.trafficPercent}%: ${k.healthy?"healthy":"unhealthy"}.`,{stream:k.healthy?"step":"stderr",step:"health"});if(n.checkpoint("health","Evaluating the provider health result."),!C.activated||!C.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:C.resourceVersions},message:C.error??"Provider health gate failed."});throw Error(C.error??`${f.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 k=await e.resolveHealthGate(s.healthGate.name,s);if(n.log(`${s.healthGate.name}: ${k.healthy?"healthy":"unhealthy"}${k.message?` — ${k.message}`:""}.`,{stream:k.healthy?"step":"stderr",step:"health"}),!k.healthy)throw t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,health:k.evidence,message:k.message??`Named health gate ${s.healthGate.name} failed.`}),Error(k.message??`Named health gate ${s.healthGate.name} failed`)}if(n.operation.kind==="release.rollback"){let k=t.releases.get(s.id);if(k.status!=="rolled_back")t.releases.transition(k.id,"rolled_back",{message:`Traffic restored through ${f.name}.`,operationId:n.operation.id,trafficPercent:0,health:{resourceVersions:C.resourceVersions}});if(a&&a.status!=="active"){let D=a.status==="activating"?a:t.releases.transition(a.id,"activating",{message:"Rollback target restoring traffic.",operationId:n.operation.id,trafficPercent:0});t.releases.transition(D.id,"active",{message:"Previous immutable release restored.",operationId:n.operation.id,trafficPercent:100,health:{resourceVersions:C.resourceVersions}})}}else t.completeHealthGate(s.id,{healthy:!0,operationId:n.operation.id,health:{providerVersion:C.providerVersion??null,resourceVersions:C.resourceVersions},message:"Provider activation and health gates completed."});return n.checkpoint("finalize","Persisted the terminal release state."),{releaseId:s.id,artifactDigest:c.digest,provider:f.name,providerVersion:C.providerVersion??null,resourceVersions:C.resourceVersions,status:t.releases.get(s.id).status}};return Object.fromEntries(iC.map((n)=>[n,r]))}class _t{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new p(void 0,{profile:t})}async describeServices(e){let t={cluster:e.cluster,services:e.services};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async listServices(e,t={}){let r={cluster:e,...t};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async listTasks(e,t,r={}){let n={cluster:e,...r};if(t)n.serviceName=t;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(n)})}async describeTasks(e,t){let r={cluster:e,tasks:t};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async updateService(e){let t={cluster:e.cluster,service:e.service};if(e.forceNewDeployment!==void 0)t.forceNewDeployment=e.forceNewDeployment;if(e.desiredCount!==void 0)t.desiredCount=e.desiredCount;if(e.taskDefinition)t.taskDefinition=e.taskDefinition;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.UpdateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async createService(e){let t={cluster:e.cluster,serviceName:e.serviceName,taskDefinition:e.taskDefinition,desiredCount:e.desiredCount};if(e.launchType)t.launchType=e.launchType;if(e.networkConfiguration)t.networkConfiguration=e.networkConfiguration;if(e.loadBalancers)t.loadBalancers=e.loadBalancers;if(e.healthCheckGracePeriodSeconds!==void 0)t.healthCheckGracePeriodSeconds=e.healthCheckGracePeriodSeconds;if(e.deploymentConfiguration)t.deploymentConfiguration=e.deploymentConfiguration;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.CreateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async deleteService(e){let t={cluster:e.cluster,service:e.service};if(e.force!==void 0)t.force=e.force;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeleteService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async listClusters(e={}){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async describeClusters(e){let t={clusters:e,include:["ATTACHMENTS","CONFIGURATIONS","SETTINGS","STATISTICS","TAGS"]};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async stopTask(e){let t={cluster:e.cluster,task:e.task};if(e.reason)t.reason=e.reason;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.StopTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async runTask(e){let t={cluster:e.cluster,taskDefinition:e.taskDefinition};if(e.count!==void 0)t.count=e.count;if(e.launchType)t.launchType=e.launchType;if(e.networkConfiguration)t.networkConfiguration=e.networkConfiguration;if(e.overrides)t.overrides=e.overrides;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RunTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async registerTaskDefinition(e){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RegisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async deregisterTaskDefinition(e){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeregisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:e})})}async describeTaskDefinition(e){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:e,include:["TAGS"]})})}async listTaskDefinitionFamilies(e){let t={};if(e?.familyPrefix)t.familyPrefix=e.familyPrefix;if(e?.status)t.status=e.status;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTaskDefinitionFamilies","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async waitForServiceStable(e,t,r=40,n=15000){for(let i=0;i<r;i++){let s=(await this.describeServices({cluster:e,services:[t]})).services?.[0];if(s){let c=s.deployments?.find((u)=>u.status==="PRIMARY");if(c&&c.runningCount===c.desiredCount&&s.deployments?.length===1)return!0}await new Promise((c)=>setTimeout(c,n))}return!1}async forceNewDeployment(e,t){return this.updateService({cluster:e,service:t,forceNewDeployment:!0})}async scaleService(e,t,r){return this.updateService({cluster:e,service:t,desiredCount:r})}}import{createHash as sC}from"node:crypto";var ml={info:0,low:1,medium:2,high:3,critical:4},fl={record:0,warn:1,block:2},rh=new Set(["skipped","unavailable","unsupported","stale"]);function Ut(e){return typeof e==="string"?e:void 0}function Po(e,t){try{return JSON.parse(String(e))}catch{return t}}function bi(e){return JSON.stringify(h(e))}function aC(e){if(!e)return;return String(h(e,2000))}function ll(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:Ut(e.project_id),environmentId:Ut(e.environment_id),resourceId:Ut(e.resource_id),releaseId:Ut(e.release_id),scannerId:String(e.scanner_id),scannerVersion:String(e.scanner_version),status:String(e.status),error:Ut(e.error),metadata:Po(e.metadata,{}),findingsCount:Number(e.findings_count),startedAt:String(e.started_at),completedAt:String(e.completed_at),durationMs:Number(e.duration_ms)}}function nh(e){return{id:String(e.id),fingerprint:String(e.fingerprint),organizationId:String(e.organization_id),projectId:Ut(e.project_id),environmentId:Ut(e.environment_id),resourceId:Ut(e.resource_id),releaseId:Ut(e.release_id),scanRunId:String(e.scan_run_id),scannerId:String(e.scanner_id),scannerVersion:String(e.scanner_version),ruleId:String(e.rule_id),severity:String(e.severity),title:String(e.title),description:String(e.description),evidence:Po(e.evidence,{}),remediation:Ut(e.remediation),subject:String(e.subject),status:String(e.status),ownerActorId:Ut(e.owner_actor_id),recurrenceCount:Number(e.recurrence_count),firstSeenAt:String(e.first_seen_at),lastSeenAt:String(e.last_seen_at),resolvedAt:Ut(e.resolved_at),updatedAt:String(e.updated_at)}}function pl(e){return{id:String(e.id),organizationId:String(e.organization_id),environmentId:Ut(e.environment_id),name:String(e.name),rules:Po(e.rules,[]),requiredScanners:Po(e.required_scanners,[]),scannerFailMode:String(e.scanner_fail_mode),enabled:Number(e.enabled)===1,version:Number(e.version),createdByActorId:Ut(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function ih(e,t){let r=Ut(e.revoked_at),n=String(e.expires_at);return{id:String(e.id),findingId:String(e.finding_id),policyId:Ut(e.policy_id),reason:String(e.reason),referenceUrl:Ut(e.reference_url),createdByActorId:String(e.created_by_actor_id),expiresAt:n,revokedAt:r,state:r?"revoked":n<=t?"expired":"active",createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function gl(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:Ut(e.environment_id),releaseId:String(e.release_id),kind:String(e.kind),format:String(e.format),digest:String(e.digest),summary:Po(e.summary,{}),content:Ut(e.content),sensitive:Number(e.sensitive)===1,createdAt:String(e.created_at)}}function oh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:String(e.environment_id),operationId:Ut(e.operation_id),policyId:String(e.policy_id),policyVersion:Number(e.policy_version),outcome:String(e.outcome),scannerVersions:Po(e.scanner_versions,{}),findingIds:Po(e.finding_ids,[]),waiverIds:Po(e.waiver_ids,[]),explanation:String(e.explanation),createdAt:String(e.created_at)}}function cC(e,t){let r=[e.trim().toLowerCase(),t.ruleId.trim().toLowerCase(),t.organizationId,t.projectId??"",t.environmentId??"",t.resourceId??"",t.releaseId??"",t.subject.trim().toLowerCase()].join("\x00");return sC("sha256").update(r).digest("hex")}function sh(e){if(!e)return;let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw Error("Security references must use HTTP or HTTPS");return t.toString()}function ah(e){if(!e.length)throw Error("A security policy needs at least one rule");return e.map((t)=>{if(!(t.minimumSeverity in ml))throw Error(`Unknown security severity: ${t.minimumSeverity}`);if(!(t.action in fl))throw Error(`Unknown security policy action: ${t.action}`);return{minimumSeverity:t.minimumSeverity,action:t.action,...t.scannerId?{scannerId:t.scannerId.trim()}:{}}})}class Ot{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)}recordScan(e){if(!e.organizationId||!e.scannerId.trim()||!e.scannerVersion.trim())throw Error("Organization, scanner id, and scanner version are required");let t=e.completedAt??this.now(),r=e.startedAt??t,n=e.durationMs??Math.max(0,new Date(t).getTime()-new Date(r).getTime()),i=e.findings??[],o=this.idFn(),s=new Set,c=[];return this.controlPlane.transaction(()=>{this.run(`INSERT INTO security_scan_runs
|
|
114
|
+
[output truncated]`}function GI(e){return/^[A-Za-z0-9_.@:-]+$/.test(e)}function dl(e){return/^[A-Za-z0-9_-]+$/.test(e)}function JI(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Kr(e,t){let r=[],n=t.servicesDetail??t.services??[];for(let s of n){let c=String(s?.name??"");if(!c||!GI(c))continue;for(let u of qI)r.push({id:`${u}:${c}`,label:`${JI(u)} ${c}`,group:"service",target:c,mutates:!0,confirm:c,danger:u==="stop"||u==="disable"})}for(let[s,c]of Object.entries(e.sites??{})){if(!c||!dl(s))continue;let u=w(c);if(u==="server-app"||u==="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&&dl(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||!dl(s))continue;if(c.scheduler||c.schedule){let u=sn(c)==="laravel";r.push({id:`scheduler:run:${s}`,label:`${u?"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"}),A(e))r.push({id:"backup:restore",label:"Restore latest DB backup",group:"backup",target:"database",mutates:!0,confirm:"restore",danger:!0})}return r}function ni(e,t,r){return Kr(t,r).find((n)=>n.id===e)}function HI(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 WI(){return`eval "$(cd ${L} && pantry env 2>/dev/null)"`}function Qf(e,t,r){let n=`${J(e,t)}/current`;return["set -uo pipefail",`[ -d ${n} ] || { echo "site ${t} has no current release" >&2; exit 1; }`,`cd ${n} && ${WI()} && php artisan ${r}`]}function KI(e,t,r){if(e==="laravel")return Qf(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 QI(e,t,r){if(e==="laravel")return Qf(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 YI(){return["set -uo pipefail",`[ -x ${fn} ] || { echo "scheduled backups are not provisioned on this server" >&2; exit 1; }`,fn]}function Kf(e,t,r){return{operation:e,command:t,ok:r.success,stdout:Ks(r.perInstance?.[0]?.output??""),stderr:Ks(r.perInstance?.[0]?.error??r.error??"")}}async function Jr(e,t,r,n={}){let i=e.project.slug,o;try{o=_({config:e})}catch(C){return{operation:r.id,ok:!1,error:`Could not initialize the cloud driver: ${C?.message??C}`}}let s={driver:o,slug:i,environment:t,role:"app"};if(r.group==="deploy"){let C=n.to&&/^[A-Za-z0-9._-]+$/.test(n.to)?n.to:void 0,k=await Hs(s,{siteName:r.target,to:C,site:e.sites?.[r.target]});return Kf(r.id,`rollback ${r.target}${C?` → ${C}`:""}`,k)}if(r.id==="backup:restore"){let C=await Gs(s,{database:A(e)});return Kf(r.id,"db restore",C)}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 u,a;if(r.group==="service"){let[C,...k]=r.id.split(":");u=HI(C,k.join(":")),a=`systemctl ${C} ${r.target}`}else if(r.group==="worker"){let C=sn(e.sites?.[r.target]??{});u=KI(C,i,r.target),a=C==="laravel"?`queue:restart (${r.target})`:`restart queue units (${r.target})`}else if(r.group==="scheduler"){let C=sn(e.sites?.[r.target]??{});u=QI(C,i,r.target),a=C==="laravel"?`schedule:run (${r.target})`:`restart scheduler (${r.target})`}else if(r.id==="backup:run")u=YI(),a="ts-cloud backup";else return{operation:r.id,ok:!1,error:"Unknown operation."};let f=await o.runRemoteDeploy({targets:[c[0]],commands:u,comment:`ts-cloud dashboard:${r.id}`,tags:{Project:i,Environment:t,Role:"app"}});return{operation:r.id,command:a,ok:f.success,stdout:Ks(f.perInstance?.[0]?.output??""),stderr:Ks(f.perInstance?.[0]?.error??f.error??"")}}async function cr(e,t,r){let n=r.trim();if(!n)return{operation:"command",ok:!1,error:"A command is required."};let i;try{i=_({config:e})}catch(u){return{operation:"command",ok:!1,error:`Could not initialize the cloud driver: ${u?.message??u}`}}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:Ks(c.perInstance?.[0]?.output??""),stderr:Ks(c.perInstance?.[0]?.error??c.error??"")}}function lr(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 td(e,t){let r=lr(e).find((n)=>n.strategy===t);if(!r.supported)throw Error(`${t} is unavailable: ${r.explanation}`);return r}import{createHash as XI}from"node:crypto";var ZI=/^sha256:[a-f0-9]{64}$/,eC=/^[a-f0-9]{40,64}$/i;function Mi(e){return typeof e==="string"&&e?e:void 0}function ts(e,t){try{return JSON.parse(String(e))}catch{return t}}function Yf(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:ts(e.provenance,{}),attestation:ts(e.attestation,{}),verifiedAt:String(e.verified_at),createdAt:String(e.created_at)}}function Xf(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:Mi(e.source_sha),configHash:String(e.config_hash),manifest:ts(e.manifest,{}),provenance:ts(e.provenance,{}),strategy:String(e.strategy),status:String(e.status),healthGate:e.health_gate==null?void 0:ts(e.health_gate,void 0),hooks:ts(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:Mi(e.previous_release_id),promotedFromReleaseId:Mi(e.promoted_from_release_id),actorId:Mi(e.actor_id),trigger:String(e.trigger),pinned:Number(e.pinned)===1,pinReason:Mi(e.pin_reason),activatedAt:Mi(e.activated_at),failedAt:Mi(e.failed_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function tC(e){return{sequence:Number(e.sequence),id:String(e.id),releaseId:String(e.release_id),fromStatus:Mi(e.from_status),toStatus:String(e.to_status),trafficPercent:e.traffic_percent==null?void 0:Number(e.traffic_percent),health:ts(e.health,{}),message:String(e.message),operationId:Mi(e.operation_id),createdAt:String(e.created_at)}}function rC(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 ul{controlPlane;now;id;constructor(e,t={}){this.controlPlane=e;this.now=t.now??(()=>new Date),this.id=t.id??(()=>crypto.randomUUID())}registerArtifact(e){if(!ZI.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 Yf(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?Yf(t):void 0}create(e){let t=this.getArtifact(e.artifactId),r=this.controlPlane.getResource(e.resourceId),n=this.controlPlane.listEnvironments(e.projectId).find((C)=>C.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&&!eC.test(e.sourceSha))throw Error("Release source must be an immutable commit SHA");td({kind:e.kind,provider:r.provider,hasHealthGate:!!e.healthGate,replicas:e.replicas},e.strategy);let i=h(e.config),o=XI("sha256").update(JSON.stringify(i)).digest("hex"),s=this.active(e.resourceId),c=this.id(),u=this.now().toISOString(),a=e.approvalRequired?"awaiting_approval":"built",f=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(f),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",u,u]),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?Xf(t):void 0}list(e={}){return this.controlPlane.database.query("SELECT * FROM releases ORDER BY created_at DESC, rowid DESC").all().map(Xf).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(tC)}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:Mi(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:rC(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 lt{controlPlane;releases;queue;constructor(e){this.controlPlane=e;this.releases=new ul(e),this.queue=new S(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 nC(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 Zf(e,t){if(t.release.artifactId!==t.artifact.id)throw Error("Release activation artifact identity changed");td({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:nC(t.release)})}async function eh(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 iC=["release.activate","release.rollback"];function oC(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function th(e){let t=new lt(e.store),r=async(n)=>{let i=oC(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 u=typeof i.targetReleaseId==="string"&&i.targetReleaseId?i.targetReleaseId:s.previousReleaseId,a=u?t.releases.get(u):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 f=await e.resolveDriver(s);n.checkpoint("verify",`Verifying ${c.digest} and ${s.configHash} for ${f.name}.`),n.log(`Artifact ${c.digest}; source ${s.sourceSha??"not recorded"}; config ${s.configHash}.`,{stream:"system"}),n.throwIfCancellationRequested();let C;try{C=n.operation.kind==="release.rollback"?await eh(f,{release:s,artifact:c,previous:a}):await Zf(f,{release:s,artifact:c,previous:a})}catch(k){if(n.operation.kind==="release.activate"&&t.releases.get(s.id)?.status==="activating")t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,message:k instanceof Error?k.message:String(k)});throw k}for(let k of C.transitions)t.releases.progress(s.id,{message:`${n.operation.kind==="release.rollback"?"Rollback":"Activation"} traffic at ${k.trafficPercent}%.`,trafficPercent:k.trafficPercent,health:k.observed,operationId:n.operation.id}),n.log(`Traffic ${k.trafficPercent}%: ${k.healthy?"healthy":"unhealthy"}.`,{stream:k.healthy?"step":"stderr",step:"health"});if(n.checkpoint("health","Evaluating the provider health result."),!C.activated||!C.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:C.resourceVersions},message:C.error??"Provider health gate failed."});throw Error(C.error??`${f.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 k=await e.resolveHealthGate(s.healthGate.name,s);if(n.log(`${s.healthGate.name}: ${k.healthy?"healthy":"unhealthy"}${k.message?` — ${k.message}`:""}.`,{stream:k.healthy?"step":"stderr",step:"health"}),!k.healthy)throw t.completeHealthGate(s.id,{healthy:!1,operationId:n.operation.id,health:k.evidence,message:k.message??`Named health gate ${s.healthGate.name} failed.`}),Error(k.message??`Named health gate ${s.healthGate.name} failed`)}if(n.operation.kind==="release.rollback"){let k=t.releases.get(s.id);if(k.status!=="rolled_back")t.releases.transition(k.id,"rolled_back",{message:`Traffic restored through ${f.name}.`,operationId:n.operation.id,trafficPercent:0,health:{resourceVersions:C.resourceVersions}});if(a&&a.status!=="active"){let D=a.status==="activating"?a:t.releases.transition(a.id,"activating",{message:"Rollback target restoring traffic.",operationId:n.operation.id,trafficPercent:0});t.releases.transition(D.id,"active",{message:"Previous immutable release restored.",operationId:n.operation.id,trafficPercent:100,health:{resourceVersions:C.resourceVersions}})}}else t.completeHealthGate(s.id,{healthy:!0,operationId:n.operation.id,health:{providerVersion:C.providerVersion??null,resourceVersions:C.resourceVersions},message:"Provider activation and health gates completed."});return n.checkpoint("finalize","Persisted the terminal release state."),{releaseId:s.id,artifactDigest:c.digest,provider:f.name,providerVersion:C.providerVersion??null,resourceVersions:C.resourceVersions,status:t.releases.get(s.id).status}};return Object.fromEntries(iC.map((n)=>[n,r]))}class _t{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new p(void 0,{profile:t})}async describeServices(e){let t={cluster:e.cluster,services:e.services};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async listServices(e,t={}){let r={cluster:e,...t};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async listTasks(e,t,r={}){let n={cluster:e,...r};if(t)n.serviceName=t;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(n)})}async describeTasks(e,t){let r={cluster:e,tasks:t};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async updateService(e){let t={cluster:e.cluster,service:e.service};if(e.forceNewDeployment!==void 0)t.forceNewDeployment=e.forceNewDeployment;if(e.desiredCount!==void 0)t.desiredCount=e.desiredCount;if(e.taskDefinition)t.taskDefinition=e.taskDefinition;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.UpdateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async createService(e){let t={cluster:e.cluster,serviceName:e.serviceName,taskDefinition:e.taskDefinition,desiredCount:e.desiredCount};if(e.launchType)t.launchType=e.launchType;if(e.networkConfiguration)t.networkConfiguration=e.networkConfiguration;if(e.loadBalancers)t.loadBalancers=e.loadBalancers;if(e.healthCheckGracePeriodSeconds!==void 0)t.healthCheckGracePeriodSeconds=e.healthCheckGracePeriodSeconds;if(e.deploymentConfiguration)t.deploymentConfiguration=e.deploymentConfiguration;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.CreateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async deleteService(e){let t={cluster:e.cluster,service:e.service};if(e.force!==void 0)t.force=e.force;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeleteService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async listClusters(e={}){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async describeClusters(e){let t={clusters:e,include:["ATTACHMENTS","CONFIGURATIONS","SETTINGS","STATISTICS","TAGS"]};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async stopTask(e){let t={cluster:e.cluster,task:e.task};if(e.reason)t.reason=e.reason;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.StopTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async runTask(e){let t={cluster:e.cluster,taskDefinition:e.taskDefinition};if(e.count!==void 0)t.count=e.count;if(e.launchType)t.launchType=e.launchType;if(e.networkConfiguration)t.networkConfiguration=e.networkConfiguration;if(e.overrides)t.overrides=e.overrides;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RunTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async registerTaskDefinition(e){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RegisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async deregisterTaskDefinition(e){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeregisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:e})})}async describeTaskDefinition(e){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:e,include:["TAGS"]})})}async listTaskDefinitionFamilies(e){let t={};if(e?.familyPrefix)t.familyPrefix=e.familyPrefix;if(e?.status)t.status=e.status;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTaskDefinitionFamilies","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async waitForServiceStable(e,t,r=40,n=15000){for(let i=0;i<r;i++){let s=(await this.describeServices({cluster:e,services:[t]})).services?.[0];if(s){let c=s.deployments?.find((u)=>u.status==="PRIMARY");if(c&&c.runningCount===c.desiredCount&&s.deployments?.length===1)return!0}await new Promise((c)=>setTimeout(c,n))}return!1}async forceNewDeployment(e,t){return this.updateService({cluster:e,service:t,forceNewDeployment:!0})}async scaleService(e,t,r){return this.updateService({cluster:e,service:t,desiredCount:r})}}import{createHash as sC}from"node:crypto";var ml={info:0,low:1,medium:2,high:3,critical:4},fl={record:0,warn:1,block:2},rh=new Set(["skipped","unavailable","unsupported","stale"]);function Ut(e){return typeof e==="string"?e:void 0}function Po(e,t){try{return JSON.parse(String(e))}catch{return t}}function bi(e){return JSON.stringify(h(e))}function aC(e){if(!e)return;return String(h(e,2000))}function ll(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:Ut(e.project_id),environmentId:Ut(e.environment_id),resourceId:Ut(e.resource_id),releaseId:Ut(e.release_id),scannerId:String(e.scanner_id),scannerVersion:String(e.scanner_version),status:String(e.status),error:Ut(e.error),metadata:Po(e.metadata,{}),findingsCount:Number(e.findings_count),startedAt:String(e.started_at),completedAt:String(e.completed_at),durationMs:Number(e.duration_ms)}}function nh(e){return{id:String(e.id),fingerprint:String(e.fingerprint),organizationId:String(e.organization_id),projectId:Ut(e.project_id),environmentId:Ut(e.environment_id),resourceId:Ut(e.resource_id),releaseId:Ut(e.release_id),scanRunId:String(e.scan_run_id),scannerId:String(e.scanner_id),scannerVersion:String(e.scanner_version),ruleId:String(e.rule_id),severity:String(e.severity),title:String(e.title),description:String(e.description),evidence:Po(e.evidence,{}),remediation:Ut(e.remediation),subject:String(e.subject),status:String(e.status),ownerActorId:Ut(e.owner_actor_id),recurrenceCount:Number(e.recurrence_count),firstSeenAt:String(e.first_seen_at),lastSeenAt:String(e.last_seen_at),resolvedAt:Ut(e.resolved_at),updatedAt:String(e.updated_at)}}function pl(e){return{id:String(e.id),organizationId:String(e.organization_id),environmentId:Ut(e.environment_id),name:String(e.name),rules:Po(e.rules,[]),requiredScanners:Po(e.required_scanners,[]),scannerFailMode:String(e.scanner_fail_mode),enabled:Number(e.enabled)===1,version:Number(e.version),createdByActorId:Ut(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function ih(e,t){let r=Ut(e.revoked_at),n=String(e.expires_at);return{id:String(e.id),findingId:String(e.finding_id),policyId:Ut(e.policy_id),reason:String(e.reason),referenceUrl:Ut(e.reference_url),createdByActorId:String(e.created_by_actor_id),expiresAt:n,revokedAt:r,state:r?"revoked":n<=t?"expired":"active",createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function gl(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:Ut(e.environment_id),releaseId:String(e.release_id),kind:String(e.kind),format:String(e.format),digest:String(e.digest),summary:Po(e.summary,{}),content:Ut(e.content),sensitive:Number(e.sensitive)===1,createdAt:String(e.created_at)}}function oh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:String(e.environment_id),operationId:Ut(e.operation_id),policyId:String(e.policy_id),policyVersion:Number(e.policy_version),outcome:String(e.outcome),scannerVersions:Po(e.scanner_versions,{}),findingIds:Po(e.finding_ids,[]),waiverIds:Po(e.waiver_ids,[]),explanation:String(e.explanation),createdAt:String(e.created_at)}}function cC(e,t){let r=[e.trim().toLowerCase(),t.ruleId.trim().toLowerCase(),t.organizationId,t.projectId??"",t.environmentId??"",t.resourceId??"",t.releaseId??"",t.subject.trim().toLowerCase()].join("\x00");return sC("sha256").update(r).digest("hex")}function sh(e){if(!e)return;let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw Error("Security references must use HTTP or HTTPS");return t.toString()}function ah(e){if(!e.length)throw Error("A security policy needs at least one rule");return e.map((t)=>{if(!(t.minimumSeverity in ml))throw Error(`Unknown security severity: ${t.minimumSeverity}`);if(!(t.action in fl))throw Error(`Unknown security policy action: ${t.action}`);return{minimumSeverity:t.minimumSeverity,action:t.action,...t.scannerId?{scannerId:t.scannerId.trim()}:{}}})}class Ot{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)}recordScan(e){if(!e.organizationId||!e.scannerId.trim()||!e.scannerVersion.trim())throw Error("Organization, scanner id, and scanner version are required");let t=e.completedAt??this.now(),r=e.startedAt??t,n=e.durationMs??Math.max(0,new Date(t).getTime()-new Date(r).getTime()),i=e.findings??[],o=this.idFn(),s=new Set,c=[];return this.controlPlane.transaction(()=>{this.run(`INSERT INTO security_scan_runs
|
|
115
115
|
(id, organization_id, project_id, environment_id, resource_id, release_id, scanner_id, scanner_version, status, error, metadata, findings_count, started_at, completed_at, duration_ms)
|
|
116
116
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[o,e.organizationId,e.projectId??null,e.environmentId??null,e.resourceId??null,e.releaseId??null,e.scannerId.trim(),e.scannerVersion.trim(),e.status,aC(e.error)??null,bi(e.metadata??{}),i.length,r,t,Math.max(0,Math.floor(n))]);for(let u of i){let a={...u,organizationId:e.organizationId,projectId:u.projectId??e.projectId,environmentId:u.environmentId??e.environmentId,resourceId:u.resourceId??e.resourceId,releaseId:u.releaseId??e.releaseId},f=a.fingerprint?.trim()||cC(e.scannerId,a);s.add(f);let C=this.controlPlane.database.query("SELECT * FROM security_findings WHERE fingerprint = ?").get(f),k=C?this.controlPlane.database.query("SELECT * FROM security_waivers WHERE finding_id = ? AND revoked_at IS NULL AND expires_at > ? ORDER BY expires_at DESC LIMIT 1").get(String(C.id),t):void 0;if(C){let D=String(C.status)==="resolved"?Number(C.recurrence_count)+1:Number(C.recurrence_count),W=k?"waived":String(C.status)==="acknowledged"?"acknowledged":"open";this.run(`UPDATE security_findings SET scan_run_id = ?, scanner_version = ?, severity = ?, title = ?, description = ?, evidence = ?, remediation = ?,
|
|
117
117
|
status = ?, recurrence_count = ?, last_seen_at = ?, resolved_at = NULL, updated_at = ? WHERE id = ?`,[o,e.scannerVersion,a.severity,a.title.trim(),a.description.trim(),bi(a.evidence??{}),a.remediation?.trim()||null,W,D,t,t,String(C.id)]),c.push(this.getFinding(String(C.id)))}else{let D=this.idFn();this.run(`INSERT INTO security_findings
|
|
@@ -134,16 +134,16 @@ requirepass ${n.replaceAll("\\","\\\\").replaceAll(`
|
|
|
134
134
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,e.organizationId,e.projectId,e.environmentId??null,e.releaseId,e.kind,e.format,e.digest,bi(e.summary),e.content??null,e.sensitive?1:0,n]),this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,type:"security.release_artifact.created",payload:{artifactId:r,releaseId:e.releaseId,kind:e.kind,format:e.format,digest:e.digest,sensitive:e.sensitive}}),gl(this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE id = ?").get(r))}listReleaseArtifacts(e,t=!1){return this.controlPlane.database.query("SELECT * FROM release_security_artifacts WHERE release_id = ? ORDER BY created_at, kind").all(e).map(gl).map((r)=>r.sensitive&&!t?{...r,content:void 0}:r)}summary(e,t,r){let n=this.listFindings({organizationId:e,projectId:t,environmentId:r,limit:1000}),i=this.listScanRuns({organizationId:e,projectId:t,environmentId:r,limit:1000}),o={info:0,low:0,medium:0,high:0,critical:0};for(let c of n)if(c.status==="open"||c.status==="acknowledged")o[c.severity]++;let s={passed:0,failed:0,skipped:0,unavailable:0,unsupported:0,stale:0};for(let c of i)s[c.status]++;return{open:o,waived:n.filter((c)=>c.status==="waived").length,resolved:n.filter((c)=>c.status==="resolved").length,checks:s,lastScannedAt:i[0]?.completedAt}}exportPosture(e){let t=this.controlPlane.listProjects().filter((r)=>r.organizationId===e);return h({format:"ts-cloud-security-posture",version:1,exportedAt:this.now(),organizationId:e,policies:this.listPolicies(e),findings:this.listFindings({organizationId:e,limit:1000}),waivers:this.listWaivers().filter((r)=>this.getFinding(r.findingId)?.organizationId===e),scans:t.flatMap((r)=>this.listScanRuns({organizationId:e,projectId:r.id,limit:1000})),decisions:t.flatMap((r)=>this.controlPlane.listEnvironments(r.id).flatMap((n)=>this.listDecisions(n.id,1000)))})}}import{existsSync as dC,readdirSync as uC,readFileSync as lC,statSync as pC}from"node:fs";import{extname as gC,join as mC,relative as ch,sep as fC}from"node:path";var dh=[{name:"AWS Access Key ID",pattern:/(?:^|[^A-Z0-9])((AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16})(?:[^A-Z0-9]|$)/g,severity:"critical",description:"AWS Access Key ID detected"},{name:"AWS Secret Access Key",pattern:/(?:aws_secret_access_key|aws_secret_key|secret_access_key|secretAccessKey)['"]?\s*[=:]\s*['"]?([A-Za-z0-9/+=]{40})['"]?/gi,severity:"critical",description:"AWS Secret Access Key detected"},{name:"AWS Secret Key (Generic)",pattern:/(?:^|['"`:=\s])([A-Za-z0-9/+=]{40})(?:['"`\s]|$)/g,severity:"high",description:"Potential AWS Secret Key (40-char base64)"},{name:"Generic API Key",pattern:/(?:api[_-]?key|apikey|api[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9_\-]{20,})['"]?/gi,severity:"high",description:"Generic API key detected"},{name:"RSA Private Key",pattern:/-----BEGIN RSA PRIVATE KEY-----/g,severity:"critical",description:"RSA private key detected"},{name:"OpenSSH Private Key",pattern:/-----BEGIN OPENSSH PRIVATE KEY-----/g,severity:"critical",description:"OpenSSH private key detected"},{name:"EC Private Key",pattern:/-----BEGIN EC PRIVATE KEY-----/g,severity:"critical",description:"EC private key detected"},{name:"PGP Private Key",pattern:/-----BEGIN PGP PRIVATE KEY BLOCK-----/g,severity:"critical",description:"PGP private key detected"},{name:"GitHub Token",pattern:/(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}/g,severity:"critical",description:"GitHub personal access token detected"},{name:"GitHub OAuth",pattern:/github[_-]?oauth[_-]?token\s*[=:]\s*['"]?([A-Za-z0-9_]{40})['"]?/gi,severity:"critical",description:"GitHub OAuth token detected"},{name:"Slack Token",pattern:/xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*/g,severity:"critical",description:"Slack token detected"},{name:"Slack Webhook",pattern:/https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/g,severity:"high",description:"Slack webhook URL detected"},{name:"Discord Webhook",pattern:/https:\/\/discord(?:app)?\.com\/api\/webhooks\/[0-9]+\/[A-Za-z0-9_-]+/g,severity:"high",description:"Discord webhook URL detected"},{name:"JWT Token",pattern:/eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*/g,severity:"high",description:"JWT token detected"},{name:"Google API Key",pattern:/AIza[0-9A-Za-z_-]{35}/g,severity:"critical",description:"Google API key detected"},{name:"Google OAuth ID",pattern:/[0-9]+-[A-Za-z0-9_]{32}\.apps\.googleusercontent\.com/g,severity:"high",description:"Google OAuth client ID detected"},{name:"Firebase API Key",pattern:/(?:firebase[_-]?api[_-]?key)\s*[=:]\s*['"]?([A-Za-z0-9_-]{39})['"]?/gi,severity:"critical",description:"Firebase API key detected"},{name:"Cloudflare API Token",pattern:/(?:cloudflare[_-]?api[_-]?token|cf[_-]?api[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{40})['"]?/gi,severity:"critical",description:"Cloudflare API token detected"},{name:"Azure Client Secret",pattern:/(?:azure[_-]?client[_-]?secret|client[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9~._-]{34,})['"]?/gi,severity:"critical",description:"Azure client secret detected"},{name:"Heroku API Key",pattern:/(?:heroku[_-]?api[_-]?key)\s*[=:]\s*['"]?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})['"]?/gi,severity:"critical",description:"Heroku API key detected"},{name:"Database Connection String",pattern:/(?:mysql|postgres|postgresql|mongodb|redis|mongodb\+srv):\/\/[^:]+:[^@]+@[^/\s]+/gi,severity:"critical",description:"Database connection string with credentials detected"},{name:"Database Password",pattern:/(?:db[_-]?password|database[_-]?password|mysql[_-]?password|postgres[_-]?password)\s*[=:]\s*['"]?([^'"\s]{8,})['"]?/gi,severity:"critical",description:"Database password detected"},{name:"Stripe API Key",pattern:/(?:sk|pk)_(?:test|live)_[0-9a-zA-Z]{24,}/g,severity:"critical",description:"Stripe API key detected"},{name:"PayPal Client ID",pattern:/(?:paypal[_-]?client[_-]?id)\s*[=:]\s*['"]?([A-Za-z0-9_-]{80})['"]?/gi,severity:"high",description:"PayPal client ID detected"},{name:"Square Access Token",pattern:/sq0[a-z]{3}-[0-9A-Za-z_-]{22,}/g,severity:"critical",description:"Square access token detected"},{name:"Twilio API Key",pattern:/SK[a-f0-9]{32}/g,severity:"critical",description:"Twilio API key detected"},{name:"SendGrid API Key",pattern:/SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}/g,severity:"critical",description:"SendGrid API key detected"},{name:"Mailgun API Key",pattern:/key-[0-9a-zA-Z]{32}/g,severity:"critical",description:"Mailgun API key detected"},{name:"Password in Code",pattern:/(?:password|passwd|pwd)\s*[=:]\s*['"]([^'"]{8,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded password detected"},{name:"Secret/Token Assignment",pattern:/(?:secret|token|auth[_-]?token|access[_-]?token)\s*[=:]\s*['"]([A-Za-z0-9_\-/+=]{16,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded secret or token detected"},{name:"NPM Token",pattern:/(?:npm[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{36})['"]?/gi,severity:"critical",description:"NPM token detected"},{name:"SSH Private Key Path Exposed",pattern:/~\/\.ssh\/id_[a-z]+|\/home\/[^/]+\/\.ssh\/id_[a-z]+/g,severity:"medium",description:"SSH private key path exposed"},{name:"Env Variable with Secret",pattern:/(?:process\.env\.)((?=[A-Z_]*(?:SECRET|KEY|TOKEN|PASSWORD|CREDENTIAL|AUTH))[A-Z_]+)\s*(?:===?\s*['"]([^'"]+)['"])?/g,severity:"medium",description:"Environment variable containing secret may be exposed"}],hC=[".js",".jsx",".ts",".tsx",".mjs",".cjs",".vue",".svelte",".html",".htm",".css",".scss",".less",".json",".yaml",".yml",".toml",".xml",".env",".config",".conf"],yC=["node_modules",".git",".svn",".hg","dist","build","coverage",".nyc_output","__pycache__",".pytest_cache","vendor",".idea",".vscode",".turbo",".next",".nuxt","framework.bak","pantry",".pantry","tests","test","__tests__","spec","__mocks__",".github",".gitlab",".circleci",".claude/worktrees"],bC=["package-lock.json","yarn.lock","pnpm-lock.yaml","bun.lockb","bun.lock","*.min.js","*.min.css","*.map","*.d.ts","*.test.ts","*.test.js","*.spec.ts","*.spec.js",".env",".env.*"];class Xr{patterns;excludeDirs;excludeFiles;maxFileSize;constructor(e){this.patterns=[...dh,...e?.customPatterns||[]],this.excludeDirs=[...yC,...e?.excludeDirs||[]],this.excludeFiles=[...bC,...e?.excludeFiles||[]],this.maxFileSize=e?.maxFileSize||1048576}async scan(e){let t=Date.now(),r=[],n=0,{directory:i,exclude:o=[],include:s,skipPatterns:c=[]}=e,u=e.failOnSeverity||"critical";if(!dC(i))throw Error(`Directory not found: ${i}`);let a=this.getFilesToScan(i,[...this.excludeDirs,...o],s);for(let W of a){let Y=ch(i,W);if(this.shouldExcludeFile(Y))continue;try{if(pC(W).size>this.maxFileSize)continue;let ne=lC(W,"utf-8"),he=this.scanContent(ne,Y,c);r.push(...he),n++}catch{continue}}let f={critical:r.filter((W)=>W.pattern.severity==="critical").length,high:r.filter((W)=>W.pattern.severity==="high").length,medium:r.filter((W)=>W.pattern.severity==="medium").length,low:r.filter((W)=>W.pattern.severity==="low").length},C=["low","medium","high","critical"],k=C.indexOf(u),D=!0;for(let W=k;W<C.length;W++)if(f[C[W]]>0){D=!1;break}return{passed:D,findings:r,scannedFiles:n,duration:Date.now()-t,summary:f}}scanContent(e,t,r){let n=[],i=e.split(`
|
|
135
135
|
`);for(let o of this.patterns){if(r.includes(o.name))continue;o.pattern.lastIndex=0;let s;while((s=o.pattern.exec(e))!==null){let c=e.substring(0,s.index),u=c.split(`
|
|
136
136
|
`).length,a=c.lastIndexOf(`
|
|
137
|
-
`),f=s.index-a,C=i[u-1]||"";if(this.isLikelyPlaceholder(s[0],C))continue;let k=s[1]||s[0];if(o.name==="AWS Secret Key (Generic)"&&/^[a-f0-9]{40}$/i.test(k))continue;if(o.name==="AWS Secret Key (Generic)"&&!this.hasSecretCharacterDiversity(k))continue;if(o.name==="AWS Secret Key (Generic)"&&/^(?:Actions|Commands|Controllers|Handlers|Jobs|Listeners|Middleware|Models|Resources|Services)\//.test(k))continue;if(this.isLowEntropy(k))continue;n.push({file:t,line:u,column:f,match:this.maskSecret(s[0]),pattern:o,context:this.maskSecret(C.trim())})}}return n}isLikelyPlaceholder(e,t){let r=["example","placeholder","your_","YOUR_","xxx","XXX","***","test","TEST","dummy","DUMMY","fake","FAKE","sample","SAMPLE","<your","${","{{","process.env","import.meta.env","CHANGEME","TODO","FIXME"],n=e.toLowerCase(),i=t.toLowerCase();for(let s of r)if(n.includes(s.toLowerCase())||i.includes(s.toLowerCase()))return!0;let o=t.trim();if(o.startsWith("//")||o.startsWith("#")||o.startsWith("*")||o.startsWith("/*")){if(i.includes("example")||i.includes("format:")||i.includes("e.g."))return!0}return!1}isLowEntropy(e){if(e.length<8)return!1;if(new Set(e).size<8)return!0;if(/(.)\1{3,}/.test(e))return!0;return!1}hasSecretCharacterDiversity(e){let t=/[\d+=]/.test(e),r=[/[a-z]/.test(e),/[A-Z]/.test(e),/\d/.test(e),/[/+=]/.test(e)];return t&&r.filter(Boolean).length>=3}maskSecret(e){if(e.length<=8)return"*".repeat(e.length);let t=Math.min(4,Math.floor(e.length*0.2));return e.substring(0,t)+"*".repeat(e.length-t*2)+e.substring(e.length-t)}getFilesToScan(e,t,r){let n=[],i=r||hC,o=t.filter((u)=>!u.includes("/")),s=t.filter((u)=>u.includes("/")).map((u)=>u.replace(/^\.\//,"").replace(/\/+$/,"")),c=(u)=>{let a=uC(u,{withFileTypes:!0});for(let f of a){let C=mC(u,f.name);if(f.isDirectory()){let k=ch(e,C).split(fC).join("/");if(!o.includes(f.name)&&!s.includes(k))c(C)}else if(f.isFile()){let k=gC(f.name).toLowerCase();if(i.includes(k)||f.name.startsWith(".env")||f.name.endsWith(".config"))n.push(C)}}};return c(e),n}shouldExcludeFile(e){let t=e.split("/").pop()||"";for(let r of this.excludeFiles)if(r.startsWith("*")){let n=r.substring(1);if(t.endsWith(n))return!0}else if(r.endsWith("*")){let n=r.substring(0,r.length-1);if(t.startsWith(n))return!0}else if(t===r)return!0;return!1}addPattern(e){this.patterns.push(e)}getPatterns(){return[...this.patterns]}}function SC(e,t){return{status:"unavailable",findings:[],error:`${e.id} exceeded its ${t}ms timeout`,metadata:{timeoutMs:t}}}class rs{posture;defaultTimeoutMs;nowFn;constructor(e,t={}){this.posture=e;this.defaultTimeoutMs=t.defaultTimeoutMs??60000,this.nowFn=t.now??(()=>new Date)}async run(e,t){let r=this.nowFn(),n=Math.max(100,e.timeoutMs??this.defaultTimeoutMs),i=new AbortController,o,s=new Promise((f)=>{o=setTimeout(()=>{i.abort(),f(SC(e,n))},n)}),c;try{c=await Promise.race([e.scan({...t,signal:i.signal}),s])}catch(f){c={status:"unavailable",findings:[],error:f instanceof Error?f.message:String(f)}}finally{if(o)clearTimeout(o)}let u=this.nowFn(),a={...t,scannerId:e.id,scannerVersion:e.version,status:c.status,findings:c.findings,metadata:c.metadata,error:c.error,startedAt:r.toISOString(),completedAt:u.toISOString(),durationMs:Math.max(0,u.getTime()-r.getTime())};return this.posture.recordScan(a)}async runAll(e,t){return Promise.all(e.map((r)=>this.run(r,t)))}}class Ra{scanner;id="source-secrets";version="1.0.0";timeoutMs=30000;constructor(e=new Xr){this.scanner=e}async scan(e){if(!e.artifactRoot)return{status:"skipped",findings:[],error:"No artifact root was supplied"};let t=await this.scanner.scan({directory:e.artifactRoot,failOnSeverity:"critical"});return{status:t.passed?"passed":"failed",findings:t.findings.map((r)=>({...e,ruleId:r.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:r.pattern.severity,title:r.pattern.name,description:r.pattern.description,subject:`${r.file}:${r.line}`,evidence:{file:r.file,line:r.line,column:r.column,match:r.match,context:r.context},remediation:"Remove the credential, rotate it at its issuer, and use a managed secret or environment reference."})),metadata:{scannedFiles:t.scannedFiles,summary:t.summary}}}}function vC(e){let t=e?.toLowerCase();return t==="critical"||t==="high"||t==="medium"||t==="low"?t:"info"}class hl{id="trivy-image";version;timeoutMs;constructor(e={}){this.version=e.version??"local",this.timeoutMs=e.timeoutMs??120000,this.executable=e.executable??"trivy"}executable;async scan(e){if(!e.imageRef)return{status:"skipped",findings:[],error:"No image reference was supplied"};let t;try{t=Bun.spawn([this.executable,"image","--format","json","--quiet","--scanners","vuln",e.imageRef],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",TRIVY_NO_PROGRESS:"true"}})}catch(u){return{status:"unsupported",findings:[],error:u instanceof Error?u.message:String(u)}}let r=()=>t.kill();e.signal.addEventListener("abort",r,{once:!0});let[n,i,o]=await Promise.all([t.exited,new Response(t.stdout).text(),new Response(t.stderr).text()]);if(e.signal.removeEventListener("abort",r),n!==0)return{status:/not found|enoent/i.test(o)?"unsupported":"unavailable",findings:[],error:o.slice(0,2000)||`Trivy exited with ${n}`};let s=JSON.parse(i),c=[];for(let u of s.Results??[])for(let a of u.Vulnerabilities??[]){let f=a.VulnerabilityID??"unknown-vulnerability";c.push({...e,ruleId:f,severity:vC(a.Severity),title:a.Title||f,description:a.Description||`${f} affects ${a.PkgName??"an image package"}.`,subject:`${e.imageRef}:${a.PkgName??"unknown"}:${a.InstalledVersion??"unknown"}`,evidence:{image:e.imageRef,target:u.Target??"",cve:f,package:a.PkgName??"",installedVersion:a.InstalledVersion??"",fixedVersion:a.FixedVersion??"",reference:a.PrimaryURL??""},remediation:a.FixedVersion?`Upgrade ${a.PkgName} to ${a.FixedVersion} or later.`:"Remove or replace the affected package and rescan the image."})}return{status:c.length?"failed":"passed",findings:c,metadata:{imageRef:e.imageRef,vulnerabilityCount:c.length,localOnly:!0}}}}import{createHash as wC,createVerify as oO}from"node:crypto";import{existsSync as IC,readFileSync as CC}from"node:fs";import{basename as EC,join as TC,resolve as uh}from"node:path";function Pa(e){return wC("sha256").update(e).digest("hex")}function AC(e){let t=[["dependencies","required"],["optionalDependencies","optional"],["devDependencies","excluded"],["peerDependencies","required"]],r=new Map;for(let[n,i]of t){let o=e[n];if(!o||typeof o!=="object"||Array.isArray(o))continue;for(let[s,c]of Object.entries(o)){let u=String(c).replace(/^[~^]/,""),a=`${s}@${u}`;if(!r.has(a))r.set(a,{type:"library",name:s,version:u,purl:`pkg:npm/${encodeURIComponent(s)}@${encodeURIComponent(u)}`,scope:i})}}return[...r.values()].sort((n,i)=>`${n.name}@${n.version}`.localeCompare(`${i.name}@${i.version}`))}function lh(e,t={}){let r=TC(uh(e),"package.json");if(!IC(r))throw Error(`Cannot generate an SBOM: ${r} was not found`);let n=CC(r,"utf8"),i=JSON.parse(n),o=String(i.name??EC(uh(e))),s=String(i.version??"0.0.0"),c=Pa(n);return{bomFormat:"CycloneDX",specVersion:"1.5",serialNumber:t.serial??`urn:uuid:${crypto.randomUUID()}`,version:1,metadata:{timestamp:(t.now??new Date).toISOString(),component:{type:"application",name:o,version:s,purl:`pkg:npm/${encodeURIComponent(o)}@${encodeURIComponent(s)}`,hashes:[{alg:"SHA-256",content:c}]},tools:[{vendor:"ts-cloud",name:"security-posture",version:"1.0.0"}]},components:AC(i)}}async function ph(e,t={}){let r=Bun.spawn([t.executable??"syft",e,"-o","cyclonedx-json"],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",SYFT_CHECK_FOR_APP_UPDATE:"false"}}),n=()=>r.kill();t.signal?.addEventListener("abort",n,{once:!0});let[i,o,s]=await Promise.all([r.exited,new Response(r.stdout).text(),new Response(r.stderr).text()]);if(t.signal?.removeEventListener("abort",n),i!==0)throw Error(s.slice(0,2000)||`Syft exited with ${i}`);return JSON.parse(o)}function yl(e,t,r){let n=JSON.stringify(r);return e.addReleaseArtifact({...t,kind:"sbom",format:`cyclonedx-${r.specVersion}+json`,digest:`sha256:${Pa(n)}`,summary:{component:r.metadata.component.name,version:r.metadata.component.version,components:r.components.length},content:n,sensitive:!0})}function gh(e,t,r){let n={total:r.length,critical:0,high:0,medium:0,low:0,info:0,fixable:0};for(let o of r){n[o.severity]++;let s=o.evidence;if(typeof s.fixedVersion==="string"&&s.fixedVersion)n.fixable++}let i=JSON.stringify({releaseId:t.releaseId,generatedAt:new Date().toISOString(),findings:r.map((o)=>({id:o.id,ruleId:o.ruleId,severity:o.severity,subject:o.subject,remediation:o.remediation}))});return e.addReleaseArtifact({...t,kind:"vulnerability_summary",format:"ts-cloud-vulnerability-summary+json",digest:`sha256:${Pa(i)}`,summary:n,content:i,sensitive:!0})}function mh(e){if(!e.artifact&&!e.artifactSha256)throw Error("Release provenance requires artifact content or a SHA-256 digest");return{_type:"https://in-toto.io/Statement/v1",subject:[{name:e.artifactName,digest:{sha256:e.artifactSha256?.replace(/^sha256:/,"")??Pa(e.artifact)}}],predicateType:"https://slsa.dev/provenance/v1",predicate:{buildDefinition:{buildType:"https://ts-cloud.dev/build/v1",externalParameters:e.externalParameters??{},internalParameters:{},resolvedDependencies:e.resolvedDependencies??[]},runDetails:{builder:{id:"https://ts-cloud.dev/builders/local/v1"},metadata:{invocationId:e.invocationId,startedOn:e.startedAt,finishedOn:e.completedAt}}}}}function fh(e,t,r){let n=JSON.stringify(r);return e.addReleaseArtifact({...t,kind:"provenance",format:"in-toto+slsa-v1+json",digest:`sha256:${Pa(n)}`,summary:{subjects:r.subject.length,builder:r.predicate.runDetails.builder.id,buildType:r.predicate.buildDefinition.buildType},content:n,sensitive:!0})}function ue(e,t){let r=e.environments.get(t);if(!r)throw Error(`Security scope for environment '${t}' was not found`);return{organizationId:e.organization.id,projectId:e.project.id,environmentId:r.id}}function ii(e,t){let r=new Ot(e.store),n=r.listPolicies(e.organization.id);for(let[i,o]of e.environments){if(n.some((c)=>c.environmentId===o.id))continue;let s=i==="production"||o.kind==="production";n.push(r.createPolicy({organizationId:e.organization.id,environmentId:o.id,name:s?"Production baseline":"Environment baseline",scannerFailMode:s?"closed":"open",requiredScanners:["source-secrets"],rules:s?[{minimumSeverity:"critical",action:"block"},{minimumSeverity:"high",action:"block"},{minimumSeverity:"medium",action:"warn"},{minimumSeverity:"low",action:"record"}]:[{minimumSeverity:"critical",action:"warn"},{minimumSeverity:"high",action:"warn"},{minimumSeverity:"low",action:"record"}],actorId:t}))}return n}function lc(e,t,r,n={}){let i=r.findings.map((o)=>({...t,ruleId:o.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:o.pattern.severity,title:o.pattern.name,description:o.pattern.description,subject:`${o.file}:${o.line}`,evidence:{file:o.file,line:o.line,column:o.column,match:o.match,context:o.context},remediation:"Remove and rotate the credential, then reference it through a managed secret or environment variable."}));return e.recordScan({...t,scannerId:"source-secrets",scannerVersion:n.scannerVersion??"1.0.0",status:n.skipped?"skipped":r.passed?"passed":"failed",findings:n.skipped?[]:i,metadata:{scannedFiles:r.scannedFiles,durationMs:r.duration,summary:r.summary},durationMs:r.duration,error:n.skipped?"The operator explicitly skipped source-secret scanning.":void 0})}function dc(e,t,r="The operator explicitly skipped source-secret scanning."){return e.recordScan({...t,scannerId:"source-secrets",scannerVersion:"1.0.0",status:"skipped",findings:[],error:r})}function kC(e,t){let r=[],n=t.security;if(n?.firewall&&!["active","configured","ok"].includes(String(n.firewall.status)))r.push({...e,ruleId:"host-firewall-disabled",severity:"high",title:"Host firewall is not active",description:String(n.firewall.summary??"The host firewall did not report an active configuration."),subject:"host:firewall",evidence:{status:String(n.firewall.status??"unknown"),rules:Array.isArray(n.firewall.rules)?n.firewall.rules.length:0},remediation:"Apply the declarative firewall policy and confirm only required listeners are public."});for(let i of n?.ports??[]){let o=String(i.listen??""),s=Number(o.match(/:(\d+)$/)?.[1]);if(i.exposure==="public"&&Number.isFinite(s)&&![22,80,443].includes(s))r.push({...e,ruleId:"unexpected-public-listener",severity:"medium",title:`Unexpected public listener on port ${s}`,description:`${String(i.processName??"A process")} is listening publicly outside the standard SSH/HTTP/HTTPS ports.`,subject:`host:port:${s}`,evidence:{protocol:String(i.proto??""),listen:o,process:String(i.processName??"")},remediation:"Bind the service to loopback/private networking or explicitly document and firewall the required public port."})}for(let i of n?.tlsCertificates??[]){let o=Number(i.daysRemaining);if(Number.isFinite(o)&&o<30)r.push({...e,ruleId:"tls-certificate-expiry",severity:o<14?"high":"medium",title:`TLS certificate expires in ${o} days`,description:`${String(i.domain??"A configured domain")} needs renewal.`,subject:`tls:${String(i.domain??"unknown")}`,evidence:{domain:String(i.domain??""),daysRemaining:o,expires:String(i.expires??"")},remediation:"Renew the certificate and verify automatic renewal can complete before expiry."})}for(let i of t.diagnostics??[]){if(i.status==="pass"||i.status==="ok")continue;r.push({...e,ruleId:`diagnostic-${String(i.name??"unknown").toLowerCase().replace(/[^a-z0-9]+/g,"-")}`,severity:i.status==="fail"?"high":"medium",title:String(i.name??"Host security check"),description:String(i.detail??"The host security diagnostic did not pass."),subject:`diagnostic:${String(i.name??"unknown")}`,evidence:{status:String(i.status??"unknown")},remediation:"Follow the diagnostic guidance, rerun the check, and confirm the finding resolves."})}return r}function rd(e,t,r){let n=!!r.security||Array.isArray(r.diagnostics),i=n?kC(t,r):[];return e.recordScan({...t,scannerId:"host-posture",scannerVersion:"1.0.0",status:!n?"unavailable":i.length?"failed":"passed",findings:i,metadata:{source:"dashboard-live-probe",checks:Array.isArray(r.diagnostics)?r.diagnostics.length:0},error:n?void 0:"Live host posture data was unavailable; source and provider checks remain usable."})}function lr(e,t){let r=e.evaluateGate({...t.scope,operationId:t.operationId}),n=e.listFindings({...t.scope,limit:1000}).filter((i)=>i.status!=="resolved");return{decision:r,summary:{desiredConfigHash:t.desiredConfigHash??null,securityImpact:{critical:n.filter((i)=>i.severity==="critical").length,high:n.filter((i)=>i.severity==="high").length,waived:n.filter((i)=>i.status==="waived").length,assigned:n.filter((i)=>!!i.ownerActorId).length},blockingFindingIds:r.findingIds,policy:{id:r.policyId,version:r.policyVersion},scannerVersions:r.scannerVersions}}}async function uc(e,t){let r=t.scanner??new hl({timeoutMs:t.scannerTimeoutMs}),i=await new rs(e,{defaultTimeoutMs:t.scannerTimeoutMs??120000}).run(r,{...t.scope,releaseId:t.releaseId,imageRef:t.imageRef}),o={...t.scope,releaseId:t.releaseId};gh(e,o,i.findings);let s=t.generateImageSbom??ph,c=new AbortController,u=Math.max(100,t.sbomTimeoutMs??120000),a,f=new Promise((D,W)=>{a=setTimeout(()=>{c.abort(),W(Error(`syft-sbom exceeded its ${u}ms timeout`))},u)}),C="unavailable";try{let D=await Promise.race([s(t.imageRef,{signal:c.signal}),f]);yl(e,o,D),e.recordScan({...t.scope,releaseId:t.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"passed",metadata:{imageRef:t.imageRef,format:`cyclonedx-${D.specVersion}+json`,components:D.components.length,localOnly:!0}}),C="image"}catch(D){let W=D instanceof Error?D.message:String(D);try{let Y=lh(t.artifactRoot);yl(e,o,Y),e.recordScan({...t.scope,releaseId:t.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unsupported",error:`Image inventory was unavailable; attached a package-manifest SBOM instead. ${W}`,metadata:{imageRef:t.imageRef,fallback:"package-manifest",components:Y.components.length,localOnly:!0}}),C="manifest"}catch(Y){e.recordScan({...t.scope,releaseId:t.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unavailable",error:`Image and manifest SBOM generation were unavailable. ${W}; ${Y instanceof Error?Y.message:String(Y)}`,metadata:{imageRef:t.imageRef,localOnly:!0}})}}finally{if(a)clearTimeout(a)}let k=mh({artifactName:t.imageRef,artifact:t.imageSha256?void 0:t.imageRef,artifactSha256:t.imageSha256,invocationId:t.invocationId,startedAt:t.startedAt,completedAt:t.completedAt??new Date().toISOString(),externalParameters:t.externalParameters??{imageRef:t.imageRef}});return fh(e,o,k),{scan:i,sbomSource:C}}class q{client;region;endpoint;constructor(e="us-east-1",t){this.region=e,this.endpoint=t?.endpoint,this.client=new p}async request(e,t){if(this.endpoint){let r=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/x-amz-json-1.0","X-Amz-Target":`DynamoDB_20120810.${e}`},body:JSON.stringify(t)});if(!r.ok){let n=await r.text();throw Error(`DynamoDB request failed: ${r.status} ${n}`)}return r.json()}return this.client.request({service:"dynamodb",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.0","X-Amz-Target":`DynamoDB_20120810.${e}`},body:JSON.stringify(t)})}async createTable(e){return this.request("CreateTable",e)}async deleteTable(e){return this.request("DeleteTable",e)}async describeTable(e){return this.request("DescribeTable",e)}async listTables(e){return this.request("ListTables",e||{})}async putItem(e){return this.request("PutItem",e)}async getItem(e){return this.request("GetItem",e)}async updateItem(e){return this.request("UpdateItem",e)}async deleteItem(e){return this.request("DeleteItem",e)}async query(e){return this.request("Query",e)}async scan(e){return this.request("Scan",e)}async batchWriteItem(e){return this.request("BatchWriteItem",e)}async batchGetItem(e){return this.request("BatchGetItem",e)}async updateTimeToLive(e){return this.request("UpdateTimeToLive",e)}static marshal(e){let t={};for(let[r,n]of Object.entries(e))t[r]=q.marshalValue(n);return t}static marshalValue(e){if(e===null||e===void 0)return{NULL:!0};if(typeof e==="string")return{S:e};if(typeof e==="number")return{N:String(e)};if(typeof e==="boolean")return{BOOL:e};if(Array.isArray(e))return{L:e.map((t)=>q.marshalValue(t))};if(typeof e==="object")return{M:q.marshal(e)};return{S:String(e)}}static unmarshal(e){let t={};for(let[r,n]of Object.entries(e))t[r]=q.unmarshalValue(n);return t}static unmarshalValue(e){if(e.S!==void 0)return e.S;if(e.N!==void 0)return Number(e.N);if(e.BOOL!==void 0)return e.BOOL;if(e.NULL!==void 0)return null;if(e.L!==void 0)return e.L.map((t)=>q.unmarshalValue(t));if(e.M!==void 0)return q.unmarshal(e.M);if(e.SS!==void 0)return e.SS;if(e.NS!==void 0)return e.NS.map(Number);return null}}class bl extends Error{status;code;requestId;constructor(e,t,r,n){super(r);this.status=e;this.code=t;this.requestId=n}}class Qi{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 bl(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 RC}from"node:crypto";var nd="1.6.0";function Sl(){let e={type:"object",required:["error"],properties:{error:{type:"object",required:["code","message","requestId"],properties:{code:{type:"string"},message:{type:"string"},requestId:{type:"string",format:"uuid"},details:{}}}}},t=(n)=>({type:"object",required:["data","page","requestId"],properties:{data:{type:"array",items:n},page:{type:"object",required:["hasMore"],properties:{nextCursor:{type:"string"},hasMore:{type:"boolean"}}},requestId:{type:"string",format:"uuid"}}}),r=(n)=>({"200":{description:"A stable cursor page.",content:{"application/json":{schema:t(n)}}},default:{$ref:"#/components/responses/Error"}});return{openapi:"3.1.0",info:{title:"ts-cloud API",version:nd,description:"Additive changes are released within v1. Breaking request or response changes require a new URL version."},servers:[{url:"/"}],security:[{bearerAuth:[]}],paths:{...xs(),"/api/v1/projects":{get:{operationId:"listProjects",summary:"List accessible projects",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Project"})}},"/api/v1/projects/{projectId}/environments":{get:{operationId:"listEnvironments",summary:"List accessible project environments",parameters:[{$ref:"#/components/parameters/ProjectId"},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Environment"})}},"/api/v1/services":{get:{operationId:"listServices",summary:"List accessible services",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{name:"environmentId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Service"})}},"/api/v1/source/connections":{get:{operationId:"listSourceConnections",summary:"List safe Git connection metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceConnection"})},post:{operationId:"createSourceConnection",summary:"Create an encrypted Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["provider","name","host"],properties:{provider:{type:"string",enum:["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"]},name:{type:"string"},host:{type:"string",format:"uri"},token:{type:"string",writeOnly:!0},repositoryFullName:{type:"string"},repositoryUrl:{type:"string"}}}}}},responses:{"201":{description:"Encrypted connection created."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectSourceConnection",summary:"Preview or safely disconnect a Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["id"],properties:{id:{type:"string"},preview:{type:"boolean"}}}}}},responses:{"200":{description:"Impact preview or disconnected connection."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/repositories":{get:{operationId:"listSourceRepositories",summary:"List or synchronize granted repositories",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"sync",in:"query",schema:{type:"boolean"}},{name:"search",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceRepository"})}},"/api/v1/source/refs":{get:{operationId:"listSourceRefs",summary:"List repository branches or tags",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"repository",in:"query",required:!0,schema:{type:"string"}},{name:"repositoryId",in:"query",schema:{type:"string"}},{name:"type",in:"query",schema:{type:"string",enum:["branches","tags"]}}],responses:{"200":{description:"Provider reference page."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/bindings":{post:{operationId:"createSourceBinding",summary:"Bind a repository to an application",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/SourceBindingRequest"}}}},responses:{"201":{description:"Source binding created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/webhooks":{post:{operationId:"createSourceWebhook",summary:"Create and optionally reconcile a signed webhook",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["connectionId","repositoryFullName","baseUrl"],properties:{connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},baseUrl:{type:"string",format:"uri"},events:{type:"array",items:{type:"string",enum:["push","pull_request"]}},reconcile:{type:"boolean"}}}}}},responses:{"201":{description:"Webhook endpoint created; endpoint is revealed once."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-detections":{post:{operationId:"detectApplication",summary:"Detect bounded application build candidates",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["files"],properties:{files:{type:"array",maxItems:1e4,items:{$ref:"#/components/schemas/DetectionFile"}}}}}}},responses:{"200":{description:"Ranked detection candidates with evidence."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-plans":{post:{operationId:"planApplication",summary:"Validate and normalize an application manifest",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["draft"],properties:{draft:{$ref:"#/components/schemas/ApplicationInput"},suppliedSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}}}}}},responses:{"200":{description:"Validated plan, config patch, capabilities, costs, and missing secret names."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-drafts":{get:{operationId:"listApplicationDrafts",summary:"List resumable secret-free drafts",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/ApplicationDraft"})},post:{operationId:"createApplicationDraft",summary:"Create a resumable application draft",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/ApplicationDraftCreateRequest"}}}},responses:{"201":{description:"Draft created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateApplicationDraft",summary:"Optimistically update a draft",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/ApplicationDraftCreateRequest"},{type:"object",required:["id","version","step"],properties:{id:{type:"string"},version:{type:"integer",minimum:1}}}]}}}},responses:{"200":{description:"Updated draft."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/applications":{post:{operationId:"createApplication",summary:"Confirm and queue an application plan",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["draftId","version","confirmEnvironment"],properties:{draftId:{type:"string"},version:{type:"integer",minimum:1},confirmEnvironment:{type:"string",description:"Exact target environment slug."}}}}}},responses:{"202":{description:"Application operation queued; identical requests replay safely."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-artifacts":{post:{operationId:"uploadApplicationArtifact",summary:"Inspect and store a bounded ZIP or TAR source artifact",parameters:[{name:"X-Project-Id",in:"header",required:!0,schema:{type:"string"}},{name:"X-Artifact-Filename",in:"header",required:!0,schema:{type:"string"}}],requestBody:{required:!0,content:{"application/octet-stream":{schema:{type:"string",format:"binary",maxLength:104857600}}}},responses:{"201":{description:"Deduplicated artifact metadata; archive contents are never executed."},"413":{$ref:"#/components/responses/Error"},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/registry-connections":{get:{operationId:"listRegistryConnections",summary:"List safe private-registry metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/RegistryConnection"})},post:{operationId:"createRegistryConnection",summary:"Create an encrypted private-registry connection",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/RegistryConnectionRequest"}}}},responses:{"201":{description:"Encrypted registry connection created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateRegistryConnection",summary:"Test access or rotate write-only credentials",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/RegistryConnectionRequest"},{type:"object",required:["id","action"],properties:{id:{type:"string"},action:{type:"string",enum:["test","rotate"]},image:{type:"string"}}}]}}}},responses:{"200":{description:"Safe connection health metadata."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectRegistryConnection",summary:"Disconnect and erase registry credentials",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["id"],properties:{id:{type:"string"}}}}}},responses:{"200":{description:"Credentials erased and connection disconnected."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue":{get:{operationId:"listQueue",summary:"List authorized durable operations and blocking metadata",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"state",in:"query",schema:{type:"string",enum:["queued","running","succeeded","failed","cancelled","timed_out"]}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/QueueOperation"})}},"/api/v1/preview-definitions":{get:{operationId:"listPreviewDefinitions",summary:"List preview policies",responses:r({type:"object"})},post:{operationId:"createPreviewDefinition",summary:"Configure bounded preview policy",responses:{"200":{description:"Preview definition created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews":{get:{operationId:"listPreviews",summary:"List authorized persistent previews",responses:r({type:"object"})},post:{operationId:"createPreview",summary:"Create or update one immutable preview identity",responses:{"200":{description:"Preview deployment queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/destroy":{post:{operationId:"destroyPreview",summary:"Confirm tagged preview teardown",responses:{"200":{description:"Teardown queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/extend":{post:{operationId:"extendPreview",summary:"Extend preview TTL",responses:{"200":{description:"Expiry extended."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/rebuild":{post:{operationId:"rebuildPreview",summary:"Rebuild the exact recorded commit",responses:{"200":{description:"Rebuild queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/cleanup":{post:{operationId:"cleanupPreviews",summary:"Dry-run or queue TTL/keep-count teardown",responses:{"200":{description:"Cleanup plan or operations."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-templates":{get:{operationId:"listComposeTemplates",summary:"List pinned verified application templates",responses:r({type:"object"})}},"/api/v1/compose-applications":{get:{operationId:"listComposeApplications",summary:"List authorized multi-service applications",responses:r({type:"object"})},post:{operationId:"createComposeApplication",summary:"Import Compose or materialize a template",responses:{"200":{description:"Editable normalized application."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/preview":{post:{operationId:"previewComposeApplication",summary:"Parse and diagnose Compose without mutation",responses:{"200":{description:"Normalized preview and actionable diagnostics."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/services":{get:{operationId:"listComposeServices",summary:"Inspect per-service desired and observed state",responses:{"200":{description:"Service topology and status."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/{action}":{post:{operationId:"operateComposeApplication",summary:"Deploy, redeploy, start, stop, scale, or delete through the durable queue",responses:{"200":{description:"Scoped operation queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/release-artifacts":{post:{operationId:"createReleaseArtifact",summary:"Register a verified content-addressed artifact",responses:{"200":{description:"Artifact identity registered."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases":{get:{operationId:"listReleases",summary:"List unified authorized release history",responses:r({type:"object"})},post:{operationId:"createRelease",summary:"Create an immutable release from an existing artifact",responses:{"200":{description:"Release record created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/capabilities":{get:{operationId:"getReleaseCapabilities",summary:"Explain supported strategies, capacity, cost, and rollback",responses:{"200":{description:"Provider-aware strategy capabilities."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}":{get:{operationId:"getRelease",summary:"Inspect provenance, approvals, health, and transitions",responses:{"200":{description:"Release detail."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}/{action}":{post:{operationId:"operateRelease",summary:"Promote, approve, activate, roll back, report health, or pin",responses:{"200":{description:"Release lifecycle updated."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/settings":{get:{operationId:"getQueueSettings",summary:"Get effective concurrency limits",responses:{"200":{description:"Queue concurrency settings."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateQueueSettings",summary:"Confirm and audit production concurrency changes",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm","concurrency"],properties:{confirm:{const:"update queue limits"},concurrency:{$ref:"#/components/schemas/QueueConcurrency"}}}}}},responses:{"200":{description:"Updated effective limits."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/history":{delete:{operationId:"clearQueueHistory",summary:"Clear terminal jobs whose retention has elapsed",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm"],properties:{confirm:{const:"clear completed"},before:{type:"string",format:"date-time"},projectId:{type:"string"}}}}}},responses:{"200":{description:"Eligible history cleared with an audit event."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs":{get:{operationId:"listOperationLogs",summary:"Resume ordered sanitized operation logs from a cursor",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:{"200":{description:"Ordered log chunks and next cursor."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs/stream":{get:{operationId:"streamOperationLogs",summary:"Stream authorized operation logs with Last-Event-ID resume",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"Last-Event-ID",in:"header",schema:{type:"integer",minimum:0}}],responses:{"200":{description:"Server-sent log and completion events.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/cancel":{post:{operationId:"cancelOperation",summary:"Cancel queued work or request cooperative running cancellation",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{content:{"application/json":{schema:{type:"object"}}}},responses:{"200":{description:"Cancellation state recorded."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/retry":{post:{operationId:"retryOperation",summary:"Retry an allow-listed failure class within the attempt limit",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["errorClass"],properties:{errorClass:{type:"string"},delayMs:{type:"integer",minimum:0}}}}}},responses:{"200":{description:"Retry queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/deployments":{post:{operationId:"createDeployment",summary:"Queue a deployment",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/DeploymentRequest"}}}},responses:{"202":{description:"Queued operation.",content:{"application/json":{schema:{$ref:"#/components/schemas/OperationResponse"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations":{get:{operationId:"listOperations",summary:"List scoped operations",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Operation"})}},"/api/v1/events":{get:{operationId:"listEvents",summary:"List scoped audit events",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:r({$ref:"#/components/schemas/Event"})}},"/api/v1/events/stream":{get:{operationId:"streamEvents",summary:"Stream scoped audit events",responses:{"200":{description:"Authenticated server-sent event stream.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/openapi.json":{get:{operationId:"getOpenApi",summary:"Get the OpenAPI contract",security:[],responses:{"200":{description:"OpenAPI 3.1 contract."}}}}},components:{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer",bearerFormat:"tsc_v1"}},parameters:{Limit:{name:"limit",in:"query",schema:{type:"integer",minimum:1,maximum:100,default:50}},Cursor:{name:"cursor",in:"query",schema:{type:"string"}},ProjectId:{name:"projectId",in:"path",required:!0,schema:{type:"string"}},OperationId:{name:"operationId",in:"path",required:!0,schema:{type:"string"}}},responses:{Error:{description:"Stable error envelope.",content:{"application/json":{schema:e}}}},schemas:{Project:{type:"object",required:["id","slug","name"],properties:{id:{type:"string"},slug:{type:"string"},name:{type:"string"},description:{type:"string"}}},Environment:{type:"object",required:["id","projectId","slug","name","kind"],properties:{id:{type:"string"},projectId:{type:"string"},slug:{type:"string"},name:{type:"string"},kind:{type:"string"},region:{type:"string"}}},Service:{type:"object",required:["id","projectId","kind","slug","name"],properties:{id:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},kind:{type:"string"},slug:{type:"string"},name:{type:"string"},metadata:{type:"object",additionalProperties:!0}}},SourceConnection:{type:"object",required:["id","provider","name","host","status","credentialConfigured"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},status:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},grantedScopes:{type:"array",items:{type:"string"}}}},SourceRepository:{type:"object",required:["id","connectionId","fullName","cloneUrl","defaultBranch"],properties:{id:{type:"string"},connectionId:{type:"string"},fullName:{type:"string"},cloneUrl:{type:"string"},defaultBranch:{type:"string"},visibility:{type:"string"},archived:{type:"boolean"}}},SourceBindingRequest:{type:"object",additionalProperties:!1,required:["projectId","connectionId","repositoryFullName"],properties:{projectId:{type:"string"},environmentId:{type:"string"},resourceId:{type:"string"},connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},defaultBranch:{type:"string"},branchRule:{type:"string"},tagRule:{type:"string"},monorepoRoot:{type:"string"},includePaths:{type:"array",items:{type:"string"}},excludePaths:{type:"array",items:{type:"string"}},submodules:{type:"boolean"},cloneDepth:{type:"integer",minimum:1},deployKeyId:{type:"string"},autoDeploy:{type:"boolean"},pullRequestPreviews:{type:"boolean"}}},DetectionFile:{type:"object",additionalProperties:!1,required:["path"],properties:{path:{type:"string"},size:{type:"integer",minimum:0},content:{type:"string",maxLength:262144}}},ApplicationInput:{type:"object",additionalProperties:!1,required:["schemaVersion","name","slug","projectId","environmentId","source","build","runtime"],properties:{schemaVersion:{const:1},name:{type:"string"},slug:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},source:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["git","local","artifact","image"]}},additionalProperties:!0},build:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["dockerfile","buildpack","static","server","serverless","prebuilt_image"]},secretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}},additionalProperties:!0},runtime:{type:"object",required:["architecture","target"],properties:{architecture:{type:"string",enum:["x86_64","arm64"]},target:{type:"string",enum:["server","serverless","container"]},port:{type:"integer",minimum:1,maximum:65535},healthCheck:{type:"object",additionalProperties:!0}},additionalProperties:!0},environment:{type:"object",additionalProperties:{oneOf:[{type:"string"},{type:"object",additionalProperties:!1,required:["secretRef"],properties:{secretRef:{type:"string"}}}]}},requiredSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}},domain:{type:"object",properties:{hostname:{type:"string"},path:{type:"string"},tls:{type:"boolean"}}}}},ApplicationDraftCreateRequest:{type:"object",additionalProperties:!1,required:["projectId","draft"],properties:{projectId:{type:"string"},name:{type:"string"},draft:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string",enum:["source","build","runtime","environment","domain","review"]},suppliedSecretNames:{type:"array",uniqueItems:!0,description:"Names only; values must use the secrets boundary.",items:{type:"string"}}}},ApplicationDraft:{type:"object",required:["id","projectId","input","step","status","version"],properties:{id:{type:"string"},projectId:{type:"string"},input:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string"},suppliedSecretNames:{type:"array",items:{type:"string"}},status:{type:"string",enum:["draft","ready","applied"]},version:{type:"integer"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"}}},RegistryConnectionRequest:{type:"object",properties:{provider:{type:"string",enum:["docker_hub","ghcr","ecr","gcr","generic"]},name:{type:"string"},host:{type:"string"},username:{type:"string",writeOnly:!0},password:{type:"string",writeOnly:!0},token:{type:"string",writeOnly:!0},credentialExpiresAt:{type:"string",format:"date-time"},expiresAt:{type:"string",format:"date-time"}}},RegistryConnection:{type:"object",required:["id","provider","name","host","credentialConfigured","status","version"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},credentialExpiresAt:{type:"string",format:"date-time"},status:{type:"string",enum:["pending","healthy","degraded","expired","disconnected"]},healthMessage:{type:"string"},lastTestedAt:{type:"string",format:"date-time"},version:{type:"integer"}}},QueueConcurrency:{type:"object",additionalProperties:!1,properties:{project:{type:"integer",minimum:1,maximum:100},environment:{type:"integer",minimum:1,maximum:100},provider:{type:"integer",minimum:1,maximum:100},builds:{type:"integer",minimum:1,maximum:100}}},QueueOperation:{allOf:[{$ref:"#/components/schemas/Operation"},{type:"object",required:["queue"],properties:{queue:{type:"object",required:["maxAttempts","availableAt","timeoutSeconds","retryClasses","resumePolicy","cancellationMode","retentionUntil"],properties:{lockKey:{type:"string"},providerKey:{type:"string"},buildSlot:{type:"boolean"},maxAttempts:{type:"integer"},availableAt:{type:"string",format:"date-time"},timeoutSeconds:{type:"integer"},heartbeatAt:{type:"string",format:"date-time"},currentStep:{type:"string"},blockedReason:{type:"string"},retryClasses:{type:"array",items:{type:"string"}},resumePolicy:{type:"string",enum:["fail","requeue"]},cancellationMode:{type:"string",enum:["cooperative","provider_non_cancellable"]},retentionUntil:{type:"string",format:"date-time"}}},approximatePosition:{type:"object",properties:{ahead:{type:"integer"},precision:{const:"bounded"}}}}}]},DeploymentRequest:{type:"object",additionalProperties:!1,required:["projectId","environmentId"],properties:{projectId:{type:"string"},environmentId:{type:"string"},serviceId:{type:"string"},action:{type:"string",enum:["deploy","rollback"],default:"deploy"},revision:{type:"string"}}},Operation:{type:"object",required:["id","state","kind","correlationId","createdAt"],properties:{id:{type:"string"},state:{type:"string"},kind:{type:"string"},correlationId:{type:"string"},createdAt:{type:"string",format:"date-time"}}},OperationResponse:{type:"object",required:["operation","idempotentReplay","requestId"],properties:{operation:{$ref:"#/components/schemas/Operation"},idempotentReplay:{type:"boolean"},requestId:{type:"string",format:"uuid"}}},Event:{type:"object",required:["id","sequence","type","level","correlationId","createdAt"],properties:{id:{type:"string"},sequence:{type:"integer"},type:{type:"string"},level:{type:"string"},correlationId:{type:"string"},payload:{},createdAt:{type:"string",format:"date-time"}}}}}}}function PC(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}function xC(e){if(!e)return;try{let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return t&&typeof t==="object"&&!Array.isArray(t)?t:void 0}catch{return}}function tn(e,t,r,n=["createdAt","id"]){let i=Math.min(100,Math.max(1,Number(t.searchParams.get("limit"))||50)),o=xC(t.searchParams.get("cursor"));if(t.searchParams.has("cursor")&&!o)throw new m("invalid_cursor","The pagination cursor is invalid.",400);let s=0;if(o){let f=e.findIndex((C)=>n.every((k)=>C[k]===o[k]));if(f<0)throw new m("invalid_cursor","The pagination cursor is no longer available.",400);s=f+1}let c=e.slice(s,s+i),u=s+i<e.length,a=c.at(-1);return{data:c,page:{hasMore:u,nextCursor:u&&a?PC(Object.fromEntries(n.map((f)=>[f,a[f]]))):void 0},requestId:r}}function vl(e){let t=new So(e.controlPlane,e.identities),r=new S(e.controlPlane),n=new Ze(e.controlPlane),i=new Ye(e.controlPlane),o=new lt(e.controlPlane),s=e.spend?.store??new Er(e.controlPlane,{now:e.now}),c={store:s,service:e.spend?.service??new bt(s)},u=new Map,a=e.now??(()=>new Date),f=e.rateLimit??120,C=(D,W,Y,ee={})=>new Response(JSON.stringify(D),{status:W,headers:{"content-type":"application/json; charset=utf-8","cache-control":"no-store","x-request-id":Y,"x-api-version":nd,...ee}}),k=(D,W,Y,ee,ne,he)=>C({error:{code:D,message:W,requestId:ee,details:ne}},Y,ee,he);return async(D,W)=>{let Y=new URL(D.url);if(!Y.pathname.startsWith("/api/v1"))return;let ee=crypto.randomUUID();if(Y.pathname==="/api/v1/openapi.json"&&D.method==="GET")return C(Sl(),200,ee,{"cache-control":"public, max-age=300"});let ne=D.headers.get("authorization")??"",he=ne.startsWith("Bearer ")?ne.slice(7).trim():"",te=he?e.identities.verifyToken(he,W):void 0;if(!te)return k("unauthorized","A valid bearer token is required.",401,ee,void 0,{"www-authenticate":'Bearer realm="ts-cloud", error="invalid_token"'});let Pe=u.get(te.token.id),Xe=a().getTime(),$e=!Pe||Xe-Pe.start>=60000?{start:Xe,count:0}:Pe;$e.count+=1,u.set(te.token.id,$e);let Gt=Math.max(0,f-$e.count),it={"x-ratelimit-limit":String(f),"x-ratelimit-remaining":String(Gt),"x-ratelimit-reset":String(Math.ceil(($e.start+60000)/1000))};if($e.count>f)return k("rate_limited","API rate limit exceeded.",429,ee,void 0,{...it,"retry-after":String(Math.max(1,Math.ceil(($e.start+60000-Xe)/1000)))});try{let ke,He=async()=>{let Q=await D.text();if(Q.length>1048576)throw new m("payload_too_large","Request body exceeds 1 MB.",413);try{return JSON.parse(Q)}catch{throw new m("invalid_json","Request body must be valid JSON.",400)}},Tt=/^\/api\/v1\/projects\/([^/]+)\/environments$/.exec(Y.pathname),Ei=/^\/api\/v1\/operations\/([^/]+)\/logs(?:\/(stream))?$/.exec(Y.pathname),co=/^\/api\/v1\/operations\/([^/]+)\/(cancel|retry)$/.exec(Y.pathname),Fn=/^\/api\/v1\/previews\/([^/]+)\/(destroy|extend|rebuild)$/.exec(Y.pathname),Ai=/^\/api\/v1\/compose-applications\/([^/]+)\/(deploy|redeploy|start|stop|scale|delete)$/.exec(Y.pathname),ki=/^\/api\/v1\/compose-applications\/([^/]+)\/services$/.exec(Y.pathname),Ri=/^\/api\/v1\/releases\/([^/]+)\/(promote|approve|activate|rollback|health|pin)$/.exec(Y.pathname);if(D.method==="GET"&&Y.pathname==="/api/v1/projects")ke=tn(t.listProjects(te),Y,ee);else if(D.method==="GET"&&Tt)ke=tn(t.listEnvironments(te,decodeURIComponent(Tt[1])),Y,ee);else if(D.method==="GET"&&Y.pathname==="/api/v1/services"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);ke=tn(t.listServices(te,Q,Y.searchParams.get("environmentId")??void 0),Y,ee)}else if(D.method==="GET"&&Y.pathname==="/api/v1/operations")ke=tn(t.listOperations(te,Y.searchParams.get("projectId")??void 0),Y,ee);else if(D.method==="GET"&&Y.pathname==="/api/v1/previews"){let Q=Y.searchParams.get("projectId")??void 0,ge=n.previews.listInstances({projectId:Q}).filter((Ee)=>{try{return t.authorize(te,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee}));ke=tn(ge,Y,ee)}else if(D.method==="GET"&&Y.pathname==="/api/v1/compose-templates")ke=tn(Sr().map((Q)=>({...Q})),Y,ee,["id","version"]);else if(D.method==="GET"&&Y.pathname==="/api/v1/releases/capabilities"){let Q=String(Y.searchParams.get("kind")??"");ke={capabilities:cr({kind:Q,hasHealthGate:Y.searchParams.get("health")==="true",replicas:Number(Y.searchParams.get("replicas"))||1}),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/releases"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);t.authorize(te,"project:read",{type:"project",id:Q});let ge=o.releases.list({projectId:Q,environmentId:Y.searchParams.get("environmentId")??void 0,resourceId:Y.searchParams.get("resourceId")??void 0}).filter((Ee)=>{try{return t.authorize(te,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,artifact:o.releases.getArtifact(Ee.artifactId),transitions:o.releases.transitions(Ee.id),approvals:o.releases.approvals(Ee.id)}));ke=tn(ge,Y,ee)}else if(D.method==="POST"&&Y.pathname==="/api/v1/release-artifacts"){let Q=await He();t.authorize(te,"applications:manage",{type:"organization"}),ke={artifact:o.releases.registerArtifact({organizationId:te.serviceAccount.organizationId,digest:String(Q.digest??""),kind:String(Q.kind??""),uri:String(Q.uri??""),size:Number(Q.size),mediaType:typeof Q.mediaType==="string"?Q.mediaType:void 0,provenance:Q.provenance,attestation:Q.attestation}),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/releases"){let Q=await He(),ge=String(Q.resourceId??"");t.authorize(te,"applications:manage",{type:"resource",id:ge}),ke={release:o.releases.create({organizationId:te.serviceAccount.organizationId,projectId:String(Q.projectId??""),environmentId:String(Q.environmentId??""),resourceId:ge,artifactId:String(Q.artifactId??""),kind:String(Q.kind??""),sourceSha:typeof Q.sourceSha==="string"?Q.sourceSha:void 0,config:Q.config??{},manifest:Q.manifest??{},provenance:Q.provenance,strategy:String(Q.strategy??"atomic"),healthGate:Q.healthGate,hooks:Q.hooks,drainSeconds:Number(Q.drainSeconds)||void 0,graceSeconds:Number(Q.graceSeconds)||void 0,automaticRollback:Q.automaticRollback!==!1,actorId:te.actor.id,trigger:typeof Q.trigger==="string"?Q.trigger:"api",approvalRequired:Q.approvalRequired===!0,replicas:Number(Q.replicas)||void 0}),requestId:ee}}else if(D.method==="GET"&&/^\/api\/v1\/releases\/[^/]+$/.test(Y.pathname)){let Q=decodeURIComponent(Y.pathname.split("/").at(-1)),ge=o.releases.get(Q);if(!ge)throw new m("not_found","Release was not found.",404);t.authorize(te,"deployments:read",{type:"resource",id:ge.resourceId}),ke={release:ge,artifact:o.releases.getArtifact(ge.artifactId),transitions:o.releases.transitions(Q),approvals:o.releases.approvals(Q),requestId:ee}}else if(D.method==="POST"&&Ri){let Q=o.releases.get(decodeURIComponent(Ri[1]));if(!Q)throw new m("not_found","Release was not found.",404);let ge=await He(),Ee=Ri[2];if(Ee==="promote"){let Re=String(ge.targetResourceId??"");t.authorize(te,"deployments:create",{type:"resource",id:Re}),ke={release:o.releases.promote(Q.id,{targetEnvironmentId:String(ge.targetEnvironmentId??""),targetResourceId:Re,config:ge.config??{},strategy:ge.strategy,healthGate:ge.healthGate,actorId:te.actor.id,approvalRequired:ge.approvalRequired===!0}),requestId:ee}}else if(Ee==="approve")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={release:o.releases.approve(Q.id,{actorId:te.actor.id,decision:ge.decision==="rejected"?"rejected":"approved",comment:typeof ge.comment==="string"?ge.comment:void 0}),requestId:ee};else if(Ee==="activate")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(o.enqueueActivation(Q,{actorId:te.actor.id})),requestId:ee};else if(Ee==="rollback")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(o.enqueueRollback(Q,{actorId:te.actor.id,targetReleaseId:typeof ge.targetReleaseId==="string"?ge.targetReleaseId:void 0})),requestId:ee};else if(Ee==="health"){t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId});let Re=o.completeHealthGate(Q.id,{healthy:ge.healthy===!0,operationId:typeof ge.operationId==="string"?ge.operationId:void 0,health:ge.health,message:typeof ge.message==="string"?ge.message:void 0});ke={release:Re.release,rollbackOperation:Re.rollbackOperation?t.operation(Re.rollbackOperation):void 0,requestId:ee}}else t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={release:o.releases.pin(Q.id,ge.pinned!==!1,typeof ge.reason==="string"?ge.reason:void 0),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/compose-applications"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);t.authorize(te,"project:read",{type:"project",id:Q});let ge=i.applications.list({projectId:Q,environmentId:Y.searchParams.get("environmentId")??void 0}).filter((Ee)=>{try{return t.authorize(te,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,services:i.applications.services(Ee.id)}));ke=tn(ge,Y,ee)}else if(D.method==="POST"&&Y.pathname==="/api/v1/compose-applications/preview"){let Q=await He(),ge=String(Q.projectId??"");t.authorize(te,"project:read",{type:"project",id:ge}),ke={result:i.applications.preview(String(Q.source??""),{name:String(Q.name??""),slug:typeof Q.slug==="string"?Q.slug:void 0,projectId:ge,environmentId:String(Q.environmentId??"")}),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/compose-applications"){let Q=await He(),ge=String(Q.projectId??"");t.authorize(te,"applications:manage",{type:"environment",id:String(Q.environmentId??"")});let Ee={name:String(Q.name??""),slug:typeof Q.slug==="string"?Q.slug:void 0,projectId:ge,environmentId:String(Q.environmentId??""),createdByActorId:te.actor.id},Re=typeof Q.templateId==="string"?i.applications.fromTemplate(Q.templateId,Q.inputs&&typeof Q.inputs==="object"&&!Array.isArray(Q.inputs)?Q.inputs:{},{...Ee,version:typeof Q.templateVersion==="string"?Q.templateVersion:void 0}):i.applications.import(String(Q.source??""),Ee);ke={application:Re.application,diagnostics:Re.parsed.diagnostics,requestId:ee}}else if(D.method==="GET"&&ki){let Q=i.applications.get(decodeURIComponent(ki[1]));if(!Q)throw new m("not_found","Compose application was not found.",404);t.authorize(te,"deployments:read",{type:"resource",id:Q.resourceId}),ke={application:Q,services:i.applications.services(Q.id),requestId:ee}}else if(D.method==="POST"&&Ai){let Q=i.applications.get(decodeURIComponent(Ai[1]));if(!Q)throw new m("not_found","Compose application was not found.",404);let ge=Ai[2],Ee=await He();t.authorize(te,ge==="delete"||ge==="stop"?"deployments:cancel":"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(i.enqueue(Q,ge,{actorId:te.actor.id,service:typeof Ee.service==="string"?Ee.service:void 0,replicas:Number.isFinite(Number(Ee.replicas))?Number(Ee.replicas):void 0,removeVolumes:Ee.removeVolumes===!0,confirmation:typeof Ee.confirm==="string"?Ee.confirm:void 0})),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/preview-definitions"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);t.authorize(te,"project:read",{type:"project",id:Q}),ke=tn(n.previews.listDefinitions(Q).map((ge)=>({...ge})),Y,ee)}else if(D.method==="POST"&&Y.pathname==="/api/v1/preview-definitions"){let Q=await He();t.authorize(te,"config:write",{type:"resource",id:String(Q.resourceId??"")}),ke={definition:n.previews.createDefinition({...Q,projectId:String(Q.projectId??""),resourceId:String(Q.resourceId??""),baseEnvironmentId:String(Q.baseEnvironmentId??""),domainPattern:String(Q.domainPattern??""),createdByActorId:te.actor.id}),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/previews"){let Q=await He(),ge=n.previews.getDefinition(String(Q.definitionId??""));if(!ge)throw new m("not_found","Preview definition was not found.",404);t.authorize(te,"deployments:create",{type:"resource",id:ge.resourceId});let Ee=n.previews.upsert({definitionId:ge.id,sourceProvider:"api",repository:typeof Q.repository==="string"?Q.repository:"api",branch:String(Q.branch??""),pullRequestNumber:Number(Q.pullRequestNumber)||void 0,fork:Q.fork===!0,commitSha:String(Q.commitSha??""),createdByActorId:te.actor.id});ke={preview:Ee.preview,operation:t.operation(n.enqueueDeploy(Ee.preview,{created:Ee.created,actorId:te.actor.id})),requestId:ee}}else if(D.method==="POST"&&Fn){let Q=n.previews.getInstance(decodeURIComponent(Fn[1]));if(!Q)throw new m("not_found","Preview was not found.",404);let ge=await He(),Ee=Fn[2];if(Ee==="destroy"){if(t.authorize(te,"deployments:cancel",{type:"resource",id:Q.resourceId}),ge.confirm!==Q.name)throw new m("confirmation_required",`Type ${Q.name} to confirm preview teardown.`,409);ke={operation:t.operation(n.enqueueDestroy(Q,"api",te.actor.id)),requestId:ee}}else if(Ee==="extend")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={preview:n.previews.extend(Q.id,Number(ge.hours)),requestId:ee};else t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(n.enqueueDeploy(Q,{actorId:te.actor.id,reason:"manual_rebuild"})),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/previews/cleanup"){t.authorize(te,"automation:manage",{type:"organization"});let Q=await He();if(!Q.dryRun&&Q.confirm!=="cleanup previews")throw new m("confirmation_required","Type cleanup previews to confirm preview cleanup.",409);ke={...n.cleanup({dryRun:Q.dryRun===!0,maxAgeHours:Number(Q.maxAgeHours)||void 0,keepCount:Number(Q.keepCount)||void 0,actorId:te.actor.id}),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/queue"){let Q=Y.searchParams.get("projectId")??void 0,ge=Y.searchParams.get("state"),Ee=r.list({projectId:Q,state:["queued","running","succeeded","failed","cancelled","timed_out"].includes(ge)?ge:void 0,limit:500}).filter((Re)=>{let Pt=Re.operation.resourceId?{type:"resource",id:Re.operation.resourceId}:Re.operation.environmentId?{type:"environment",id:Re.operation.environmentId}:Re.operation.projectId?{type:"project",id:Re.operation.projectId}:{type:"organization"};try{return t.authorize(te,"deployments:read",Pt),!0}catch{return!1}}).map((Re)=>({...t.operation(Re.operation),queue:Re.job,approximatePosition:Re.approximatePosition}));ke=tn(Ee,Y,ee)}else if(D.method==="GET"&&Y.pathname==="/api/v1/queue/settings")t.authorize(te,"deployments:read",te.token.scope),ke={concurrency:r.limits,requestId:ee};else if(D.method==="PATCH"&&Y.pathname==="/api/v1/queue/settings"){t.authorize(te,"automation:manage",{type:"organization"});let Q=await He();if(Q.confirm!=="update queue limits")throw new m("confirmation_required","Type update queue limits to confirm production concurrency changes.",409);ke={concurrency:r.configureConcurrency(Q.concurrency??{},{organizationId:te.serviceAccount.organizationId,actorId:te.actor.id}),requestId:ee}}else if(D.method==="DELETE"&&Y.pathname==="/api/v1/queue/history"){t.authorize(te,"automation:manage",{type:"organization"});let Q=await He();if(Q.confirm!=="clear completed")throw new m("confirmation_required","Type clear completed to confirm queue retention cleanup.",409);ke={deleted:r.clearCompleted({before:typeof Q.before==="string"?Q.before:void 0,actorId:te.actor.id,projectId:typeof Q.projectId==="string"?Q.projectId:void 0}),requestId:ee}}else if(D.method==="GET"&&Ei){let Q=e.controlPlane.getOperation(decodeURIComponent(Ei[1]));if(!Q)throw new m("not_found","Operation was not found.",404);let ge=Q.resourceId?{type:"resource",id:Q.resourceId}:Q.environmentId?{type:"environment",id:Q.environmentId}:Q.projectId?{type:"project",id:Q.projectId}:{type:"organization"};t.authorize(te,"deployments:read",ge);let Ee=D.headers.get("last-event-id")?.trim(),Re=Number(Ee||Y.searchParams.get("after")||0);if(Ei[2]==="stream"){let Jt=new TextEncoder,we=Re,st,rt=!1,ze=new ReadableStream({start(Pr){let ms=()=>{if(rt)return;if(!e.identities.verifyToken(he,W)){if(rt=!0,st)clearInterval(st);Pr.close();return}let Pi=r.logs(Q.id,{after:we,limit:500});for(let Dt of Pi)we=Dt.sequence,Pr.enqueue(Jt.encode(`id: ${Dt.sequence}
|
|
137
|
+
`),f=s.index-a,C=i[u-1]||"";if(this.isLikelyPlaceholder(s[0],C))continue;let k=s[1]||s[0];if(o.name==="AWS Secret Key (Generic)"&&/^[a-f0-9]{40}$/i.test(k))continue;if(o.name==="AWS Secret Key (Generic)"&&!this.hasSecretCharacterDiversity(k))continue;if(o.name==="AWS Secret Key (Generic)"&&/^(?:Actions|Commands|Controllers|Handlers|Jobs|Listeners|Middleware|Models|Resources|Services)\//.test(k))continue;if(this.isLowEntropy(k))continue;n.push({file:t,line:u,column:f,match:this.maskSecret(s[0]),pattern:o,context:this.maskSecret(C.trim())})}}return n}isLikelyPlaceholder(e,t){let r=["example","placeholder","your_","YOUR_","xxx","XXX","***","test","TEST","dummy","DUMMY","fake","FAKE","sample","SAMPLE","<your","${","{{","process.env","import.meta.env","CHANGEME","TODO","FIXME"],n=e.toLowerCase(),i=t.toLowerCase();for(let s of r)if(n.includes(s.toLowerCase())||i.includes(s.toLowerCase()))return!0;let o=t.trim();if(o.startsWith("//")||o.startsWith("#")||o.startsWith("*")||o.startsWith("/*")){if(i.includes("example")||i.includes("format:")||i.includes("e.g."))return!0}return!1}isLowEntropy(e){if(e.length<8)return!1;if(new Set(e).size<8)return!0;if(/(.)\1{3,}/.test(e))return!0;return!1}hasSecretCharacterDiversity(e){let t=/[\d+=]/.test(e),r=[/[a-z]/.test(e),/[A-Z]/.test(e),/\d/.test(e),/[/+=]/.test(e)];return t&&r.filter(Boolean).length>=3}maskSecret(e){if(e.length<=8)return"*".repeat(e.length);let t=Math.min(4,Math.floor(e.length*0.2));return e.substring(0,t)+"*".repeat(e.length-t*2)+e.substring(e.length-t)}getFilesToScan(e,t,r){let n=[],i=r||hC,o=t.filter((u)=>!u.includes("/")),s=t.filter((u)=>u.includes("/")).map((u)=>u.replace(/^\.\//,"").replace(/\/+$/,"")),c=(u)=>{let a=uC(u,{withFileTypes:!0});for(let f of a){let C=mC(u,f.name);if(f.isDirectory()){let k=ch(e,C).split(fC).join("/");if(!o.includes(f.name)&&!s.includes(k))c(C)}else if(f.isFile()){let k=gC(f.name).toLowerCase();if(i.includes(k)||f.name.startsWith(".env")||f.name.endsWith(".config"))n.push(C)}}};return c(e),n}shouldExcludeFile(e){let t=e.split("/").pop()||"";for(let r of this.excludeFiles)if(r.startsWith("*")){let n=r.substring(1);if(t.endsWith(n))return!0}else if(r.endsWith("*")){let n=r.substring(0,r.length-1);if(t.startsWith(n))return!0}else if(t===r)return!0;return!1}addPattern(e){this.patterns.push(e)}getPatterns(){return[...this.patterns]}}function SC(e,t){return{status:"unavailable",findings:[],error:`${e.id} exceeded its ${t}ms timeout`,metadata:{timeoutMs:t}}}class rs{posture;defaultTimeoutMs;nowFn;constructor(e,t={}){this.posture=e;this.defaultTimeoutMs=t.defaultTimeoutMs??60000,this.nowFn=t.now??(()=>new Date)}async run(e,t){let r=this.nowFn(),n=Math.max(100,e.timeoutMs??this.defaultTimeoutMs),i=new AbortController,o,s=new Promise((f)=>{o=setTimeout(()=>{i.abort(),f(SC(e,n))},n)}),c;try{c=await Promise.race([e.scan({...t,signal:i.signal}),s])}catch(f){c={status:"unavailable",findings:[],error:f instanceof Error?f.message:String(f)}}finally{if(o)clearTimeout(o)}let u=this.nowFn(),a={...t,scannerId:e.id,scannerVersion:e.version,status:c.status,findings:c.findings,metadata:c.metadata,error:c.error,startedAt:r.toISOString(),completedAt:u.toISOString(),durationMs:Math.max(0,u.getTime()-r.getTime())};return this.posture.recordScan(a)}async runAll(e,t){return Promise.all(e.map((r)=>this.run(r,t)))}}class Ra{scanner;id="source-secrets";version="1.0.0";timeoutMs=30000;constructor(e=new Xr){this.scanner=e}async scan(e){if(!e.artifactRoot)return{status:"skipped",findings:[],error:"No artifact root was supplied"};let t=await this.scanner.scan({directory:e.artifactRoot,failOnSeverity:"critical"});return{status:t.passed?"passed":"failed",findings:t.findings.map((r)=>({...e,ruleId:r.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:r.pattern.severity,title:r.pattern.name,description:r.pattern.description,subject:`${r.file}:${r.line}`,evidence:{file:r.file,line:r.line,column:r.column,match:r.match,context:r.context},remediation:"Remove the credential, rotate it at its issuer, and use a managed secret or environment reference."})),metadata:{scannedFiles:t.scannedFiles,summary:t.summary}}}}function vC(e){let t=e?.toLowerCase();return t==="critical"||t==="high"||t==="medium"||t==="low"?t:"info"}class hl{id="trivy-image";version;timeoutMs;constructor(e={}){this.version=e.version??"local",this.timeoutMs=e.timeoutMs??120000,this.executable=e.executable??"trivy"}executable;async scan(e){if(!e.imageRef)return{status:"skipped",findings:[],error:"No image reference was supplied"};let t;try{t=Bun.spawn([this.executable,"image","--format","json","--quiet","--scanners","vuln",e.imageRef],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",TRIVY_NO_PROGRESS:"true"}})}catch(u){return{status:"unsupported",findings:[],error:u instanceof Error?u.message:String(u)}}let r=()=>t.kill();e.signal.addEventListener("abort",r,{once:!0});let[n,i,o]=await Promise.all([t.exited,new Response(t.stdout).text(),new Response(t.stderr).text()]);if(e.signal.removeEventListener("abort",r),n!==0)return{status:/not found|enoent/i.test(o)?"unsupported":"unavailable",findings:[],error:o.slice(0,2000)||`Trivy exited with ${n}`};let s=JSON.parse(i),c=[];for(let u of s.Results??[])for(let a of u.Vulnerabilities??[]){let f=a.VulnerabilityID??"unknown-vulnerability";c.push({...e,ruleId:f,severity:vC(a.Severity),title:a.Title||f,description:a.Description||`${f} affects ${a.PkgName??"an image package"}.`,subject:`${e.imageRef}:${a.PkgName??"unknown"}:${a.InstalledVersion??"unknown"}`,evidence:{image:e.imageRef,target:u.Target??"",cve:f,package:a.PkgName??"",installedVersion:a.InstalledVersion??"",fixedVersion:a.FixedVersion??"",reference:a.PrimaryURL??""},remediation:a.FixedVersion?`Upgrade ${a.PkgName} to ${a.FixedVersion} or later.`:"Remove or replace the affected package and rescan the image."})}return{status:c.length?"failed":"passed",findings:c,metadata:{imageRef:e.imageRef,vulnerabilityCount:c.length,localOnly:!0}}}}import{createHash as wC,createVerify as oO}from"node:crypto";import{existsSync as IC,readFileSync as CC}from"node:fs";import{basename as EC,join as TC,resolve as uh}from"node:path";function Pa(e){return wC("sha256").update(e).digest("hex")}function AC(e){let t=[["dependencies","required"],["optionalDependencies","optional"],["devDependencies","excluded"],["peerDependencies","required"]],r=new Map;for(let[n,i]of t){let o=e[n];if(!o||typeof o!=="object"||Array.isArray(o))continue;for(let[s,c]of Object.entries(o)){let u=String(c).replace(/^[~^]/,""),a=`${s}@${u}`;if(!r.has(a))r.set(a,{type:"library",name:s,version:u,purl:`pkg:npm/${encodeURIComponent(s)}@${encodeURIComponent(u)}`,scope:i})}}return[...r.values()].sort((n,i)=>`${n.name}@${n.version}`.localeCompare(`${i.name}@${i.version}`))}function lh(e,t={}){let r=TC(uh(e),"package.json");if(!IC(r))throw Error(`Cannot generate an SBOM: ${r} was not found`);let n=CC(r,"utf8"),i=JSON.parse(n),o=String(i.name??EC(uh(e))),s=String(i.version??"0.0.0"),c=Pa(n);return{bomFormat:"CycloneDX",specVersion:"1.5",serialNumber:t.serial??`urn:uuid:${crypto.randomUUID()}`,version:1,metadata:{timestamp:(t.now??new Date).toISOString(),component:{type:"application",name:o,version:s,purl:`pkg:npm/${encodeURIComponent(o)}@${encodeURIComponent(s)}`,hashes:[{alg:"SHA-256",content:c}]},tools:[{vendor:"ts-cloud",name:"security-posture",version:"1.0.0"}]},components:AC(i)}}async function ph(e,t={}){let r=Bun.spawn([t.executable??"syft",e,"-o","cyclonedx-json"],{stdout:"pipe",stderr:"pipe",env:{PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",SYFT_CHECK_FOR_APP_UPDATE:"false"}}),n=()=>r.kill();t.signal?.addEventListener("abort",n,{once:!0});let[i,o,s]=await Promise.all([r.exited,new Response(r.stdout).text(),new Response(r.stderr).text()]);if(t.signal?.removeEventListener("abort",n),i!==0)throw Error(s.slice(0,2000)||`Syft exited with ${i}`);return JSON.parse(o)}function yl(e,t,r){let n=JSON.stringify(r);return e.addReleaseArtifact({...t,kind:"sbom",format:`cyclonedx-${r.specVersion}+json`,digest:`sha256:${Pa(n)}`,summary:{component:r.metadata.component.name,version:r.metadata.component.version,components:r.components.length},content:n,sensitive:!0})}function gh(e,t,r){let n={total:r.length,critical:0,high:0,medium:0,low:0,info:0,fixable:0};for(let o of r){n[o.severity]++;let s=o.evidence;if(typeof s.fixedVersion==="string"&&s.fixedVersion)n.fixable++}let i=JSON.stringify({releaseId:t.releaseId,generatedAt:new Date().toISOString(),findings:r.map((o)=>({id:o.id,ruleId:o.ruleId,severity:o.severity,subject:o.subject,remediation:o.remediation}))});return e.addReleaseArtifact({...t,kind:"vulnerability_summary",format:"ts-cloud-vulnerability-summary+json",digest:`sha256:${Pa(i)}`,summary:n,content:i,sensitive:!0})}function mh(e){if(!e.artifact&&!e.artifactSha256)throw Error("Release provenance requires artifact content or a SHA-256 digest");return{_type:"https://in-toto.io/Statement/v1",subject:[{name:e.artifactName,digest:{sha256:e.artifactSha256?.replace(/^sha256:/,"")??Pa(e.artifact)}}],predicateType:"https://slsa.dev/provenance/v1",predicate:{buildDefinition:{buildType:"https://ts-cloud.dev/build/v1",externalParameters:e.externalParameters??{},internalParameters:{},resolvedDependencies:e.resolvedDependencies??[]},runDetails:{builder:{id:"https://ts-cloud.dev/builders/local/v1"},metadata:{invocationId:e.invocationId,startedOn:e.startedAt,finishedOn:e.completedAt}}}}}function fh(e,t,r){let n=JSON.stringify(r);return e.addReleaseArtifact({...t,kind:"provenance",format:"in-toto+slsa-v1+json",digest:`sha256:${Pa(n)}`,summary:{subjects:r.subject.length,builder:r.predicate.runDetails.builder.id,buildType:r.predicate.buildDefinition.buildType},content:n,sensitive:!0})}function ue(e,t){let r=e.environments.get(t);if(!r)throw Error(`Security scope for environment '${t}' was not found`);return{organizationId:e.organization.id,projectId:e.project.id,environmentId:r.id}}function ii(e,t){let r=new Ot(e.store),n=r.listPolicies(e.organization.id);for(let[i,o]of e.environments){if(n.some((c)=>c.environmentId===o.id))continue;let s=i==="production"||o.kind==="production";n.push(r.createPolicy({organizationId:e.organization.id,environmentId:o.id,name:s?"Production baseline":"Environment baseline",scannerFailMode:s?"closed":"open",requiredScanners:["source-secrets"],rules:s?[{minimumSeverity:"critical",action:"block"},{minimumSeverity:"high",action:"block"},{minimumSeverity:"medium",action:"warn"},{minimumSeverity:"low",action:"record"}]:[{minimumSeverity:"critical",action:"warn"},{minimumSeverity:"high",action:"warn"},{minimumSeverity:"low",action:"record"}],actorId:t}))}return n}function lc(e,t,r,n={}){let i=r.findings.map((o)=>({...t,ruleId:o.pattern.name.toLowerCase().replace(/[^a-z0-9]+/g,"-"),severity:o.pattern.severity,title:o.pattern.name,description:o.pattern.description,subject:`${o.file}:${o.line}`,evidence:{file:o.file,line:o.line,column:o.column,match:o.match,context:o.context},remediation:"Remove and rotate the credential, then reference it through a managed secret or environment variable."}));return e.recordScan({...t,scannerId:"source-secrets",scannerVersion:n.scannerVersion??"1.0.0",status:n.skipped?"skipped":r.passed?"passed":"failed",findings:n.skipped?[]:i,metadata:{scannedFiles:r.scannedFiles,durationMs:r.duration,summary:r.summary},durationMs:r.duration,error:n.skipped?"The operator explicitly skipped source-secret scanning.":void 0})}function dc(e,t,r="The operator explicitly skipped source-secret scanning."){return e.recordScan({...t,scannerId:"source-secrets",scannerVersion:"1.0.0",status:"skipped",findings:[],error:r})}function kC(e,t){let r=[],n=t.security;if(n?.firewall&&!["active","configured","ok"].includes(String(n.firewall.status)))r.push({...e,ruleId:"host-firewall-disabled",severity:"high",title:"Host firewall is not active",description:String(n.firewall.summary??"The host firewall did not report an active configuration."),subject:"host:firewall",evidence:{status:String(n.firewall.status??"unknown"),rules:Array.isArray(n.firewall.rules)?n.firewall.rules.length:0},remediation:"Apply the declarative firewall policy and confirm only required listeners are public."});for(let i of n?.ports??[]){let o=String(i.listen??""),s=Number(o.match(/:(\d+)$/)?.[1]);if(i.exposure==="public"&&Number.isFinite(s)&&![22,80,443].includes(s))r.push({...e,ruleId:"unexpected-public-listener",severity:"medium",title:`Unexpected public listener on port ${s}`,description:`${String(i.processName??"A process")} is listening publicly outside the standard SSH/HTTP/HTTPS ports.`,subject:`host:port:${s}`,evidence:{protocol:String(i.proto??""),listen:o,process:String(i.processName??"")},remediation:"Bind the service to loopback/private networking or explicitly document and firewall the required public port."})}for(let i of n?.tlsCertificates??[]){let o=Number(i.daysRemaining);if(Number.isFinite(o)&&o<30)r.push({...e,ruleId:"tls-certificate-expiry",severity:o<14?"high":"medium",title:`TLS certificate expires in ${o} days`,description:`${String(i.domain??"A configured domain")} needs renewal.`,subject:`tls:${String(i.domain??"unknown")}`,evidence:{domain:String(i.domain??""),daysRemaining:o,expires:String(i.expires??"")},remediation:"Renew the certificate and verify automatic renewal can complete before expiry."})}for(let i of t.diagnostics??[]){if(i.status==="pass"||i.status==="ok")continue;r.push({...e,ruleId:`diagnostic-${String(i.name??"unknown").toLowerCase().replace(/[^a-z0-9]+/g,"-")}`,severity:i.status==="fail"?"high":"medium",title:String(i.name??"Host security check"),description:String(i.detail??"The host security diagnostic did not pass."),subject:`diagnostic:${String(i.name??"unknown")}`,evidence:{status:String(i.status??"unknown")},remediation:"Follow the diagnostic guidance, rerun the check, and confirm the finding resolves."})}return r}function rd(e,t,r){let n=!!r.security||Array.isArray(r.diagnostics),i=n?kC(t,r):[];return e.recordScan({...t,scannerId:"host-posture",scannerVersion:"1.0.0",status:!n?"unavailable":i.length?"failed":"passed",findings:i,metadata:{source:"dashboard-live-probe",checks:Array.isArray(r.diagnostics)?r.diagnostics.length:0},error:n?void 0:"Live host posture data was unavailable; source and provider checks remain usable."})}function dr(e,t){let r=e.evaluateGate({...t.scope,operationId:t.operationId}),n=e.listFindings({...t.scope,limit:1000}).filter((i)=>i.status!=="resolved");return{decision:r,summary:{desiredConfigHash:t.desiredConfigHash??null,securityImpact:{critical:n.filter((i)=>i.severity==="critical").length,high:n.filter((i)=>i.severity==="high").length,waived:n.filter((i)=>i.status==="waived").length,assigned:n.filter((i)=>!!i.ownerActorId).length},blockingFindingIds:r.findingIds,policy:{id:r.policyId,version:r.policyVersion},scannerVersions:r.scannerVersions}}}async function uc(e,t){let r=t.scanner??new hl({timeoutMs:t.scannerTimeoutMs}),i=await new rs(e,{defaultTimeoutMs:t.scannerTimeoutMs??120000}).run(r,{...t.scope,releaseId:t.releaseId,imageRef:t.imageRef}),o={...t.scope,releaseId:t.releaseId};gh(e,o,i.findings);let s=t.generateImageSbom??ph,c=new AbortController,u=Math.max(100,t.sbomTimeoutMs??120000),a,f=new Promise((D,W)=>{a=setTimeout(()=>{c.abort(),W(Error(`syft-sbom exceeded its ${u}ms timeout`))},u)}),C="unavailable";try{let D=await Promise.race([s(t.imageRef,{signal:c.signal}),f]);yl(e,o,D),e.recordScan({...t.scope,releaseId:t.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"passed",metadata:{imageRef:t.imageRef,format:`cyclonedx-${D.specVersion}+json`,components:D.components.length,localOnly:!0}}),C="image"}catch(D){let W=D instanceof Error?D.message:String(D);try{let Y=lh(t.artifactRoot);yl(e,o,Y),e.recordScan({...t.scope,releaseId:t.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unsupported",error:`Image inventory was unavailable; attached a package-manifest SBOM instead. ${W}`,metadata:{imageRef:t.imageRef,fallback:"package-manifest",components:Y.components.length,localOnly:!0}}),C="manifest"}catch(Y){e.recordScan({...t.scope,releaseId:t.releaseId,scannerId:"syft-sbom",scannerVersion:"local",status:"unavailable",error:`Image and manifest SBOM generation were unavailable. ${W}; ${Y instanceof Error?Y.message:String(Y)}`,metadata:{imageRef:t.imageRef,localOnly:!0}})}}finally{if(a)clearTimeout(a)}let k=mh({artifactName:t.imageRef,artifact:t.imageSha256?void 0:t.imageRef,artifactSha256:t.imageSha256,invocationId:t.invocationId,startedAt:t.startedAt,completedAt:t.completedAt??new Date().toISOString(),externalParameters:t.externalParameters??{imageRef:t.imageRef}});return fh(e,o,k),{scan:i,sbomSource:C}}class G{client;region;endpoint;constructor(e="us-east-1",t){this.region=e,this.endpoint=t?.endpoint,this.client=new p}async request(e,t){if(this.endpoint){let r=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/x-amz-json-1.0","X-Amz-Target":`DynamoDB_20120810.${e}`},body:JSON.stringify(t)});if(!r.ok){let n=await r.text();throw Error(`DynamoDB request failed: ${r.status} ${n}`)}return r.json()}return this.client.request({service:"dynamodb",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.0","X-Amz-Target":`DynamoDB_20120810.${e}`},body:JSON.stringify(t)})}async createTable(e){return this.request("CreateTable",e)}async deleteTable(e){return this.request("DeleteTable",e)}async describeTable(e){return this.request("DescribeTable",e)}async listTables(e){return this.request("ListTables",e||{})}async putItem(e){return this.request("PutItem",e)}async getItem(e){return this.request("GetItem",e)}async updateItem(e){return this.request("UpdateItem",e)}async deleteItem(e){return this.request("DeleteItem",e)}async query(e){return this.request("Query",e)}async scan(e){return this.request("Scan",e)}async batchWriteItem(e){return this.request("BatchWriteItem",e)}async batchGetItem(e){return this.request("BatchGetItem",e)}async updateTimeToLive(e){return this.request("UpdateTimeToLive",e)}static marshal(e){let t={};for(let[r,n]of Object.entries(e))t[r]=G.marshalValue(n);return t}static marshalValue(e){if(e===null||e===void 0)return{NULL:!0};if(typeof e==="string")return{S:e};if(typeof e==="number")return{N:String(e)};if(typeof e==="boolean")return{BOOL:e};if(Array.isArray(e))return{L:e.map((t)=>G.marshalValue(t))};if(typeof e==="object")return{M:G.marshal(e)};return{S:String(e)}}static unmarshal(e){let t={};for(let[r,n]of Object.entries(e))t[r]=G.unmarshalValue(n);return t}static unmarshalValue(e){if(e.S!==void 0)return e.S;if(e.N!==void 0)return Number(e.N);if(e.BOOL!==void 0)return e.BOOL;if(e.NULL!==void 0)return null;if(e.L!==void 0)return e.L.map((t)=>G.unmarshalValue(t));if(e.M!==void 0)return G.unmarshal(e.M);if(e.SS!==void 0)return e.SS;if(e.NS!==void 0)return e.NS.map(Number);return null}}class bl extends Error{status;code;requestId;constructor(e,t,r,n){super(r);this.status=e;this.code=t;this.requestId=n}}class Qi{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 bl(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 RC}from"node:crypto";var nd="1.6.0";function Sl(){let e={type:"object",required:["error"],properties:{error:{type:"object",required:["code","message","requestId"],properties:{code:{type:"string"},message:{type:"string"},requestId:{type:"string",format:"uuid"},details:{}}}}},t=(n)=>({type:"object",required:["data","page","requestId"],properties:{data:{type:"array",items:n},page:{type:"object",required:["hasMore"],properties:{nextCursor:{type:"string"},hasMore:{type:"boolean"}}},requestId:{type:"string",format:"uuid"}}}),r=(n)=>({"200":{description:"A stable cursor page.",content:{"application/json":{schema:t(n)}}},default:{$ref:"#/components/responses/Error"}});return{openapi:"3.1.0",info:{title:"ts-cloud API",version:nd,description:"Additive changes are released within v1. Breaking request or response changes require a new URL version."},servers:[{url:"/"}],security:[{bearerAuth:[]}],paths:{...xs(),"/api/v1/projects":{get:{operationId:"listProjects",summary:"List accessible projects",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Project"})}},"/api/v1/projects/{projectId}/environments":{get:{operationId:"listEnvironments",summary:"List accessible project environments",parameters:[{$ref:"#/components/parameters/ProjectId"},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Environment"})}},"/api/v1/services":{get:{operationId:"listServices",summary:"List accessible services",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{name:"environmentId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Service"})}},"/api/v1/source/connections":{get:{operationId:"listSourceConnections",summary:"List safe Git connection metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceConnection"})},post:{operationId:"createSourceConnection",summary:"Create an encrypted Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["provider","name","host"],properties:{provider:{type:"string",enum:["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"]},name:{type:"string"},host:{type:"string",format:"uri"},token:{type:"string",writeOnly:!0},repositoryFullName:{type:"string"},repositoryUrl:{type:"string"}}}}}},responses:{"201":{description:"Encrypted connection created."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectSourceConnection",summary:"Preview or safely disconnect a Git connection",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["id"],properties:{id:{type:"string"},preview:{type:"boolean"}}}}}},responses:{"200":{description:"Impact preview or disconnected connection."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/repositories":{get:{operationId:"listSourceRepositories",summary:"List or synchronize granted repositories",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"sync",in:"query",schema:{type:"boolean"}},{name:"search",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/SourceRepository"})}},"/api/v1/source/refs":{get:{operationId:"listSourceRefs",summary:"List repository branches or tags",parameters:[{name:"connectionId",in:"query",required:!0,schema:{type:"string"}},{name:"repository",in:"query",required:!0,schema:{type:"string"}},{name:"repositoryId",in:"query",schema:{type:"string"}},{name:"type",in:"query",schema:{type:"string",enum:["branches","tags"]}}],responses:{"200":{description:"Provider reference page."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/bindings":{post:{operationId:"createSourceBinding",summary:"Bind a repository to an application",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/SourceBindingRequest"}}}},responses:{"201":{description:"Source binding created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/source/webhooks":{post:{operationId:"createSourceWebhook",summary:"Create and optionally reconcile a signed webhook",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["connectionId","repositoryFullName","baseUrl"],properties:{connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},baseUrl:{type:"string",format:"uri"},events:{type:"array",items:{type:"string",enum:["push","pull_request"]}},reconcile:{type:"boolean"}}}}}},responses:{"201":{description:"Webhook endpoint created; endpoint is revealed once."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-detections":{post:{operationId:"detectApplication",summary:"Detect bounded application build candidates",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["files"],properties:{files:{type:"array",maxItems:1e4,items:{$ref:"#/components/schemas/DetectionFile"}}}}}}},responses:{"200":{description:"Ranked detection candidates with evidence."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-plans":{post:{operationId:"planApplication",summary:"Validate and normalize an application manifest",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["draft"],properties:{draft:{$ref:"#/components/schemas/ApplicationInput"},suppliedSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}}}}}},responses:{"200":{description:"Validated plan, config patch, capabilities, costs, and missing secret names."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-drafts":{get:{operationId:"listApplicationDrafts",summary:"List resumable secret-free drafts",parameters:[{name:"projectId",in:"query",required:!0,schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/ApplicationDraft"})},post:{operationId:"createApplicationDraft",summary:"Create a resumable application draft",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/ApplicationDraftCreateRequest"}}}},responses:{"201":{description:"Draft created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateApplicationDraft",summary:"Optimistically update a draft",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/ApplicationDraftCreateRequest"},{type:"object",required:["id","version","step"],properties:{id:{type:"string"},version:{type:"integer",minimum:1}}}]}}}},responses:{"200":{description:"Updated draft."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/applications":{post:{operationId:"createApplication",summary:"Confirm and queue an application plan",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["draftId","version","confirmEnvironment"],properties:{draftId:{type:"string"},version:{type:"integer",minimum:1},confirmEnvironment:{type:"string",description:"Exact target environment slug."}}}}}},responses:{"202":{description:"Application operation queued; identical requests replay safely."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/application-artifacts":{post:{operationId:"uploadApplicationArtifact",summary:"Inspect and store a bounded ZIP or TAR source artifact",parameters:[{name:"X-Project-Id",in:"header",required:!0,schema:{type:"string"}},{name:"X-Artifact-Filename",in:"header",required:!0,schema:{type:"string"}}],requestBody:{required:!0,content:{"application/octet-stream":{schema:{type:"string",format:"binary",maxLength:104857600}}}},responses:{"201":{description:"Deduplicated artifact metadata; archive contents are never executed."},"413":{$ref:"#/components/responses/Error"},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/registry-connections":{get:{operationId:"listRegistryConnections",summary:"List safe private-registry metadata",parameters:[{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/RegistryConnection"})},post:{operationId:"createRegistryConnection",summary:"Create an encrypted private-registry connection",requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/RegistryConnectionRequest"}}}},responses:{"201":{description:"Encrypted registry connection created."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateRegistryConnection",summary:"Test access or rotate write-only credentials",requestBody:{required:!0,content:{"application/json":{schema:{allOf:[{$ref:"#/components/schemas/RegistryConnectionRequest"},{type:"object",required:["id","action"],properties:{id:{type:"string"},action:{type:"string",enum:["test","rotate"]},image:{type:"string"}}}]}}}},responses:{"200":{description:"Safe connection health metadata."},default:{$ref:"#/components/responses/Error"}}},delete:{operationId:"disconnectRegistryConnection",summary:"Disconnect and erase registry credentials",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["id"],properties:{id:{type:"string"}}}}}},responses:{"200":{description:"Credentials erased and connection disconnected."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue":{get:{operationId:"listQueue",summary:"List authorized durable operations and blocking metadata",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"state",in:"query",schema:{type:"string",enum:["queued","running","succeeded","failed","cancelled","timed_out"]}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/QueueOperation"})}},"/api/v1/preview-definitions":{get:{operationId:"listPreviewDefinitions",summary:"List preview policies",responses:r({type:"object"})},post:{operationId:"createPreviewDefinition",summary:"Configure bounded preview policy",responses:{"200":{description:"Preview definition created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews":{get:{operationId:"listPreviews",summary:"List authorized persistent previews",responses:r({type:"object"})},post:{operationId:"createPreview",summary:"Create or update one immutable preview identity",responses:{"200":{description:"Preview deployment queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/destroy":{post:{operationId:"destroyPreview",summary:"Confirm tagged preview teardown",responses:{"200":{description:"Teardown queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/extend":{post:{operationId:"extendPreview",summary:"Extend preview TTL",responses:{"200":{description:"Expiry extended."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/{previewId}/rebuild":{post:{operationId:"rebuildPreview",summary:"Rebuild the exact recorded commit",responses:{"200":{description:"Rebuild queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/previews/cleanup":{post:{operationId:"cleanupPreviews",summary:"Dry-run or queue TTL/keep-count teardown",responses:{"200":{description:"Cleanup plan or operations."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-templates":{get:{operationId:"listComposeTemplates",summary:"List pinned verified application templates",responses:r({type:"object"})}},"/api/v1/compose-applications":{get:{operationId:"listComposeApplications",summary:"List authorized multi-service applications",responses:r({type:"object"})},post:{operationId:"createComposeApplication",summary:"Import Compose or materialize a template",responses:{"200":{description:"Editable normalized application."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/preview":{post:{operationId:"previewComposeApplication",summary:"Parse and diagnose Compose without mutation",responses:{"200":{description:"Normalized preview and actionable diagnostics."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/services":{get:{operationId:"listComposeServices",summary:"Inspect per-service desired and observed state",responses:{"200":{description:"Service topology and status."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/compose-applications/{applicationId}/{action}":{post:{operationId:"operateComposeApplication",summary:"Deploy, redeploy, start, stop, scale, or delete through the durable queue",responses:{"200":{description:"Scoped operation queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/release-artifacts":{post:{operationId:"createReleaseArtifact",summary:"Register a verified content-addressed artifact",responses:{"200":{description:"Artifact identity registered."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases":{get:{operationId:"listReleases",summary:"List unified authorized release history",responses:r({type:"object"})},post:{operationId:"createRelease",summary:"Create an immutable release from an existing artifact",responses:{"200":{description:"Release record created."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/capabilities":{get:{operationId:"getReleaseCapabilities",summary:"Explain supported strategies, capacity, cost, and rollback",responses:{"200":{description:"Provider-aware strategy capabilities."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}":{get:{operationId:"getRelease",summary:"Inspect provenance, approvals, health, and transitions",responses:{"200":{description:"Release detail."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/releases/{releaseId}/{action}":{post:{operationId:"operateRelease",summary:"Promote, approve, activate, roll back, report health, or pin",responses:{"200":{description:"Release lifecycle updated."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/settings":{get:{operationId:"getQueueSettings",summary:"Get effective concurrency limits",responses:{"200":{description:"Queue concurrency settings."},default:{$ref:"#/components/responses/Error"}}},patch:{operationId:"updateQueueSettings",summary:"Confirm and audit production concurrency changes",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm","concurrency"],properties:{confirm:{const:"update queue limits"},concurrency:{$ref:"#/components/schemas/QueueConcurrency"}}}}}},responses:{"200":{description:"Updated effective limits."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/queue/history":{delete:{operationId:"clearQueueHistory",summary:"Clear terminal jobs whose retention has elapsed",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["confirm"],properties:{confirm:{const:"clear completed"},before:{type:"string",format:"date-time"},projectId:{type:"string"}}}}}},responses:{"200":{description:"Eligible history cleared with an audit event."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs":{get:{operationId:"listOperationLogs",summary:"Resume ordered sanitized operation logs from a cursor",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:{"200":{description:"Ordered log chunks and next cursor."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/logs/stream":{get:{operationId:"streamOperationLogs",summary:"Stream authorized operation logs with Last-Event-ID resume",parameters:[{$ref:"#/components/parameters/OperationId"},{name:"Last-Event-ID",in:"header",schema:{type:"integer",minimum:0}}],responses:{"200":{description:"Server-sent log and completion events.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/cancel":{post:{operationId:"cancelOperation",summary:"Cancel queued work or request cooperative running cancellation",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{content:{"application/json":{schema:{type:"object"}}}},responses:{"200":{description:"Cancellation state recorded."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations/{operationId}/retry":{post:{operationId:"retryOperation",summary:"Retry an allow-listed failure class within the attempt limit",parameters:[{$ref:"#/components/parameters/OperationId"}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",additionalProperties:!1,required:["errorClass"],properties:{errorClass:{type:"string"},delayMs:{type:"integer",minimum:0}}}}}},responses:{"200":{description:"Retry queued."},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/deployments":{post:{operationId:"createDeployment",summary:"Queue a deployment",parameters:[{name:"Idempotency-Key",in:"header",required:!0,schema:{type:"string",minLength:8,maxLength:128}}],requestBody:{required:!0,content:{"application/json":{schema:{$ref:"#/components/schemas/DeploymentRequest"}}}},responses:{"202":{description:"Queued operation.",content:{"application/json":{schema:{$ref:"#/components/schemas/OperationResponse"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/operations":{get:{operationId:"listOperations",summary:"List scoped operations",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{$ref:"#/components/parameters/Limit"},{$ref:"#/components/parameters/Cursor"}],responses:r({$ref:"#/components/schemas/Operation"})}},"/api/v1/events":{get:{operationId:"listEvents",summary:"List scoped audit events",parameters:[{name:"projectId",in:"query",schema:{type:"string"}},{name:"after",in:"query",schema:{type:"integer",minimum:0}},{$ref:"#/components/parameters/Limit"}],responses:r({$ref:"#/components/schemas/Event"})}},"/api/v1/events/stream":{get:{operationId:"streamEvents",summary:"Stream scoped audit events",responses:{"200":{description:"Authenticated server-sent event stream.",content:{"text/event-stream":{schema:{type:"string"}}}},default:{$ref:"#/components/responses/Error"}}}},"/api/v1/openapi.json":{get:{operationId:"getOpenApi",summary:"Get the OpenAPI contract",security:[],responses:{"200":{description:"OpenAPI 3.1 contract."}}}}},components:{securitySchemes:{bearerAuth:{type:"http",scheme:"bearer",bearerFormat:"tsc_v1"}},parameters:{Limit:{name:"limit",in:"query",schema:{type:"integer",minimum:1,maximum:100,default:50}},Cursor:{name:"cursor",in:"query",schema:{type:"string"}},ProjectId:{name:"projectId",in:"path",required:!0,schema:{type:"string"}},OperationId:{name:"operationId",in:"path",required:!0,schema:{type:"string"}}},responses:{Error:{description:"Stable error envelope.",content:{"application/json":{schema:e}}}},schemas:{Project:{type:"object",required:["id","slug","name"],properties:{id:{type:"string"},slug:{type:"string"},name:{type:"string"},description:{type:"string"}}},Environment:{type:"object",required:["id","projectId","slug","name","kind"],properties:{id:{type:"string"},projectId:{type:"string"},slug:{type:"string"},name:{type:"string"},kind:{type:"string"},region:{type:"string"}}},Service:{type:"object",required:["id","projectId","kind","slug","name"],properties:{id:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},kind:{type:"string"},slug:{type:"string"},name:{type:"string"},metadata:{type:"object",additionalProperties:!0}}},SourceConnection:{type:"object",required:["id","provider","name","host","status","credentialConfigured"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},status:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},grantedScopes:{type:"array",items:{type:"string"}}}},SourceRepository:{type:"object",required:["id","connectionId","fullName","cloneUrl","defaultBranch"],properties:{id:{type:"string"},connectionId:{type:"string"},fullName:{type:"string"},cloneUrl:{type:"string"},defaultBranch:{type:"string"},visibility:{type:"string"},archived:{type:"boolean"}}},SourceBindingRequest:{type:"object",additionalProperties:!1,required:["projectId","connectionId","repositoryFullName"],properties:{projectId:{type:"string"},environmentId:{type:"string"},resourceId:{type:"string"},connectionId:{type:"string"},repositoryId:{type:"string"},repositoryFullName:{type:"string"},defaultBranch:{type:"string"},branchRule:{type:"string"},tagRule:{type:"string"},monorepoRoot:{type:"string"},includePaths:{type:"array",items:{type:"string"}},excludePaths:{type:"array",items:{type:"string"}},submodules:{type:"boolean"},cloneDepth:{type:"integer",minimum:1},deployKeyId:{type:"string"},autoDeploy:{type:"boolean"},pullRequestPreviews:{type:"boolean"}}},DetectionFile:{type:"object",additionalProperties:!1,required:["path"],properties:{path:{type:"string"},size:{type:"integer",minimum:0},content:{type:"string",maxLength:262144}}},ApplicationInput:{type:"object",additionalProperties:!1,required:["schemaVersion","name","slug","projectId","environmentId","source","build","runtime"],properties:{schemaVersion:{const:1},name:{type:"string"},slug:{type:"string"},projectId:{type:"string"},environmentId:{type:"string"},source:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["git","local","artifact","image"]}},additionalProperties:!0},build:{type:"object",required:["kind"],properties:{kind:{type:"string",enum:["dockerfile","buildpack","static","server","serverless","prebuilt_image"]},secretNames:{type:"array",uniqueItems:!0,items:{type:"string"}}},additionalProperties:!0},runtime:{type:"object",required:["architecture","target"],properties:{architecture:{type:"string",enum:["x86_64","arm64"]},target:{type:"string",enum:["server","serverless","container"]},port:{type:"integer",minimum:1,maximum:65535},healthCheck:{type:"object",additionalProperties:!0}},additionalProperties:!0},environment:{type:"object",additionalProperties:{oneOf:[{type:"string"},{type:"object",additionalProperties:!1,required:["secretRef"],properties:{secretRef:{type:"string"}}}]}},requiredSecretNames:{type:"array",uniqueItems:!0,items:{type:"string"}},domain:{type:"object",properties:{hostname:{type:"string"},path:{type:"string"},tls:{type:"boolean"}}}}},ApplicationDraftCreateRequest:{type:"object",additionalProperties:!1,required:["projectId","draft"],properties:{projectId:{type:"string"},name:{type:"string"},draft:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string",enum:["source","build","runtime","environment","domain","review"]},suppliedSecretNames:{type:"array",uniqueItems:!0,description:"Names only; values must use the secrets boundary.",items:{type:"string"}}}},ApplicationDraft:{type:"object",required:["id","projectId","input","step","status","version"],properties:{id:{type:"string"},projectId:{type:"string"},input:{$ref:"#/components/schemas/ApplicationInput"},step:{type:"string"},suppliedSecretNames:{type:"array",items:{type:"string"}},status:{type:"string",enum:["draft","ready","applied"]},version:{type:"integer"},createdAt:{type:"string",format:"date-time"},updatedAt:{type:"string",format:"date-time"}}},RegistryConnectionRequest:{type:"object",properties:{provider:{type:"string",enum:["docker_hub","ghcr","ecr","gcr","generic"]},name:{type:"string"},host:{type:"string"},username:{type:"string",writeOnly:!0},password:{type:"string",writeOnly:!0},token:{type:"string",writeOnly:!0},credentialExpiresAt:{type:"string",format:"date-time"},expiresAt:{type:"string",format:"date-time"}}},RegistryConnection:{type:"object",required:["id","provider","name","host","credentialConfigured","status","version"],properties:{id:{type:"string"},provider:{type:"string"},name:{type:"string"},host:{type:"string"},credentialConfigured:{type:"boolean"},credentialFingerprint:{type:"string"},credentialExpiresAt:{type:"string",format:"date-time"},status:{type:"string",enum:["pending","healthy","degraded","expired","disconnected"]},healthMessage:{type:"string"},lastTestedAt:{type:"string",format:"date-time"},version:{type:"integer"}}},QueueConcurrency:{type:"object",additionalProperties:!1,properties:{project:{type:"integer",minimum:1,maximum:100},environment:{type:"integer",minimum:1,maximum:100},provider:{type:"integer",minimum:1,maximum:100},builds:{type:"integer",minimum:1,maximum:100}}},QueueOperation:{allOf:[{$ref:"#/components/schemas/Operation"},{type:"object",required:["queue"],properties:{queue:{type:"object",required:["maxAttempts","availableAt","timeoutSeconds","retryClasses","resumePolicy","cancellationMode","retentionUntil"],properties:{lockKey:{type:"string"},providerKey:{type:"string"},buildSlot:{type:"boolean"},maxAttempts:{type:"integer"},availableAt:{type:"string",format:"date-time"},timeoutSeconds:{type:"integer"},heartbeatAt:{type:"string",format:"date-time"},currentStep:{type:"string"},blockedReason:{type:"string"},retryClasses:{type:"array",items:{type:"string"}},resumePolicy:{type:"string",enum:["fail","requeue"]},cancellationMode:{type:"string",enum:["cooperative","provider_non_cancellable"]},retentionUntil:{type:"string",format:"date-time"}}},approximatePosition:{type:"object",properties:{ahead:{type:"integer"},precision:{const:"bounded"}}}}}]},DeploymentRequest:{type:"object",additionalProperties:!1,required:["projectId","environmentId"],properties:{projectId:{type:"string"},environmentId:{type:"string"},serviceId:{type:"string"},action:{type:"string",enum:["deploy","rollback"],default:"deploy"},revision:{type:"string"}}},Operation:{type:"object",required:["id","state","kind","correlationId","createdAt"],properties:{id:{type:"string"},state:{type:"string"},kind:{type:"string"},correlationId:{type:"string"},createdAt:{type:"string",format:"date-time"}}},OperationResponse:{type:"object",required:["operation","idempotentReplay","requestId"],properties:{operation:{$ref:"#/components/schemas/Operation"},idempotentReplay:{type:"boolean"},requestId:{type:"string",format:"uuid"}}},Event:{type:"object",required:["id","sequence","type","level","correlationId","createdAt"],properties:{id:{type:"string"},sequence:{type:"integer"},type:{type:"string"},level:{type:"string"},correlationId:{type:"string"},payload:{},createdAt:{type:"string",format:"date-time"}}}}}}}function PC(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}function xC(e){if(!e)return;try{let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return t&&typeof t==="object"&&!Array.isArray(t)?t:void 0}catch{return}}function tn(e,t,r,n=["createdAt","id"]){let i=Math.min(100,Math.max(1,Number(t.searchParams.get("limit"))||50)),o=xC(t.searchParams.get("cursor"));if(t.searchParams.has("cursor")&&!o)throw new m("invalid_cursor","The pagination cursor is invalid.",400);let s=0;if(o){let f=e.findIndex((C)=>n.every((k)=>C[k]===o[k]));if(f<0)throw new m("invalid_cursor","The pagination cursor is no longer available.",400);s=f+1}let c=e.slice(s,s+i),u=s+i<e.length,a=c.at(-1);return{data:c,page:{hasMore:u,nextCursor:u&&a?PC(Object.fromEntries(n.map((f)=>[f,a[f]]))):void 0},requestId:r}}function vl(e){let t=new So(e.controlPlane,e.identities),r=new S(e.controlPlane),n=new Ze(e.controlPlane),i=new Ye(e.controlPlane),o=new lt(e.controlPlane),s=e.spend?.store??new wr(e.controlPlane,{now:e.now}),c={store:s,service:e.spend?.service??new bt(s)},u=new Map,a=e.now??(()=>new Date),f=e.rateLimit??120,C=(D,W,Y,ee={})=>new Response(JSON.stringify(D),{status:W,headers:{"content-type":"application/json; charset=utf-8","cache-control":"no-store","x-request-id":Y,"x-api-version":nd,...ee}}),k=(D,W,Y,ee,ne,he)=>C({error:{code:D,message:W,requestId:ee,details:ne}},Y,ee,he);return async(D,W)=>{let Y=new URL(D.url);if(!Y.pathname.startsWith("/api/v1"))return;let ee=crypto.randomUUID();if(Y.pathname==="/api/v1/openapi.json"&&D.method==="GET")return C(Sl(),200,ee,{"cache-control":"public, max-age=300"});let ne=D.headers.get("authorization")??"",he=ne.startsWith("Bearer ")?ne.slice(7).trim():"",te=he?e.identities.verifyToken(he,W):void 0;if(!te)return k("unauthorized","A valid bearer token is required.",401,ee,void 0,{"www-authenticate":'Bearer realm="ts-cloud", error="invalid_token"'});let Pe=u.get(te.token.id),Xe=a().getTime(),$e=!Pe||Xe-Pe.start>=60000?{start:Xe,count:0}:Pe;$e.count+=1,u.set(te.token.id,$e);let Gt=Math.max(0,f-$e.count),it={"x-ratelimit-limit":String(f),"x-ratelimit-remaining":String(Gt),"x-ratelimit-reset":String(Math.ceil(($e.start+60000)/1000))};if($e.count>f)return k("rate_limited","API rate limit exceeded.",429,ee,void 0,{...it,"retry-after":String(Math.max(1,Math.ceil(($e.start+60000-Xe)/1000)))});try{let ke,He=async()=>{let Q=await D.text();if(Q.length>1048576)throw new m("payload_too_large","Request body exceeds 1 MB.",413);try{return JSON.parse(Q)}catch{throw new m("invalid_json","Request body must be valid JSON.",400)}},Tt=/^\/api\/v1\/projects\/([^/]+)\/environments$/.exec(Y.pathname),Ei=/^\/api\/v1\/operations\/([^/]+)\/logs(?:\/(stream))?$/.exec(Y.pathname),co=/^\/api\/v1\/operations\/([^/]+)\/(cancel|retry)$/.exec(Y.pathname),Fn=/^\/api\/v1\/previews\/([^/]+)\/(destroy|extend|rebuild)$/.exec(Y.pathname),Ai=/^\/api\/v1\/compose-applications\/([^/]+)\/(deploy|redeploy|start|stop|scale|delete)$/.exec(Y.pathname),ki=/^\/api\/v1\/compose-applications\/([^/]+)\/services$/.exec(Y.pathname),Ri=/^\/api\/v1\/releases\/([^/]+)\/(promote|approve|activate|rollback|health|pin)$/.exec(Y.pathname);if(D.method==="GET"&&Y.pathname==="/api/v1/projects")ke=tn(t.listProjects(te),Y,ee);else if(D.method==="GET"&&Tt)ke=tn(t.listEnvironments(te,decodeURIComponent(Tt[1])),Y,ee);else if(D.method==="GET"&&Y.pathname==="/api/v1/services"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);ke=tn(t.listServices(te,Q,Y.searchParams.get("environmentId")??void 0),Y,ee)}else if(D.method==="GET"&&Y.pathname==="/api/v1/operations")ke=tn(t.listOperations(te,Y.searchParams.get("projectId")??void 0),Y,ee);else if(D.method==="GET"&&Y.pathname==="/api/v1/previews"){let Q=Y.searchParams.get("projectId")??void 0,ge=n.previews.listInstances({projectId:Q}).filter((Ee)=>{try{return t.authorize(te,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee}));ke=tn(ge,Y,ee)}else if(D.method==="GET"&&Y.pathname==="/api/v1/compose-templates")ke=tn(vr().map((Q)=>({...Q})),Y,ee,["id","version"]);else if(D.method==="GET"&&Y.pathname==="/api/v1/releases/capabilities"){let Q=String(Y.searchParams.get("kind")??"");ke={capabilities:lr({kind:Q,hasHealthGate:Y.searchParams.get("health")==="true",replicas:Number(Y.searchParams.get("replicas"))||1}),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/releases"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);t.authorize(te,"project:read",{type:"project",id:Q});let ge=o.releases.list({projectId:Q,environmentId:Y.searchParams.get("environmentId")??void 0,resourceId:Y.searchParams.get("resourceId")??void 0}).filter((Ee)=>{try{return t.authorize(te,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,artifact:o.releases.getArtifact(Ee.artifactId),transitions:o.releases.transitions(Ee.id),approvals:o.releases.approvals(Ee.id)}));ke=tn(ge,Y,ee)}else if(D.method==="POST"&&Y.pathname==="/api/v1/release-artifacts"){let Q=await He();t.authorize(te,"applications:manage",{type:"organization"}),ke={artifact:o.releases.registerArtifact({organizationId:te.serviceAccount.organizationId,digest:String(Q.digest??""),kind:String(Q.kind??""),uri:String(Q.uri??""),size:Number(Q.size),mediaType:typeof Q.mediaType==="string"?Q.mediaType:void 0,provenance:Q.provenance,attestation:Q.attestation}),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/releases"){let Q=await He(),ge=String(Q.resourceId??"");t.authorize(te,"applications:manage",{type:"resource",id:ge}),ke={release:o.releases.create({organizationId:te.serviceAccount.organizationId,projectId:String(Q.projectId??""),environmentId:String(Q.environmentId??""),resourceId:ge,artifactId:String(Q.artifactId??""),kind:String(Q.kind??""),sourceSha:typeof Q.sourceSha==="string"?Q.sourceSha:void 0,config:Q.config??{},manifest:Q.manifest??{},provenance:Q.provenance,strategy:String(Q.strategy??"atomic"),healthGate:Q.healthGate,hooks:Q.hooks,drainSeconds:Number(Q.drainSeconds)||void 0,graceSeconds:Number(Q.graceSeconds)||void 0,automaticRollback:Q.automaticRollback!==!1,actorId:te.actor.id,trigger:typeof Q.trigger==="string"?Q.trigger:"api",approvalRequired:Q.approvalRequired===!0,replicas:Number(Q.replicas)||void 0}),requestId:ee}}else if(D.method==="GET"&&/^\/api\/v1\/releases\/[^/]+$/.test(Y.pathname)){let Q=decodeURIComponent(Y.pathname.split("/").at(-1)),ge=o.releases.get(Q);if(!ge)throw new m("not_found","Release was not found.",404);t.authorize(te,"deployments:read",{type:"resource",id:ge.resourceId}),ke={release:ge,artifact:o.releases.getArtifact(ge.artifactId),transitions:o.releases.transitions(Q),approvals:o.releases.approvals(Q),requestId:ee}}else if(D.method==="POST"&&Ri){let Q=o.releases.get(decodeURIComponent(Ri[1]));if(!Q)throw new m("not_found","Release was not found.",404);let ge=await He(),Ee=Ri[2];if(Ee==="promote"){let Re=String(ge.targetResourceId??"");t.authorize(te,"deployments:create",{type:"resource",id:Re}),ke={release:o.releases.promote(Q.id,{targetEnvironmentId:String(ge.targetEnvironmentId??""),targetResourceId:Re,config:ge.config??{},strategy:ge.strategy,healthGate:ge.healthGate,actorId:te.actor.id,approvalRequired:ge.approvalRequired===!0}),requestId:ee}}else if(Ee==="approve")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={release:o.releases.approve(Q.id,{actorId:te.actor.id,decision:ge.decision==="rejected"?"rejected":"approved",comment:typeof ge.comment==="string"?ge.comment:void 0}),requestId:ee};else if(Ee==="activate")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(o.enqueueActivation(Q,{actorId:te.actor.id})),requestId:ee};else if(Ee==="rollback")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(o.enqueueRollback(Q,{actorId:te.actor.id,targetReleaseId:typeof ge.targetReleaseId==="string"?ge.targetReleaseId:void 0})),requestId:ee};else if(Ee==="health"){t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId});let Re=o.completeHealthGate(Q.id,{healthy:ge.healthy===!0,operationId:typeof ge.operationId==="string"?ge.operationId:void 0,health:ge.health,message:typeof ge.message==="string"?ge.message:void 0});ke={release:Re.release,rollbackOperation:Re.rollbackOperation?t.operation(Re.rollbackOperation):void 0,requestId:ee}}else t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={release:o.releases.pin(Q.id,ge.pinned!==!1,typeof ge.reason==="string"?ge.reason:void 0),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/compose-applications"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);t.authorize(te,"project:read",{type:"project",id:Q});let ge=i.applications.list({projectId:Q,environmentId:Y.searchParams.get("environmentId")??void 0}).filter((Ee)=>{try{return t.authorize(te,"deployments:read",{type:"resource",id:Ee.resourceId}),!0}catch{return!1}}).map((Ee)=>({...Ee,services:i.applications.services(Ee.id)}));ke=tn(ge,Y,ee)}else if(D.method==="POST"&&Y.pathname==="/api/v1/compose-applications/preview"){let Q=await He(),ge=String(Q.projectId??"");t.authorize(te,"project:read",{type:"project",id:ge}),ke={result:i.applications.preview(String(Q.source??""),{name:String(Q.name??""),slug:typeof Q.slug==="string"?Q.slug:void 0,projectId:ge,environmentId:String(Q.environmentId??"")}),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/compose-applications"){let Q=await He(),ge=String(Q.projectId??"");t.authorize(te,"applications:manage",{type:"environment",id:String(Q.environmentId??"")});let Ee={name:String(Q.name??""),slug:typeof Q.slug==="string"?Q.slug:void 0,projectId:ge,environmentId:String(Q.environmentId??""),createdByActorId:te.actor.id},Re=typeof Q.templateId==="string"?i.applications.fromTemplate(Q.templateId,Q.inputs&&typeof Q.inputs==="object"&&!Array.isArray(Q.inputs)?Q.inputs:{},{...Ee,version:typeof Q.templateVersion==="string"?Q.templateVersion:void 0}):i.applications.import(String(Q.source??""),Ee);ke={application:Re.application,diagnostics:Re.parsed.diagnostics,requestId:ee}}else if(D.method==="GET"&&ki){let Q=i.applications.get(decodeURIComponent(ki[1]));if(!Q)throw new m("not_found","Compose application was not found.",404);t.authorize(te,"deployments:read",{type:"resource",id:Q.resourceId}),ke={application:Q,services:i.applications.services(Q.id),requestId:ee}}else if(D.method==="POST"&&Ai){let Q=i.applications.get(decodeURIComponent(Ai[1]));if(!Q)throw new m("not_found","Compose application was not found.",404);let ge=Ai[2],Ee=await He();t.authorize(te,ge==="delete"||ge==="stop"?"deployments:cancel":"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(i.enqueue(Q,ge,{actorId:te.actor.id,service:typeof Ee.service==="string"?Ee.service:void 0,replicas:Number.isFinite(Number(Ee.replicas))?Number(Ee.replicas):void 0,removeVolumes:Ee.removeVolumes===!0,confirmation:typeof Ee.confirm==="string"?Ee.confirm:void 0})),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/preview-definitions"){let Q=Y.searchParams.get("projectId");if(!Q)throw new m("validation_error","projectId is required.",422);t.authorize(te,"project:read",{type:"project",id:Q}),ke=tn(n.previews.listDefinitions(Q).map((ge)=>({...ge})),Y,ee)}else if(D.method==="POST"&&Y.pathname==="/api/v1/preview-definitions"){let Q=await He();t.authorize(te,"config:write",{type:"resource",id:String(Q.resourceId??"")}),ke={definition:n.previews.createDefinition({...Q,projectId:String(Q.projectId??""),resourceId:String(Q.resourceId??""),baseEnvironmentId:String(Q.baseEnvironmentId??""),domainPattern:String(Q.domainPattern??""),createdByActorId:te.actor.id}),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/previews"){let Q=await He(),ge=n.previews.getDefinition(String(Q.definitionId??""));if(!ge)throw new m("not_found","Preview definition was not found.",404);t.authorize(te,"deployments:create",{type:"resource",id:ge.resourceId});let Ee=n.previews.upsert({definitionId:ge.id,sourceProvider:"api",repository:typeof Q.repository==="string"?Q.repository:"api",branch:String(Q.branch??""),pullRequestNumber:Number(Q.pullRequestNumber)||void 0,fork:Q.fork===!0,commitSha:String(Q.commitSha??""),createdByActorId:te.actor.id});ke={preview:Ee.preview,operation:t.operation(n.enqueueDeploy(Ee.preview,{created:Ee.created,actorId:te.actor.id})),requestId:ee}}else if(D.method==="POST"&&Fn){let Q=n.previews.getInstance(decodeURIComponent(Fn[1]));if(!Q)throw new m("not_found","Preview was not found.",404);let ge=await He(),Ee=Fn[2];if(Ee==="destroy"){if(t.authorize(te,"deployments:cancel",{type:"resource",id:Q.resourceId}),ge.confirm!==Q.name)throw new m("confirmation_required",`Type ${Q.name} to confirm preview teardown.`,409);ke={operation:t.operation(n.enqueueDestroy(Q,"api",te.actor.id)),requestId:ee}}else if(Ee==="extend")t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={preview:n.previews.extend(Q.id,Number(ge.hours)),requestId:ee};else t.authorize(te,"deployments:create",{type:"resource",id:Q.resourceId}),ke={operation:t.operation(n.enqueueDeploy(Q,{actorId:te.actor.id,reason:"manual_rebuild"})),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/previews/cleanup"){t.authorize(te,"automation:manage",{type:"organization"});let Q=await He();if(!Q.dryRun&&Q.confirm!=="cleanup previews")throw new m("confirmation_required","Type cleanup previews to confirm preview cleanup.",409);ke={...n.cleanup({dryRun:Q.dryRun===!0,maxAgeHours:Number(Q.maxAgeHours)||void 0,keepCount:Number(Q.keepCount)||void 0,actorId:te.actor.id}),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/queue"){let Q=Y.searchParams.get("projectId")??void 0,ge=Y.searchParams.get("state"),Ee=r.list({projectId:Q,state:["queued","running","succeeded","failed","cancelled","timed_out"].includes(ge)?ge:void 0,limit:500}).filter((Re)=>{let Pt=Re.operation.resourceId?{type:"resource",id:Re.operation.resourceId}:Re.operation.environmentId?{type:"environment",id:Re.operation.environmentId}:Re.operation.projectId?{type:"project",id:Re.operation.projectId}:{type:"organization"};try{return t.authorize(te,"deployments:read",Pt),!0}catch{return!1}}).map((Re)=>({...t.operation(Re.operation),queue:Re.job,approximatePosition:Re.approximatePosition}));ke=tn(Ee,Y,ee)}else if(D.method==="GET"&&Y.pathname==="/api/v1/queue/settings")t.authorize(te,"deployments:read",te.token.scope),ke={concurrency:r.limits,requestId:ee};else if(D.method==="PATCH"&&Y.pathname==="/api/v1/queue/settings"){t.authorize(te,"automation:manage",{type:"organization"});let Q=await He();if(Q.confirm!=="update queue limits")throw new m("confirmation_required","Type update queue limits to confirm production concurrency changes.",409);ke={concurrency:r.configureConcurrency(Q.concurrency??{},{organizationId:te.serviceAccount.organizationId,actorId:te.actor.id}),requestId:ee}}else if(D.method==="DELETE"&&Y.pathname==="/api/v1/queue/history"){t.authorize(te,"automation:manage",{type:"organization"});let Q=await He();if(Q.confirm!=="clear completed")throw new m("confirmation_required","Type clear completed to confirm queue retention cleanup.",409);ke={deleted:r.clearCompleted({before:typeof Q.before==="string"?Q.before:void 0,actorId:te.actor.id,projectId:typeof Q.projectId==="string"?Q.projectId:void 0}),requestId:ee}}else if(D.method==="GET"&&Ei){let Q=e.controlPlane.getOperation(decodeURIComponent(Ei[1]));if(!Q)throw new m("not_found","Operation was not found.",404);let ge=Q.resourceId?{type:"resource",id:Q.resourceId}:Q.environmentId?{type:"environment",id:Q.environmentId}:Q.projectId?{type:"project",id:Q.projectId}:{type:"organization"};t.authorize(te,"deployments:read",ge);let Ee=D.headers.get("last-event-id")?.trim(),Re=Number(Ee||Y.searchParams.get("after")||0);if(Ei[2]==="stream"){let Jt=new TextEncoder,we=Re,st,rt=!1,ze=new ReadableStream({start(Pr){let ms=()=>{if(rt)return;if(!e.identities.verifyToken(he,W)){if(rt=!0,st)clearInterval(st);Pr.close();return}let Pi=r.logs(Q.id,{after:we,limit:500});for(let Dt of Pi)we=Dt.sequence,Pr.enqueue(Jt.encode(`id: ${Dt.sequence}
|
|
138
138
|
event: log
|
|
139
139
|
data: ${JSON.stringify(Dt)}
|
|
140
140
|
|
|
141
141
|
`));let At=e.controlPlane.getOperation(Q.id);if(At&&["succeeded","failed","cancelled","timed_out"].includes(At.state)&&!r.logs(Q.id,{after:we,limit:1}).length){if(rt=!0,st)clearInterval(st);Pr.enqueue(Jt.encode(`event: complete
|
|
142
142
|
data: ${JSON.stringify({state:At.state,cursor:we})}
|
|
143
143
|
|
|
144
|
-
`)),Pr.close()}};if(ms(),!rt)st=setInterval(ms,500);D.signal.addEventListener("abort",()=>{if(rt=!0,st)clearInterval(st);try{Pr.close()}catch{}},{once:!0})},cancel(){if(rt=!0,st)clearInterval(st)}});return new Response(ze,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no","x-request-id":ee,...it}})}let Pt=r.logs(Q.id,{after:Re,limit:Number(Y.searchParams.get("limit"))||void 0});ke={data:Pt,cursor:Pt.at(-1)?.sequence??Re,hasMore:Pt.length>=Math.min(1000,Math.max(1,Number(Y.searchParams.get("limit"))||200)),requestId:ee}}else if(D.method==="POST"&&co){let Q=e.controlPlane.getOperation(decodeURIComponent(co[1]));if(!Q)throw new m("not_found","Operation was not found.",404);let ge=Q.resourceId?{type:"resource",id:Q.resourceId}:Q.environmentId?{type:"environment",id:Q.environmentId}:Q.projectId?{type:"project",id:Q.projectId}:{type:"organization"},Ee=await He();if(co[2]==="cancel")t.authorize(te,"deployments:cancel",ge),ke={operation:t.operation(r.requestCancellation(Q.id,te.actor.id)),requestId:ee};else t.authorize(te,"deployments:create",ge),ke={operation:t.operation(r.retry(Q.id,String(Ee.errorClass??"manual"),{delayMs:Number(Ee.delayMs)||0,actorId:te.actor.id})),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/source/connections"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:read",te.token.scope),ke=tn(e.sources.listConnections(te.serviceAccount.organizationId),Y,ee,["createdAt","id"])}else if(D.method==="GET"&&Y.pathname==="/api/v1/source/repositories"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:read",te.token.scope);let Q=e.sources.getConnection(Y.searchParams.get("connectionId")??"");if(!Q||Q.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);if(Y.searchParams.get("sync")==="true")t.authorize(te,"sources:manage",{type:"organization"}),await
|
|
144
|
+
`)),Pr.close()}};if(ms(),!rt)st=setInterval(ms,500);D.signal.addEventListener("abort",()=>{if(rt=!0,st)clearInterval(st);try{Pr.close()}catch{}},{once:!0})},cancel(){if(rt=!0,st)clearInterval(st)}});return new Response(ze,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no","x-request-id":ee,...it}})}let Pt=r.logs(Q.id,{after:Re,limit:Number(Y.searchParams.get("limit"))||void 0});ke={data:Pt,cursor:Pt.at(-1)?.sequence??Re,hasMore:Pt.length>=Math.min(1000,Math.max(1,Number(Y.searchParams.get("limit"))||200)),requestId:ee}}else if(D.method==="POST"&&co){let Q=e.controlPlane.getOperation(decodeURIComponent(co[1]));if(!Q)throw new m("not_found","Operation was not found.",404);let ge=Q.resourceId?{type:"resource",id:Q.resourceId}:Q.environmentId?{type:"environment",id:Q.environmentId}:Q.projectId?{type:"project",id:Q.projectId}:{type:"organization"},Ee=await He();if(co[2]==="cancel")t.authorize(te,"deployments:cancel",ge),ke={operation:t.operation(r.requestCancellation(Q.id,te.actor.id)),requestId:ee};else t.authorize(te,"deployments:create",ge),ke={operation:t.operation(r.retry(Q.id,String(Ee.errorClass??"manual"),{delayMs:Number(Ee.delayMs)||0,actorId:te.actor.id})),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/source/connections"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:read",te.token.scope),ke=tn(e.sources.listConnections(te.serviceAccount.organizationId),Y,ee,["createdAt","id"])}else if(D.method==="GET"&&Y.pathname==="/api/v1/source/repositories"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:read",te.token.scope);let Q=e.sources.getConnection(Y.searchParams.get("connectionId")??"");if(!Q||Q.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);if(Y.searchParams.get("sync")==="true")t.authorize(te,"sources:manage",{type:"organization"}),await qr(e.sources,Q.id,{search:Y.searchParams.get("search")??void 0});ke=tn(e.sources.listRepositories(Q.id,Y.searchParams.get("search")??void 0),Y,ee,["fullName","id"])}else if(D.method==="GET"&&Y.pathname==="/api/v1/source/refs"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:read",te.token.scope);let Q=Y.searchParams.get("connectionId")??"",ge=e.sources.getConnection(Q);if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);ke=await sr(e.sources,{connectionId:Q,repository:Y.searchParams.get("repository")??"",repositoryId:Y.searchParams.get("repositoryId")??void 0,type:Y.searchParams.get("type")==="tags"?"tags":"branches",cursor:Y.searchParams.get("cursor")??void 0,deployKeyId:Y.searchParams.get("deployKeyId")??void 0})}else if(D.method==="POST"&&Y.pathname==="/api/v1/application-detections"){t.authorize(te,"applications:manage",te.token.scope);let Q=await He();if(!Array.isArray(Q.files)||Q.files.length>1e4)throw new m("validation_error","files must contain at most 10,000 entries.",422);ke={candidates:xt(Q.files.map((ge)=>({path:String(ge.path??""),size:Number(ge.size??0),content:typeof ge.content==="string"?ge.content.slice(0,262144):void 0}))),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/application-plans"){t.authorize(te,"applications:manage",te.token.scope);let Q=await He();ke={plan:de(Q.draft,Array.isArray(Q.suppliedSecretNames)?Q.suppliedSecretNames.map(String):[]),requestId:ee}}else if(D.method==="GET"&&Y.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);let Q=Y.searchParams.get("projectId")??"";t.authorize(te,"applications:read",{type:"project",id:Q}),ke=tn(e.applications.drafts.list(Q),Y,ee,["updatedAt","id"])}else if(D.method==="POST"&&Y.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);let Q=await He(),ge=String(Q.projectId??Q.draft?.projectId??"");t.authorize(te,"applications:manage",{type:"project",id:ge});let Ee=e.controlPlane.getProject(ge);if(!Ee||Ee.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Project was not found.",404);let Re=e.applications.drafts.create({organizationId:Ee.organizationId,projectId:ge,name:String(Q.name??Q.draft?.name??"Application draft"),draft:{...Q.draft,projectId:ge},step:Q.step,suppliedSecretNames:Array.isArray(Q.suppliedSecretNames)?Q.suppliedSecretNames.map(String):[],actorId:te.actor.id});return C({draft:Re,requestId:ee},201,ee,it)}else if(D.method==="PATCH"&&Y.pathname==="/api/v1/application-drafts"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);let Q=await He(),ge=e.applications.drafts.get(String(Q.id??""));if(!ge)throw new m("not_found","Application draft was not found.",404);t.authorize(te,"applications:manage",{type:"project",id:ge.projectId}),ke={draft:e.applications.drafts.update(ge.id,Number(Q.version),{draft:{...Q.draft,projectId:ge.projectId},step:Q.step,suppliedSecretNames:Array.isArray(Q.suppliedSecretNames)?Q.suppliedSecretNames.map(String):void 0,actorId:te.actor.id}),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/applications"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);let Q=D.headers.get("idempotency-key")??"";if(!Q)throw new m("idempotency_required","Idempotency-Key is required for application creation.",428);if(!/^[A-Za-z0-9._:-]{8,128}$/.test(Q))throw new m("validation_error","Idempotency-Key must contain 8-128 safe characters.",422);let ge=await He(),Ee=e.applications.drafts.get(String(ge.draftId??""));if(!Ee)throw new m("not_found","Application draft was not found.",404);t.authorize(te,"applications:manage",{type:"project",id:Ee.projectId});let Re=RC("sha256").update(`POST
|
|
145
145
|
/api/v1/applications
|
|
146
|
-
${JSON.stringify(ge)}`).digest("hex"),Pt=e.identities.getIdempotency(te.token.id,Q);if(Pt){if(Pt.requestHash!==Re)throw new m("idempotency_conflict","Idempotency-Key was already used for another request.",409);let we=Pt.operationId?e.controlPlane.getOperation(Pt.operationId):void 0,st=we?.resourceId?e.controlPlane.getResource(we.resourceId):void 0;if(!we||!st)throw new m("idempotency_unavailable","The original application operation is no longer available.",409);return C({resource:st,operation:t.operation(we),plan:de(Ee.input,Ee.suppliedSecretNames),idempotentReplay:!0,requestId:ee},202,ee,{...it,"idempotent-replayed":"true"})}let Jt=Wr({controlPlane:e.controlPlane,drafts:e.applications.drafts,draftId:Ee.id,expectedVersion:Number(ge.version),confirmEnvironment:String(ge.confirmEnvironment??""),actorId:te.actor.id});return e.identities.saveIdempotency({tokenId:te.token.id,key:Q,requestHash:Re,operationId:Jt.operation.id,responseStatus:202,responseBody:{draftId:Ee.id}}),C({resource:Jt.resource,operation:t.operation(Jt.operation),plan:Jt.plan,idempotentReplay:!1,requestId:ee},202,ee,it)}else if(D.method==="GET"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:read",te.token.scope),ke=tn(e.applications.registries.list(te.serviceAccount.organizationId),Y,ee,["createdAt","id"])}else if(D.method==="POST"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:manage",{type:"organization"});let Q=await He(),ge=e.applications.registries.create({organizationId:te.serviceAccount.organizationId,provider:Q.provider,name:String(Q.name??"Container registry"),host:String(Q.host??""),credential:Q.token||Q.password?{username:typeof Q.username==="string"?Q.username:void 0,password:typeof Q.password==="string"?Q.password:void 0,token:typeof Q.token==="string"?Q.token:void 0}:void 0,credentialExpiresAt:typeof Q.credentialExpiresAt==="string"?Q.credentialExpiresAt:void 0,actorId:te.actor.id});return C({registry:ge,requestId:ee},201,ee,it)}else if(D.method==="PATCH"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:manage",{type:"organization"});let Q=await He(),ge=e.applications.registries.get(String(Q.id??""));if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Registry connection was not found.",404);if(Q.action==="test")ke={registry:await e.applications.registries.test(ge.id,{image:typeof Q.image==="string"?Q.image:void 0}),requestId:ee};else if(Q.action==="rotate")ke={registry:e.applications.registries.rotate(ge.id,{username:Q.username,password:Q.password,token:Q.token},{expiresAt:Q.expiresAt,actorId:te.actor.id}),requestId:ee};else throw new m("validation_error","action must be test or rotate.",422)}else if(D.method==="DELETE"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:manage",{type:"organization"});let Q=await He(),ge=e.applications.registries.get(String(Q.id??""));if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Registry connection was not found.",404);ke={registry:e.applications.registries.disconnect(ge.id,te.actor.id),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/application-artifacts"){if(!e.applications?.artifacts)throw new m("not_found","Application artifact storage is unavailable.",404);let Q=D.headers.get("x-project-id")??"";t.authorize(te,"applications:manage",{type:"project",id:Q});let ge=e.controlPlane.getProject(Q);if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Project was not found.",404);if(Number(D.headers.get("content-length")??0)>104857600)throw new m("payload_too_large","Artifact exceeds 100 MB.",413);let Re=e.applications.artifacts.create({organizationId:ge.organizationId,projectId:Q,filename:D.headers.get("x-artifact-filename")??"application.zip",bytes:new Uint8Array(await D.arrayBuffer()),actorId:te.actor.id});return C({artifact:Re,requestId:ee},201,ee,it)}else if(D.method==="POST"&&Y.pathname==="/api/v1/source/connections"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:manage",{type:"organization"});let Q=await He(),ge=String(Q.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(ge))throw new m("validation_error","A supported provider is required.",422);let Ee=ge==="github"&&(Q.privateKey||Q.appId)?{appId:typeof Q.appId==="string"?Q.appId:void 0,installationId:typeof Q.installationId==="string"?Q.installationId:void 0,privateKey:typeof Q.privateKey==="string"?Q.privateKey:void 0}:ge!=="generic_ssh"&&Q.token?{token:String(Q.token),username:typeof Q.username==="string"?Q.username:void 0}:void 0,Re,Pt,Jt;return e.controlPlane.database.transaction(()=>{if(Re=e.sources.createConnection({organizationId:te.serviceAccount.organizationId,provider:ge,name:String(Q.name??ge),host:String(Q.host??""),owner:typeof Q.owner==="string"?Q.owner:void 0,authKind:Q.authKind,credential:Ee,createdByActorId:te.actor.id}),typeof Q.repositoryUrl==="string"&&typeof Q.repositoryFullName==="string")Pt=e.sources.upsertRepository({connectionId:Re.id,providerRepositoryId:`manual:${Q.repositoryFullName}`,fullName:Q.repositoryFullName,cloneUrl:Q.repositoryUrl,defaultBranch:String(Q.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"api"}});if(ge==="generic_ssh")Jt=e.sources.createDeployKey({connectionId:Re.id,name:String(Q.deployKeyName??"Repository deploy key"),publicKey:String(Q.publicKey??""),privateKey:String(Q.deployPrivateKey??""),host:String(Q.sshHost??""),hostKey:String(Q.hostKey??""),actorId:te.actor.id})})(),C({connection:Re,repository:Pt,deployKey:Jt,requestId:ee},201,ee,it)}else if(D.method==="POST"&&Y.pathname==="/api/v1/source/bindings"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);let Q=await He(),ge=String(Q.projectId??"");t.authorize(te,"sources:manage",{type:"project",id:ge});let Ee=e.sources.getConnection(String(Q.connectionId??""));if(!Ee||Ee.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);let Re=e.sources.createBinding({projectId:ge,environmentId:typeof Q.environmentId==="string"?Q.environmentId:void 0,resourceId:typeof Q.resourceId==="string"?Q.resourceId:void 0,connectionId:Ee.id,repositoryId:typeof Q.repositoryId==="string"?Q.repositoryId:void 0,repositoryFullName:String(Q.repositoryFullName??""),defaultBranch:String(Q.defaultBranch??"main"),branchRule:typeof Q.branchRule==="string"?Q.branchRule:void 0,tagRule:typeof Q.tagRule==="string"?Q.tagRule:void 0,monorepoRoot:String(Q.monorepoRoot??"."),includePaths:Array.isArray(Q.includePaths)?Q.includePaths.map(String):[],excludePaths:Array.isArray(Q.excludePaths)?Q.excludePaths.map(String):[],submodules:Q.submodules===!0,cloneDepth:typeof Q.cloneDepth==="number"?Q.cloneDepth:void 0,deployKeyId:typeof Q.deployKeyId==="string"&&Q.deployKeyId?Q.deployKeyId:void 0,autoDeploy:Q.autoDeploy!==!1,pullRequestPreviews:Q.pullRequestPreviews!==!1,actorId:te.actor.id});return C({binding:Re,requestId:ee},201,ee,it)}else if(D.method==="POST"&&Y.pathname==="/api/v1/source/webhooks"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:manage",{type:"organization"});let Q=await He(),ge=e.sources.getConnection(String(Q.connectionId??""));if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);let Ee=typeof Q.baseUrl==="string"?Q.baseUrl:void 0;if(!Ee)throw new m("validation_error","baseUrl is required.",422);let Re=e.sources.createWebhook({connectionId:ge.id,repositoryId:typeof Q.repositoryId==="string"?Q.repositoryId:void 0,repositoryFullName:String(Q.repositoryFullName??""),events:Array.isArray(Q.events)?Q.events.map(String):void 0}),Pt=Nt(Ee,Re.webhook),Jt=Q.reconcile===!1?Re.webhook:await
|
|
146
|
+
${JSON.stringify(ge)}`).digest("hex"),Pt=e.identities.getIdempotency(te.token.id,Q);if(Pt){if(Pt.requestHash!==Re)throw new m("idempotency_conflict","Idempotency-Key was already used for another request.",409);let we=Pt.operationId?e.controlPlane.getOperation(Pt.operationId):void 0,st=we?.resourceId?e.controlPlane.getResource(we.resourceId):void 0;if(!we||!st)throw new m("idempotency_unavailable","The original application operation is no longer available.",409);return C({resource:st,operation:t.operation(we),plan:de(Ee.input,Ee.suppliedSecretNames),idempotentReplay:!0,requestId:ee},202,ee,{...it,"idempotent-replayed":"true"})}let Jt=Wr({controlPlane:e.controlPlane,drafts:e.applications.drafts,draftId:Ee.id,expectedVersion:Number(ge.version),confirmEnvironment:String(ge.confirmEnvironment??""),actorId:te.actor.id});return e.identities.saveIdempotency({tokenId:te.token.id,key:Q,requestHash:Re,operationId:Jt.operation.id,responseStatus:202,responseBody:{draftId:Ee.id}}),C({resource:Jt.resource,operation:t.operation(Jt.operation),plan:Jt.plan,idempotentReplay:!1,requestId:ee},202,ee,it)}else if(D.method==="GET"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:read",te.token.scope),ke=tn(e.applications.registries.list(te.serviceAccount.organizationId),Y,ee,["createdAt","id"])}else if(D.method==="POST"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:manage",{type:"organization"});let Q=await He(),ge=e.applications.registries.create({organizationId:te.serviceAccount.organizationId,provider:Q.provider,name:String(Q.name??"Container registry"),host:String(Q.host??""),credential:Q.token||Q.password?{username:typeof Q.username==="string"?Q.username:void 0,password:typeof Q.password==="string"?Q.password:void 0,token:typeof Q.token==="string"?Q.token:void 0}:void 0,credentialExpiresAt:typeof Q.credentialExpiresAt==="string"?Q.credentialExpiresAt:void 0,actorId:te.actor.id});return C({registry:ge,requestId:ee},201,ee,it)}else if(D.method==="PATCH"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:manage",{type:"organization"});let Q=await He(),ge=e.applications.registries.get(String(Q.id??""));if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Registry connection was not found.",404);if(Q.action==="test")ke={registry:await e.applications.registries.test(ge.id,{image:typeof Q.image==="string"?Q.image:void 0}),requestId:ee};else if(Q.action==="rotate")ke={registry:e.applications.registries.rotate(ge.id,{username:Q.username,password:Q.password,token:Q.token},{expiresAt:Q.expiresAt,actorId:te.actor.id}),requestId:ee};else throw new m("validation_error","action must be test or rotate.",422)}else if(D.method==="DELETE"&&Y.pathname==="/api/v1/registry-connections"){if(!e.applications)throw new m("not_found","Application onboarding is unavailable.",404);t.authorize(te,"applications:manage",{type:"organization"});let Q=await He(),ge=e.applications.registries.get(String(Q.id??""));if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Registry connection was not found.",404);ke={registry:e.applications.registries.disconnect(ge.id,te.actor.id),requestId:ee}}else if(D.method==="POST"&&Y.pathname==="/api/v1/application-artifacts"){if(!e.applications?.artifacts)throw new m("not_found","Application artifact storage is unavailable.",404);let Q=D.headers.get("x-project-id")??"";t.authorize(te,"applications:manage",{type:"project",id:Q});let ge=e.controlPlane.getProject(Q);if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Project was not found.",404);if(Number(D.headers.get("content-length")??0)>104857600)throw new m("payload_too_large","Artifact exceeds 100 MB.",413);let Re=e.applications.artifacts.create({organizationId:ge.organizationId,projectId:Q,filename:D.headers.get("x-artifact-filename")??"application.zip",bytes:new Uint8Array(await D.arrayBuffer()),actorId:te.actor.id});return C({artifact:Re,requestId:ee},201,ee,it)}else if(D.method==="POST"&&Y.pathname==="/api/v1/source/connections"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:manage",{type:"organization"});let Q=await He(),ge=String(Q.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(ge))throw new m("validation_error","A supported provider is required.",422);let Ee=ge==="github"&&(Q.privateKey||Q.appId)?{appId:typeof Q.appId==="string"?Q.appId:void 0,installationId:typeof Q.installationId==="string"?Q.installationId:void 0,privateKey:typeof Q.privateKey==="string"?Q.privateKey:void 0}:ge!=="generic_ssh"&&Q.token?{token:String(Q.token),username:typeof Q.username==="string"?Q.username:void 0}:void 0,Re,Pt,Jt;return e.controlPlane.database.transaction(()=>{if(Re=e.sources.createConnection({organizationId:te.serviceAccount.organizationId,provider:ge,name:String(Q.name??ge),host:String(Q.host??""),owner:typeof Q.owner==="string"?Q.owner:void 0,authKind:Q.authKind,credential:Ee,createdByActorId:te.actor.id}),typeof Q.repositoryUrl==="string"&&typeof Q.repositoryFullName==="string")Pt=e.sources.upsertRepository({connectionId:Re.id,providerRepositoryId:`manual:${Q.repositoryFullName}`,fullName:Q.repositoryFullName,cloneUrl:Q.repositoryUrl,defaultBranch:String(Q.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"api"}});if(ge==="generic_ssh")Jt=e.sources.createDeployKey({connectionId:Re.id,name:String(Q.deployKeyName??"Repository deploy key"),publicKey:String(Q.publicKey??""),privateKey:String(Q.deployPrivateKey??""),host:String(Q.sshHost??""),hostKey:String(Q.hostKey??""),actorId:te.actor.id})})(),C({connection:Re,repository:Pt,deployKey:Jt,requestId:ee},201,ee,it)}else if(D.method==="POST"&&Y.pathname==="/api/v1/source/bindings"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);let Q=await He(),ge=String(Q.projectId??"");t.authorize(te,"sources:manage",{type:"project",id:ge});let Ee=e.sources.getConnection(String(Q.connectionId??""));if(!Ee||Ee.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);let Re=e.sources.createBinding({projectId:ge,environmentId:typeof Q.environmentId==="string"?Q.environmentId:void 0,resourceId:typeof Q.resourceId==="string"?Q.resourceId:void 0,connectionId:Ee.id,repositoryId:typeof Q.repositoryId==="string"?Q.repositoryId:void 0,repositoryFullName:String(Q.repositoryFullName??""),defaultBranch:String(Q.defaultBranch??"main"),branchRule:typeof Q.branchRule==="string"?Q.branchRule:void 0,tagRule:typeof Q.tagRule==="string"?Q.tagRule:void 0,monorepoRoot:String(Q.monorepoRoot??"."),includePaths:Array.isArray(Q.includePaths)?Q.includePaths.map(String):[],excludePaths:Array.isArray(Q.excludePaths)?Q.excludePaths.map(String):[],submodules:Q.submodules===!0,cloneDepth:typeof Q.cloneDepth==="number"?Q.cloneDepth:void 0,deployKeyId:typeof Q.deployKeyId==="string"&&Q.deployKeyId?Q.deployKeyId:void 0,autoDeploy:Q.autoDeploy!==!1,pullRequestPreviews:Q.pullRequestPreviews!==!1,actorId:te.actor.id});return C({binding:Re,requestId:ee},201,ee,it)}else if(D.method==="POST"&&Y.pathname==="/api/v1/source/webhooks"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:manage",{type:"organization"});let Q=await He(),ge=e.sources.getConnection(String(Q.connectionId??""));if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);let Ee=typeof Q.baseUrl==="string"?Q.baseUrl:void 0;if(!Ee)throw new m("validation_error","baseUrl is required.",422);let Re=e.sources.createWebhook({connectionId:ge.id,repositoryId:typeof Q.repositoryId==="string"?Q.repositoryId:void 0,repositoryFullName:String(Q.repositoryFullName??""),events:Array.isArray(Q.events)?Q.events.map(String):void 0}),Pt=Nt(Ee,Re.webhook),Jt=Q.reconcile===!1?Re.webhook:await ar(e.sources,Re.webhook.id,Ee);return C({webhook:Jt,endpoint:Pt,endpointRevealOnce:!0,requestId:ee},201,ee,it)}else if(D.method==="DELETE"&&Y.pathname==="/api/v1/source/connections"){if(!e.sources)throw new m("not_found","Source integrations are unavailable.",404);t.authorize(te,"sources:manage",{type:"organization"});let Q=await He(),ge=e.sources.getConnection(String(Q.id??""));if(!ge||ge.organizationId!==te.serviceAccount.organizationId)throw new m("not_found","Source connection was not found.",404);let Ee=e.sources.listBindings({connectionId:ge.id,status:"active"});if(Q.preview===!0)return C({preview:!0,affectedBindings:Ee,requestId:ee},200,ee,it);return C({...e.sources.disconnectConnection(ge.id,te.actor.id),requestId:ee},200,ee,it)}else if(D.method==="GET"&&(Y.pathname==="/api/v1/events"||Y.pathname==="/api/v1/events/stream")){let Q=t.listEvents(te,Y.searchParams.get("projectId")??void 0,Number(Y.searchParams.get("after"))||void 0);if(Y.pathname.endsWith("/stream")){let ge=new TextEncoder,Ee=Q.reduce((we,st)=>Math.max(we,Number(st.sequence)),Number(Y.searchParams.get("after"))||0),Re,Pt=!1,Jt=new ReadableStream({start(we){let st=(rt)=>we.enqueue(ge.encode(`id: ${rt.sequence}
|
|
147
147
|
event: ${rt.type}
|
|
148
148
|
data: ${JSON.stringify(rt)}
|
|
149
149
|
|
|
@@ -151,7 +151,7 @@ data: ${JSON.stringify(rt)}
|
|
|
151
151
|
|
|
152
152
|
`));Re=setInterval(()=>{if(Pt)return;let rt=e.identities.verifyToken(he,W);if(!rt){if(Pt=!0,Re)clearInterval(Re);we.close();return}try{let ze=t.listEvents(rt,Y.searchParams.get("projectId")??void 0,Ee);for(let Pr of ze)st(Pr),Ee=Math.max(Ee,Number(Pr.sequence));if(!ze.length)we.enqueue(ge.encode(`: heartbeat ${Date.now()}
|
|
153
153
|
|
|
154
|
-
`))}catch{if(Pt=!0,Re)clearInterval(Re);we.close()}},1000),D.signal.addEventListener("abort",()=>{if(Pt=!0,Re)clearInterval(Re);try{we.close()}catch{}},{once:!0})},cancel(){if(Pt=!0,Re)clearInterval(Re)}});return new Response(Jt,{status:200,headers:{"content-type":"text/event-stream","cache-control":"no-store",connection:"keep-alive","x-accel-buffering":"no","x-request-id":ee,...it}})}ke=tn(Q,Y,ee,["sequence","id"])}else if(D.method==="POST"&&Y.pathname==="/api/v1/deployments"){let Q=D.headers.get("idempotency-key")??"";if(!Q)throw new m("idempotency_required","Idempotency-Key is required for deployment requests.",428);let ge=await D.text();if(ge.length>1048576)throw new m("payload_too_large","Request body exceeds 1 MB.",413);let Ee;try{Ee=JSON.parse(ge)}catch{throw new m("invalid_json","Request body must be valid JSON.",400)}if(!Ee||typeof Ee.projectId!=="string"||typeof Ee.environmentId!=="string"||Ee.action!==void 0&&!["deploy","rollback"].includes(Ee.action))throw new m("validation_error","projectId, environmentId, and a valid action are required.",422);let Re=t.createDeployment(te,Ee,Q);return C({operation:Re.operation,idempotentReplay:Re.replay,requestId:ee},202,ee,{...it,...Re.replay?{"idempotent-replayed":"true"}:{}})}else{let Q=await Ns({...c,authorization:t,now:a},te,{method:D.method,url:Y,body:He});if(Q===void 0)throw new m("not_found","API resource was not found.",404);ke=Q}return C(ke,200,ee,it)}catch(ke){if(ke instanceof m)return k(ke.code,ke.message,ke.status,ee,ke.details,it);if(Y.pathname.startsWith("/api/v1/source/")||Y.pathname.startsWith("/api/v1/application")||Y.pathname.startsWith("/api/v1/compose-")||Y.pathname==="/api/v1/registry-connections")return k("validation_error",ke instanceof Error?ke.message:"Integration request could not be completed.",422,ee,void 0,it);return k("internal_error","The API request could not be completed.",500,ee,void 0,it)}}}import{createHash as DC,randomBytes as OC}from"node:crypto";var yh=new Set(ce),bh=7776000000,Sh=31536000000,vh=86400000;function ro(e){return typeof e==="string"?e:void 0}function hh(e){return DC("sha256").update(e).digest("hex")}function _C(e){try{let t=JSON.parse(String(e));return Array.isArray(t)?t.filter((r)=>typeof r==="string"&&yh.has(r)):[]}catch{return[]}}function NC(e){let t=String(e.scope_type);return t==="organization"?{type:t}:{type:t,id:String(e.scope_id)}}function wl(e){let t=ro(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:ro(e.description),createdByActorId:ro(e.created_by_actor_id),disabledAt:t,createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:t?"disabled":"active"}}function Il(e,t){let r=ro(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:_C(e.capabilities),scope:NC(e),expiresAt:n,lastUsedAt:ro(e.last_used_at),lastNetworkHint:ro(e.last_network_hint),revokedAt:r,rotatedFromTokenId:ro(e.rotated_from_token_id),createdByActorId:ro(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:r?"revoked":n<=t?"expired":"active"}}function MC(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:ro(e.operation_id),responseStatus:Number(e.response_status),responseBody:t,expiresAt:String(e.expires_at),createdAt:String(e.created_at)}}class
|
|
154
|
+
`))}catch{if(Pt=!0,Re)clearInterval(Re);we.close()}},1000),D.signal.addEventListener("abort",()=>{if(Pt=!0,Re)clearInterval(Re);try{we.close()}catch{}},{once:!0})},cancel(){if(Pt=!0,Re)clearInterval(Re)}});return new Response(Jt,{status:200,headers:{"content-type":"text/event-stream","cache-control":"no-store",connection:"keep-alive","x-accel-buffering":"no","x-request-id":ee,...it}})}ke=tn(Q,Y,ee,["sequence","id"])}else if(D.method==="POST"&&Y.pathname==="/api/v1/deployments"){let Q=D.headers.get("idempotency-key")??"";if(!Q)throw new m("idempotency_required","Idempotency-Key is required for deployment requests.",428);let ge=await D.text();if(ge.length>1048576)throw new m("payload_too_large","Request body exceeds 1 MB.",413);let Ee;try{Ee=JSON.parse(ge)}catch{throw new m("invalid_json","Request body must be valid JSON.",400)}if(!Ee||typeof Ee.projectId!=="string"||typeof Ee.environmentId!=="string"||Ee.action!==void 0&&!["deploy","rollback"].includes(Ee.action))throw new m("validation_error","projectId, environmentId, and a valid action are required.",422);let Re=t.createDeployment(te,Ee,Q);return C({operation:Re.operation,idempotentReplay:Re.replay,requestId:ee},202,ee,{...it,...Re.replay?{"idempotent-replayed":"true"}:{}})}else{let Q=await Ns({...c,authorization:t,now:a},te,{method:D.method,url:Y,body:He});if(Q===void 0)throw new m("not_found","API resource was not found.",404);ke=Q}return C(ke,200,ee,it)}catch(ke){if(ke instanceof m)return k(ke.code,ke.message,ke.status,ee,ke.details,it);if(Y.pathname.startsWith("/api/v1/source/")||Y.pathname.startsWith("/api/v1/application")||Y.pathname.startsWith("/api/v1/compose-")||Y.pathname==="/api/v1/registry-connections")return k("validation_error",ke instanceof Error?ke.message:"Integration request could not be completed.",422,ee,void 0,it);return k("internal_error","The API request could not be completed.",500,ee,void 0,it)}}}import{createHash as DC,randomBytes as OC}from"node:crypto";var yh=new Set(ce),bh=7776000000,Sh=31536000000,vh=86400000;function ro(e){return typeof e==="string"?e:void 0}function hh(e){return DC("sha256").update(e).digest("hex")}function _C(e){try{let t=JSON.parse(String(e));return Array.isArray(t)?t.filter((r)=>typeof r==="string"&&yh.has(r)):[]}catch{return[]}}function NC(e){let t=String(e.scope_type);return t==="organization"?{type:t}:{type:t,id:String(e.scope_id)}}function wl(e){let t=ro(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:ro(e.description),createdByActorId:ro(e.created_by_actor_id),disabledAt:t,createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:t?"disabled":"active"}}function Il(e,t){let r=ro(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:_C(e.capabilities),scope:NC(e),expiresAt:n,lastUsedAt:ro(e.last_used_at),lastNetworkHint:ro(e.last_network_hint),revokedAt:r,rotatedFromTokenId:ro(e.rotated_from_token_id),createdByActorId:ro(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at),state:r?"revoked":n<=t?"expired":"active"}}function MC(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:ro(e.operation_id),responseStatus:Number(e.response_status),responseBody:t,expiresAt:String(e.expires_at),createdAt:String(e.created_at)}}class Ge{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)
|
|
155
155
|
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?wl(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?wl(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(wl).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((k)=>!yh.has(k)))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 k of n)if(!re({membership:r,grants:this.controlPlane.listGrants(r.id),capability:k,target:o}).allowed)throw Error(`Service-account membership does not grant ${k} at the token scope`);let s=e.expiresAt?new Date(e.expiresAt):new Date(this.nowFn().getTime()+bh);if(!Number.isFinite(s.getTime())||s.getTime()<=this.nowFn().getTime()+60000||s.getTime()>this.nowFn().getTime()+Sh)throw Error("API token expiry must be between one minute and one year from now");let c=this.idFn(),u=OC(32).toString("base64url"),a=`tsc_v1.${c}.${u}`,f=`tsc_v1.${c.slice(0,8)}`,C=this.now();return this.run(`INSERT INTO api_tokens (id, service_account_id, name, token_hash, token_prefix, capabilities, scope_type, scope_id,
|
|
156
156
|
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",hh(a),f,JSON.stringify(n.sort()),i.type,i.type==="organization"?null:i.id??null,s.toISOString(),e.rotatedFromTokenId??null,e.createdByActorId??null,C,C]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:e.createdByActorId,type:"api.token.created",payload:{serviceAccountId:t.id,tokenId:c,prefix:f,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?Il(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)=>Il(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],hh(e));if(!n)return;let i=Il(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 u=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 = ?",[u,t?.slice(0,128)??null,u,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?MC(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()+vh).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)
|
|
157
157
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,e.tokenId,e.key,e.requestHash,e.operationId??null,e.responseStatus,JSON.stringify(e.responseBody),i,n]),this.getIdempotency(e.tokenId,e.key)}purgeExpired(){let e=this.now(),t=this.controlPlane.database.run("DELETE FROM api_tokens WHERE (expires_at < ? OR revoked_at IS NOT NULL) AND created_at < ?",[e,new Date(this.nowFn().getTime()-2592000000).toISOString()]).changes,r=this.controlPlane.database.run("DELETE FROM api_idempotency_records WHERE expires_at < ?",[e]).changes;return{tokens:t,idempotency:r}}}import{createHash as jT}from"node:crypto";import{existsSync as ao,mkdtempSync as cp,readdirSync as cb,rmSync as gs,statSync as Sb}from"node:fs";import{readFile as Li,writeFile as ls}from"node:fs/promises";import{tmpdir as kd}from"node:os";import{dirname as UT,extname as Fa,join as Et,normalize as zT,relative as VT,resolve as qT,sep as GT}from"node:path";import{fileURLToPath as JT}from"node:url";class xa{region;client;constructor(e="us-east-1",t=new p){this.region=e;this.client=t}request(e,t){return this.client.request({service:"backup",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`CryoControllerFrontendService.${e}`},body:JSON.stringify(t)})}startBackupJob(e){return this.request("StartBackupJob",e)}describeBackupJob(e){return this.request("DescribeBackupJob",{BackupJobId:e})}startRestoreJob(e){return this.request("StartRestoreJob",e)}describeRestoreJob(e){return this.request("DescribeRestoreJob",{RestoreJobId:e})}deleteRecoveryPoint(e,t){return this.request("DeleteRecoveryPoint",{BackupVaultName:e,RecoveryPointArn:t})}}import{isIP as kh}from"node:net";var $C={every_minute:"* * * * *",every_five_minutes:"*/5 * * * *",hourly:"0 * * * *",daily:"0 0 * * *",weekly:"0 0 * * 0"},LC={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},wh={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function Ih(e){try{return new Intl.DateTimeFormat("en",{timeZone:e}).format(new Date),e}catch{throw Error(`Unknown schedule timezone: ${e}`)}}function id(e,t,r,n){let i=t[e.toUpperCase()]??Number(e);if(!Number.isInteger(i)||i<r||i>n)throw Error(`Schedule field value ${e} is outside ${r}-${n}.`);return i}function Qs(e,t,r,n={},i){if(e==="*"||e==="?")return;let o=new Set;for(let s of e.split(",")){let[c,u]=s.split("/"),a=u?id(u,{},1,r-t+1):1,f,C;if(c==="*")f=t,C=r;else if(c.includes("-")){let k=c.split("-");f=id(k[0],n,t,r),C=id(k[1],n,t,r)}else f=id(c,n,t,r),C=f;if(C<f)throw Error("Schedule ranges must be ascending.");for(let k=f;k<=C;k+=a)o.add(i?i(k):k===7&&r===7?0:k)}return o}function BC(e,t){let r=Object.fromEntries(new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"numeric",day:"numeric",weekday:"short",hour:"numeric",minute:"numeric",hourCycle:"h23"}).formatToParts(e).map((n)=>[n.type,n.value]));return{minute:Number(r.minute),hour:Number(r.hour),day:Number(r.day),month:Number(r.month),weekday:wh[r.weekday.toUpperCase()],year:Number(r.year),key:`${r.year}-${r.month}-${r.day} ${r.hour}:${r.minute}`}}function Ch(e){let r=(e.startsWith("cron(")?e.slice(5,-1).trim():e.trim()).split(/\s+/);if(r.length!==5&&r.length!==6)throw Error("Cron schedules require five standard fields or six EventBridge fields.");let[n,i,o,s,c,u]=r,a=r.length===6;return{minute:Qs(n,0,59),hour:Qs(i,0,23),day:Qs(o,1,31),month:Qs(s,1,12,LC),weekday:Qs(c,a?1:0,7,wh,a?(f)=>f===7?6:f-1:void 0),year:u?Qs(u,1970,2199):void 0,dayWildcard:o==="*"||o==="?",weekdayWildcard:c==="*"||c==="?"}}function FC(e,t){if(!((!t.minute||t.minute.has(e.minute))&&(!t.hour||t.hour.has(e.hour))&&(!t.month||t.month.has(e.month))&&(!t.year||t.year.has(e.year))))return!1;let n=!t.day||t.day.has(e.day),i=!t.weekday||t.weekday.has(e.weekday);return t.dayWildcard?i:t.weekdayWildcard?n:n||i}function Eh(e){let t=/^rate\(\s*(\d+)\s+(minute|minutes|hour|hours|day|days)\s*\)$/i.exec(e);if(!t)return;let r=Number(t[1]);if(r<1)throw Error("Rate amount must be positive.");return r*(t[2].toLowerCase().startsWith("minute")?60000:t[2].toLowerCase().startsWith("hour")?3600000:86400000)}function Ys(e){let t=e.trim(),r=$C[t.toLowerCase()]??t;if(!r)throw Error("Schedule expression is required.");let n=Eh(r);if(n){let i=n/60000;return{original:t,normalized:`rate(${i} minutes)`,kind:"rate",description:i%1440===0?`Every ${i/1440} day(s)`:i%60===0?`Every ${i/60} hour(s)`:`Every ${i} minute(s)`}}return Ch(r),{original:t,normalized:r.startsWith("cron(")?r:`cron(${r})`,kind:"cron",description:`Cron ${r.replace(/^cron\(|\)$/g,"")}`}}function dt(e,t,r=new Date,n=5){let i=Ys(e),o=Ih(t),s=Math.min(20,Math.max(1,n)),c=Eh(i.normalized);if(c)return Array.from({length:s},(D,W)=>new Date(r.getTime()+c*(W+1)).toISOString());let u=Ch(i.normalized),a=[],f=new Set,C=new Date(Math.floor(r.getTime()/60000)*60000+60000),k=0;while(a.length<s&&k<1100000){let D=BC(C,o);if(FC(D,u)&&!f.has(D.key))a.push(C.toISOString()),f.add(D.key);C=new Date(C.getTime()+60000),k++}if(a.length<s)throw Error("Schedule produced no runs within the bounded preview horizon.");return a}function ut(e,t="UTC",r=new Date,n=5){let i=Ys(e),o=dt(i.normalized,t,r,n),s=i.kind==="cron"?["Server cron and EventBridge use the same wall-clock preview; provider-specific extensions are retained only when supported."]:["Rate schedules use elapsed-time intervals and are not shifted by DST."];return{...i,timezone:Ih(t),nextRuns:o,capabilities:{server:i.kind==="cron",eventbridge:!0,notes:s}}}function oi(e){let t=Ys(e.expression),r=t.normalized.slice(5,-1).trim().split(/\s+/),n=t.kind==="cron"&&r.length===5;if(e.provider==="server")return{provider:"server",supported:n,features:{timezone:!0,flexibleWindow:!1,catchUp:!1,replaceOverlap:!1},notes:[t.kind==="rate"?"Server cron requires a cron expression; use an equivalent cron schedule.":r.length!==5?"EventBridge six-field cron extensions cannot be installed as server cron.":"Cron is reconciled through a root-owned ts-cloud entry.",e.missedRunPolicy==="catch_up"?"Catch-up is handled by the control plane, not cron.":"Missed runs are skipped by cron."]};if(e.provider==="eventbridge")return{provider:"eventbridge",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["Five-field cron is translated explicitly to EventBridge six-field syntax. Flexible windows are provider-native; overlap and catch-up remain control-plane policies."]};if(e.provider==="lambda")return{provider:"lambda",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["The schedule invokes one immutable Lambda target."]};return{provider:"platform",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!0,replaceOverlap:!0},notes:["The durable control-plane worker enforces all configured policies."]}}function jC(e){if(e.queues===!0)return[{queue:"default",processes:e.queueConcurrency??1}];if(!Array.isArray(e.queues))return[];return e.queues.map((t)=>{if(typeof t==="string")return{queue:t,processes:e.queueConcurrency??1};let[r,n]=Object.entries(t)[0]??["default",e.queueConcurrency??1];return{queue:r,processes:n}})}function Qr(e,t,r){let n=new Set,i=new Set,o=new Map(r.resources.map((C)=>[C.slug,C])),s=0,c=0;for(let[C,k]of Object.entries(t.sites??{})){let D=o.get(C);if(k.scheduler){let ee=`config:site:${C}:scheduler`;n.add(ee),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:D?.id,name:`${C} scheduler`,provider:"server",expression:"* * * * *",timezone:"UTC",flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:`scheduler:run:${C}`},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:300,enabled:!0,origin:"config",sourceKey:ee,observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),s++}let W=k,Y=Array.isArray(W.queues??W.workers)?W.queues??W.workers:[];for(let[ee,ne]of Y.entries()){let he=typeof ne==="string"?{queue:ne}:ne,te=String(he.queue??he.name??"default"),Pe=`config:site:${C}:worker:${ee}:${te}`;i.add(Pe),e.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:D?.id,name:`${C}:${te}`,provider:"systemd",queue:te,processes:Number(he.processes)||1,timeoutSeconds:Number(he.timeout)||60,restartPolicy:"always",target:{operationId:`worker:restart:${C}`,site:C},enabled:!0,origin:"config",sourceKey:Pe,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),c++}}let u=t.infrastructure?.compute?.backups;if(u?.enabled)n.add("config:platform:backup"),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:"Scheduled backup",provider:"server",expression:String(u.schedule??"0 2 * * *"),timezone:String(u.timezone??"UTC"),flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:"backup:run"},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:60},timeoutSeconds:3600,enabled:!0,origin:"config",sourceKey:"config:platform:backup",observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),s++;let a=t.environments?.[r.environment.slug]?.app;if(a){if(a.scheduler!=="off"){let C=`config:serverless:${r.environment.slug}:scheduler`;n.add(C),e.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name} serverless scheduler`,provider:"eventbridge",expression:"rate(1 minute)",timezone:"UTC",flexibleMinutes:0,target:{kind:"serverless_scheduler",action:"schedule:run"},payloadRefs:{},missedRunPolicy:a.scheduler==="sub-minute"?"catch_up":"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:a.cliTimeout??900,enabled:!0,origin:"config",sourceKey:C,observedState:{source:"cloud.config.ts",mode:a.scheduler??"on"},reconciliationStatus:"pending"}),s++}for(let{queue:C,processes:k}of jC(a)){let D=`config:serverless:${r.environment.slug}:worker:${C}`;i.add(D),e.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name}:${C}`,provider:"lambda",queue:C,processes:k,timeoutSeconds:a.queueTimeout??120,restartPolicy:"on_failure",target:{function:"queue",queue:C},enabled:!0,origin:"config",sourceKey:D,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),c++}}let f=0;for(let C of e.list(r.project.id,{environmentId:r.environment.id}).filter((k)=>k.origin==="config"&&k.sourceKey&&!n.has(k.sourceKey)))e.reconcile(C.id,"drifted",{...C.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),f++;for(let C of e.listWorkers(r.project.id,r.environment.id).filter((k)=>k.origin==="config"&&k.sourceKey&&!i.has(k.sourceKey)))e.reconcileWorker(C.id,"drifted",{...C.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),f++;return{jobs:s,workers:c,drifted:f}}class si{store;queue;constructor(e,t={}){this.store=e;this.queue=t.queue??new S(e.controlPlane)}enqueue(e,t){let r=new Date(t.scheduledFor??this.store.now()).toISOString(),n=`${e.id}:${t.trigger==="manual"?crypto.randomUUID():r}`,i=this.store.activeExecution(e.id);if(i&&e.overlapPolicy==="forbid")return this.store.createExecution({jobId:e.id,trigger:t.trigger,scheduledFor:r,idempotencyKey:n,status:"skipped",output:{reason:"overlap_forbidden",activeExecutionId:i.id}});if(i&&e.overlapPolicy==="replace"&&i.operationId)try{this.queue.requestCancellation(i.operationId,t.actorId)}catch{}let o=this.store.createExecution({jobId:e.id,trigger:t.trigger,scheduledFor:r,idempotencyKey:n,status:"queued",output:{semantics:"at_least_once"}});if(o.operationId)return o;let s=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:t.actorId,kind:"job.execute",input:{jobId:e.id,executionId:o.id},idempotencyKey:`job-execution:${o.id}`,lockKey:e.overlapPolicy==="allow"?`job-execution:${o.id}`:`job:${e.id}`,maxAttempts:e.retryPolicy.maxAttempts,timeoutSeconds:e.timeoutSeconds,retryClasses:["job_transient"],resumePolicy:"requeue"}).operation;return this.store.attachOperation(o.id,s.id)}tick(e=this.store.now()){let t=[];for(let r of this.store.due(e.toISOString())){let n=r.nextRunAt,i=dt(r.normalizedExpression,r.timezone,e,1)[0];if(r.missedRunPolicy==="catch_up"){let o=n,s=0;while(o<=e.toISOString()&&s<10)t.push(this.enqueue(r,{trigger:o===n?"scheduled":"catch_up",scheduledFor:o})),o=dt(r.normalizedExpression,r.timezone,new Date(o),1)[0],s++}else t.push(this.enqueue(r,{trigger:"scheduled",scheduledFor:n}));this.store.markScheduled(r.id,n,i)}return t}}function Th(e){return{"job.execute":async(r)=>{let n=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},i=e.store.get(String(n.jobId??"")),o=e.store.getExecution(String(n.executionId??""));if(!i||!o)throw Error("Scheduled job execution is no longer available.");e.store.transitionExecution(o.id,"running",{attempt:r.operation.attempt}),r.checkpoint("execute",`Running ${i.name} on ${i.provider}.`),r.log(`Trigger ${o.trigger}; scheduled for ${o.scheduledFor}; semantics at-least-once.`,{stream:"system"});let s=await e.executor(i,i.target,r);if(s.stdout)r.log(s.stdout,{stream:"stdout"});if(s.stderr)r.log(s.stderr,{stream:"stderr"});if(!s.ok){if(e.store.transitionExecution(o.id,r.operation.attempt>=i.retryPolicy.maxAttempts?"dead":"failed",{attempt:r.operation.attempt,error:s.stderr??"Job execution failed."}),s.retryable)throw new Ue(s.stderr??"Scheduled job failed transiently.","job_transient");throw Error(s.stderr??"Scheduled job failed.")}return e.store.transitionExecution(o.id,"succeeded",{attempt:r.operation.attempt,output:s.output??{}}),{jobId:i.id,executionId:o.id,provider:i.provider}}}}var Fr=(e)=>typeof e==="string"&&e?e:void 0,Ah=(e)=>Number(e)===1,ns=(e)=>{try{return JSON.parse(String(e))}catch{return{}}},xo=(e,t,r,n)=>{let i=Number(e);return Number.isFinite(i)?Math.min(n,Math.max(r,Math.floor(i))):t};function od(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:Fr(e.environment_id),resourceId:Fr(e.resource_id),name:String(e.name),provider:String(e.provider),expression:String(e.expression),normalizedExpression:String(e.normalized_expression),timezone:String(e.timezone),startsAt:Fr(e.starts_at),endsAt:Fr(e.ends_at),flexibleMinutes:Number(e.flexible_minutes),target:ns(e.target),payloadRefs:ns(e.payload_refs),missedRunPolicy:String(e.missed_run_policy),overlapPolicy:String(e.overlap_policy),retryPolicy:ns(e.retry_policy),timeoutSeconds:Number(e.timeout_seconds),enabled:Ah(e.enabled),origin:String(e.origin),sourceKey:Fr(e.source_key),ownerActorId:Fr(e.owner_actor_id),observedState:ns(e.observed_state),reconciliationStatus:String(e.reconciliation_status),nextRunAt:Fr(e.next_run_at),lastScheduledFor:Fr(e.last_scheduled_for),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function sd(e){return{id:String(e.id),jobId:String(e.job_id),operationId:Fr(e.operation_id),trigger:String(e.trigger),scheduledFor:String(e.scheduled_for),idempotencyKey:String(e.idempotency_key),status:String(e.status),attempt:Number(e.attempt),startedAt:Fr(e.started_at),finishedAt:Fr(e.finished_at),output:ns(e.output),error:Fr(e.error),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Cl(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:Fr(e.environment_id),resourceId:Fr(e.resource_id),name:String(e.name),provider:String(e.provider),queue:String(e.queue),processes:Number(e.processes),timeoutSeconds:Number(e.timeout_seconds),restartPolicy:String(e.restart_policy),target:ns(e.target),enabled:Ah(e.enabled),origin:String(e.origin),sourceKey:Fr(e.source_key),ownerActorId:Fr(e.owner_actor_id),observedState:ns(e.observed_state),reconciliationStatus:String(e.reconciliation_status),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class Yr{controlPlane;options;constructor(e,t={}){this.controlPlane=e;this.options=t}now(){return this.options.now?.()??new Date}create(e){if(!e.name.trim())throw Error("Scheduled jobs require a name.");let t=ut(e.expression,e.timezone,this.now(),1),r=crypto.randomUUID(),n=this.now().toISOString(),i=e.startsAt?new Date(e.startsAt).toISOString():void 0,o=e.endsAt?new Date(e.endsAt).toISOString():void 0;if(i&&o&&i>=o)throw Error("Schedule start must be before end.");let s=t.nextRuns.find((c)=>(!i||c>=i)&&(!o||c<=o));return this.controlPlane.database.run("INSERT INTO scheduled_jobs (id,organization_id,project_id,environment_id,resource_id,name,provider,expression,normalized_expression,timezone,starts_at,ends_at,flexible_minutes,target,payload_refs,missed_run_policy,overlap_policy,retry_policy,timeout_seconds,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,next_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name.trim().slice(0,120),e.provider,e.expression,t.normalized,e.timezone,i??null,o??null,xo(e.flexibleMinutes,0,0,1440),JSON.stringify(e.target),JSON.stringify(e.payloadRefs),e.missedRunPolicy,e.overlapPolicy,JSON.stringify({maxAttempts:xo(e.retryPolicy.maxAttempts,3,1,20),backoffSeconds:xo(e.retryPolicy.backoffSeconds,30,0,86400),deadLetterRef:e.retryPolicy.deadLetterRef}),xo(e.timeoutSeconds,900,1,86400),e.enabled?1:0,e.origin,e.sourceKey??null,e.ownerActorId??null,JSON.stringify(e.observedState),e.reconciliationStatus,s??null,1,n,n]),this.get(r)}get(e){let t=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE id=?").get(e);return t?od(t):void 0}getBySource(e,t,r){let n=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE project_id=? AND environment_id IS ? AND source_key=?").get(e,t??null,r);return n?od(n):void 0}list(e,t={}){let r=["project_id=?"],n=[e];if(t.environmentId)r.push("environment_id=?"),n.push(t.environmentId);if(t.resourceIds?.length)r.push(`resource_id IN (${t.resourceIds.map(()=>"?").join(",")})`),n.push(...t.resourceIds);if(t.enabled!=null)r.push("enabled=?"),n.push(t.enabled?1:0);return this.controlPlane.database.query(`SELECT * FROM scheduled_jobs WHERE ${r.join(" AND ")} ORDER BY next_run_at IS NULL,next_run_at,name`).all(...n).map(od)}setEnabled(e,t){this.controlPlane.database.run("UPDATE scheduled_jobs SET enabled=?,version=version+1,updated_at=? WHERE id=?",[t?1:0,this.now().toISOString(),e]);let r=this.get(e);if(!r)throw Error("Scheduled job was not found.");return r}updateSchedule(e,t){let r=this.get(e);if(!r)throw Error("Scheduled job was not found.");let n=t.expression??r.expression,i=t.timezone??r.timezone,o=ut(n,i,this.now(),1),s=this.now().toISOString();return this.controlPlane.database.run("UPDATE scheduled_jobs SET expression=?,normalized_expression=?,timezone=?,missed_run_policy=?,overlap_policy=?,timeout_seconds=?,next_run_at=?,reconciliation_status=?,version=version+1,updated_at=? WHERE id=?",[n,o.normalized,i,t.missedRunPolicy??r.missedRunPolicy,t.overlapPolicy??r.overlapPolicy,xo(t.timeoutSeconds,r.timeoutSeconds,1,86400),o.nextRuns[0],"pending",s,e]),this.get(e)}remove(e){let t=this.get(e);if(!t)throw Error("Scheduled job was not found.");if(t.origin==="config")throw Error("Config-defined jobs must be removed from configuration, not destructively deleted.");this.controlPlane.database.run("DELETE FROM scheduled_jobs WHERE id=?",[e])}markScheduled(e,t,r){this.controlPlane.database.run("UPDATE scheduled_jobs SET last_scheduled_for=?,next_run_at=?,updated_at=? WHERE id=?",[t,r??null,this.now().toISOString(),e])}reconcile(e,t,r){return this.controlPlane.database.run("UPDATE scheduled_jobs SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[t,JSON.stringify(r),this.now().toISOString(),e]),this.get(e)}upsertConfigJob(e){let t=this.getBySource(e.projectId,e.environmentId,e.sourceKey);if(!t)return this.create(e);let r=ut(e.expression,e.timezone,this.now(),1),n=this.now().toISOString();if(t.resourceId===e.resourceId&&t.name===e.name&&t.provider===e.provider&&t.expression===e.expression&&t.normalizedExpression===r.normalized&&t.timezone===e.timezone&&JSON.stringify(t.target)===JSON.stringify(e.target)&&JSON.stringify(t.payloadRefs)===JSON.stringify(e.payloadRefs)&&t.missedRunPolicy===e.missedRunPolicy&&t.overlapPolicy===e.overlapPolicy&&JSON.stringify(t.retryPolicy)===JSON.stringify(e.retryPolicy)&&t.timeoutSeconds===e.timeoutSeconds&&t.enabled===e.enabled)return t;return this.controlPlane.database.run("UPDATE scheduled_jobs SET resource_id=?,name=?,provider=?,expression=?,normalized_expression=?,timezone=?,target=?,payload_refs=?,missed_run_policy=?,overlap_policy=?,retry_policy=?,timeout_seconds=?,enabled=?,observed_state=?,reconciliation_status=?,next_run_at=COALESCE(next_run_at,?),version=version+1,updated_at=? WHERE id=?",[e.resourceId??null,e.name,e.provider,e.expression,r.normalized,e.timezone,JSON.stringify(e.target),JSON.stringify(e.payloadRefs),e.missedRunPolicy,e.overlapPolicy,JSON.stringify(e.retryPolicy),e.timeoutSeconds,e.enabled?1:0,JSON.stringify(e.observedState),e.reconciliationStatus,r.nextRuns[0],n,t.id]),this.get(t.id)}due(e=this.now().toISOString()){return this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE enabled=1 AND next_run_at IS NOT NULL AND next_run_at<=? AND (starts_at IS NULL OR starts_at<=?) AND (ends_at IS NULL OR ends_at>=?) ORDER BY next_run_at LIMIT 200").all(e,e,e).map(od)}createExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE idempotency_key=?").get(e.idempotencyKey);if(t)return sd(t);let r=crypto.randomUUID(),n=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO job_executions (id,job_id,operation_id,trigger,scheduled_for,idempotency_key,status,attempt,output,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)",[r,e.jobId,e.operationId??null,e.trigger,e.scheduledFor,e.idempotencyKey,e.status,0,JSON.stringify(e.output),n,n]),this.getExecution(r)}getExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE id=?").get(e);return t?sd(t):void 0}listExecutions(e,t=100){return this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? ORDER BY scheduled_for DESC,created_at DESC LIMIT ?").all(e,Math.min(1000,Math.max(1,t))).map(sd)}activeExecution(e){let t=this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? AND status IN ('queued','running') ORDER BY created_at DESC LIMIT 1").get(e);return t?sd(t):void 0}attachOperation(e,t){return this.controlPlane.database.run("UPDATE job_executions SET operation_id=?,updated_at=? WHERE id=?",[t,this.now().toISOString(),e]),this.getExecution(e)}transitionExecution(e,t,r={}){let n=this.now().toISOString(),i=t==="running"?n:null,o=["succeeded","failed","skipped","dead"].includes(t)?n:null;return this.controlPlane.database.run("UPDATE job_executions SET status=?,attempt=COALESCE(?,attempt),started_at=COALESCE(started_at,?),finished_at=?,output=COALESCE(?,output),error=?,updated_at=? WHERE id=?",[t,r.attempt??null,i,o,r.output?JSON.stringify(r.output):null,r.error?.slice(0,2000)??null,n,e]),this.getExecution(e)}upsertWorker(e){let t=e.sourceKey?this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE project_id=? AND source_key=? AND environment_id IS ?").get(e.projectId,e.sourceKey,e.environmentId??null):void 0,r=t?Cl(t):void 0,n=r?.id??crypto.randomUUID(),i=this.now().toISOString(),o=xo(e.processes,1,0,1000),s=xo(e.timeoutSeconds,60,1,86400);if(r&&r.resourceId===e.resourceId&&r.name===e.name.slice(0,120)&&r.provider===e.provider&&r.queue===e.queue.slice(0,200)&&r.processes===o&&r.timeoutSeconds===s&&r.restartPolicy===e.restartPolicy&&JSON.stringify(r.target)===JSON.stringify(e.target)&&r.enabled===e.enabled)return r;return this.controlPlane.database.run("INSERT INTO worker_definitions (id,organization_id,project_id,environment_id,resource_id,name,provider,queue,processes,timeout_seconds,restart_policy,target,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET name=excluded.name,resource_id=excluded.resource_id,provider=excluded.provider,queue=excluded.queue,processes=excluded.processes,timeout_seconds=excluded.timeout_seconds,restart_policy=excluded.restart_policy,target=excluded.target,enabled=excluded.enabled,observed_state=excluded.observed_state,reconciliation_status=excluded.reconciliation_status,version=worker_definitions.version+1,updated_at=excluded.updated_at",[n,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name.slice(0,120),e.provider,e.queue.slice(0,200),o,s,e.restartPolicy,JSON.stringify(e.target),e.enabled?1:0,e.origin,e.sourceKey??null,e.ownerActorId??null,JSON.stringify(e.observedState),e.reconciliationStatus,1,r?.createdAt??i,i]),this.getWorker(n)}getWorker(e){let t=this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE id=?").get(e);return t?Cl(t):void 0}listWorkers(e,t){return this.controlPlane.database.query(`SELECT * FROM worker_definitions WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(Cl)}setWorkerProcesses(e,t){this.controlPlane.database.run("UPDATE worker_definitions SET processes=?,reconciliation_status='pending',version=version+1,updated_at=? WHERE id=?",[xo(t,1,0,1000),this.now().toISOString(),e]);let r=this.getWorker(e);if(!r)throw Error("Worker was not found.");return r}reconcileWorker(e,t,r){this.controlPlane.database.run("UPDATE worker_definitions SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[t,JSON.stringify(r),this.now().toISOString(),e]);let n=this.getWorker(e);if(!n)throw Error("Worker was not found.");return n}}var pt=(e)=>e==null?void 0:String(e),ad=(e)=>Number(e)===1,Oo=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}};function Rh(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),name:String(e.name),provider:String(e.provider),endpoint:pt(e.endpoint),endpointPolicy:String(e.endpoint_policy),bucket:pt(e.bucket),prefix:String(e.prefix),region:pt(e.region),forcePathStyle:ad(e.force_path_style),credentialRef:pt(e.credential_ref),encryption:String(e.encryption),encryptionKeyRef:pt(e.encryption_key_ref),immutability:Oo(e.immutability,{}),status:String(e.status),lastTestedAt:pt(e.last_tested_at),lastSuccessAt:pt(e.last_success_at),lastFailureAt:pt(e.last_failure_at),lastError:pt(e.last_error),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function El(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:pt(e.environment_id),resourceId:pt(e.resource_id),dataServiceId:pt(e.data_service_id),destinationId:String(e.destination_id),name:String(e.name),resourceKind:String(e.resource_kind),schedule:String(e.schedule),timezone:String(e.timezone),retention:Oo(e.retention,{}),compression:String(e.compression),encryption:String(e.encryption),includePatterns:Oo(e.include_patterns,[]),excludePatterns:Oo(e.exclude_patterns,[]),expectedRpoMinutes:Number(e.expected_rpo_minutes),expectedRtoMinutes:Number(e.expected_rto_minutes),healthCheckId:pt(e.health_check_id),enabled:ad(e.enabled),nextRunAt:pt(e.next_run_at),lastRunAt:pt(e.last_run_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Tl(e){return{id:String(e.id),projectId:String(e.project_id),policyId:pt(e.policy_id),destinationId:String(e.destination_id),resourceId:pt(e.resource_id),dataServiceId:pt(e.data_service_id),backupJobId:pt(e.backup_job_id),kind:String(e.kind),pointInTime:String(e.point_in_time),uri:String(e.uri),sizeBytes:Number(e.size_bytes),checksum:String(e.checksum),manifest:Oo(e.manifest,{}),toolVersion:pt(e.tool_version),engineVersion:pt(e.engine_version),expiresAt:pt(e.expires_at),lockedUntil:pt(e.locked_until),held:ad(e.held),pinned:ad(e.pinned),status:String(e.status),verificationState:String(e.verification_state),verifiedAt:pt(e.verified_at),durationMs:e.duration_ms==null?void 0:Number(e.duration_ms),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Al(e){return{id:String(e.id),projectId:String(e.project_id),policyId:pt(e.policy_id),recoveryPointId:pt(e.recovery_point_id),operationId:pt(e.operation_id),kind:String(e.kind),status:String(e.status),idempotencyKey:String(e.idempotency_key),target:Oo(e.target,{}),restoreMode:pt(e.restore_mode),cancellability:String(e.cancellability),safetyBackupId:pt(e.safety_backup_id),healthResult:e.health_result?Oo(e.health_result,{}):void 0,progress:Oo(e.progress,{}),error:pt(e.error),startedAt:pt(e.started_at),finishedAt:pt(e.finished_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function UC(e){let t=e.toLowerCase();if(t==="localhost"||t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".internal"))return!0;if(kh(t)===6)return t==="::1"||t.startsWith("fe80:");if(kh(t)!==4)return!1;let[r,n]=t.split(".").map(Number);return r===10||r===127||r===0||r===169&&n===254||r===172&&n>=16&&n<=31||r===192&&n===168}function zC(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Backup destination names must be 2-63 lowercase letters, numbers, or dashes.");if(e.provider!=="aws_backup"&&!e.bucket)throw Error("S3 backup destinations require a bucket.");if(e.provider==="s3_compatible"&&!e.endpoint)throw Error("S3-compatible destinations require an explicit endpoint.");if(e.provider==="s3_compatible"&&!e.credentialRef)throw Error("S3-compatible destinations require a credential reference.");if(e.encryption!=="provider"&&!e.encryptionKeyRef)throw Error("Client-side encryption requires an encryption key reference.");if(e.endpoint){let t=new URL(e.endpoint);if(t.protocol!=="https:"||t.username||t.password||t.search||t.hash||t.pathname!=="/")throw Error("Backup endpoints must be origin-only HTTPS URLs without credentials, paths, queries, or fragments.");if(UC(t.hostname)&&e.endpointPolicy!=="allow_private")throw Error("Private backup endpoints require endpointPolicy allow_private.")}}class ai{controlPlane;now;constructor(e,t=()=>new Date){this.controlPlane=e;this.now=t}createDestination(e){zC(e);let t=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_destinations (id,organization_id,project_id,name,provider,endpoint,endpoint_policy,bucket,prefix,region,force_path_style,credential_ref,encryption,encryption_key_ref,immutability,status,last_tested_at,last_success_at,last_failure_at,last_error,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.organizationId,e.projectId,e.name,e.provider,e.endpoint??null,e.endpointPolicy,e.bucket??null,e.prefix,e.region??null,e.forcePathStyle?1:0,e.credentialRef??null,e.encryption,e.encryptionKeyRef??null,JSON.stringify(e.immutability),e.status,e.lastTestedAt??null,e.lastSuccessAt??null,e.lastFailureAt??null,e.lastError??null,1,r,r]),this.getDestination(t)}getDestination(e){let t=this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE id=?").get(e);return t?Rh(t):void 0}listDestinations(e){return this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE project_id=? ORDER BY name").all(e).map(Rh)}recordDestinationTest(e,t){let r=this.now().toISOString();return this.controlPlane.database.run("UPDATE backup_destinations SET status=?,last_tested_at=?,last_success_at=CASE WHEN ? THEN ? ELSE last_success_at END,last_failure_at=CASE WHEN ? THEN last_failure_at ELSE ? END,last_error=?,version=version+1,updated_at=? WHERE id=?",[t.ok?"healthy":"failing",r,t.ok?1:0,r,t.ok?1:0,r,t.ok?null:String(t.error??"Destination test failed.").slice(0,1000),r,e]),this.getDestination(e)}createPolicy(e){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(e.name))throw Error("Backup policy names must be lowercase slugs.");if(!e.resourceId&&!e.dataServiceId&&!["control_plane","infrastructure"].includes(e.resourceKind))throw Error("A backup policy requires a resource or data service target.");let t=this.getDestination(e.destinationId);if(!t||t.projectId!==e.projectId)throw Error("Backup destination was not found.");if(e.resourceKind==="control_plane"&&t.encryption==="provider")throw Error("Control-plane backups require client-side destination encryption.");if(["logical_database","volume","files","control_plane"].includes(e.resourceKind)&&t.provider==="aws_backup")throw Error(`${e.resourceKind} backups require an object-storage destination.`);if(e.resourceKind==="infrastructure"&&t.provider!=="aws_backup")throw Error("Infrastructure backups require an AWS Backup destination.");let r=Ys(e.schedule),n=dt(r.normalized,e.timezone,this.now(),1)[0],i=crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_policies (id,organization_id,project_id,environment_id,resource_id,data_service_id,destination_id,name,resource_kind,schedule,timezone,retention,compression,encryption,include_patterns,exclude_patterns,expected_rpo_minutes,expected_rto_minutes,health_check_id,enabled,next_run_at,last_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[i,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.dataServiceId??null,e.destinationId,e.name,e.resourceKind,r.normalized,e.timezone,JSON.stringify(e.retention),e.compression,e.encryption,JSON.stringify(e.includePatterns),JSON.stringify(e.excludePatterns),e.expectedRpoMinutes,e.expectedRtoMinutes,e.healthCheckId??null,e.enabled?1:0,n,e.lastRunAt??null,1,o,o]),this.getPolicy(i)}getPolicy(e){let t=this.controlPlane.database.query("SELECT * FROM backup_policies WHERE id=?").get(e);return t?El(t):void 0}listPolicies(e,t){return this.controlPlane.database.query(`SELECT * FROM backup_policies WHERE project_id=?${t?" AND environment_id=?":""} ORDER BY name`).all(e,...t?[t]:[]).map(El)}duePolicies(e=this.now()){return this.controlPlane.database.query("SELECT * FROM backup_policies WHERE enabled=1 AND next_run_at<=? ORDER BY next_run_at,id").all(e.toISOString()).map(El)}advancePolicy(e,t){let r=this.getPolicy(e);if(!r)throw Error("Backup policy was not found.");let n=dt(r.schedule,r.timezone,new Date(t),1)[0];return this.controlPlane.database.run("UPDATE backup_policies SET last_run_at=?,next_run_at=?,version=version+1,updated_at=? WHERE id=?",[t,n,this.now().toISOString(),e]),this.getPolicy(e)}createJob(e){let t=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE idempotency_key=?").get(e.idempotencyKey);if(t)return Al(t);let r=crypto.randomUUID(),n=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_jobs (id,project_id,policy_id,recovery_point_id,operation_id,kind,status,idempotency_key,target,restore_mode,cancellability,safety_backup_id,health_result,progress,error,started_at,finished_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.projectId,e.policyId??null,e.recoveryPointId??null,e.operationId??null,e.kind,e.status,e.idempotencyKey,JSON.stringify(e.target),e.restoreMode??null,e.cancellability,e.safetyBackupId??null,e.healthResult?JSON.stringify(e.healthResult):null,JSON.stringify(e.progress),e.error??null,e.startedAt??null,e.finishedAt??null,n,n]),this.getJob(r)}getJob(e){let t=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE id=?").get(e);return t?Al(t):void 0}listJobs(e){return this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE project_id=? ORDER BY created_at DESC").all(e).map(Al)}updateJob(e,t){let r=this.getJob(e);if(!r)throw Error("Backup job was not found.");let n={...r,...t};return this.controlPlane.database.run("UPDATE backup_jobs SET status=?,operation_id=?,recovery_point_id=?,progress=?,health_result=?,error=?,started_at=?,finished_at=?,safety_backup_id=?,updated_at=? WHERE id=?",[n.status,n.operationId??null,n.recoveryPointId??null,JSON.stringify(n.progress),n.healthResult?JSON.stringify(n.healthResult):null,n.error??null,n.startedAt??null,n.finishedAt??null,n.safetyBackupId??null,this.now().toISOString(),e]),this.getJob(e)}createRecoveryPoint(e){if(!/^sha256:[a-f0-9]{64}$/i.test(e.checksum))throw Error("Recovery points require a SHA-256 checksum.");if(typeof e.uri!=="string"||!["s3:","aws-backup:","file:"].some((n)=>e.uri.startsWith(n)))throw Error("Recovery point URI uses an unsupported destination scheme.");let t=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO recovery_points (id,project_id,policy_id,destination_id,resource_id,data_service_id,backup_job_id,kind,point_in_time,uri,size_bytes,checksum,manifest,tool_version,engine_version,expires_at,locked_until,held,pinned,status,verification_state,verified_at,duration_ms,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.projectId,e.policyId??null,e.destinationId,e.resourceId??null,e.dataServiceId??null,e.backupJobId??null,e.kind,e.pointInTime,e.uri,e.sizeBytes,e.checksum,JSON.stringify(e.manifest),e.toolVersion??null,e.engineVersion??null,e.expiresAt??null,e.lockedUntil??null,e.held?1:0,e.pinned?1:0,e.status,e.verificationState,e.verifiedAt??null,e.durationMs??null,r,r]),this.getRecoveryPoint(t)}getRecoveryPoint(e){let t=this.controlPlane.database.query("SELECT * FROM recovery_points WHERE id=?").get(e);return t?Tl(t):void 0}listRecoveryPoints(e,t){return this.controlPlane.database.query(`SELECT * FROM recovery_points WHERE project_id=?${t?" AND policy_id=?":""} ORDER BY point_in_time DESC`).all(e,...t?[t]:[]).map(Tl)}updateRecoveryPoint(e,t){let r=this.getRecoveryPoint(e);if(!r)throw Error("Recovery point was not found.");let n={...r,...t};return this.controlPlane.database.run("UPDATE recovery_points SET status=?,verification_state=?,verified_at=?,held=?,pinned=?,manifest=?,duration_ms=?,updated_at=? WHERE id=?",[n.status,n.verificationState,n.verifiedAt??null,n.held?1:0,n.pinned?1:0,JSON.stringify(n.manifest),n.durationMs??null,this.now().toISOString(),e]),this.getRecoveryPoint(e)}retentionCandidates(e=this.now()){let t=this.controlPlane.database.query(`SELECT rp.* FROM recovery_points rp
|
|
@@ -167,9 +167,9 @@ data: ${JSON.stringify(rt)}
|
|
|
167
167
|
`)){if(!r.startsWith("TSCLOUD_SYSTEMD\t"))continue;let[,n,i,o,s,c,u,a,f,C,k,D,W,Y]=r.split("\t");if(!n||!/^[A-Za-z0-9_.@:-]+\.service$/.test(n))continue;t.push({unit:n,load:i,active:o,sub:s,description:c,enabled:u,pid:Number(a)||void 0,memoryBytes:qh(f),restartCount:Number(C)||0,activeSince:k||void 0,fragmentPath:D||void 0,workingDirectory:W?.startsWith("/")?W:void 0,user:Y||void 0})}return t}function IE(e,t,r=t.server??"local"){let n=t.now??new Date;return e.map((i)=>{let o=so(i.active==="active"?i.sub||i.active:i.active),s=i.unit.replace(/\.service$/,""),c=/^(.*?) (?:release [^ ]+|queue worker|daemon |scheduler)(?: |$)/.exec(i.description??"")?.[1]??(t.project&&s.startsWith(`${t.project}-`)?s.slice(t.project.length+1).split("@",1)[0]:void 0),u=s.includes("@")?s.slice(s.indexOf("@")+1):void 0,a=i.workingDirectory?[{target:i.workingDirectory,type:"working-directory"}]:[],f=["start","stop","restart","logs","exec","inspect",...a.length?["files"]:[]];return{id:$i("systemd",r,i.unit),provider:"systemd",kind:"service",name:s,displayName:i.description||s,status:o,rawStatus:[i.load,i.active,i.sub].filter(Boolean).join("/"),health:o==="running"?"healthy":o==="failed"?"unhealthy":"unknown",desiredReplicas:1,runningReplicas:o==="running"?1:0,ageSeconds:ds(i.activeSince,n),restartCount:i.restartCount,tags:{enabled:i.enabled??"unknown"},links:{project:t.project,environment:t.environment,server:t.server??r.replace(/^systemd:/,""),service:c,release:u,providerId:i.unit},resources:{memoryBytes:i.memoryBytes},replicas:[{id:$i("systemd",r,`${i.unit}:main`),name:"main",status:o,pid:i.pid,startedAt:i.activeSince,restartCount:i.restartCount,resources:{memoryBytes:i.memoryBytes}}],networks:[],mounts:a,capabilities:cs(f,a.length?"This systemd runtime does not support redeploy or replica scaling through the scoped explorer":"File transfer requires a provider-reported service working directory; redeploy and scaling are unavailable"),config:oo({fragmentPath:i.fragmentPath,workingDirectory:i.workingDirectory,user:i.user,environment:i.environment,enabled:i.enabled}),discoveredAt:n.toISOString(),sourceId:r}})}class jl{read;id;provider="systemd";constructor(e,t="systemd:local"){this.read=e;this.id=t}async discover(e){return IE(wE(await this.read(e)),e,this.id)}}function CE(e,t){if(!e.success)throw Error(e.error||e.perInstance?.[0]?.error||`${t} discovery failed`);return e.perInstance?.[0]?.output??""}function EE(){return["set -uo pipefail",'command -v systemctl >/dev/null 2>&1 || { echo "systemctl is unavailable" >&2; exit 127; }',"systemctl list-units --type=service --all --plain --no-legend 2>/dev/null | awk '{print $1}' | while IFS= read -r unit; do",' [ -n "$unit" ] || continue',' clean() { printf "%s" "$1" | tr "\\t\\r\\n" " "; }',' load=$(systemctl show "$unit" -p LoadState --value 2>/dev/null || true)',' active=$(systemctl show "$unit" -p ActiveState --value 2>/dev/null || true)',' sub=$(systemctl show "$unit" -p SubState --value 2>/dev/null || true)',' description=$(systemctl show "$unit" -p Description --value 2>/dev/null || true)',' enabled=$(systemctl is-enabled "$unit" 2>/dev/null || true)',' pid=$(systemctl show "$unit" -p MainPID --value 2>/dev/null || true)',' memory=$(systemctl show "$unit" -p MemoryCurrent --value 2>/dev/null || true)',' restarts=$(systemctl show "$unit" -p NRestarts --value 2>/dev/null || true)',' since=$(systemctl show "$unit" -p ActiveEnterTimestamp --value 2>/dev/null || true)',' fragment=$(systemctl show "$unit" -p FragmentPath --value 2>/dev/null || true)',' working=$(systemctl show "$unit" -p WorkingDirectory --value 2>/dev/null || true)',' user=$(systemctl show "$unit" -p User --value 2>/dev/null || true)',' printf "TSCLOUD_SYSTEMD\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\n" "$(clean "$unit")" "$(clean "$load")" "$(clean "$active")" "$(clean "$sub")" "$(clean "$description")" "$(clean "$enabled")" "$(clean "$pid")" "$(clean "$memory")" "$(clean "$restarts")" "$(clean "$since")" "$(clean "$fragment")" "$(clean "$working")" "$(clean "$user")"',"done"]}function TE(){return["set -uo pipefail",'if ! command -v docker >/dev/null 2>&1; then echo "[]"; exit 0; fi',"ids=$(docker ps -aq)",'if [ -z "$ids" ]; then echo "[]"; else docker inspect $ids; fi']}function Xh(e,t,r,n,i){let o=`${e}:${r.id}`,s=async()=>CE(await t.runRemoteDeploy({targets:[r],commands:e==="systemd"?EE():TE(),timeoutSeconds:30,comment:`ts-cloud runtime discovery:${e}`,tags:{Project:n.project.slug,Environment:i,Role:"app"}}),o);return e==="systemd"?new jl(s,o):new Fl(s,o)}async function pd(e,t=100){let r=[],n;for(let i=0;i<t;i++){let o=await e(n);if(r.push(...o.items),!o.nextToken)return r;n=o.nextToken}throw Error(`Provider pagination exceeded ${t} pages`)}class Zh{client;prefix;id="ecs:aws";provider="ecs";constructor(e,t){this.client=e;this.prefix=t}async discover(e){let t=await pd(async(o)=>{let s=await this.client.listClusters({nextToken:o,maxResults:100});return{items:s.clusterArns??[],nextToken:s.nextToken}}),r=[],n=[],i=[];for(let o of t){let s=(await pd(async(c)=>{let u=await this.client.listServices(o,{nextToken:c,maxResults:100});return{items:u.serviceArns??[],nextToken:u.nextToken}})).filter((c)=>c.split("/").at(-1)?.startsWith(this.prefix));for(let c=0;c<s.length;c+=10){let u=await this.client.describeServices({cluster:o,services:s.slice(c,c+10)});r.push(...u.services??[])}for(let c of r.filter((u)=>u.clusterArn===o||!u.clusterArn)){let u=await pd(async(a)=>{let f=await this.client.listTasks(o,c.serviceName,{nextToken:a,maxResults:100});return{items:f.taskArns??[],nextToken:f.nextToken}});for(let a=0;a<u.length;a+=100){let f=await this.client.describeTasks(o,u.slice(a,a+100));n.push(...f.tasks??[])}}}if(this.client.describeTaskDefinition)for(let o of[...new Set(r.map((s)=>s.taskDefinition).filter((s)=>!!s))]){let s=await this.client.describeTaskDefinition(o);if(s.taskDefinition)i.push(s.taskDefinition)}return Qh(r,n,e,this.id,i)}}class ey{client;prefix;id="lambda:aws";provider="lambda";constructor(e,t){this.client=e;this.prefix=t}async discover(e){let t=(await pd(async(r)=>{let n=await this.client.listFunctions({Marker:r,MaxItems:50});return{items:n.Functions??[],nextToken:n.NextMarker}})).filter((r)=>r.FunctionName?.startsWith(this.prefix));return Yh(t,e,this.id)}}async function AE(e,t,r={}){let n=[],i=H(e),o=B(e),s=e.aws?.profile,c=e.aws?.region??e.project.region??"us-east-1",u=`${e.project.slug}-${t}`;if(i!=="serverless"){let a=r.driver??_({config:e}),f=await a.findComputeTargets({slug:e.project.slug,environment:t,role:"app"});for(let C of f)n.push(Xh("systemd",a,C,e,t)),n.push(Xh("docker",a,C,e,t))}if(o==="aws")n.push(new Zh(r.ecs??new _t(c,s),u)),n.push(new ey(r.lambda??new P(c,s),u));return n}async function wi(e,t,r={}){let n={project:e.project.slug,environment:t};try{return await Gh(await AE(e,t,r),n)}catch(i){return{generatedAt:new Date().toISOString(),workloads:[],sources:[{id:"runtime:bootstrap",provider:B(e)==="aws"?"ecs":"systemd",status:"error",discoveredAt:new Date().toISOString(),staleAfterSeconds:60,itemCount:0,message:String(i?.message??i).slice(0,500)}],degraded:!0}}}var ty=65536,Oa=49152,md=/^[A-Za-z0-9_.@:-]+\.service$/,fd=/^[a-fA-F0-9]{12,128}$/,kE=["/boot","/dev","/etc","/proc","/root","/run","/sys","/var/run"];function ea(e){let t=Buffer.from(e);return t.byteLength<=ty?e:`${t.subarray(0,ty-24).toString("utf8")}
|
|
168
168
|
[output truncated]`}function gd(e){return{success:!1,instanceCount:0,perInstance:[],error:e instanceof Error?e.message:String(e)}}function Dn(e){return`'${e.replaceAll("'",`'"'"'`)}'`}function RE(e,t){return Number.isFinite(e)?Math.min(1e4,Math.max(0,Math.floor(e))):t}function PE(e){let t=e.config,r=typeof t.clusterArn==="string"?t.clusterArn:void 0,n=e.links.providerId||e.name;return r&&n?{cluster:r,service:n}:void 0}function xE(e,t){return e.find((r)=>r.id===t.links.server)??(e.length===1?e[0]:void 0)}function DE(e,t){if(e.provider==="systemd"){let r=e.links.providerId;if(!r||!md.test(r)||!["start","stop","restart"].includes(t))return;return[`systemctl ${t} ${r}`,`systemctl is-active ${r} 2>/dev/null || true`]}if(e.provider==="docker"){let r=e.links.providerId;if(!r||!fd.test(r)||!["start","stop","restart"].includes(t))return;return[`docker ${t} ${r}`,`docker inspect --format '{{.State.Status}}' ${r}`]}return}function OE(e,t){if(!t.startsWith("/")||t.includes("\x00"))return{ok:!1,error:"An absolute path is required."};let r=[];for(let c of t.split("/")){if(!c||c===".")continue;if(c===".."){if(!r.length)return{ok:!1,error:"Path traversal is not allowed."};r.pop()}else r.push(c)}let n=`/${r.join("/")}`;if(kE.some((c)=>n===c||n.startsWith(`${c}/`)))return{ok:!1,error:"Sensitive host paths are not available through runtime file access."};let i=e.links.project?.replace(/[^A-Za-z0-9_-]/g,""),o=e.links.service?.replace(/[^A-Za-z0-9_-]/g,"");if(![...i&&o?[`/var/www/${i}/${o}`,`/srv/${i}/${o}`]:[],...e.mounts.map((c)=>c.target).filter((c)=>c.startsWith("/"))].some((c)=>n===c||n.startsWith(`${c.replace(/\/$/,"")}/`)))return{ok:!1,error:"Path is outside this service’s owned roots."};return{ok:!0,path:n}}function _E(e,t){let r=e.links.project?.replace(/[^A-Za-z0-9_-]/g,""),n=e.links.service?.replace(/[^A-Za-z0-9_-]/g,"");return[...r&&n?[`/var/www/${r}/${n}`,`/srv/${r}/${n}`]:[],...e.mounts.map((i)=>i.target).filter((i)=>i.startsWith("/"))].sort((i,o)=>o.length-i.length).find((i)=>t===i||t.startsWith(`${i.replace(/\/$/,"")}/`))}var ry={process:["ps","-eo","pid,ppid,user,%cpu,%mem,etime,command","--sort=-%cpu"],sockets:["ss","-lntup"],filesystem:["df","-h"]};class Ce{config;environment;dependencies;region;profile;constructor(e,t,r={}){this.config=e;this.environment=t;this.dependencies=r;this.region=e.aws?.region??e.project.region??"us-east-1",this.profile=e.aws?.profile}async inventory(){return this.dependencies.inventory?.()??wi(this.config,this.environment,{driver:this.dependencies.driver})}async workload(e){return(await this.inventory()).workloads.find((t)=>t.id===e)}async remote(e,t,r,n){let i=this.dependencies.driver??_({config:this.config}),o=await i.findComputeTargets({slug:this.config.project.slug,environment:this.environment,role:"app"}),s=xE(o,e);if(!s)throw Error("The workload server is no longer reachable in this scope.");return i.runRemoteDeploy({targets:[s],commands:t,timeoutSeconds:r,comment:n,tags:{Project:this.config.project.slug,Environment:this.environment,Role:"app"}})}async run(e){let t=await this.workload(e.workloadId),r={workloadId:e.workloadId,action:e.action};if(!t)return{...r,ok:!1,error:"Workload was not found in the current project and environment."};let n=t.capabilities[e.action];if(!n.supported)return{...r,ok:!1,error:n.reason??`${e.action} is unsupported for ${t.provider}.`};if(n.requiresConfirmation&&e.confirm!==t.name)return{...r,ok:!1,error:`Type "${t.name}" to ${e.action} this workload.`};if(n.requiresRecentAuth&&!e.recentAuth)return{...r,ok:!1,error:"Sign in again before using elevated runtime access."};if(e.action==="inspect")return{...r,ok:!0,workload:t};if(t.provider==="systemd"||t.provider==="docker"){let i=DE(t,e.action);if(!i)return{...r,ok:!1,error:`${e.action} is not implemented for ${t.provider}.`};let o=await this.remote(t,["set -uo pipefail",...i],60,`ts-cloud runtime:${e.action}`).catch(gd);return{...r,ok:o.success,command:i[0],stdout:ea(o.perInstance?.[0]?.output??""),stderr:ea(o.perInstance?.[0]?.error??o.error??""),error:o.success?void 0:o.error??"Runtime operation failed."}}if(t.provider==="ecs"){let i=PE(t);if(!i)return{...r,ok:!1,error:"ECS cluster or service identity is unavailable."};let o=this.dependencies.ecs??new _t(this.region,this.profile);if(e.action==="scale"){let s=RE(e.replicas,t.desiredReplicas??1);return await o.scaleService(i.cluster,i.service,s),{...r,ok:!0,command:`ecs scale ${t.name} ${s}`}}if(e.action==="start"||e.action==="stop"){let s=e.action==="stop"?0:Math.max(1,t.desiredReplicas??1);return await o.scaleService(i.cluster,i.service,s),{...r,ok:!0,command:`ecs scale ${t.name} ${s}`}}if(e.action==="restart"||e.action==="redeploy")return await o.forceNewDeployment(i.cluster,i.service),{...r,ok:!0,command:`ecs redeploy ${t.name}`}}return{...r,ok:!1,error:`${e.action} is not implemented for ${t.provider}.`}}async exec(e){let t={workloadId:e.workloadId,preset:e.preset},r=await this.workload(e.workloadId);if(!r)return{...t,ok:!1,error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_EXEC==="0")return{...t,ok:!1,error:"Runtime exec is disabled by TS_CLOUD_RUNTIME_EXEC."};if(!r.capabilities.exec.supported)return{...t,ok:!1,error:r.capabilities.exec.reason??"Exec is unsupported for this workload."};if(e.confirm!==r.name)return{...t,ok:!1,error:`Type "${r.name}" to open exec access.`};if(!e.recentAuth)return{...t,ok:!1,error:"Sign in again before using elevated runtime access."};let n=e.preset&&ry[e.preset];if(!n&&!e.command?.trim())return{...t,ok:!1,error:"Choose a diagnostic preset or provide a command."};if(e.command&&r.provider!=="docker")return{...t,ok:!1,error:"Free-form exec is restricted to isolated containers; use a diagnostic preset for system services."};let i=r.links.providerId??"",o;if(r.provider==="docker"&&fd.test(i)){let c=e.command?.trim()||n.map(Dn).join(" ");o=`docker exec ${i} sh -lc ${Dn(c)}`}else if(r.provider==="systemd"&&md.test(i)&&e.preset)o=e.preset==="process"?`systemctl status ${i} --no-pager --full`:ry[e.preset].map(Dn).join(" ");if(!o)return{...t,ok:!1,error:"Exec target identity is invalid or unsupported."};let s=await this.remote(r,["set -uo pipefail",o],60,"ts-cloud runtime:exec").catch(gd);return{...t,ok:s.success,command:o,stdout:ea(s.perInstance?.[0]?.output??""),stderr:ea(s.perInstance?.[0]?.error??s.error??""),error:s.success?void 0:s.error??"Exec command failed."}}async readFile(e){let t={workloadId:e.workloadId,path:e.path},r=await this.fileTarget(e);if("error"in r)return{...t,ok:!1,error:r.error};let{workload:n,path:i,root:o,providerId:s}=r,u=`sh -c ${Dn('resolved=$(realpath -m "$1"); root=$(realpath -m "$3"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; test -f "$resolved"; size=$(wc -c < "$resolved"); printf "__TSCLOUD_SIZE__=%s\\n" "$size"; head -c "$2" "$resolved" | base64')} sh ${Dn(i)} ${Oa} ${Dn(o)}`,a=n.provider==="docker"?`docker exec ${s} ${u}`:u,f=await this.remote(n,[a],30,"ts-cloud runtime:file-read").catch(gd);if(!f.success)return{...t,ok:!1,error:f.error??f.perInstance?.[0]?.error??"File read failed."};let C=f.perInstance?.[0]?.output??"",k=/__TSCLOUD_SIZE__=(\d+)\r?\n/.exec(C);if(!k)return{...t,ok:!1,error:"The remote file response was invalid."};let D=Number(k[1]),W=C.slice((k.index??0)+k[0].length).replace(/\s+/g,"");if(Buffer.from(W,"base64").byteLength>Oa)return{...t,ok:!1,error:"The remote file exceeded the transfer limit."};return{...t,ok:!0,contentBase64:W,size:D,truncated:D>Oa}}async writeFile(e){let t={workloadId:e.workloadId,path:e.path},r=await this.fileTarget(e);if("error"in r)return{...t,ok:!1,error:r.error};if(!/^[A-Za-z0-9+/]*={0,2}$/.test(e.contentBase64))return{...t,ok:!1,error:"File content must be valid base64."};let n=Buffer.from(e.contentBase64,"base64");if(n.toString("base64")!==e.contentBase64)return{...t,ok:!1,error:"File content must be canonical base64."};if(n.byteLength>Oa)return{...t,ok:!1,error:`File uploads are limited to ${Oa} bytes.`};let{workload:i,path:o,root:s,providerId:c}=r,a=`sh -c ${Dn('resolved=$(realpath -m "$1"); root=$(realpath -m "$2"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; mkdir -p "$(dirname "$resolved")"; tmp="$resolved.ts-cloud-$$"; base64 -d > "$tmp"; chmod 600 "$tmp"; mv "$tmp" "$resolved"')} sh ${Dn(o)} ${Dn(s)}`,f=i.provider==="docker"?`printf %s ${Dn(e.contentBase64)} | docker exec -i ${c} ${a}`:`printf %s ${Dn(e.contentBase64)} | ${a}`,C=await this.remote(i,[f],30,"ts-cloud runtime:file-write").catch(gd);return{...t,ok:C.success,size:n.byteLength,truncated:!1,error:C.success?void 0:C.error??C.perInstance?.[0]?.error??"File write failed."}}async fileTarget(e){let t=await this.workload(e.workloadId);if(!t)return{error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_FILE_ACCESS==="0")return{error:"Runtime file access is disabled by TS_CLOUD_RUNTIME_FILE_ACCESS."};if(!t.capabilities.files.supported)return{error:t.capabilities.files.reason??"File access is unsupported for this workload."};if(e.confirm!==t.name)return{error:`Type "${t.name}" to access workload files.`};if(!e.recentAuth)return{error:"Sign in again before using elevated runtime access."};let r=OE(t,e.path);if(!r.ok)return{error:r.error};let n=_E(t,r.path),i=t.links.providerId??"";if(!n||t.provider==="systemd"&&!md.test(i)||t.provider==="docker"&&!fd.test(i))return{error:"File target identity is invalid or unsupported."};return{workload:t,path:r.path,root:n,providerId:i}}async logs(e,t={}){let r=await this.workload(e);if(!r)throw Error("Workload was not found in the current project and environment.");if(!r.capabilities.logs.supported)throw Error(r.capabilities.logs.reason??"Logs are unsupported for this workload.");let n=Math.min(1000,Math.max(1,Math.floor(t.limit??200)));if(r.provider==="lambda"||r.provider==="ecs"){let f=this.dependencies.logs??new se(this.region,this.profile),C=r.config.logGroups,k=r.provider==="lambda"?`/aws/lambda/${r.name}`:Array.isArray(C)&&typeof C[0]==="string"?C[0]:void 0;if(!k)throw Error("The ECS task definition does not declare an awslogs group.");let D=await f.filterLogEvents({logGroupName:k,startTime:t.since?.getTime(),limit:n}),W=(D.events??[]).slice(0,n).map((Y)=>({timestamp:Y.timestamp==null?void 0:new Date(Y.timestamp).toISOString(),message:ea(String(Y.message??""))}));return{workloadId:e,provider:r.provider,lines:W,nextCursor:D.nextToken,truncated:(D.events?.length??0)>=n}}let i=r.links.providerId??"",o=t.since&&Number.isFinite(t.since.getTime())?t.since:void 0,s=r.provider==="systemd"&&md.test(i)?`journalctl -u ${i} --no-pager -n ${n} -o short-iso${o?` --since ${Dn(o.toISOString())}`:""}`:r.provider==="docker"&&fd.test(i)?`docker logs --timestamps --tail ${n}${o?` --since ${Math.floor(o.getTime()/1000)}`:""} ${i} 2>&1`:void 0;if(!s)throw Error("Log target identity is invalid.");let c=await this.remote(r,[s],30,"ts-cloud runtime:logs");if(!c.success)throw Error(c.error??c.perInstance?.[0]?.error??"Log read failed.");let u=ea(c.perInstance?.[0]?.output??""),a=u.split(`
|
|
169
169
|
`).filter(Boolean).slice(-n).map((f)=>{let C=/^(\d{4}-\d{2}-\d{2}T\S+)\s+(.*)$/.exec(f);return{timestamp:C?.[1],message:C?.[2]??f}});return{workloadId:e,provider:r.provider,lines:a,truncated:u.includes("[output truncated]")||a.length>=n}}}import{randomUUID as NE}from"node:crypto";class Ul{records=new Map;maxBufferBytes;ttlMs;now;constructor(e={}){this.maxBufferBytes=Math.max(1024,e.maxBufferBytes??262144),this.ttlMs=Math.max(1000,e.ttlMs??900000),this.now=e.now??(()=>new Date)}create(e,t){this.sweep();let r=this.now().toISOString(),n={id:NE(),workloadId:t,kind:e,state:"open",chunks:[],cursor:0,droppedBytes:0,bufferedBytes:0,createdAt:r,updatedAt:r,abort:new AbortController,listeners:new Set};return this.records.set(n.id,n),this.snapshot(n,0)}signal(e){return this.records.get(e)?.abort.signal}append(e,t,r="stdout"){let n=this.records.get(e);if(!n||n.state!=="open"||!t)return n?this.snapshot(n,n.cursor):void 0;let i=Buffer.from(t),o=i.byteLength>this.maxBufferBytes?i.subarray(i.byteLength-this.maxBufferBytes).toString("utf8"):t,s={cursor:++n.cursor,stream:r,data:o,at:this.now().toISOString()};n.chunks.push(s),n.bufferedBytes+=Buffer.byteLength(o),n.updatedAt=s.at;while(n.bufferedBytes>this.maxBufferBytes&&n.chunks.length>1){let c=n.chunks.shift(),u=Buffer.byteLength(c.data);n.bufferedBytes-=u,n.droppedBytes+=u}return this.publish(n),this.snapshot(n,s.cursor-1)}read(e,t,r=0){let n=this.records.get(e);if(!n||n.workloadId!==t)return;return n.updatedAt=this.now().toISOString(),this.snapshot(n,Math.max(0,Math.floor(r)))}close(e,t="complete",r){let n=this.records.get(e);if(!n||n.state!=="open")return n?this.snapshot(n,n.cursor):void 0;if(n.state=t,n.error=r,n.updatedAt=this.now().toISOString(),t==="cancelled")n.abort.abort();return this.publish(n),this.snapshot(n,n.cursor)}cancel(e,t){let r=this.records.get(e);if(!r||r.workloadId!==t)return;return this.close(e,"cancelled")}subscribe(e,t,r){let n=this.records.get(e);if(!n||n.workloadId!==t)return;return n.listeners.add(r),()=>n.listeners.delete(r)}sweep(){let e=this.now().getTime()-this.ttlMs,t=0;for(let[r,n]of this.records){if(new Date(n.updatedAt).getTime()>e)continue;n.abort.abort(),this.records.delete(r),t++}return t}clear(){for(let e of this.records.values())e.abort.abort();this.records.clear()}snapshot(e,t){let r=e.chunks[0]?.cursor??e.cursor+1,n=t>0&&t<r-1;return{id:e.id,workloadId:e.workloadId,kind:e.kind,state:e.state,chunks:e.chunks.filter((i)=>n||i.cursor>t),cursor:e.cursor,reset:n,droppedBytes:e.droppedBytes,createdAt:e.createdAt,updatedAt:e.updatedAt,error:e.error}}publish(e){let t=this.snapshot(e,0);for(let r of e.listeners)r(t)}}import{randomBytes as ny,scryptSync as iy,timingSafeEqual as ME}from"node:crypto";function Gl(e,t){if(e.role==="admin")return[...t];return t.filter((r)=>!!e.sites?.[r])}var zl=32768,Vl=8,ql=1,$E=32,LE=16;function $o(e){let t=ny(LE),r=iy(e,t,$E,{N:zl,r:Vl,p:ql,maxmem:268435456});return`scrypt$${zl}$${Vl}$${ql}$${t.toString("base64url")}$${r.toString("base64url")}`}function Ii(e,t){try{let r=t.split("$");if(r.length!==6||r[0]!=="scrypt")return!1;let[,n,i,o,s,c]=r,u=Number(n),a=Number(i),f=Number(o);if(!Number.isFinite(u)||!Number.isFinite(a)||!Number.isFinite(f))return!1;let C=Buffer.from(s,"base64url"),k=Buffer.from(c,"base64url");if(C.length===0||k.length===0)return!1;let D=iy(e,C,k.length,{N:u,r:a,p:f,maxmem:268435456});return ME(D,k)}catch{return!1}}function oy(e){let[t,r,n,i]=e.split("$");return t!=="scrypt"||Number(r)!==zl||Number(n)!==Vl||Number(i)!==ql}function Jl(){return ny(18).toString("base64url")}var Hl="/usr/local/bin/vtctldclient",BE="21.0.0";function yd(e){return`'${String(e).split("'").join("'\\''")}'`}function bd(e){return A(e)?.vitess??{}}function sy(e){return/^[A-Za-z_][A-Za-z0-9_]{0,63}$/.test(e)}function FE(e){return/^[0-9a-f]{8}(?:_[0-9a-f]{4}){3}_[0-9a-f]{12}$/i.test(e)}function jE(e=BE){let t=yd(e);return[`if ${Hl} --version 2>/dev/null | grep -q ${t}; then echo "vtctldclient ${e} already installed"; else`," command -v curl >/dev/null 2>&1 || (apt-get update -y && apt-get install -y curl ca-certificates)",' if [ "$(uname -m)" != "x86_64" ]; then',' echo "vtctldclient: Vitess publishes only an x86_64 release tarball; this box is $(uname -m). Build from source or install via pantry." >&2'," exit 1"," fi",' tmp="$(mktemp -d)"',` api="https://api.github.com/repos/vitessio/vitess/releases/tags/v${e}"`,` url="$(curl -fsSL "$api" | grep -oE '"browser_download_url"[[:space:]]*:[[:space:]]*"[^"]+vitess-[0-9][^"]*\\.tar\\.gz"' | head -1 | sed -E 's/.*"(https[^"]+)"/\\1/')"`,' if [ -z "$url" ]; then echo "vtctldclient: no release tarball found for v'+e+'" >&2; rm -rf "$tmp"; exit 1; fi',` curl -fsSL "$url" | tar -xz -C "$tmp" --strip-components=2 --wildcards --occurrence=1 '*/bin/vtctldclient' || true`,' if [ ! -s "$tmp/vtctldclient" ]; then',' echo "vtctldclient: could not extract the binary from $url" >&2',' rm -rf "$tmp"; exit 1'," fi",` install -m 0755 "$tmp/vtctldclient" ${Hl}`,' rm -rf "$tmp"',` echo "installed vtctldclient ${e}"`,"fi"]}function ay(e){if(!e.vtctldAddr)return null;return`${Hl} --server ${yd(e.vtctldAddr)}`}function UE(e,t,r={}){let n=ay(e);if(!n)return null;let i=r.sharded?" --sharded":"";return[`${n} CreateKeyspace${i} ${yd(t)}`]}function zE(e,t,r){let n=ay(e);if(!n)return null;return['vschema_tmp="$(mktemp)"',`cat > "$vschema_tmp" <<'TS_CLOUD_VSCHEMA_EOF'`,r,"TS_CLOUD_VSCHEMA_EOF",`${n} ApplyVSchema --vschema-file "$vschema_tmp" ${yd(t)}`,'rm -f "$vschema_tmp"']}function VE(e,t,r="vitess"){return $s([`SET @@ddl_strategy='${r}';`,t.endsWith(";")?t:`${t};`],e,Ls)}function qE(e,t){let r=t?[`USE ${t.replace(/[^A-Z0-9_]/gi,"")};`,"SHOW VITESS_MIGRATIONS;"]:["SHOW VITESS_MIGRATIONS;"],n=$s(r,e,Ls);return n[0]=n[0].replace(" --skip-column-names",""),n}function GE(e){let t=e.split(`
|
|
170
|
-
`).map((s)=>s.trimEnd()).filter((s)=>s.trim().length>0);if(t.length===0)return[];let r=t[0].split("\t").map((s)=>s.trim()),n=(s)=>r.indexOf(s),i={uuid:n("migration_uuid"),keyspace:n("keyspace"),shard:n("shard"),table:n("mysql_table"),status:n("migration_status"),strategy:n("strategy"),added:n("added_timestamp"),completed:n("completed_timestamp"),progress:n("progress")};if(i.uuid===-1)return[];let o=[];for(let s of t.slice(1)){let c=s.split("\t"),u=(f)=>f>=0?(c[f]??"").trim():"",a=u(i.uuid);if(!a)continue;o.push({uuid:a,keyspace:u(i.keyspace),shard:u(i.shard),table:u(i.table),status:u(i.status),strategy:u(i.strategy),added:u(i.added),completed:u(i.completed),progress:u(i.progress)})}return o}function JE(e){return e.filter((t)=>t.status.toLowerCase()==="failed")}function HE(e){return e.filter((t)=>["running","queued","ready"].includes(t.status.toLowerCase()))}function WE(e,t,r){let n=r.toUpperCase();return $s([`ALTER VITESS_MIGRATION '${t}' ${n};`],e,Ls)}function ta(e){if(Ho(e)!=="vitess")return{ok:!1,error:"The configured database engine is not Vitess."};return null}function hd(e){if(!e.vtctldAddr)return{ok:!1,error:"No vtctld address is configured. Creating keyspaces and applying a VSchema are topology operations that vtgate cannot perform. Set `infrastructure.appDatabase.vitess.vtctldAddr` (for example `vtctld.internal:15999`) and redeploy."};return null}async function cy(e,t){let r=ta(e);if(r)return r;let n=bd(e);return Vr(e,t,jE(n.clientVersion),"ts-cloud vitess:install-client")}async function dy(e,t,r,n={}){let i=ta(e);if(i)return{...i,keyspace:r};if(!sy(r))return{ok:!1,error:"Keyspace name must be a valid identifier.",keyspace:r};let o=bd(e),s=hd(o);if(s)return{...s,keyspace:r};let c=UE(o,r,n);if(!c)return{...hd({}),keyspace:r};return{...await Vr(e,t,c,`ts-cloud vitess:create-keyspace ${r}`),keyspace:r}}async function uy(e,t,r,n){let i=ta(e);if(i)return{...i,keyspace:r};if(!sy(r))return{ok:!1,error:"Keyspace name must be a valid identifier.",keyspace:r};try{let a=JSON.parse(n);if(!a||typeof a!=="object")return{ok:!1,error:"The VSchema must be a JSON object.",keyspace:r}}catch(a){return{ok:!1,error:`The VSchema is not valid JSON: ${a?.message??a}`,keyspace:r}}let o=bd(e),s=hd(o);if(s)return{...s,keyspace:r};let c=zE(o,r,n);if(!c)return{...hd({}),keyspace:r};return{...await Vr(e,t,c,`ts-cloud vitess:apply-vschema ${r}`),keyspace:r}}async function ly(e,t,r){let n=ta(e);if(n)return n;if(!r.trim())return{ok:!1,error:"No SQL was provided."};let i=bd(e);return Vr(e,t,VE(A(e),r,i.ddlStrategy??"vitess"),"ts-cloud vitess:apply-schema")}async function py(e,t,r){let n=ta(e);if(n)return{...n,migrations:[],failed:[],running:[]};let i=await Vr(e,t,qE(A(e),r),"ts-cloud vitess:migrations"),o=i.ok&&i.stdout?GE(i.stdout):[];return{...i,migrations:o,failed:JE(o),running:HE(o)}}async function gy(e,t,r,n){let i=ta(e);if(i)return{...i,uuid:r};if(!FE(r))return{ok:!1,error:"Migration UUID is not in the expected format.",uuid:r};return{...await Vr(e,t,WE(A(e),r,n),`ts-cloud vitess:migration ${n} ${r}`),uuid:r}}function KE(e){let t=e.infrastructure?.appDatabase;if(t?.engine&&t.engine!=="vitess")return`This project already declares ${t.engine} as its application database.`;let r=e.infrastructure?.compute?.managedServices,n=r?["mysql","mariadb","postgres"].find((i)=>Boolean(r[i])):void 0;if(n)return`This server already declares the ${n} database service.`;return}function QE(e,t){let r=t.keyspace.trim(),n=t.username.trim(),i=t.password,o=KE(e);if(o)throw Error(o);if(!Yi(r))throw Error("Keyspace must contain letters, numbers, or underscores and cannot start with a number.");if(!Yi(n))throw Error("Username must contain letters, numbers, or underscores and cannot start with a number.");if(i.length<16)throw Error("Password must contain at least 16 characters.");if(t.confirm!==r)throw Error(`Type "${r}" to confirm Vitess provisioning.`);let s={mode:"cluster",cell:"zone1",keyspaces:[{name:r,sharded:t.sharded===!0}],vtgatePort:15306,username:n,password:i,bindAddress:"127.0.0.1"};return{service:s,appDatabase:{engine:"vitess",name:r,username:n,host:"127.0.0.1",port:15306,ssl:!1},commands:[...kr(),...Mo(s)]}}async function my(e,t,r){let n=QE(e,r);return{...await Vr(e,t,n.commands,`ts-cloud vitess:provision ${n.appDatabase.name}`),database:n.appDatabase,service:Object.fromEntries(Object.entries(n.service).filter(([o])=>o!=="password"))}}var YE={capability:"runtime:terminal",scope:"organization"};var XE={"GET /api/health":{capability:"project:read",anyUser:!0},"GET /api/dashboard-data":{capability:"project:read",anyUser:!0},"GET /api/config":{capability:"config:read",anyUser:!0},"GET /api/me":{capability:"project:read",anyUser:!0},"GET /api/search":{capability:"project:read",anyUser:!0},"GET /api/search/preferences":{capability:"project:read",anyUser:!0},"POST /api/search/preferences":{capability:"project:read",anyUser:!0},"DELETE /api/search/preferences":{capability:"project:read",anyUser:!0},"GET /api/auth/security":{capability:"project:read",anyUser:!0},"GET /api/auth/sessions":{capability:"project:read",anyUser:!0},"DELETE /api/auth/sessions":{capability:"project:read",anyUser:!0},"POST /api/auth/sessions/revoke-others":{capability:"project:read",anyUser:!0},"POST /api/auth/password/change":{capability:"project:read",anyUser:!0},"POST /api/auth/mfa/enroll":{capability:"project:read",anyUser:!0},"POST /api/auth/mfa/verify":{capability:"project:read",anyUser:!0},"DELETE /api/auth/mfa":{capability:"project:read",anyUser:!0},"POST /api/auth/step-up":{capability:"project:read",anyUser:!0},"GET /api/auth/oidc/providers":{capability:"users:read",scope:"organization"},"POST /api/auth/oidc/providers":{capability:"users:manage",scope:"organization"},"PATCH /api/auth/oidc/providers":{capability:"users:manage",scope:"organization"},"GET /api/automation":{capability:"users:read",scope:"organization"},"POST /api/automation/service-accounts":{capability:"users:manage",scope:"organization"},"PATCH /api/automation/service-accounts":{capability:"users:manage",scope:"organization"},"POST /api/automation/tokens":{capability:"users:manage",scope:"organization"},"POST /api/automation/tokens/rotate":{capability:"users:manage",scope:"organization"},"DELETE /api/automation/tokens":{capability:"users:manage",scope:"organization"},"GET /api/security/posture":{capability:"security:read"},"GET /api/security/export":{capability:"security:read"},"POST /api/security/scan":{capability:"security:manage"},"POST /api/security/review":{capability:"deployments:create"},"POST /api/security/policies":{capability:"security:manage"},"PATCH /api/security/policies":{capability:"security:manage"},"POST /api/security/waivers":{capability:"security:waive"},"DELETE /api/security/waivers":{capability:"security:waive"},"PATCH /api/security/findings":{capability:"security:manage"},"POST /api/security/comments":{capability:"security:manage"},"GET /api/sources":{capability:"sources:read"},"POST /api/sources/connections":{capability:"sources:manage"},"PATCH /api/sources/connections":{capability:"sources:manage"},"DELETE /api/sources/connections":{capability:"sources:manage"},"POST /api/sources/deploy-keys":{capability:"sources:manage"},"DELETE /api/sources/deploy-keys":{capability:"sources:manage"},"POST /api/sources/repositories/sync":{capability:"sources:manage"},"GET /api/sources/references":{capability:"sources:read"},"POST /api/sources/bindings":{capability:"sources:manage"},"PATCH /api/sources/bindings":{capability:"sources:manage"},"POST /api/sources/webhooks":{capability:"sources:manage"},"PATCH /api/sources/webhooks":{capability:"sources:manage"},"DELETE /api/sources/webhooks":{capability:"sources:manage"},"GET /api/onboarding":{capability:"applications:read"},"POST /api/onboarding/detect":{capability:"applications:manage"},"POST /api/onboarding/plan":{capability:"applications:manage"},"POST /api/onboarding/drafts":{capability:"applications:manage"},"PATCH /api/onboarding/drafts":{capability:"applications:manage"},"POST /api/onboarding/artifacts":{capability:"applications:manage"},"POST /api/onboarding/registries":{capability:"applications:manage"},"PATCH /api/onboarding/registries":{capability:"applications:manage"},"DELETE /api/onboarding/registries":{capability:"applications:manage"},"POST /api/onboarding/apply":{capability:"applications:manage"},"GET /api/compose":{capability:"applications:read",anyUser:!0},"POST /api/compose/preview":{capability:"applications:manage",anyUser:!0},"POST /api/compose/import":{capability:"applications:manage",anyUser:!0},"POST /api/compose/template":{capability:"applications:manage",anyUser:!0},"POST /api/compose/action":{capability:"project:read",anyUser:!0},"POST /api/compose/logs":{capability:"runtime:logs",anyUser:!0},"POST /api/compose/shell":{capability:"runtime:terminal",scope:"organization"},"GET /api/compose/import":{capability:"applications:manage"},"GET /api/compose/template":{capability:"applications:manage"},"GET /api/compose/logs":{capability:"runtime:logs"},"GET /api/compose/shell":{capability:"runtime:terminal",scope:"organization"},"GET /api/organization":{capability:"users:read",scope:"organization"},"GET /api/organization/invitations":{capability:"users:read",scope:"organization"},"POST /api/organization/invitations":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/invitations":{capability:"users:manage",scope:"organization"},"POST /api/organization/invitations/resend":{capability:"users:manage",scope:"organization"},"PATCH /api/organization/memberships":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/memberships":{capability:"users:manage",scope:"organization"},"POST /api/organization/grants":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/grants":{capability:"users:manage",scope:"organization"},"GET /api/control-plane/operations":{capability:"deployments:read"},"GET /api/control-plane/events":{capability:"audit:read"},"GET /api/queue":{capability:"deployments:read",anyUser:!0},"GET /api/queue/logs":{capability:"deployments:read",anyUser:!0},"GET /api/queue/stream":{capability:"deployments:read",anyUser:!0},"POST /api/queue/cancel":{capability:"deployments:cancel",anyUser:!0},"POST /api/queue/retry":{capability:"deployments:create",anyUser:!0},"GET /api/queue/settings":{capability:"deployments:read"},"PATCH /api/queue/settings":{capability:"automation:manage",scope:"organization"},"DELETE /api/queue/history":{capability:"automation:manage",scope:"organization"},"GET /api/previews":{capability:"deployments:read",anyUser:!0},"GET /api/releases":{capability:"deployments:read",anyUser:!0},"POST /api/releases/action":{capability:"deployments:create",anyUser:!0},"POST /api/previews/deploy":{capability:"deployments:create",anyUser:!0},"POST /api/previews/destroy":{capability:"deployments:cancel",anyUser:!0},"POST /api/previews/extend":{capability:"deployments:create",anyUser:!0},"POST /api/previews/rebuild":{capability:"deployments:create",anyUser:!0},"POST /api/previews/definitions":{capability:"config:write",anyUser:!0},"POST /api/previews/cleanup":{capability:"automation:manage",scope:"organization"},"GET /api/tags":{capability:"project:read"},"POST /api/tags":{capability:"tags:manage"},"DELETE /api/tags":{capability:"tags:manage"},"POST /api/sites/deploy":{capability:"deployments:create",scope:"site",siteFrom:"body"},"PATCH /api/sites":{capability:"config:write",scope:"site",siteFrom:"body"},"POST /api/sites":{capability:"config:write"},"DELETE /api/sites":{capability:"config:write"},"POST /api/env":{capability:"config:write"},"GET /api/ssh-keys":{capability:"fleet:read"},"POST /api/ssh-keys":{capability:"fleet:manage"},"DELETE /api/ssh-keys":{capability:"fleet:manage"},"GET /api/firewall":{capability:"fleet:read"},"POST /api/firewall":{capability:"fleet:manage"},"DELETE /api/firewall":{capability:"fleet:manage"},"GET /api/databases":{capability:"data:read"},"POST /api/databases":{capability:"data:admin"},"GET /api/databases/vitess":{capability:"data:read"},"GET /api/databases/vitess/migrations":{capability:"data:read"},"POST /api/databases/vitess/migrations/action":{capability:"data:admin"},"POST /api/databases/vitess/provision":{capability:"runtime:terminal",scope:"organization"},"POST /api/databases/vitess/keyspaces":{capability:"data:admin"},"POST /api/databases/vitess/vschema":{capability:"data:admin"},"POST /api/databases/vitess/schema":{capability:"data:admin"},"POST /api/databases/vitess/install-client":{capability:"data:admin"},"GET /api/databases/backups":{capability:"backups:read"},"POST /api/databases/backup":{capability:"backups:create"},"POST /api/databases/users":{capability:"data:admin"},"GET /api/data-services":{capability:"data:read"},"GET /api/data-services/capabilities":{capability:"data:read"},"GET /api/data-services/connections":{capability:"data:read"},"POST /api/data-services/preview":{capability:"data:read"},"POST /api/data-services":{capability:"data:admin"},"POST /api/data-services/action":{capability:"data:admin"},"POST /api/data-services/dependencies":{capability:"data:admin"},"POST /api/data-services/management":{capability:"data:admin"},"POST /api/data-services/reveal":{capability:"data:admin"},"GET /api/backups":{capability:"backups:read"},"POST /api/backups/destinations":{capability:"backups:create"},"POST /api/backups/destinations/test":{capability:"backups:create"},"POST /api/backups/policies":{capability:"backups:create"},"POST /api/backups/run":{capability:"backups:create"},"POST /api/backups/verify":{capability:"backups:create"},"POST /api/backups/restore":{capability:"backups:restore"},"POST /api/backups/recovery-points":{capability:"backups:create"},"POST /api/backups/retention":{capability:"backups:create"},"GET /api/configuration":{capability:"config:read"},"GET /api/configuration/export":{capability:"config:read"},"POST /api/configuration/plan":{capability:"config:read"},"POST /api/configuration":{capability:"config:write"},"POST /api/configuration/import":{capability:"config:write"},"POST /api/configuration/dependencies":{capability:"config:write"},"POST /api/configuration/transfer":{capability:"config:write"},"POST /api/configuration/bulk":{capability:"config:write"},"POST /api/configuration/reveal":{capability:"secrets:read"},"DELETE /api/configuration":{capability:"config:write"},"GET /api/volumes":{capability:"data:read"},"POST /api/volumes":{capability:"data:admin"},"POST /api/volumes/attach":{capability:"data:admin"},"POST /api/volumes/detach":{capability:"data:admin"},"POST /api/volumes/resize":{capability:"data:admin"},"POST /api/volumes/snapshot":{capability:"backups:create"},"POST /api/volumes/restore":{capability:"backups:restore"},"POST /api/volumes/adopt":{capability:"data:admin"},"POST /api/volumes/discover":{capability:"data:read"},"DELETE /api/volumes":{capability:"data:admin"},"GET /api/fleet":{capability:"fleet:read"},"POST /api/fleet":{capability:"fleet:manage"},"POST /api/fleet/action":{capability:"fleet:manage"},"GET /api/capacity":{capability:"fleet:read"},"POST /api/capacity":{capability:"fleet:manage"},"POST /api/capacity/member":{capability:"fleet:manage"},"POST /api/capacity/explain":{capability:"fleet:read"},"POST /api/capacity/action":{capability:"fleet:manage"},"GET /api/regions":{capability:"config:read"},"POST /api/regions":{capability:"config:write"},"POST /api/regions/action":{capability:"config:write"},"GET /api/maintenance":{capability:"automation:read"},"POST /api/maintenance/cleanup-preview":{capability:"automation:manage"},"POST /api/maintenance/cleanup-apply":{capability:"automation:manage"},"POST /api/maintenance/drill":{capability:"automation:manage"},"POST /api/maintenance/drill-run":{capability:"automation:manage"},"GET /api/actions":{capability:"runtime:read"},"GET /api/runtime/workloads":{capability:"runtime:read"},"GET /api/runtime/logs":{capability:"runtime:logs"},"POST /api/runtime/log-sessions":{capability:"runtime:logs"},"GET /api/runtime/log-sessions":{capability:"runtime:logs"},"GET /api/runtime/log-stream":{capability:"runtime:logs"},"DELETE /api/runtime/log-sessions":{capability:"runtime:logs"},"POST /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"GET /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"GET /api/runtime/exec-stream":{capability:"runtime:terminal",scope:"organization"},"DELETE /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/files/read":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/files/write":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/operations":{capability:"runtime:restart"},"GET /api/telemetry/status":{capability:"runtime:read"},"GET /api/telemetry/settings":{capability:"runtime:read"},"PATCH /api/telemetry/settings":{capability:"config:write",scope:"organization"},"GET /api/telemetry/query":{capability:"runtime:logs"},"GET /api/telemetry/tail":{capability:"runtime:logs"},"GET /api/telemetry/series":{capability:"runtime:read"},"POST /api/telemetry/refresh":{capability:"runtime:logs"},"POST /api/telemetry/export":{capability:"runtime:logs"},"GET /api/telemetry/saved-queries":{capability:"runtime:logs"},"POST /api/telemetry/saved-queries":{capability:"runtime:logs"},"DELETE /api/telemetry/saved-queries":{capability:"runtime:logs"},"GET /api/health/checks":{capability:"runtime:read"},"POST /api/health/checks":{capability:"config:write"},"PATCH /api/health/checks":{capability:"config:write"},"POST /api/health/checks/test":{capability:"runtime:read"},"POST /api/health/checks/run":{capability:"runtime:restart"},"GET /api/protection":{capability:"security:read"},"POST /api/protection/attack-mode":{capability:"security:manage"},"POST /api/protection/pause":{capability:"security:manage"},"GET /api/protection/ip-rules":{capability:"security:read"},"POST /api/protection/ip-rules":{capability:"security:manage"},"DELETE /api/protection/ip-rules":{capability:"security:manage"},"GET /api/usage":{capability:"billing:read"},"GET /api/spend/budgets":{capability:"billing:read"},"POST /api/spend/budgets":{capability:"billing:manage"},"PATCH /api/spend/budgets":{capability:"billing:manage"},"DELETE /api/spend/budgets":{capability:"billing:manage"},"POST /api/spend/check":{capability:"billing:manage"},"GET /api/spend/enforcement":{capability:"billing:read"},"POST /api/spend/release":{capability:"billing:manage"},"GET /api/spend/anomalies":{capability:"billing:read"},"POST /api/spend/anomalies/acknowledge":{capability:"billing:manage"},"GET /api/alerts":{capability:"runtime:read"},"GET /api/alerts/rules":{capability:"runtime:read"},"POST /api/alerts/rules":{capability:"config:write"},"PATCH /api/alerts/rules":{capability:"config:write"},"POST /api/alerts/evaluate":{capability:"runtime:restart"},"POST /api/alerts/action":{capability:"runtime:restart"},"POST /api/alerts/silences":{capability:"config:write"},"GET /api/notifications/channels":{capability:"automation:read",scope:"organization"},"POST /api/notifications/channels":{capability:"automation:manage",scope:"organization"},"PATCH /api/notifications/channels":{capability:"automation:manage",scope:"organization"},"POST /api/notifications/channels/test":{capability:"automation:manage",scope:"organization"},"GET /api/notifications/routes":{capability:"automation:read",scope:"organization"},"POST /api/notifications/routes":{capability:"automation:manage",scope:"organization"},"PATCH /api/notifications/routes":{capability:"automation:manage",scope:"organization"},"POST /api/notifications/routes/preview":{capability:"automation:read",scope:"organization"},"GET /api/notifications/deliveries":{capability:"automation:read",scope:"organization"},"POST /api/notifications/deliveries/retry":{capability:"automation:manage",scope:"organization"},"GET /api/jobs":{capability:"automation:read"},"POST /api/jobs":{capability:"automation:manage"},"PATCH /api/jobs":{capability:"automation:manage"},"POST /api/jobs/preview":{capability:"automation:read"},"POST /api/jobs/action":{capability:"automation:manage"},"POST /api/jobs/reconcile":{capability:"automation:manage"},"GET /api/jobs/history":{capability:"automation:read"},"GET /api/workers":{capability:"automation:read"},"POST /api/workers/action":{capability:"automation:manage"},"POST /api/actions/run":{capability:"fleet:manage"},"GET /api/server/operations":{capability:"fleet:read"},"POST /api/server/operations/run":{capability:"fleet:manage"},"POST /api/server/command":{capability:"runtime:terminal",scope:"organization"},"GET /api/terminal":{capability:"runtime:terminal",scope:"organization"},"GET /api/users":{capability:"users:read",scope:"organization"},"POST /api/users":{capability:"users:manage",scope:"organization"},"DELETE /api/users":{capability:"users:manage",scope:"organization"},"GET /api/serverless/operations":{capability:"deployments:read"},"POST /api/serverless/operations/run":{capability:"deployments:create"},"POST /api/serverless/command":{capability:"runtime:terminal",scope:"organization"},"GET /api/serverless/dlq":{capability:"data:read"},"POST /api/serverless/dlq/redrive":{capability:"data:write"},"POST /api/serverless/dlq/purge":{capability:"data:admin"},"GET /api/serverless/secrets":{capability:"secrets:read"},"POST /api/serverless/secrets":{capability:"secrets:write"},"DELETE /api/serverless/secrets":{capability:"secrets:write"},"POST /api/serverless/functions/config":{capability:"config:write"},"GET /api/serverless/alarms":{capability:"runtime:read"},"POST /api/serverless/alarms":{capability:"config:write"},"DELETE /api/serverless/alarms":{capability:"config:write"},"GET /api/serverless/traces":{capability:"runtime:read"},"POST /api/serverless/scheduler":{capability:"automation:manage"}};function Wl(e,t){return XE[`${e.toUpperCase()} ${t}`]??YE}import{createHmac as ZE,randomBytes as eT,timingSafeEqual as tT}from"node:crypto";import{chmodSync as rT,existsSync as nT,mkdirSync as iT,readFileSync as oT,writeFileSync as sT}from"node:fs";import{dirname as aT}from"node:path";var _a="ts_cloud_session";var cT=28800000;function fy(e){let t=process.env.TS_CLOUD_DASHBOARD_SECRET?.trim();if(t)return t;let r=R(e,"dashboard-secret");try{if(nT(r)){let i=oT(r,"utf8").trim();if(i)return i}}catch{}let n=eT(32).toString("base64url");try{iT(aT(r),{recursive:!0}),sT(r,`${n}
|
|
170
|
+
`).map((s)=>s.trimEnd()).filter((s)=>s.trim().length>0);if(t.length===0)return[];let r=t[0].split("\t").map((s)=>s.trim()),n=(s)=>r.indexOf(s),i={uuid:n("migration_uuid"),keyspace:n("keyspace"),shard:n("shard"),table:n("mysql_table"),status:n("migration_status"),strategy:n("strategy"),added:n("added_timestamp"),completed:n("completed_timestamp"),progress:n("progress")};if(i.uuid===-1)return[];let o=[];for(let s of t.slice(1)){let c=s.split("\t"),u=(f)=>f>=0?(c[f]??"").trim():"",a=u(i.uuid);if(!a)continue;o.push({uuid:a,keyspace:u(i.keyspace),shard:u(i.shard),table:u(i.table),status:u(i.status),strategy:u(i.strategy),added:u(i.added),completed:u(i.completed),progress:u(i.progress)})}return o}function JE(e){return e.filter((t)=>t.status.toLowerCase()==="failed")}function HE(e){return e.filter((t)=>["running","queued","ready"].includes(t.status.toLowerCase()))}function WE(e,t,r){let n=r.toUpperCase();return $s([`ALTER VITESS_MIGRATION '${t}' ${n};`],e,Ls)}function ta(e){if(Ho(e)!=="vitess")return{ok:!1,error:"The configured database engine is not Vitess."};return null}function hd(e){if(!e.vtctldAddr)return{ok:!1,error:"No vtctld address is configured. Creating keyspaces and applying a VSchema are topology operations that vtgate cannot perform. Set `infrastructure.appDatabase.vitess.vtctldAddr` (for example `vtctld.internal:15999`) and redeploy."};return null}async function cy(e,t){let r=ta(e);if(r)return r;let n=bd(e);return Vr(e,t,jE(n.clientVersion),"ts-cloud vitess:install-client")}async function dy(e,t,r,n={}){let i=ta(e);if(i)return{...i,keyspace:r};if(!sy(r))return{ok:!1,error:"Keyspace name must be a valid identifier.",keyspace:r};let o=bd(e),s=hd(o);if(s)return{...s,keyspace:r};let c=UE(o,r,n);if(!c)return{...hd({}),keyspace:r};return{...await Vr(e,t,c,`ts-cloud vitess:create-keyspace ${r}`),keyspace:r}}async function uy(e,t,r,n){let i=ta(e);if(i)return{...i,keyspace:r};if(!sy(r))return{ok:!1,error:"Keyspace name must be a valid identifier.",keyspace:r};try{let a=JSON.parse(n);if(!a||typeof a!=="object")return{ok:!1,error:"The VSchema must be a JSON object.",keyspace:r}}catch(a){return{ok:!1,error:`The VSchema is not valid JSON: ${a?.message??a}`,keyspace:r}}let o=bd(e),s=hd(o);if(s)return{...s,keyspace:r};let c=zE(o,r,n);if(!c)return{...hd({}),keyspace:r};return{...await Vr(e,t,c,`ts-cloud vitess:apply-vschema ${r}`),keyspace:r}}async function ly(e,t,r){let n=ta(e);if(n)return n;if(!r.trim())return{ok:!1,error:"No SQL was provided."};let i=bd(e);return Vr(e,t,VE(A(e),r,i.ddlStrategy??"vitess"),"ts-cloud vitess:apply-schema")}async function py(e,t,r){let n=ta(e);if(n)return{...n,migrations:[],failed:[],running:[]};let i=await Vr(e,t,qE(A(e),r),"ts-cloud vitess:migrations"),o=i.ok&&i.stdout?GE(i.stdout):[];return{...i,migrations:o,failed:JE(o),running:HE(o)}}async function gy(e,t,r,n){let i=ta(e);if(i)return{...i,uuid:r};if(!FE(r))return{ok:!1,error:"Migration UUID is not in the expected format.",uuid:r};return{...await Vr(e,t,WE(A(e),r,n),`ts-cloud vitess:migration ${n} ${r}`),uuid:r}}function KE(e){let t=e.infrastructure?.appDatabase;if(t?.engine&&t.engine!=="vitess")return`This project already declares ${t.engine} as its application database.`;let r=e.infrastructure?.compute?.managedServices,n=r?["mysql","mariadb","postgres"].find((i)=>Boolean(r[i])):void 0;if(n)return`This server already declares the ${n} database service.`;return}function QE(e,t){let r=t.keyspace.trim(),n=t.username.trim(),i=t.password,o=KE(e);if(o)throw Error(o);if(!Yi(r))throw Error("Keyspace must contain letters, numbers, or underscores and cannot start with a number.");if(!Yi(n))throw Error("Username must contain letters, numbers, or underscores and cannot start with a number.");if(i.length<16)throw Error("Password must contain at least 16 characters.");if(t.confirm!==r)throw Error(`Type "${r}" to confirm Vitess provisioning.`);let s={mode:"cluster",cell:"zone1",keyspaces:[{name:r,sharded:t.sharded===!0}],vtgatePort:15306,username:n,password:i,bindAddress:"127.0.0.1"};return{service:s,appDatabase:{engine:"vitess",name:r,username:n,host:"127.0.0.1",port:15306,ssl:!1},commands:[...Ht(),...Mo(s)]}}async function my(e,t,r){let n=QE(e,r);return{...await Vr(e,t,n.commands,`ts-cloud vitess:provision ${n.appDatabase.name}`),database:n.appDatabase,service:Object.fromEntries(Object.entries(n.service).filter(([o])=>o!=="password"))}}var YE={capability:"runtime:terminal",scope:"organization"};var XE={"GET /api/health":{capability:"project:read",anyUser:!0},"GET /api/dashboard-data":{capability:"project:read",anyUser:!0},"GET /api/config":{capability:"config:read",anyUser:!0},"GET /api/me":{capability:"project:read",anyUser:!0},"GET /api/search":{capability:"project:read",anyUser:!0},"GET /api/search/preferences":{capability:"project:read",anyUser:!0},"POST /api/search/preferences":{capability:"project:read",anyUser:!0},"DELETE /api/search/preferences":{capability:"project:read",anyUser:!0},"GET /api/auth/security":{capability:"project:read",anyUser:!0},"GET /api/auth/sessions":{capability:"project:read",anyUser:!0},"DELETE /api/auth/sessions":{capability:"project:read",anyUser:!0},"POST /api/auth/sessions/revoke-others":{capability:"project:read",anyUser:!0},"POST /api/auth/password/change":{capability:"project:read",anyUser:!0},"POST /api/auth/mfa/enroll":{capability:"project:read",anyUser:!0},"POST /api/auth/mfa/verify":{capability:"project:read",anyUser:!0},"DELETE /api/auth/mfa":{capability:"project:read",anyUser:!0},"POST /api/auth/step-up":{capability:"project:read",anyUser:!0},"GET /api/auth/oidc/providers":{capability:"users:read",scope:"organization"},"POST /api/auth/oidc/providers":{capability:"users:manage",scope:"organization"},"PATCH /api/auth/oidc/providers":{capability:"users:manage",scope:"organization"},"GET /api/automation":{capability:"users:read",scope:"organization"},"POST /api/automation/service-accounts":{capability:"users:manage",scope:"organization"},"PATCH /api/automation/service-accounts":{capability:"users:manage",scope:"organization"},"POST /api/automation/tokens":{capability:"users:manage",scope:"organization"},"POST /api/automation/tokens/rotate":{capability:"users:manage",scope:"organization"},"DELETE /api/automation/tokens":{capability:"users:manage",scope:"organization"},"GET /api/security/posture":{capability:"security:read"},"GET /api/security/export":{capability:"security:read"},"POST /api/security/scan":{capability:"security:manage"},"POST /api/security/review":{capability:"deployments:create"},"POST /api/security/policies":{capability:"security:manage"},"PATCH /api/security/policies":{capability:"security:manage"},"POST /api/security/waivers":{capability:"security:waive"},"DELETE /api/security/waivers":{capability:"security:waive"},"PATCH /api/security/findings":{capability:"security:manage"},"POST /api/security/comments":{capability:"security:manage"},"GET /api/sources":{capability:"sources:read"},"POST /api/sources/connections":{capability:"sources:manage"},"PATCH /api/sources/connections":{capability:"sources:manage"},"DELETE /api/sources/connections":{capability:"sources:manage"},"POST /api/sources/deploy-keys":{capability:"sources:manage"},"DELETE /api/sources/deploy-keys":{capability:"sources:manage"},"POST /api/sources/repositories/sync":{capability:"sources:manage"},"GET /api/sources/references":{capability:"sources:read"},"POST /api/sources/bindings":{capability:"sources:manage"},"PATCH /api/sources/bindings":{capability:"sources:manage"},"POST /api/sources/webhooks":{capability:"sources:manage"},"PATCH /api/sources/webhooks":{capability:"sources:manage"},"DELETE /api/sources/webhooks":{capability:"sources:manage"},"GET /api/onboarding":{capability:"applications:read"},"POST /api/onboarding/detect":{capability:"applications:manage"},"POST /api/onboarding/plan":{capability:"applications:manage"},"POST /api/onboarding/drafts":{capability:"applications:manage"},"PATCH /api/onboarding/drafts":{capability:"applications:manage"},"POST /api/onboarding/artifacts":{capability:"applications:manage"},"POST /api/onboarding/registries":{capability:"applications:manage"},"PATCH /api/onboarding/registries":{capability:"applications:manage"},"DELETE /api/onboarding/registries":{capability:"applications:manage"},"POST /api/onboarding/apply":{capability:"applications:manage"},"GET /api/compose":{capability:"applications:read",anyUser:!0},"POST /api/compose/preview":{capability:"applications:manage",anyUser:!0},"POST /api/compose/import":{capability:"applications:manage",anyUser:!0},"POST /api/compose/template":{capability:"applications:manage",anyUser:!0},"POST /api/compose/action":{capability:"project:read",anyUser:!0},"POST /api/compose/logs":{capability:"runtime:logs",anyUser:!0},"POST /api/compose/shell":{capability:"runtime:terminal",scope:"organization"},"GET /api/compose/import":{capability:"applications:manage"},"GET /api/compose/template":{capability:"applications:manage"},"GET /api/compose/logs":{capability:"runtime:logs"},"GET /api/compose/shell":{capability:"runtime:terminal",scope:"organization"},"GET /api/organization":{capability:"users:read",scope:"organization"},"GET /api/organization/invitations":{capability:"users:read",scope:"organization"},"POST /api/organization/invitations":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/invitations":{capability:"users:manage",scope:"organization"},"POST /api/organization/invitations/resend":{capability:"users:manage",scope:"organization"},"PATCH /api/organization/memberships":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/memberships":{capability:"users:manage",scope:"organization"},"POST /api/organization/grants":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/grants":{capability:"users:manage",scope:"organization"},"GET /api/control-plane/operations":{capability:"deployments:read"},"GET /api/control-plane/events":{capability:"audit:read"},"GET /api/queue":{capability:"deployments:read",anyUser:!0},"GET /api/queue/logs":{capability:"deployments:read",anyUser:!0},"GET /api/queue/stream":{capability:"deployments:read",anyUser:!0},"POST /api/queue/cancel":{capability:"deployments:cancel",anyUser:!0},"POST /api/queue/retry":{capability:"deployments:create",anyUser:!0},"GET /api/queue/settings":{capability:"deployments:read"},"PATCH /api/queue/settings":{capability:"automation:manage",scope:"organization"},"DELETE /api/queue/history":{capability:"automation:manage",scope:"organization"},"GET /api/previews":{capability:"deployments:read",anyUser:!0},"GET /api/releases":{capability:"deployments:read",anyUser:!0},"POST /api/releases/action":{capability:"deployments:create",anyUser:!0},"POST /api/previews/deploy":{capability:"deployments:create",anyUser:!0},"POST /api/previews/destroy":{capability:"deployments:cancel",anyUser:!0},"POST /api/previews/extend":{capability:"deployments:create",anyUser:!0},"POST /api/previews/rebuild":{capability:"deployments:create",anyUser:!0},"POST /api/previews/definitions":{capability:"config:write",anyUser:!0},"POST /api/previews/cleanup":{capability:"automation:manage",scope:"organization"},"GET /api/tags":{capability:"project:read"},"POST /api/tags":{capability:"tags:manage"},"DELETE /api/tags":{capability:"tags:manage"},"POST /api/sites/deploy":{capability:"deployments:create",scope:"site",siteFrom:"body"},"PATCH /api/sites":{capability:"config:write",scope:"site",siteFrom:"body"},"POST /api/sites":{capability:"config:write"},"DELETE /api/sites":{capability:"config:write"},"POST /api/env":{capability:"config:write"},"GET /api/ssh-keys":{capability:"fleet:read"},"POST /api/ssh-keys":{capability:"fleet:manage"},"DELETE /api/ssh-keys":{capability:"fleet:manage"},"GET /api/firewall":{capability:"fleet:read"},"POST /api/firewall":{capability:"fleet:manage"},"DELETE /api/firewall":{capability:"fleet:manage"},"GET /api/databases":{capability:"data:read"},"POST /api/databases":{capability:"data:admin"},"GET /api/databases/vitess":{capability:"data:read"},"GET /api/databases/vitess/migrations":{capability:"data:read"},"POST /api/databases/vitess/migrations/action":{capability:"data:admin"},"POST /api/databases/vitess/provision":{capability:"runtime:terminal",scope:"organization"},"POST /api/databases/vitess/keyspaces":{capability:"data:admin"},"POST /api/databases/vitess/vschema":{capability:"data:admin"},"POST /api/databases/vitess/schema":{capability:"data:admin"},"POST /api/databases/vitess/install-client":{capability:"data:admin"},"GET /api/databases/backups":{capability:"backups:read"},"POST /api/databases/backup":{capability:"backups:create"},"POST /api/databases/users":{capability:"data:admin"},"GET /api/data-services":{capability:"data:read"},"GET /api/data-services/capabilities":{capability:"data:read"},"GET /api/data-services/connections":{capability:"data:read"},"POST /api/data-services/preview":{capability:"data:read"},"POST /api/data-services":{capability:"data:admin"},"POST /api/data-services/action":{capability:"data:admin"},"POST /api/data-services/dependencies":{capability:"data:admin"},"POST /api/data-services/management":{capability:"data:admin"},"POST /api/data-services/reveal":{capability:"data:admin"},"GET /api/backups":{capability:"backups:read"},"POST /api/backups/destinations":{capability:"backups:create"},"POST /api/backups/destinations/test":{capability:"backups:create"},"POST /api/backups/policies":{capability:"backups:create"},"POST /api/backups/run":{capability:"backups:create"},"POST /api/backups/verify":{capability:"backups:create"},"POST /api/backups/restore":{capability:"backups:restore"},"POST /api/backups/recovery-points":{capability:"backups:create"},"POST /api/backups/retention":{capability:"backups:create"},"GET /api/configuration":{capability:"config:read"},"GET /api/configuration/export":{capability:"config:read"},"POST /api/configuration/plan":{capability:"config:read"},"POST /api/configuration":{capability:"config:write"},"POST /api/configuration/import":{capability:"config:write"},"POST /api/configuration/dependencies":{capability:"config:write"},"POST /api/configuration/transfer":{capability:"config:write"},"POST /api/configuration/bulk":{capability:"config:write"},"POST /api/configuration/reveal":{capability:"secrets:read"},"DELETE /api/configuration":{capability:"config:write"},"GET /api/volumes":{capability:"data:read"},"POST /api/volumes":{capability:"data:admin"},"POST /api/volumes/attach":{capability:"data:admin"},"POST /api/volumes/detach":{capability:"data:admin"},"POST /api/volumes/resize":{capability:"data:admin"},"POST /api/volumes/snapshot":{capability:"backups:create"},"POST /api/volumes/restore":{capability:"backups:restore"},"POST /api/volumes/adopt":{capability:"data:admin"},"POST /api/volumes/discover":{capability:"data:read"},"DELETE /api/volumes":{capability:"data:admin"},"GET /api/fleet":{capability:"fleet:read"},"POST /api/fleet":{capability:"fleet:manage"},"POST /api/fleet/action":{capability:"fleet:manage"},"GET /api/capacity":{capability:"fleet:read"},"POST /api/capacity":{capability:"fleet:manage"},"POST /api/capacity/member":{capability:"fleet:manage"},"POST /api/capacity/explain":{capability:"fleet:read"},"POST /api/capacity/action":{capability:"fleet:manage"},"GET /api/regions":{capability:"config:read"},"POST /api/regions":{capability:"config:write"},"POST /api/regions/action":{capability:"config:write"},"GET /api/maintenance":{capability:"automation:read"},"POST /api/maintenance/cleanup-preview":{capability:"automation:manage"},"POST /api/maintenance/cleanup-apply":{capability:"automation:manage"},"POST /api/maintenance/drill":{capability:"automation:manage"},"POST /api/maintenance/drill-run":{capability:"automation:manage"},"GET /api/actions":{capability:"runtime:read"},"GET /api/runtime/workloads":{capability:"runtime:read"},"GET /api/runtime/logs":{capability:"runtime:logs"},"POST /api/runtime/log-sessions":{capability:"runtime:logs"},"GET /api/runtime/log-sessions":{capability:"runtime:logs"},"GET /api/runtime/log-stream":{capability:"runtime:logs"},"DELETE /api/runtime/log-sessions":{capability:"runtime:logs"},"POST /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"GET /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"GET /api/runtime/exec-stream":{capability:"runtime:terminal",scope:"organization"},"DELETE /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/files/read":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/files/write":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/operations":{capability:"runtime:restart"},"GET /api/telemetry/status":{capability:"runtime:read"},"GET /api/telemetry/settings":{capability:"runtime:read"},"PATCH /api/telemetry/settings":{capability:"config:write",scope:"organization"},"GET /api/telemetry/query":{capability:"runtime:logs"},"GET /api/telemetry/tail":{capability:"runtime:logs"},"GET /api/telemetry/series":{capability:"runtime:read"},"POST /api/telemetry/refresh":{capability:"runtime:logs"},"POST /api/telemetry/export":{capability:"runtime:logs"},"GET /api/telemetry/saved-queries":{capability:"runtime:logs"},"POST /api/telemetry/saved-queries":{capability:"runtime:logs"},"DELETE /api/telemetry/saved-queries":{capability:"runtime:logs"},"GET /api/health/checks":{capability:"runtime:read"},"POST /api/health/checks":{capability:"config:write"},"PATCH /api/health/checks":{capability:"config:write"},"POST /api/health/checks/test":{capability:"runtime:read"},"POST /api/health/checks/run":{capability:"runtime:restart"},"GET /api/protection":{capability:"security:read"},"POST /api/protection/attack-mode":{capability:"security:manage"},"POST /api/protection/pause":{capability:"security:manage"},"GET /api/protection/ip-rules":{capability:"security:read"},"POST /api/protection/ip-rules":{capability:"security:manage"},"DELETE /api/protection/ip-rules":{capability:"security:manage"},"GET /api/usage":{capability:"billing:read"},"GET /api/spend/budgets":{capability:"billing:read"},"POST /api/spend/budgets":{capability:"billing:manage"},"PATCH /api/spend/budgets":{capability:"billing:manage"},"DELETE /api/spend/budgets":{capability:"billing:manage"},"POST /api/spend/check":{capability:"billing:manage"},"GET /api/spend/enforcement":{capability:"billing:read"},"POST /api/spend/release":{capability:"billing:manage"},"GET /api/spend/anomalies":{capability:"billing:read"},"POST /api/spend/anomalies/acknowledge":{capability:"billing:manage"},"GET /api/alerts":{capability:"runtime:read"},"GET /api/alerts/rules":{capability:"runtime:read"},"POST /api/alerts/rules":{capability:"config:write"},"PATCH /api/alerts/rules":{capability:"config:write"},"POST /api/alerts/evaluate":{capability:"runtime:restart"},"POST /api/alerts/action":{capability:"runtime:restart"},"POST /api/alerts/silences":{capability:"config:write"},"GET /api/notifications/channels":{capability:"automation:read",scope:"organization"},"POST /api/notifications/channels":{capability:"automation:manage",scope:"organization"},"PATCH /api/notifications/channels":{capability:"automation:manage",scope:"organization"},"POST /api/notifications/channels/test":{capability:"automation:manage",scope:"organization"},"GET /api/notifications/routes":{capability:"automation:read",scope:"organization"},"POST /api/notifications/routes":{capability:"automation:manage",scope:"organization"},"PATCH /api/notifications/routes":{capability:"automation:manage",scope:"organization"},"POST /api/notifications/routes/preview":{capability:"automation:read",scope:"organization"},"GET /api/notifications/deliveries":{capability:"automation:read",scope:"organization"},"POST /api/notifications/deliveries/retry":{capability:"automation:manage",scope:"organization"},"GET /api/jobs":{capability:"automation:read"},"POST /api/jobs":{capability:"automation:manage"},"PATCH /api/jobs":{capability:"automation:manage"},"POST /api/jobs/preview":{capability:"automation:read"},"POST /api/jobs/action":{capability:"automation:manage"},"POST /api/jobs/reconcile":{capability:"automation:manage"},"GET /api/jobs/history":{capability:"automation:read"},"GET /api/workers":{capability:"automation:read"},"POST /api/workers/action":{capability:"automation:manage"},"POST /api/actions/run":{capability:"fleet:manage"},"GET /api/server/operations":{capability:"fleet:read"},"POST /api/server/operations/run":{capability:"fleet:manage"},"POST /api/server/command":{capability:"runtime:terminal",scope:"organization"},"GET /api/terminal":{capability:"runtime:terminal",scope:"organization"},"GET /api/users":{capability:"users:read",scope:"organization"},"POST /api/users":{capability:"users:manage",scope:"organization"},"DELETE /api/users":{capability:"users:manage",scope:"organization"},"GET /api/serverless/operations":{capability:"deployments:read"},"POST /api/serverless/operations/run":{capability:"deployments:create"},"POST /api/serverless/command":{capability:"runtime:terminal",scope:"organization"},"GET /api/serverless/dlq":{capability:"data:read"},"POST /api/serverless/dlq/redrive":{capability:"data:write"},"POST /api/serverless/dlq/purge":{capability:"data:admin"},"GET /api/serverless/secrets":{capability:"secrets:read"},"POST /api/serverless/secrets":{capability:"secrets:write"},"DELETE /api/serverless/secrets":{capability:"secrets:write"},"POST /api/serverless/functions/config":{capability:"config:write"},"GET /api/serverless/alarms":{capability:"runtime:read"},"POST /api/serverless/alarms":{capability:"config:write"},"DELETE /api/serverless/alarms":{capability:"config:write"},"GET /api/serverless/traces":{capability:"runtime:read"},"POST /api/serverless/scheduler":{capability:"automation:manage"}};function Wl(e,t){return XE[`${e.toUpperCase()} ${t}`]??YE}import{createHmac as ZE,randomBytes as eT,timingSafeEqual as tT}from"node:crypto";import{chmodSync as rT,existsSync as nT,mkdirSync as iT,readFileSync as oT,writeFileSync as sT}from"node:fs";import{dirname as aT}from"node:path";var _a="ts_cloud_session";var cT=28800000;function fy(e){let t=process.env.TS_CLOUD_DASHBOARD_SECRET?.trim();if(t)return t;let r=R(e,"dashboard-secret");try{if(nT(r)){let i=oT(r,"utf8").trim();if(i)return i}}catch{}let n=eT(32).toString("base64url");try{iT(aT(r),{recursive:!0}),sT(r,`${n}
|
|
171
171
|
`),rT(r,384)}catch{}return n}function dT(e,t){return ZE("sha256",t).update(e).digest("base64url")}function hy(e,t){if(!e)return null;let r=e.lastIndexOf(".");if(r<=0)return null;let n=e.slice(0,r),i=e.slice(r+1),o=dT(n,t),s=Buffer.from(i),c=Buffer.from(o);if(s.length!==c.length||!tT(s,c))return null;try{let u=JSON.parse(Buffer.from(n,"base64url").toString("utf8"));if(typeof u?.u!=="string"||typeof u?.exp!=="number")return null;if(u.mv!==void 0&&(!u.mv||typeof u.mv!=="object"||Array.isArray(u.mv)||Object.values(u.mv).some((a)=>!Number.isInteger(a)||a<1)))return null;if(Date.now()>=u.exp)return null;return u}catch{return null}}function Kl(e,t){if(!e)return;for(let r of e.split(";")){let n=r.indexOf("=");if(n<0)continue;if(r.slice(0,n).trim()===t)return decodeURIComponent(r.slice(n+1).trim())}return}function ra(e,t={secure:!0}){let r=Math.floor((t.maxAgeMs??cT)/1000),n=[`${_a}=${encodeURIComponent(e)}`,"Path=/","HttpOnly","SameSite=Lax",`Max-Age=${r}`];if(t.secure)n.push("Secure");return n.join("; ")}function Sd(e={secure:!0}){let t=[`${_a}=`,"Path=/","HttpOnly","SameSite=Lax","Max-Age=0"];if(e.secure)t.push("Secure");return t.join("; ")}import{chmodSync as uT,existsSync as lT,mkdirSync as pT,readFileSync as gT,writeFileSync as mT}from"node:fs";import{dirname as fT}from"node:path";function yy(){return je("dashboard-users.json")}function vd(e){return/^[a-z0-9][a-z0-9._-]{1,31}$/i.test(e)}function hT(e){if(!e||typeof e.username!=="string"||!vd(e.username)||typeof e.passwordHash!=="string")return null;let t=e.role==="admin"?"admin":"member",r={};if(e.sites&&typeof e.sites==="object"){for(let[n,i]of Object.entries(e.sites))if(i==="owner"||i==="collaborator")r[n]=i}return{username:e.username,passwordHash:e.passwordHash,role:t,sites:r,name:typeof e.name==="string"?e.name:void 0,email:typeof e.email==="string"?e.email.trim().toLowerCase():void 0,createdAt:typeof e.createdAt==="string"?e.createdAt:void 0}}function yT(e){try{let t=JSON.parse(e);if(!Array.isArray(t?.users))return[];return t.users.map(hT).filter((r)=>r!==null)}catch{return[]}}function by(e){return R(e,"dashboard-users.json")}function nn(e){let t=by(e);if(!lT(t))return[];try{return yT(gT(t,"utf8"))}catch{return[]}}function wd(e,t){let r=by(e);pT(fT(r),{recursive:!0}),mT(r,`${JSON.stringify({users:t},null,2)}
|
|
172
|
-
`),uT(r,384)}function Nn(e,t){let r=t.trim().toLowerCase();return e.find((n)=>n.username.toLowerCase()===r)}function Sy(e,t="admin"){let r=nn(e);if(r.some((s)=>s.role==="admin"))return{users:r};let n=process.env.TS_CLOUD_UI_PASSWORD?.trim()||Jl(),i={username:t,passwordHash:$o(n),role:"admin",sites:{},name:"Administrator",createdAt:new Date().toISOString()},o=[...r,i];return wd(e,o),{users:o,generated:{username:t,password:n}}}function Na(e,t){let r=nn(e),n=Nn(r,t.username),i=t.password?.trim()||(n?void 0:Jl()),o={username:n?.username??t.username,passwordHash:i?$o(i):n.passwordHash,role:n?.role??"member",sites:t.sites,name:t.name??n?.name,email:t.email?.trim().toLowerCase()??n?.email,createdAt:n?.createdAt??new Date().toISOString()},s=n?r.map((c)=>c.username.toLowerCase()===o.username.toLowerCase()?o:c):[...r,o];return wd(e,s),{user:o,password:i}}function Id(e,t,r){let n=nn(e),i=Nn(n,t);if(!i)throw Error("Authentication user was not found");let o={...i,passwordHash:r};return wd(e,n.map((s)=>s.username.toLowerCase()===i.username.toLowerCase()?o:s)),o}function Ql(e,t){let r=nn(e),n=Nn(r,t);if(!n)return{ok:!1,error:`No such user: ${t}`};if(n.role==="admin"&&r.filter((i)=>i.role==="admin").length===1)return{ok:!1,error:"Cannot remove the last admin."};return wd(e,r.filter((i)=>i.username.toLowerCase()!==n.username.toLowerCase())),{ok:!0}}function ia(e){return{username:e.username,name:e.name??e.username,role:e.role,email:e.email,sites:e.sites,siteCount:Object.keys(e.sites).length,createdAt:e.createdAt}}var bT={username:"local",passwordHash:"",role:"admin",sites:{},name:"Local (auth disabled)"};function vy(e){let{cwd:t,enabled:r,secret:n,authorization:i,authentication:o}=e,s=(u)=>{if(!o)return;let a=Kl(u.headers.get("cookie"),_a);return a?.startsWith("v2.")?o.verifySessionToken(a):void 0},c=(u)=>{let a=i.store.getActorByExternalId("user",`dashboard:${u.username.toLowerCase()}`),f=a?i.store.getMembershipForActor(i.organizationId,a.id):void 0;return{actor:a,membership:f}};return{enabled:r,resolveUser(u){if(!r)return bT;let a=Kl(u.headers.get("cookie"),_a),f=s(u),C=f?void 0:hy(a,n),k=f?.identity.username??C?.u;if(!k)return null;let D=Nn(nn(t),k);if(!D)return null;let{membership:W}=c(D);if(!W||W.status!=="active"||!f&&C?.mv?.[i.organizationId]!==W.sessionVersion)return null;if(!W.lastActiveAt||Date.now()-new Date(W.lastActiveAt).getTime()>300000)i.store.touchMembership(W.id);return D},resolveSession(u){return s(u)?.session??null},check(u,a,f,C){if(!r)return{ok:!0};if(!f)return{ok:!1,status:401,error:"Sign in to continue.",unauthenticated:!0};let k=Wl(u.method,a);if(k.anyUser)return{ok:!0};if(k.siteFrom==="body"&&!C)return{ok:!1,status:400,error:"This request must name a site."};let{membership:D}=c(f);if(!D)return{ok:!1,status:401,error:"Sign in to continue.",unauthenticated:!0};let W=k.scope==="organization"?{organizationId:i.organizationId}:i.store.resolveAuthorizationTarget(i.organizationId,{type:"project",id:i.projectId});if(k.scope==="site"){let ee=new URL(u.url).searchParams.get("env")??i.defaultEnvironment,ne=i.store.getEnvironmentBySlug(i.projectId,ee),he=i.store.listResources(i.projectId,ne?.id).find((te)=>te.kind==="application"&&te.slug===C);W=he?i.store.resolveAuthorizationTarget(i.organizationId,{type:"resource",id:he.id}):void 0}if(!(W?re({membership:D,grants:i.store.listGrants(D.id),capability:k.capability,target:W}):{allowed:!1}).allowed)return{ok:!1,status:403,error:"You do not have access to this."};return{ok:!0}}}}async function wy(e,t){if(Wl(e.method,t).siteFrom!=="body")return;try{let n=await e.clone().json();return String(n?.name??"").trim()||void 0}catch{return}}import{createHash as ST}from"node:crypto";function Iy(e,t,r){for(let n of r){let i=
|
|
172
|
+
`),uT(r,384)}function Nn(e,t){let r=t.trim().toLowerCase();return e.find((n)=>n.username.toLowerCase()===r)}function Sy(e,t="admin"){let r=nn(e);if(r.some((s)=>s.role==="admin"))return{users:r};let n=process.env.TS_CLOUD_UI_PASSWORD?.trim()||Jl(),i={username:t,passwordHash:$o(n),role:"admin",sites:{},name:"Administrator",createdAt:new Date().toISOString()},o=[...r,i];return wd(e,o),{users:o,generated:{username:t,password:n}}}function Na(e,t){let r=nn(e),n=Nn(r,t.username),i=t.password?.trim()||(n?void 0:Jl()),o={username:n?.username??t.username,passwordHash:i?$o(i):n.passwordHash,role:n?.role??"member",sites:t.sites,name:t.name??n?.name,email:t.email?.trim().toLowerCase()??n?.email,createdAt:n?.createdAt??new Date().toISOString()},s=n?r.map((c)=>c.username.toLowerCase()===o.username.toLowerCase()?o:c):[...r,o];return wd(e,s),{user:o,password:i}}function Id(e,t,r){let n=nn(e),i=Nn(n,t);if(!i)throw Error("Authentication user was not found");let o={...i,passwordHash:r};return wd(e,n.map((s)=>s.username.toLowerCase()===i.username.toLowerCase()?o:s)),o}function Ql(e,t){let r=nn(e),n=Nn(r,t);if(!n)return{ok:!1,error:`No such user: ${t}`};if(n.role==="admin"&&r.filter((i)=>i.role==="admin").length===1)return{ok:!1,error:"Cannot remove the last admin."};return wd(e,r.filter((i)=>i.username.toLowerCase()!==n.username.toLowerCase())),{ok:!0}}function ia(e){return{username:e.username,name:e.name??e.username,role:e.role,email:e.email,sites:e.sites,siteCount:Object.keys(e.sites).length,createdAt:e.createdAt}}var bT={username:"local",passwordHash:"",role:"admin",sites:{},name:"Local (auth disabled)"};function vy(e){let{cwd:t,enabled:r,secret:n,authorization:i,authentication:o}=e,s=(u)=>{if(!o)return;let a=Kl(u.headers.get("cookie"),_a);return a?.startsWith("v2.")?o.verifySessionToken(a):void 0},c=(u)=>{let a=i.store.getActorByExternalId("user",`dashboard:${u.username.toLowerCase()}`),f=a?i.store.getMembershipForActor(i.organizationId,a.id):void 0;return{actor:a,membership:f}};return{enabled:r,resolveUser(u){if(!r)return bT;let a=Kl(u.headers.get("cookie"),_a),f=s(u),C=f?void 0:hy(a,n),k=f?.identity.username??C?.u;if(!k)return null;let D=Nn(nn(t),k);if(!D)return null;let{membership:W}=c(D);if(!W||W.status!=="active"||!f&&C?.mv?.[i.organizationId]!==W.sessionVersion)return null;if(!W.lastActiveAt||Date.now()-new Date(W.lastActiveAt).getTime()>300000)i.store.touchMembership(W.id);return D},resolveSession(u){return s(u)?.session??null},check(u,a,f,C){if(!r)return{ok:!0};if(!f)return{ok:!1,status:401,error:"Sign in to continue.",unauthenticated:!0};let k=Wl(u.method,a);if(k.anyUser)return{ok:!0};if(k.siteFrom==="body"&&!C)return{ok:!1,status:400,error:"This request must name a site."};let{membership:D}=c(f);if(!D)return{ok:!1,status:401,error:"Sign in to continue.",unauthenticated:!0};let W=k.scope==="organization"?{organizationId:i.organizationId}:i.store.resolveAuthorizationTarget(i.organizationId,{type:"project",id:i.projectId});if(k.scope==="site"){let ee=new URL(u.url).searchParams.get("env")??i.defaultEnvironment,ne=i.store.getEnvironmentBySlug(i.projectId,ee),he=i.store.listResources(i.projectId,ne?.id).find((te)=>te.kind==="application"&&te.slug===C);W=he?i.store.resolveAuthorizationTarget(i.organizationId,{type:"resource",id:he.id}):void 0}if(!(W?re({membership:D,grants:i.store.listGrants(D.id),capability:k.capability,target:W}):{allowed:!1}).allowed)return{ok:!1,status:403,error:"You do not have access to this."};return{ok:!0}}}}async function wy(e,t){if(Wl(e.method,t).siteFrom!=="body")return;try{let n=await e.clone().json();return String(n?.name??"").trim()||void 0}catch{return}}import{createHash as ST}from"node:crypto";function Iy(e,t,r){for(let n of r){let i=er(t.store,n);if(e.getIdentityByActor(i.id))continue;e.createIdentity({actorId:i.id,username:n.username,email:n.email,emailVerified:!!n.email,passwordHash:n.passwordHash,requiresPasswordUpgrade:!0})}}function vT(e,t,r){let n=r.split("@")[0].toLowerCase().replace(/[^a-z0-9._-]/g,"-").replace(/^[^a-z0-9]+/,"").slice(0,24),i=/^[a-z0-9][a-z0-9._-]{1,31}$/.test(n)?n:"sso-user";if(!e.getIdentityByUsername(i)&&!Nn(t,i))return i;let o=ST("sha256").update(r).digest("hex").slice(0,7);return`${i.slice(0,24)}-${o}`}function Cy(e,t,r,n){if(n.provider.organizationId!==t.organization.id)throw Error("OIDC provider is not configured for this organization");let i=e.getOidcSubject(n.provider.id,n.subject),o=i?e.getIdentity(i.identityId):e.getIdentityByEmail(n.email);if(o?.disabledAt)throw Error("OIDC identity is disabled");if(!i&&o&&!o.emailVerifiedAt)throw Error("OIDC cannot automatically link an unverified local email address");let s=nn(r),c=!1,u=o?Nn(s,o.username):void 0;if(o&&!u)throw Error("OIDC identity has no dashboard user");if(!o){let C=vT(e,s,n.email);u=Na(r,{username:C,name:n.name,email:n.email,sites:{}}).user;let D=er(t.store,u);o=e.createIdentity({actorId:D.id,username:u.username,email:n.email,emailVerified:!0,passwordHash:u.passwordHash}),c=!0}else if(o.email!==n.email)o=e.setVerifiedEmail(o.id,n.email);let a=t.store.getActor(o.actorId);if(!a)throw Error("OIDC identity actor was not found");let f=t.store.getMembershipForActor(t.organization.id,a.id);if(f?.status==="revoked")throw Error("OIDC organization membership is revoked");if(!f)t.store.createMembership({organizationId:t.organization.id,actorId:a.id,roleTemplate:n.provider.defaultRole,scope:{type:"organization"},source:"manual"});return e.linkOidcSubject(n.provider.id,o.id,n.subject,n.email),{identity:o,user:u,provisioned:c}}function Ey(e,t,r){let n=t.store.getMembershipForActor(t.organization.id,r.actorId);if(!n||n.status!=="active"||n.roleTemplate==="owner"||!r.emailVerifiedAt||!r.email)return!1;let i=r.email.split("@")[1]?.toLowerCase();return e.listOidcProviders(t.organization.id).some((o)=>o.enforceSso&&!!i&&o.allowedDomains.includes(i))}function wT(e){return e.replace(/[&<>"']/g,(t)=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}function Ty(e=!1,t=[]){let r=e?"/serverless":"/",n=t.map((o)=>`<a class="sso-button" href="/auth/oidc/${encodeURIComponent(o.slug)}/start?return=${encodeURIComponent(r)}">Continue with ${wT(o.name)}</a>`).join("");return`<!doctype html>
|
|
173
173
|
<html lang="en">
|
|
174
174
|
<head>
|
|
175
175
|
<meta charset="UTF-8">
|
|
@@ -456,7 +456,7 @@ data: ${JSON.stringify(rt)}
|
|
|
456
456
|
},
|
|
457
457
|
${u}`}class Zl{client;region;constructor(e="us-east-1"){this.region=e,this.client=new p}async getTraceSummaries(e){let t={StartTime:Math.floor(e.startTime.getTime()/1000),EndTime:Math.floor(e.endTime.getTime()/1000),TimeRangeType:"Event",Sampling:!1};if(e.filterExpression)t.FilterExpression=e.filterExpression;if(e.nextToken)t.NextToken=e.nextToken;let r=await this.client.request({service:"xray",region:this.region,method:"POST",path:"/TraceSummaries",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});return{summaries:r?.TraceSummaries??[],nextToken:r?.NextToken}}async batchGetTraces(e){if(!e.length)return[];return(await this.client.request({service:"xray",region:this.region,method:"POST",path:"/Traces",headers:{"Content-Type":"application/json"},body:JSON.stringify({TraceIds:e.slice(0,5)})}))?.Traces??[]}}var Fy=65536;function jr(e){return e.length<=Fy?e:`${e.slice(0,Fy)}
|
|
458
458
|
|
|
459
|
-
[output truncated]`}function tp(e,t){return e.environments?.[t]?.app}function rp(e,t,r){let n=[],i=tp(e,t);n.push({id:"redeploy",label:"Redeploy current build",group:"deploy",target:"app",mutates:!0,confirm:"redeploy"}),n.push({id:"rollback",label:"Roll back to previous build",group:"deploy",target:"app",mutates:!0,confirm:"rollback",danger:!0});let o=r.maintenance?.enabled;if(o!==!0)n.push({id:"maintenance:on",label:"Enable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"maintenance",danger:!0});if(o!==!1)n.push({id:"maintenance:off",label:"Disable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"live"});if(i?.assets||r.assetsInfo)n.push({id:"assets:invalidate",label:"Invalidate CDN cache",group:"assets",target:"assets",mutates:!0,confirm:"invalidate"});if(i?.database?.connection==="aurora-serverless")n.push({id:"db:scale",label:"Scale Aurora capacity",group:"database",target:"database",mutates:!0,confirm:"scale",inputs:[{name:"min",label:"Min ACUs",placeholder:String(i.database.minCapacity??0.5)},{name:"max",label:"Max ACUs",placeholder:String(i.database.maxCapacity??4)}]});for(let s of r.queues??[]){let c=String(s?.name??"").trim();if(c&&/^[A-Za-z0-9_-]+$/.test(c))n.push({id:`queue:purge:${c}`,label:`Purge queue (${c})`,group:"queue",target:c,mutates:!0,confirm:c,danger:!0})}return n}function jy(e,t,r,n){return rp(t,r,n).find((i)=>i.id===e)}async function kT(e,t,r){try{let n=new v(r),{Stacks:i}=await n.describeStacks({stackName:Oe(e,t)}),o={};for(let u of i?.[0]?.Outputs??[])if(u.OutputKey)o[u.OutputKey]=u.OutputValue??"";let s=o.AssetsCdnDomain;if(!s)return null;return(await new E(r).findDistributionByDomain(s))?.Id??null}catch{return null}}async function Uy(e,t,r,n={}){try{if(r.id==="redeploy")return await Ms(e,t),{operation:r.id,command:"serverless redeploy",ok:!0,stdout:"Redeploy complete."};if(r.id==="rollback")return await Us(e,t),{operation:r.id,command:"serverless rollback",ok:!0,stdout:"Rollback complete."};if(r.id==="maintenance:on")return await _o(e,t,!0),{operation:r.id,command:"maintenance on",ok:!0,stdout:"Application is now in maintenance mode."};if(r.id==="maintenance:off")return await _o(e,t,!1),{operation:r.id,command:"maintenance off",ok:!0,stdout:"Application is live."};if(r.id==="db:scale"){let i=Number(n.min),o=Number(n.max);if(!Number.isFinite(i)||!Number.isFinite(o)||i<=0||o<i)return{operation:r.id,ok:!1,error:"Provide valid Aurora capacities (0 < min ≤ max)."};return await Fs(e,t,i,o),{operation:r.id,command:`db:scale ${i}-${o} ACU`,ok:!0,stdout:`Scaling applied (${i}-${o} ACUs); takes effect shortly.`}}if(r.id==="assets:invalidate"){let i=await z(e,t),o=await kT(e,t,i.region);if(!o)return{operation:r.id,ok:!1,error:"Could not resolve the asset CloudFront distribution for this environment."};let c=await new E(i.region).invalidateAll(o);return{operation:r.id,command:`cloudfront invalidate ${o} /*`,ok:!0,stdout:`Invalidation ${c?.Id??"created"} for ${o} (/*).`}}if(r.group==="queue"&&r.id.startsWith("queue:purge:")){let i=r.target,o=await z(e,t),s=new V(o.region),c=`${o.slug}-${t}-${i}`,{QueueUrl:u}=await s.getQueueUrl(c);return await s.purgeQueue(u),{operation:r.id,command:`sqs purge ${c}`,ok:!0,stdout:`Purged queue ${c}.`}}return{operation:r.id,ok:!1,error:"Unknown or unavailable serverless operation."}}catch(i){return{operation:r.id,ok:!1,error:jr(i?.message??String(i))}}}async function zy(e,t,r){let n=r.trim();if(!n)return{operation:"command",ok:!1,error:"A command is required."};try{let i=await Vt(e,t,n);return{operation:"command",command:n,ok:!0,stdout:jr(i||"(no output)")}}catch(i){return{operation:"command",command:n,ok:!1,error:jr(i?.message??String(i))}}}var np="No dead-letter queue is provisioned for this environment.";async function ip(e,t,r){try{let{QueueUrl:n}=await e.getQueueUrl(`${t}-${r}-dlq`);return n}catch{return null}}async function Vy(e,t,r=10){try{let n=await z(e,t),i=new V(n.region),o=await ip(i,n.slug,t);if(!o)return{ok:!1,messages:[],error:np};return{ok:!0,messages:((await i.receiveMessages({queueUrl:o,maxMessages:Math.min(10,Math.max(1,r)),waitTimeSeconds:1,visibilityTimeout:2})).Messages??[]).map((u)=>({id:u.MessageId,receiptHandle:u.ReceiptHandle,body:jr(String(u.Body??""))}))}}catch(n){return{ok:!1,messages:[],error:jr(n?.message??String(n))}}}async function qy(e,t,r={}){try{let n=await z(e,t),i=tp(e,t),s=(i?Qt(i,n.slug,t):[]).map((D)=>D.name.replace(`${n.slug}-${t}-`,"")),c=r.targetQueue&&s.includes(r.targetQueue)?r.targetQueue:s[0];if(!c)return{operation:"dlq:redrive",ok:!1,error:"No source queue is configured to redrive into."};let u=new V(n.region),a=await ip(u,n.slug,t);if(!a)return{operation:"dlq:redrive",ok:!1,error:np};let{QueueUrl:f}=await u.getQueueUrl(`${n.slug}-${t}-${c}`),C=Math.min(50,Math.max(1,r.max??10)),k=0;while(k<C){let W=(await u.receiveMessages({queueUrl:a,maxMessages:Math.min(10,C-k),waitTimeSeconds:1,visibilityTimeout:30})).Messages??[];if(!W.length)break;for(let Y of W)await u.sendMessage({queueUrl:f,messageBody:String(Y.Body??"")}),await u.deleteMessage(a,Y.ReceiptHandle),k++}return{operation:"dlq:redrive",command:`redrive → ${c}`,ok:!0,stdout:`Moved ${k} message(s) from the DLQ to ${c}.`}}catch(n){return{operation:"dlq:redrive",ok:!1,error:jr(n?.message??String(n))}}}async function Gy(e,t){try{let r=await z(e,t),n=new V(r.region),i=await ip(n,r.slug,t);if(!i)return{operation:"dlq:purge",ok:!1,error:np};return await n.purgeQueue(i),{operation:"dlq:purge",command:"sqs purge dlq",ok:!0,stdout:"Dead-letter queue purged."}}catch(r){return{operation:"dlq:purge",ok:!1,error:jr(r?.message??String(r))}}}function Jy(e,t){let r=tp(e,t);if(!r?.secrets)return[];return Array.isArray(r.secrets)?r.secrets.map((n)=>({key:n.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),secretId:n})):Object.entries(r.secrets).map(([n,i])=>({key:n,secretId:String(i)}))}async function Hy(e,t,r,n){if(!r.trim())return{operation:"secret:set",ok:!1,error:"A secret id is required."};try{let i=await z(e,t),o=new K(i.region);try{await o.putSecretValue({SecretId:r,SecretString:n})}catch{await o.createSecret({Name:r,SecretString:n})}return{operation:"secret:set",command:`secret set ${r}`,ok:!0,stdout:`Secret ${r} updated. Redeploy to apply it to the functions.`}}catch(i){return{operation:"secret:set",ok:!1,error:jr(i?.message??String(i))}}}async function Wy(e,t,r){if(!r.trim())return{operation:"secret:delete",ok:!1,error:"A secret id is required."};try{let n=await z(e,t);return await new K(n.region).deleteSecret({SecretId:r,RecoveryWindowInDays:7}),{operation:"secret:delete",command:`secret delete ${r}`,ok:!0,stdout:`Secret ${r} scheduled for deletion (recoverable for 7 days).`}}catch(n){return{operation:"secret:delete",ok:!1,error:jr(n?.message??String(n))}}}var RT=new Set(["http","queue","cli"]);async function Ky(e,t,r,n){if(!RT.has(r))return{operation:"function:config",ok:!1,error:`Unknown function mode '${r}'.`};let i=n.memory==null?void 0:Number(n.memory),o=n.timeout==null?void 0:Number(n.timeout);if(i!=null&&(!Number.isInteger(i)||i<128||i>10240))return{operation:"function:config",ok:!1,error:"Memory must be an integer between 128 and 10240 MB."};if(o!=null&&(!Number.isInteger(o)||o<1||o>900))return{operation:"function:config",ok:!1,error:"Timeout must be an integer between 1 and 900 seconds."};if(i==null&&o==null)return{operation:"function:config",ok:!1,error:"Provide a memory and/or timeout value."};try{let s=await z(e,t),c=new P(s.region),u=`${s.slug}-${t}-${r}`;await c.updateFunctionConfiguration({FunctionName:u,...i!=null?{MemorySize:i}:{},...o!=null?{Timeout:o}:{}});let a=[i!=null?`${i} MB`:"",o!=null?`${o}s`:""].filter(Boolean).join(", ");return{operation:"function:config",command:`update ${u} (${a})`,ok:!0,stdout:`Updated ${u}: ${a}.`}}catch(s){return{operation:"function:config",ok:!1,error:jr(s?.message??String(s))}}}var ep=[{key:"http-errors",label:"HTTP function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"errors / 5 min"},{key:"http-throttles",label:"HTTP function throttles",namespace:"AWS/Lambda",metricName:"Throttles",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"throttles / 5 min"},{key:"http-duration",label:"HTTP function duration (avg)",namespace:"AWS/Lambda",metricName:"Duration",statistic:"Average",comparison:"GreaterThanThreshold",fnMode:"http",unit:"ms"},{key:"http-concurrency",label:"HTTP concurrent executions",namespace:"AWS/Lambda",metricName:"ConcurrentExecutions",statistic:"Maximum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"concurrent"},{key:"queue-errors",label:"Queue function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"queue",unit:"errors / 5 min"}];function PT(e){return ep.find((t)=>t.key===e)}async function Qy(e,t){try{let r=await z(e,t);return{ok:!0,alarms:await new G(r.region).describeAlarms({AlarmNamePrefix:`${r.slug}-${t}-`,MaxRecords:100}),presets:ep}}catch(r){return{ok:!1,alarms:[],presets:ep,error:jr(r?.message??String(r))}}}async function Yy(e,t,r,n){let i=PT(r);if(!i)return{operation:"alarm:create",ok:!1,error:`Unknown alarm metric '${r}'.`};if(!Number.isFinite(n)||n<0)return{operation:"alarm:create",ok:!1,error:"Provide a non-negative threshold."};try{let o=await z(e,t),s=new G(o.region),c=`${o.slug}-${t}-${i.key}`,u=i.fnMode?[{Name:"FunctionName",Value:`${o.slug}-${t}-${i.fnMode}`}]:[];return await s.putMetricAlarm({AlarmName:c,Namespace:i.namespace,MetricName:i.metricName,ComparisonOperator:i.comparison,Threshold:n,EvaluationPeriods:1,Period:300,Statistic:i.statistic,Dimensions:u,AlarmDescription:`ts-cloud: ${i.label} > ${n} ${i.unit}`}),{operation:"alarm:create",command:`alarm ${c}`,ok:!0,stdout:`Alarm ${c} armed at ${n} ${i.unit}.`}}catch(o){return{operation:"alarm:create",ok:!1,error:jr(o?.message??String(o))}}}async function Xy(e,t,r){try{let n=await z(e,t);if(!r.startsWith(`${n.slug}-${t}-`))return{operation:"alarm:delete",ok:!1,error:"Refusing to delete an alarm outside this environment."};return await new G(n.region).deleteAlarms([r]),{operation:"alarm:delete",command:`delete alarm ${r}`,ok:!0,stdout:`Alarm ${r} deleted.`}}catch(n){return{operation:"alarm:delete",ok:!1,error:jr(n?.message??String(n))}}}function xT(e){let t=e.HasFault?"fault":e.HasError?"error":e.HasThrottle?"throttle":"ok";return{id:String(e.Id??""),timestamp:Number.isFinite(Number(e.StartTime))?new Date(Number(e.StartTime)*1000).toISOString():void 0,durationMs:Math.round((e.Duration??0)*1000),responseMs:Math.round((e.ResponseTime??0)*1000),status:t,method:e.Http?.HttpMethod??"-",url:e.Http?.HttpURL??"-",httpStatus:e.Http?.HttpStatus??0}}async function Ed(e,t,r=30){try{let n=await z(e,t),i=new Zl(n.region),o=new Date,s=new Date(o.getTime()-Math.min(360,Math.max(1,r))*60000),c=`${n.slug}-${t}-http`,u=await i.getTraceSummaries({startTime:s,endTime:o,filterExpression:`service("${c}")`});if(!u.summaries.length)u=await i.getTraceSummaries({startTime:s,endTime:o});return{ok:!0,traces:u.summaries.slice(0,100).map(xT)}}catch(n){return{ok:!1,traces:[],error:jr(n?.message??String(n))}}}async function op(e,t,r){try{let n=await z(e,t),i=`${n.slug}-${t}-scheduler`;if(r==="run"){let s=await Vt(e,t,"schedule:run");return{operation:"scheduler:run",command:"schedule:run",ok:!0,stdout:jr(s||"Scheduler run triggered.")}}let o=new ve(n.region);if(r==="enable")await o.enableRule({Name:i});else await o.disableRule({Name:i});return{operation:`scheduler:${r}`,command:`${r} ${i}`,ok:!0,stdout:`Scheduler rule ${i} ${r}d.`}}catch(n){return{operation:`scheduler:${r}`,ok:!1,error:jr(n?.message??String(n))}}}function Zy(e,t,r){let n=(Array.isArray(r)?r:String(r??"").split(",")).map(String).filter(Boolean);if(!n.length){if(t)return;let o=e.map((s)=>s.id);return o.length?o:["__no_authorized_telemetry_resources__"]}let i=n.map((o)=>e.find((s)=>s.id===o||s.slug===o)?.id).filter((o)=>!!o);if(i.length!==n.length)throw Error("One or more telemetry resources are outside your authorized scope.");return[...new Set(i)]}import{createHash as rb}from"node:crypto";function Lo(e){let t=Number(e);return Number.isFinite(t)&&t>=0?t:null}function DT(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return null;let t=Date.parse(`${e}T12:00:00.000Z`);return Number.isFinite(t)?new Date(t).toISOString():null}function OT(e,t){if(!e||typeof e!=="object")return[];let r={source:t.name},n=[],i=t.now,o=(a,f,C,k=i)=>{if(f!==null)n.push({name:a,value:f,unit:C,timestamp:k,attributes:r})};o("storage.egress.month",Lo(e.monthBytes),"bytes"),o("storage.egress.today",Lo(e.todayBytes),"bytes"),o("storage.egress.projected_month",Lo(e.projectedMonthBytes),"bytes");let s=Lo(e.budgetBytes);if(s!==null&&s>0){o("storage.egress.budget",s,"bytes");let a=e.budgetUsedPercent,f=typeof a==="number"&&Number.isFinite(a)?a:Lo(e.monthBytes)!==null?Math.round(Lo(e.monthBytes)/s*1000)/10:null;o("storage.egress.budget_used_percent",f,"percent")}let c=t.maxReplayDays??45,u=Array.isArray(e.days)?e.days.slice(-c):[];for(let a of u){let f=DT(String(a?.date??"")),C=Lo(a?.bytes);if(!f||C===null)continue;n.push({name:"storage.egress.day",value:C,unit:"bytes",timestamp:f,attributes:r});let k=Lo(a?.downloads);if(k!==null)n.push({name:"storage.egress.day_downloads",value:k,unit:"count",timestamp:f,attributes:r})}return n}async function _T(e,t=process.env,r=fetch){let n=e.tokenEnv?t[e.tokenEnv]:void 0,i=await r(e.url,{headers:n?{Authorization:`Bearer ${n}`}:{},signal:AbortSignal.timeout(1e4)});if(!i.ok)throw Error(`HTTP ${i.status}`);return await i.json()}async function eb(e,t){let r=[],n=[];if(!Array.isArray(e)||e.length===0)return{metrics:r,errors:n};let i=await Promise.all(e.map(async(o)=>{if(!o?.name||!o?.url)return{endpoint:o,error:"egress endpoint needs both a name and a url"};try{let s=await _T(o,t.env,t.fetchImpl);return{endpoint:o,report:s}}catch(s){return{endpoint:o,error:s instanceof Error?s.message:String(s)}}}));for(let o of i){let s=`egress:${o.endpoint?.name??"unnamed"}`;if("error"in o&&o.error){n.push({source:s,message:o.error});continue}r.push(...OT(o.report,{name:o.endpoint.name,now:t.now}))}return{metrics:r,errors:n}}class nb{now;entries=new Map;constructor(e=Date.now){this.now=e}async getOrCreate(e,t,r,n){let i=this.entries.get(e);if(!r&&i&&i.expiresAt>this.now())return{value:await i.promise,cached:!0};let o=n().catch((s)=>{throw this.entries.delete(e),s});return this.entries.set(e,{expiresAt:this.now()+t,promise:o}),{value:await o,cached:!1}}invalidate(e){for(let t of this.entries.keys())if(t.startsWith(e))this.entries.delete(t)}}class ib{now;lastRun=new Map;constructor(e=Date.now){this.now=e}shouldRun(e,t,r=!1){let n=this.now(),i=this.lastRun.get(e);if(!r&&i!=null&&n-i<t)return!1;return this.lastRun.set(e,n),!0}}var ob=new nb,NT=new ib,MT=2000,$T=3600000;function LT(e,t){if(e.kind==="log"&&!t.collectLogs)return!1;if(e.kind==="trace"&&!t.collectTraces)return!1;if((e.kind==="request"||e.name.startsWith("request."))&&!t.collectRequestAnalytics)return!1;if(!["log","trace","request"].includes(e.kind)&&!e.name.startsWith("request."))return!0;let r=e.requestId??e.traceId??`${e.source}\x00${e.workloadId??""}\x00${e.timestamp}`;return Number.parseInt(rb("sha256").update(r).digest("hex").slice(0,8),16)/4294967295<=t.samplingRate}function Rr(...e){return`telemetry:${rb("sha256").update(e.map((t)=>String(t??"")).join("\x00")).digest("hex").slice(0,40)}`}function La(e,t,r,n){if(!n)return;return e.listResources(t,r).find((i)=>i.slug===n)?.id}function BT(e,t){let r=String(t??"").toLowerCase();if(["debug","info","warn","warning","error","fatal"].includes(r))return r==="fatal"?"error":r;return/fatal|panic|exception|error/i.test(e)?"error":/warn|timeout|throttl|retr(?:y|ies)/i.test(e)?"warning":"info"}function tb(e){let t=e.timestamp&&Number.isFinite(new Date(e.timestamp).getTime())?new Date(e.timestamp).toISOString():new Date().toISOString(),r={};try{let Y=JSON.parse(e.message);if(Y&&typeof Y==="object"&&!Array.isArray(Y))r=Y}catch{}let n=Object.fromEntries(Object.entries(r).filter(([Y])=>!/^(?:body|requestBody|responseBody|headers|authorization|cookie|cookies|query|queryString)$/i.test(Y))),i=String(r.requestId??r.request_id??r["x-request-id"]??"")||void 0,o=String(r.traceId??r.trace_id??r["x-amzn-trace-id"]??"")||void 0,s=Number(r.durationMs??r.duration_ms??r.latencyMs??r.latency_ms),c=Number(r.statusCode??r.status_code??r.status),u=String(r.method??r.httpMethod??"")||void 0,a=lo(String(r.pathTemplate??r.path??r.url??"")||void 0),f=String(r.releaseId??r.release_id??"")||void 0,C=String(r.deploymentId??r.deployment_id??"")||void 0,k={projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,source:e.source,timestamp:t,requestId:i,traceId:o,releaseId:f,deploymentId:C,workloadId:e.workloadId},D=Object.keys(r).length?JSON.stringify(n):e.message,W=[{...k,id:Rr(e.source,e.name,t,D),kind:"log",name:e.name,level:BT(D,r.level),message:D,attributes:n}];if(u&&a&&Number.isFinite(c)){if(W.push({...k,id:Rr("request",i,t,u,a,c),kind:"request",name:"http.request",method:u,pathTemplate:a,host:r.host,statusCode:c,durationMs:Number.isFinite(s)?s:void 0,bytesIn:Number(r.bytesIn)||void 0,bytesOut:Number(r.bytesOut)||void 0,region:r.region,cacheResult:r.cacheResult??r.cache,upstream:r.upstream,attributes:{userAgentFamily:r.userAgentFamily??"",protocol:r.protocol??""}}),Number.isFinite(s))W.push({...k,id:Rr("request-duration",i,t),kind:"metric",name:"request.duration",value:s,unit:"ms",attributes:{method:u,pathTemplate:a,statusCode:c}});if(W.push({...k,id:Rr("request-count",i,t),kind:"metric",name:"request.count",value:1,unit:"count",attributes:{method:u,pathTemplate:a,statusCode:c}}),c>=500)W.push({...k,id:Rr("request-error",i,t),kind:"metric",name:"request.error",value:1,unit:"count",attributes:{method:u,pathTemplate:a,statusCode:c}})}return W}async function FT(e){let t=new tt(e.controlPlane),r=et(e.controlPlane,e.projectId),n=new Date,i=[],o=[],s={projectId:e.projectId,environmentId:e.environmentId},c=H(e.config);try{let k=(c==="serverless"?await di(e.config,e.environment):await hi(e.config,e.environment,{includeSiteHealth:e.includeSiteHealth,telemetryOnly:e.lightweight}))??{};if(c==="serverless"){for(let W of k.functionsDetail??[]){let Y=La(e.controlPlane,e.projectId,e.environmentId,W.key),ee={...s,resourceId:Y,source:"cloudwatch",timestamp:n.toISOString(),workloadId:W.name,attributes:{provider:"aws",functionName:W.name,aggregationWindow:"24h"}};for(let[ne,he,te]of[["snapshot.traffic.requests_24h",W.invocations,"count"],["snapshot.errors.count_24h",W.errors,"count"],["snapshot.latency.p50_24h",W.p50,"ms"],["snapshot.latency.p95_24h",W.p95,"ms"],["snapshot.latency.p99_24h",W.p99,"ms"],["snapshot.saturation.throttles_24h",W.throttles,"count"],["snapshot.memory.max_24h",W.maxMem,"MB"]])if(Number.isFinite(Number(he)))i.push({...ee,id:Rr("cloudwatch",W.name,ne,n.toISOString()),kind:"metric",name:ne,value:Number(he),unit:te})}try{let W=await z(e.config,e.environment),Y=new G(W.region),ee=new Date(n.getTime()-3600000),ne=300;for(let he of W.functions){let te=[{Name:"FunctionName",Value:he.name}],[Pe,Xe,$e,Gt,it]=await Promise.all([Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Sum"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Errors",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Sum"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:te,StartTime:ee,EndTime:n,Period:300,ExtendedStatistics:["p50","p95","p99"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Throttles",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Sum"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"ConcurrentExecutions",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Maximum"]})]),ke=La(e.controlPlane,e.projectId,e.environmentId,he.mode),He=(Tt,Ei,co,Fn)=>{for(let Ai of Tt){let ki=Ai.Timestamp&&Number.isFinite(new Date(Ai.Timestamp).getTime())?new Date(Ai.Timestamp).toISOString():void 0,Ri=co(Ai);if(ki&&Ri!=null&&Number.isFinite(Ri))i.push({...s,resourceId:ke,id:Rr("cloudwatch-series",he.name,Ei,ki),kind:"metric",source:"cloudwatch",name:Ei,timestamp:ki,value:Ri,unit:Fn,workloadId:he.name,region:W.region,attributes:{provider:"aws",functionName:he.name,aggregationWindow:"300s"}})}};He(Pe,"traffic.requests",(Tt)=>Tt.Sum,"count"),He(Xe,"errors.count",(Tt)=>Tt.Sum,"count"),He($e,"latency.p50",(Tt)=>Tt.Percentiles?.p50,"ms"),He($e,"latency.p95",(Tt)=>Tt.Percentiles?.p95,"ms"),He($e,"latency.p99",(Tt)=>Tt.Percentiles?.p99,"ms"),He(Gt,"saturation.throttles",(Tt)=>Tt.Sum,"count"),He(it,"saturation.concurrency",(Tt)=>Tt.Maximum,"count")}}catch(W){o.push({source:"cloudwatch:series",message:W instanceof Error?W.message:String(W)})}for(let W of(k.serverlessLogs??[]).slice(0,MT))i.push(...tb({...s,source:`cloudwatch:${W.source}`,name:`${W.source}.log`,timestamp:W.timestamp,message:String(W.message),resourceId:La(e.controlPlane,e.projectId,e.environmentId,W.source)}));for(let W of k.queuesDetail??[]){let Y={...s,source:"cloudwatch",timestamp:n.toISOString(),attributes:{queue:W.name}};i.push({...Y,id:Rr("queue-depth",W.name,n.toISOString()),kind:"metric",name:"queue.depth",value:Number(W.visible??W.depth??0),unit:"count"}),i.push({...Y,id:Rr("queue-inflight",W.name,n.toISOString()),kind:"metric",name:"queue.inflight",value:Number(W.inFlight??0),unit:"count"})}let D=await Ed(e.config,e.environment,30);if(!D.ok)o.push({source:"xray",message:D.error??"X-Ray traces are unavailable."});for(let W of D.traces)i.push({...s,id:Rr("xray",W.id),kind:"trace",source:"xray",name:"http.trace",timestamp:W.timestamp??n.toISOString(),traceId:W.id,durationMs:W.durationMs,statusCode:W.httpStatus,method:W.method,pathTemplate:W.url,attributes:{status:W.status,responseMs:W.responseMs}})}else{let D=k.systemMetrics;if(k.metricsUnavailable||!D)o.push({source:"host",message:"The host metrics probe is unavailable."});else{let W=Number(D.memTotalMb)>0?Number(D.memUsedMb)/Number(D.memTotalMb)*100:0,Y=Number(D.swapTotalMb)>0?Number(D.swapUsedMb)/Number(D.swapTotalMb)*100:0,ee=[["host.load",Number(D.load),"load"],["host.load.5m",Number(D.load5),"load"],["host.load.15m",Number(D.load15),"load"],["host.cpu.capacity",Number(D.cpus),"count"],["host.cpu.used_percent",Number(D.cpuUsedPct),"percent"],["host.memory.used",Number(D.memUsedMb)*1024*1024,"bytes"],["host.memory.total",Number(D.memTotalMb)*1024*1024,"bytes"],["host.memory.available",Number(D.memAvailableMb)*1024*1024,"bytes"],["host.memory.cache",Number(D.memCacheMb)*1024*1024,"bytes"],["host.memory.used_percent",W,"percent"],["host.swap.used",Number(D.swapUsedMb)*1024*1024,"bytes"],["host.swap.total",Number(D.swapTotalMb)*1024*1024,"bytes"],["host.swap.used_percent",Y,"percent"],["host.disk.used_percent",Number(D.diskUsedPct),"percent"],["host.disk.used",Number(D.diskUsedGb)*1073741824,"bytes"],["host.disk.total",Number(D.diskTotalGb)*1073741824,"bytes"],["host.disk.inode_used_percent",Number(D.inodeUsedPct),"percent"],["host.network.rx",Number(D.networkRxBytes),"bytes"],["host.network.tx",Number(D.networkTxBytes),"bytes"],["host.network.rx_rate",Number(D.networkRxBytesPerSec),"bytes_per_second"],["host.network.tx_rate",Number(D.networkTxBytesPerSec),"bytes_per_second"],["host.network.rx_today",Number(D.networkRxBytesToday),"bytes"],["host.network.tx_today",Number(D.networkTxBytesToday),"bytes"],["host.network.rx_month",Number(D.networkRxBytesMonth),"bytes"],["host.network.tx_month",Number(D.networkTxBytesMonth),"bytes"],["host.processes",Number(D.processes),"count"],["host.uptime",Number(D.uptimeSeconds),"seconds"]];for(let[ne,he,te]of ee)if(Number.isFinite(he))i.push({...s,id:Rr("host",ne,n.toISOString()),kind:"metric",source:"host",name:ne,timestamp:n.toISOString(),value:he,unit:te});for(let ne of D.disks??[]){if(ne.usedPercent===null||!Number.isFinite(Number(ne.usedPercent)))continue;i.push({...s,id:Rr("host",`disk:${ne.path}`,n.toISOString()),kind:"metric",source:"host",name:"host.filesystem.used_percent",timestamp:n.toISOString(),value:Number(ne.usedPercent),unit:"percent",attributes:{path:String(ne.path),mounted:ne.mounted!==!1}})}for(let ne of k.siteHealth??[]){let he=String(ne.project??e.config.project.slug),te=String(ne.name),Pe=te.startsWith(`${he}:`)?te.slice(he.length+1):te,Xe=`site:${he}:${Pe}`,$e=La(e.controlPlane,e.projectId,e.environmentId,te),Gt={...s,resourceId:$e,source:Xe,timestamp:ne.checkedAt||n.toISOString(),host:ne.route,attributes:{project:he,site:Pe,route:String(ne.route),status:String(ne.status)}},it=[["site.health.up",ne.status==="live"?1:0,"boolean"],["site.http.status",Number(ne.httpStatus),"status"],["site.response.time",Number(ne.responseMs),"ms"]];if(ne.tlsDaysRemaining!=null)it.push(["site.tls.days_remaining",Number(ne.tlsDaysRemaining),"days"]);for(let[ke,He,Tt]of it)if(Number.isFinite(He))i.push({...Gt,id:Rr(Xe,ke,Gt.timestamp),kind:"metric",name:ke,value:He,unit:Tt})}}}}catch(k){o.push({source:c==="serverless"?"aws":"host",message:k instanceof Error?k.message:String(k)})}{let k=e.config.infrastructure?.compute?.monitoring,D=typeof k==="object"?k?.egressEndpoints:void 0,W=await eb(D,{now:n.toISOString()});o.push(...W.errors);for(let Y of W.metrics)i.push({...s,id:Rr(Y.attributes.source,Y.name,Y.timestamp),kind:"metric",source:`egress:${Y.attributes.source}`,name:Y.name,timestamp:Y.timestamp,value:Y.value,unit:Y.unit,attributes:Y.attributes})}if(!e.lightweight)try{let k=await wi(e.config,e.environment),D=new Ce(e.config,e.environment,{inventory:async()=>k});for(let W of k.workloads){let Y=La(e.controlPlane,e.projectId,e.environmentId,W.links.service),ee={...s,resourceId:Y,source:`runtime:${W.provider}`,timestamp:n.toISOString(),workloadId:W.id,releaseId:W.links.release,attributes:{status:W.status,provider:W.provider,service:W.links.service??""}};if(i.push({...ee,id:Rr(W.id,"health",n.toISOString()),kind:"metric",name:"health.up",value:W.status==="running"?1:0,unit:"boolean"}),i.push({...ee,id:Rr(W.id,"restarts",n.toISOString()),kind:"metric",name:"saturation.restarts",value:W.restartCount??0,unit:"count"}),W.resources?.memoryBytes!=null)i.push({...ee,id:Rr(W.id,"memory",n.toISOString()),kind:"metric",name:"runtime.memory.used",value:W.resources.memoryBytes,unit:"bytes"});if(!W.capabilities.logs.supported)continue;try{let ne=await D.logs(W.id,{limit:100,since:new Date(n.getTime()-300000)});for(let he of ne.lines)i.push(...tb({...s,resourceId:Y,source:`runtime:${W.provider}`,name:`${W.links.service??W.name}.log`,timestamp:he.timestamp,message:he.message,workloadId:W.id}))}catch(ne){o.push({source:`runtime:${W.provider}`,message:ne instanceof Error?ne.message:String(ne)})}}for(let W of k.sources.filter((Y)=>Y.status!=="fresh"))o.push({source:W.id,message:W.message??`Runtime source is ${W.status}.`})}catch(k){o.push({source:"runtime",message:k instanceof Error?k.message:String(k)})}if(!e.lightweight)for(let k of e.controlPlane.listEvents({projectId:e.projectId,limit:1000})){let D=k.payload;i.push({...s,id:`telemetry:event:${k.id}`,resourceId:k.resourceId,kind:"event",source:"control-plane",name:k.type,timestamp:k.createdAt,level:k.level,message:k.type,deploymentId:k.operationId,releaseId:typeof D.releaseId==="string"?D.releaseId:void 0,traceId:k.correlationId,attributes:D})}let u=i.filter((k)=>LT(k,r)).map((k)=>({...k,sampled:r.samplingRate<1&&(k.kind==="log"||k.kind==="trace"||k.kind==="request"||k.name.startsWith("request."))})),a=t.appendMany(u).length;if(NT.shouldRun(e.projectId,$T,!e.lightweight))t.enforceRetention(r,e.projectId);let f=t.status(e.projectId,e.environmentId,r.rawDays,r.samplingRate);for(let k of o)if(!f.some((D)=>D.source===k.source))f.push({source:k.source,freshness:"unavailable",samplingRate:r.samplingRate,retentionDays:r.rawDays,estimatedDailyBytes:0,message:k.message});let C=n.toISOString();return e.controlPlane.setSetting(`telemetry.collection:${e.projectId}:${e.environmentId??"all"}`,{generatedAt:C,errors:o,statuses:f,policy:r}),{collected:a,cached:!1,generatedAt:C,statuses:f,errors:o,policy:r}}async function li(e){let r=`${`${e.projectId}:${e.environmentId??"all"}:${e.environment}`}:${e.lightweight?"lightweight":"full"}`,n=H(e.config)==="serverless"?300000:60000,i=await ob.getOrCreate(r,n,!!e.force,()=>FT(e));return{...i.value,cached:i.cached}}function sb(e){ob.invalidate(`${e}:`)}function ab(e,t={}){let r=t.shell||(process.platform==="win32"?"powershell.exe":"bash"),n=Bun.spawn([r,"-i"],{stdin:"pipe",stdout:"pipe",stderr:"pipe",cwd:t.cwd,env:{...process.env,TERM:"xterm-256color",PS1:"\\w $ "}}),i=new TextDecoder,o=async(s)=>{if(!s)return;let c=s.getReader();try{for(;;){let{done:u,value:a}=await c.read();if(u)break;if(a)e(i.decode(a))}}catch{}};if(o(n.stdout),o(n.stderr),t.onExit)n.exited.then((s)=>t.onExit(s)).catch(()=>{});return{write(s){try{n.stdin.write(s),n.stdin.flush()}catch{}},close(){try{n.stdin.end()}catch{}try{n.kill()}catch{}}}}var HT="127.0.0.1",WT=7676,db=65536,vb="ts-cloud-dashboard-",ca=UT(JT(import.meta.url));function KT(e){try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function QT(e=kd(),t=KT){let r=0;for(let n of cb(e,{withFileTypes:!0})){if(!n.isDirectory()||!n.name.startsWith(vb))continue;let i=Et(e,n.name),o=n.name.match(/^ts-cloud-dashboard-(\d+)-/);if(o){let s=Number(o[1]);if(s===process.pid||t(s))continue}else if(cb(i).length>0)continue;gs(i,{recursive:!0,force:!0}),r+=1}return r}var YT={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".ico":"image/x-icon"};function b(e,t=200,r={}){return new Response(JSON.stringify(e,null,2),{status:t,headers:{"content-type":"application/json; charset=utf-8",...r}})}function XT(e,t,r,n){let i=new TextEncoder,o=Math.max(0,Math.floor(r)),s,c,u=!1,a=new ReadableStream({start(f){let C=()=>{if(u)return;if(u=!0,s?.(),c)clearInterval(c);n.removeEventListener("abort",C);try{f.close()}catch{}},k=(W)=>{if(u)return;if(W.reset)f.enqueue(i.encode(`event: reset
|
|
459
|
+
[output truncated]`}function tp(e,t){return e.environments?.[t]?.app}function rp(e,t,r){let n=[],i=tp(e,t);n.push({id:"redeploy",label:"Redeploy current build",group:"deploy",target:"app",mutates:!0,confirm:"redeploy"}),n.push({id:"rollback",label:"Roll back to previous build",group:"deploy",target:"app",mutates:!0,confirm:"rollback",danger:!0});let o=r.maintenance?.enabled;if(o!==!0)n.push({id:"maintenance:on",label:"Enable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"maintenance",danger:!0});if(o!==!1)n.push({id:"maintenance:off",label:"Disable maintenance mode",group:"maintenance",target:"app",mutates:!0,confirm:"live"});if(i?.assets||r.assetsInfo)n.push({id:"assets:invalidate",label:"Invalidate CDN cache",group:"assets",target:"assets",mutates:!0,confirm:"invalidate"});if(i?.database?.connection==="aurora-serverless")n.push({id:"db:scale",label:"Scale Aurora capacity",group:"database",target:"database",mutates:!0,confirm:"scale",inputs:[{name:"min",label:"Min ACUs",placeholder:String(i.database.minCapacity??0.5)},{name:"max",label:"Max ACUs",placeholder:String(i.database.maxCapacity??4)}]});for(let s of r.queues??[]){let c=String(s?.name??"").trim();if(c&&/^[A-Za-z0-9_-]+$/.test(c))n.push({id:`queue:purge:${c}`,label:`Purge queue (${c})`,group:"queue",target:c,mutates:!0,confirm:c,danger:!0})}return n}function jy(e,t,r,n){return rp(t,r,n).find((i)=>i.id===e)}async function kT(e,t,r){try{let n=new v(r),{Stacks:i}=await n.describeStacks({stackName:Oe(e,t)}),o={};for(let u of i?.[0]?.Outputs??[])if(u.OutputKey)o[u.OutputKey]=u.OutputValue??"";let s=o.AssetsCdnDomain;if(!s)return null;return(await new E(r).findDistributionByDomain(s))?.Id??null}catch{return null}}async function Uy(e,t,r,n={}){try{if(r.id==="redeploy")return await Ms(e,t),{operation:r.id,command:"serverless redeploy",ok:!0,stdout:"Redeploy complete."};if(r.id==="rollback")return await Us(e,t),{operation:r.id,command:"serverless rollback",ok:!0,stdout:"Rollback complete."};if(r.id==="maintenance:on")return await _o(e,t,!0),{operation:r.id,command:"maintenance on",ok:!0,stdout:"Application is now in maintenance mode."};if(r.id==="maintenance:off")return await _o(e,t,!1),{operation:r.id,command:"maintenance off",ok:!0,stdout:"Application is live."};if(r.id==="db:scale"){let i=Number(n.min),o=Number(n.max);if(!Number.isFinite(i)||!Number.isFinite(o)||i<=0||o<i)return{operation:r.id,ok:!1,error:"Provide valid Aurora capacities (0 < min ≤ max)."};return await Fs(e,t,i,o),{operation:r.id,command:`db:scale ${i}-${o} ACU`,ok:!0,stdout:`Scaling applied (${i}-${o} ACUs); takes effect shortly.`}}if(r.id==="assets:invalidate"){let i=await z(e,t),o=await kT(e,t,i.region);if(!o)return{operation:r.id,ok:!1,error:"Could not resolve the asset CloudFront distribution for this environment."};let c=await new E(i.region).invalidateAll(o);return{operation:r.id,command:`cloudfront invalidate ${o} /*`,ok:!0,stdout:`Invalidation ${c?.Id??"created"} for ${o} (/*).`}}if(r.group==="queue"&&r.id.startsWith("queue:purge:")){let i=r.target,o=await z(e,t),s=new V(o.region),c=`${o.slug}-${t}-${i}`,{QueueUrl:u}=await s.getQueueUrl(c);return await s.purgeQueue(u),{operation:r.id,command:`sqs purge ${c}`,ok:!0,stdout:`Purged queue ${c}.`}}return{operation:r.id,ok:!1,error:"Unknown or unavailable serverless operation."}}catch(i){return{operation:r.id,ok:!1,error:jr(i?.message??String(i))}}}async function zy(e,t,r){let n=r.trim();if(!n)return{operation:"command",ok:!1,error:"A command is required."};try{let i=await Vt(e,t,n);return{operation:"command",command:n,ok:!0,stdout:jr(i||"(no output)")}}catch(i){return{operation:"command",command:n,ok:!1,error:jr(i?.message??String(i))}}}var np="No dead-letter queue is provisioned for this environment.";async function ip(e,t,r){try{let{QueueUrl:n}=await e.getQueueUrl(`${t}-${r}-dlq`);return n}catch{return null}}async function Vy(e,t,r=10){try{let n=await z(e,t),i=new V(n.region),o=await ip(i,n.slug,t);if(!o)return{ok:!1,messages:[],error:np};return{ok:!0,messages:((await i.receiveMessages({queueUrl:o,maxMessages:Math.min(10,Math.max(1,r)),waitTimeSeconds:1,visibilityTimeout:2})).Messages??[]).map((u)=>({id:u.MessageId,receiptHandle:u.ReceiptHandle,body:jr(String(u.Body??""))}))}}catch(n){return{ok:!1,messages:[],error:jr(n?.message??String(n))}}}async function qy(e,t,r={}){try{let n=await z(e,t),i=tp(e,t),s=(i?Yt(i,n.slug,t):[]).map((D)=>D.name.replace(`${n.slug}-${t}-`,"")),c=r.targetQueue&&s.includes(r.targetQueue)?r.targetQueue:s[0];if(!c)return{operation:"dlq:redrive",ok:!1,error:"No source queue is configured to redrive into."};let u=new V(n.region),a=await ip(u,n.slug,t);if(!a)return{operation:"dlq:redrive",ok:!1,error:np};let{QueueUrl:f}=await u.getQueueUrl(`${n.slug}-${t}-${c}`),C=Math.min(50,Math.max(1,r.max??10)),k=0;while(k<C){let W=(await u.receiveMessages({queueUrl:a,maxMessages:Math.min(10,C-k),waitTimeSeconds:1,visibilityTimeout:30})).Messages??[];if(!W.length)break;for(let Y of W)await u.sendMessage({queueUrl:f,messageBody:String(Y.Body??"")}),await u.deleteMessage(a,Y.ReceiptHandle),k++}return{operation:"dlq:redrive",command:`redrive → ${c}`,ok:!0,stdout:`Moved ${k} message(s) from the DLQ to ${c}.`}}catch(n){return{operation:"dlq:redrive",ok:!1,error:jr(n?.message??String(n))}}}async function Gy(e,t){try{let r=await z(e,t),n=new V(r.region),i=await ip(n,r.slug,t);if(!i)return{operation:"dlq:purge",ok:!1,error:np};return await n.purgeQueue(i),{operation:"dlq:purge",command:"sqs purge dlq",ok:!0,stdout:"Dead-letter queue purged."}}catch(r){return{operation:"dlq:purge",ok:!1,error:jr(r?.message??String(r))}}}function Jy(e,t){let r=tp(e,t);if(!r?.secrets)return[];return Array.isArray(r.secrets)?r.secrets.map((n)=>({key:n.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),secretId:n})):Object.entries(r.secrets).map(([n,i])=>({key:n,secretId:String(i)}))}async function Hy(e,t,r,n){if(!r.trim())return{operation:"secret:set",ok:!1,error:"A secret id is required."};try{let i=await z(e,t),o=new K(i.region);try{await o.putSecretValue({SecretId:r,SecretString:n})}catch{await o.createSecret({Name:r,SecretString:n})}return{operation:"secret:set",command:`secret set ${r}`,ok:!0,stdout:`Secret ${r} updated. Redeploy to apply it to the functions.`}}catch(i){return{operation:"secret:set",ok:!1,error:jr(i?.message??String(i))}}}async function Wy(e,t,r){if(!r.trim())return{operation:"secret:delete",ok:!1,error:"A secret id is required."};try{let n=await z(e,t);return await new K(n.region).deleteSecret({SecretId:r,RecoveryWindowInDays:7}),{operation:"secret:delete",command:`secret delete ${r}`,ok:!0,stdout:`Secret ${r} scheduled for deletion (recoverable for 7 days).`}}catch(n){return{operation:"secret:delete",ok:!1,error:jr(n?.message??String(n))}}}var RT=new Set(["http","queue","cli"]);async function Ky(e,t,r,n){if(!RT.has(r))return{operation:"function:config",ok:!1,error:`Unknown function mode '${r}'.`};let i=n.memory==null?void 0:Number(n.memory),o=n.timeout==null?void 0:Number(n.timeout);if(i!=null&&(!Number.isInteger(i)||i<128||i>10240))return{operation:"function:config",ok:!1,error:"Memory must be an integer between 128 and 10240 MB."};if(o!=null&&(!Number.isInteger(o)||o<1||o>900))return{operation:"function:config",ok:!1,error:"Timeout must be an integer between 1 and 900 seconds."};if(i==null&&o==null)return{operation:"function:config",ok:!1,error:"Provide a memory and/or timeout value."};try{let s=await z(e,t),c=new P(s.region),u=`${s.slug}-${t}-${r}`;await c.updateFunctionConfiguration({FunctionName:u,...i!=null?{MemorySize:i}:{},...o!=null?{Timeout:o}:{}});let a=[i!=null?`${i} MB`:"",o!=null?`${o}s`:""].filter(Boolean).join(", ");return{operation:"function:config",command:`update ${u} (${a})`,ok:!0,stdout:`Updated ${u}: ${a}.`}}catch(s){return{operation:"function:config",ok:!1,error:jr(s?.message??String(s))}}}var ep=[{key:"http-errors",label:"HTTP function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"errors / 5 min"},{key:"http-throttles",label:"HTTP function throttles",namespace:"AWS/Lambda",metricName:"Throttles",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"throttles / 5 min"},{key:"http-duration",label:"HTTP function duration (avg)",namespace:"AWS/Lambda",metricName:"Duration",statistic:"Average",comparison:"GreaterThanThreshold",fnMode:"http",unit:"ms"},{key:"http-concurrency",label:"HTTP concurrent executions",namespace:"AWS/Lambda",metricName:"ConcurrentExecutions",statistic:"Maximum",comparison:"GreaterThanThreshold",fnMode:"http",unit:"concurrent"},{key:"queue-errors",label:"Queue function errors",namespace:"AWS/Lambda",metricName:"Errors",statistic:"Sum",comparison:"GreaterThanThreshold",fnMode:"queue",unit:"errors / 5 min"}];function PT(e){return ep.find((t)=>t.key===e)}async function Qy(e,t){try{let r=await z(e,t);return{ok:!0,alarms:await new q(r.region).describeAlarms({AlarmNamePrefix:`${r.slug}-${t}-`,MaxRecords:100}),presets:ep}}catch(r){return{ok:!1,alarms:[],presets:ep,error:jr(r?.message??String(r))}}}async function Yy(e,t,r,n){let i=PT(r);if(!i)return{operation:"alarm:create",ok:!1,error:`Unknown alarm metric '${r}'.`};if(!Number.isFinite(n)||n<0)return{operation:"alarm:create",ok:!1,error:"Provide a non-negative threshold."};try{let o=await z(e,t),s=new q(o.region),c=`${o.slug}-${t}-${i.key}`,u=i.fnMode?[{Name:"FunctionName",Value:`${o.slug}-${t}-${i.fnMode}`}]:[];return await s.putMetricAlarm({AlarmName:c,Namespace:i.namespace,MetricName:i.metricName,ComparisonOperator:i.comparison,Threshold:n,EvaluationPeriods:1,Period:300,Statistic:i.statistic,Dimensions:u,AlarmDescription:`ts-cloud: ${i.label} > ${n} ${i.unit}`}),{operation:"alarm:create",command:`alarm ${c}`,ok:!0,stdout:`Alarm ${c} armed at ${n} ${i.unit}.`}}catch(o){return{operation:"alarm:create",ok:!1,error:jr(o?.message??String(o))}}}async function Xy(e,t,r){try{let n=await z(e,t);if(!r.startsWith(`${n.slug}-${t}-`))return{operation:"alarm:delete",ok:!1,error:"Refusing to delete an alarm outside this environment."};return await new q(n.region).deleteAlarms([r]),{operation:"alarm:delete",command:`delete alarm ${r}`,ok:!0,stdout:`Alarm ${r} deleted.`}}catch(n){return{operation:"alarm:delete",ok:!1,error:jr(n?.message??String(n))}}}function xT(e){let t=e.HasFault?"fault":e.HasError?"error":e.HasThrottle?"throttle":"ok";return{id:String(e.Id??""),timestamp:Number.isFinite(Number(e.StartTime))?new Date(Number(e.StartTime)*1000).toISOString():void 0,durationMs:Math.round((e.Duration??0)*1000),responseMs:Math.round((e.ResponseTime??0)*1000),status:t,method:e.Http?.HttpMethod??"-",url:e.Http?.HttpURL??"-",httpStatus:e.Http?.HttpStatus??0}}async function Ed(e,t,r=30){try{let n=await z(e,t),i=new Zl(n.region),o=new Date,s=new Date(o.getTime()-Math.min(360,Math.max(1,r))*60000),c=`${n.slug}-${t}-http`,u=await i.getTraceSummaries({startTime:s,endTime:o,filterExpression:`service("${c}")`});if(!u.summaries.length)u=await i.getTraceSummaries({startTime:s,endTime:o});return{ok:!0,traces:u.summaries.slice(0,100).map(xT)}}catch(n){return{ok:!1,traces:[],error:jr(n?.message??String(n))}}}async function op(e,t,r){try{let n=await z(e,t),i=`${n.slug}-${t}-scheduler`;if(r==="run"){let s=await Vt(e,t,"schedule:run");return{operation:"scheduler:run",command:"schedule:run",ok:!0,stdout:jr(s||"Scheduler run triggered.")}}let o=new ve(n.region);if(r==="enable")await o.enableRule({Name:i});else await o.disableRule({Name:i});return{operation:`scheduler:${r}`,command:`${r} ${i}`,ok:!0,stdout:`Scheduler rule ${i} ${r}d.`}}catch(n){return{operation:`scheduler:${r}`,ok:!1,error:jr(n?.message??String(n))}}}function Zy(e,t,r){let n=(Array.isArray(r)?r:String(r??"").split(",")).map(String).filter(Boolean);if(!n.length){if(t)return;let o=e.map((s)=>s.id);return o.length?o:["__no_authorized_telemetry_resources__"]}let i=n.map((o)=>e.find((s)=>s.id===o||s.slug===o)?.id).filter((o)=>!!o);if(i.length!==n.length)throw Error("One or more telemetry resources are outside your authorized scope.");return[...new Set(i)]}import{createHash as rb}from"node:crypto";function Lo(e){let t=Number(e);return Number.isFinite(t)&&t>=0?t:null}function DT(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return null;let t=Date.parse(`${e}T12:00:00.000Z`);return Number.isFinite(t)?new Date(t).toISOString():null}function OT(e,t){if(!e||typeof e!=="object")return[];let r={source:t.name},n=[],i=t.now,o=(a,f,C,k=i)=>{if(f!==null)n.push({name:a,value:f,unit:C,timestamp:k,attributes:r})};o("storage.egress.month",Lo(e.monthBytes),"bytes"),o("storage.egress.today",Lo(e.todayBytes),"bytes"),o("storage.egress.projected_month",Lo(e.projectedMonthBytes),"bytes");let s=Lo(e.budgetBytes);if(s!==null&&s>0){o("storage.egress.budget",s,"bytes");let a=e.budgetUsedPercent,f=typeof a==="number"&&Number.isFinite(a)?a:Lo(e.monthBytes)!==null?Math.round(Lo(e.monthBytes)/s*1000)/10:null;o("storage.egress.budget_used_percent",f,"percent")}let c=t.maxReplayDays??45,u=Array.isArray(e.days)?e.days.slice(-c):[];for(let a of u){let f=DT(String(a?.date??"")),C=Lo(a?.bytes);if(!f||C===null)continue;n.push({name:"storage.egress.day",value:C,unit:"bytes",timestamp:f,attributes:r});let k=Lo(a?.downloads);if(k!==null)n.push({name:"storage.egress.day_downloads",value:k,unit:"count",timestamp:f,attributes:r})}return n}async function _T(e,t=process.env,r=fetch){let n=e.tokenEnv?t[e.tokenEnv]:void 0,i=await r(e.url,{headers:n?{Authorization:`Bearer ${n}`}:{},signal:AbortSignal.timeout(1e4)});if(!i.ok)throw Error(`HTTP ${i.status}`);return await i.json()}async function eb(e,t){let r=[],n=[];if(!Array.isArray(e)||e.length===0)return{metrics:r,errors:n};let i=await Promise.all(e.map(async(o)=>{if(!o?.name||!o?.url)return{endpoint:o,error:"egress endpoint needs both a name and a url"};try{let s=await _T(o,t.env,t.fetchImpl);return{endpoint:o,report:s}}catch(s){return{endpoint:o,error:s instanceof Error?s.message:String(s)}}}));for(let o of i){let s=`egress:${o.endpoint?.name??"unnamed"}`;if("error"in o&&o.error){n.push({source:s,message:o.error});continue}r.push(...OT(o.report,{name:o.endpoint.name,now:t.now}))}return{metrics:r,errors:n}}class nb{now;entries=new Map;constructor(e=Date.now){this.now=e}async getOrCreate(e,t,r,n){let i=this.entries.get(e);if(!r&&i&&i.expiresAt>this.now())return{value:await i.promise,cached:!0};let o=n().catch((s)=>{throw this.entries.delete(e),s});return this.entries.set(e,{expiresAt:this.now()+t,promise:o}),{value:await o,cached:!1}}invalidate(e){for(let t of this.entries.keys())if(t.startsWith(e))this.entries.delete(t)}}class ib{now;lastRun=new Map;constructor(e=Date.now){this.now=e}shouldRun(e,t,r=!1){let n=this.now(),i=this.lastRun.get(e);if(!r&&i!=null&&n-i<t)return!1;return this.lastRun.set(e,n),!0}}var ob=new nb,NT=new ib,MT=2000,$T=3600000;function LT(e,t){if(e.kind==="log"&&!t.collectLogs)return!1;if(e.kind==="trace"&&!t.collectTraces)return!1;if((e.kind==="request"||e.name.startsWith("request."))&&!t.collectRequestAnalytics)return!1;if(!["log","trace","request"].includes(e.kind)&&!e.name.startsWith("request."))return!0;let r=e.requestId??e.traceId??`${e.source}\x00${e.workloadId??""}\x00${e.timestamp}`;return Number.parseInt(rb("sha256").update(r).digest("hex").slice(0,8),16)/4294967295<=t.samplingRate}function Rr(...e){return`telemetry:${rb("sha256").update(e.map((t)=>String(t??"")).join("\x00")).digest("hex").slice(0,40)}`}function La(e,t,r,n){if(!n)return;return e.listResources(t,r).find((i)=>i.slug===n)?.id}function BT(e,t){let r=String(t??"").toLowerCase();if(["debug","info","warn","warning","error","fatal"].includes(r))return r==="fatal"?"error":r;return/fatal|panic|exception|error/i.test(e)?"error":/warn|timeout|throttl|retr(?:y|ies)/i.test(e)?"warning":"info"}function tb(e){let t=e.timestamp&&Number.isFinite(new Date(e.timestamp).getTime())?new Date(e.timestamp).toISOString():new Date().toISOString(),r={};try{let Y=JSON.parse(e.message);if(Y&&typeof Y==="object"&&!Array.isArray(Y))r=Y}catch{}let n=Object.fromEntries(Object.entries(r).filter(([Y])=>!/^(?:body|requestBody|responseBody|headers|authorization|cookie|cookies|query|queryString)$/i.test(Y))),i=String(r.requestId??r.request_id??r["x-request-id"]??"")||void 0,o=String(r.traceId??r.trace_id??r["x-amzn-trace-id"]??"")||void 0,s=Number(r.durationMs??r.duration_ms??r.latencyMs??r.latency_ms),c=Number(r.statusCode??r.status_code??r.status),u=String(r.method??r.httpMethod??"")||void 0,a=lo(String(r.pathTemplate??r.path??r.url??"")||void 0),f=String(r.releaseId??r.release_id??"")||void 0,C=String(r.deploymentId??r.deployment_id??"")||void 0,k={projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,source:e.source,timestamp:t,requestId:i,traceId:o,releaseId:f,deploymentId:C,workloadId:e.workloadId},D=Object.keys(r).length?JSON.stringify(n):e.message,W=[{...k,id:Rr(e.source,e.name,t,D),kind:"log",name:e.name,level:BT(D,r.level),message:D,attributes:n}];if(u&&a&&Number.isFinite(c)){if(W.push({...k,id:Rr("request",i,t,u,a,c),kind:"request",name:"http.request",method:u,pathTemplate:a,host:r.host,statusCode:c,durationMs:Number.isFinite(s)?s:void 0,bytesIn:Number(r.bytesIn)||void 0,bytesOut:Number(r.bytesOut)||void 0,region:r.region,cacheResult:r.cacheResult??r.cache,upstream:r.upstream,attributes:{userAgentFamily:r.userAgentFamily??"",protocol:r.protocol??""}}),Number.isFinite(s))W.push({...k,id:Rr("request-duration",i,t),kind:"metric",name:"request.duration",value:s,unit:"ms",attributes:{method:u,pathTemplate:a,statusCode:c}});if(W.push({...k,id:Rr("request-count",i,t),kind:"metric",name:"request.count",value:1,unit:"count",attributes:{method:u,pathTemplate:a,statusCode:c}}),c>=500)W.push({...k,id:Rr("request-error",i,t),kind:"metric",name:"request.error",value:1,unit:"count",attributes:{method:u,pathTemplate:a,statusCode:c}})}return W}async function FT(e){let t=new tt(e.controlPlane),r=et(e.controlPlane,e.projectId),n=new Date,i=[],o=[],s={projectId:e.projectId,environmentId:e.environmentId},c=H(e.config);try{let k=(c==="serverless"?await di(e.config,e.environment):await hi(e.config,e.environment,{includeSiteHealth:e.includeSiteHealth,telemetryOnly:e.lightweight}))??{};if(c==="serverless"){for(let W of k.functionsDetail??[]){let Y=La(e.controlPlane,e.projectId,e.environmentId,W.key),ee={...s,resourceId:Y,source:"cloudwatch",timestamp:n.toISOString(),workloadId:W.name,attributes:{provider:"aws",functionName:W.name,aggregationWindow:"24h"}};for(let[ne,he,te]of[["snapshot.traffic.requests_24h",W.invocations,"count"],["snapshot.errors.count_24h",W.errors,"count"],["snapshot.latency.p50_24h",W.p50,"ms"],["snapshot.latency.p95_24h",W.p95,"ms"],["snapshot.latency.p99_24h",W.p99,"ms"],["snapshot.saturation.throttles_24h",W.throttles,"count"],["snapshot.memory.max_24h",W.maxMem,"MB"]])if(Number.isFinite(Number(he)))i.push({...ee,id:Rr("cloudwatch",W.name,ne,n.toISOString()),kind:"metric",name:ne,value:Number(he),unit:te})}try{let W=await z(e.config,e.environment),Y=new q(W.region),ee=new Date(n.getTime()-3600000),ne=300;for(let he of W.functions){let te=[{Name:"FunctionName",Value:he.name}],[Pe,Xe,$e,Gt,it]=await Promise.all([Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Sum"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Errors",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Sum"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:te,StartTime:ee,EndTime:n,Period:300,ExtendedStatistics:["p50","p95","p99"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Throttles",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Sum"]}),Y.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"ConcurrentExecutions",Dimensions:te,StartTime:ee,EndTime:n,Period:300,Statistics:["Maximum"]})]),ke=La(e.controlPlane,e.projectId,e.environmentId,he.mode),He=(Tt,Ei,co,Fn)=>{for(let Ai of Tt){let ki=Ai.Timestamp&&Number.isFinite(new Date(Ai.Timestamp).getTime())?new Date(Ai.Timestamp).toISOString():void 0,Ri=co(Ai);if(ki&&Ri!=null&&Number.isFinite(Ri))i.push({...s,resourceId:ke,id:Rr("cloudwatch-series",he.name,Ei,ki),kind:"metric",source:"cloudwatch",name:Ei,timestamp:ki,value:Ri,unit:Fn,workloadId:he.name,region:W.region,attributes:{provider:"aws",functionName:he.name,aggregationWindow:"300s"}})}};He(Pe,"traffic.requests",(Tt)=>Tt.Sum,"count"),He(Xe,"errors.count",(Tt)=>Tt.Sum,"count"),He($e,"latency.p50",(Tt)=>Tt.Percentiles?.p50,"ms"),He($e,"latency.p95",(Tt)=>Tt.Percentiles?.p95,"ms"),He($e,"latency.p99",(Tt)=>Tt.Percentiles?.p99,"ms"),He(Gt,"saturation.throttles",(Tt)=>Tt.Sum,"count"),He(it,"saturation.concurrency",(Tt)=>Tt.Maximum,"count")}}catch(W){o.push({source:"cloudwatch:series",message:W instanceof Error?W.message:String(W)})}for(let W of(k.serverlessLogs??[]).slice(0,MT))i.push(...tb({...s,source:`cloudwatch:${W.source}`,name:`${W.source}.log`,timestamp:W.timestamp,message:String(W.message),resourceId:La(e.controlPlane,e.projectId,e.environmentId,W.source)}));for(let W of k.queuesDetail??[]){let Y={...s,source:"cloudwatch",timestamp:n.toISOString(),attributes:{queue:W.name}};i.push({...Y,id:Rr("queue-depth",W.name,n.toISOString()),kind:"metric",name:"queue.depth",value:Number(W.visible??W.depth??0),unit:"count"}),i.push({...Y,id:Rr("queue-inflight",W.name,n.toISOString()),kind:"metric",name:"queue.inflight",value:Number(W.inFlight??0),unit:"count"})}let D=await Ed(e.config,e.environment,30);if(!D.ok)o.push({source:"xray",message:D.error??"X-Ray traces are unavailable."});for(let W of D.traces)i.push({...s,id:Rr("xray",W.id),kind:"trace",source:"xray",name:"http.trace",timestamp:W.timestamp??n.toISOString(),traceId:W.id,durationMs:W.durationMs,statusCode:W.httpStatus,method:W.method,pathTemplate:W.url,attributes:{status:W.status,responseMs:W.responseMs}})}else{let D=k.systemMetrics;if(k.metricsUnavailable||!D)o.push({source:"host",message:"The host metrics probe is unavailable."});else{let W=Number(D.memTotalMb)>0?Number(D.memUsedMb)/Number(D.memTotalMb)*100:0,Y=Number(D.swapTotalMb)>0?Number(D.swapUsedMb)/Number(D.swapTotalMb)*100:0,ee=[["host.load",Number(D.load),"load"],["host.load.5m",Number(D.load5),"load"],["host.load.15m",Number(D.load15),"load"],["host.cpu.capacity",Number(D.cpus),"count"],["host.cpu.used_percent",Number(D.cpuUsedPct),"percent"],["host.memory.used",Number(D.memUsedMb)*1024*1024,"bytes"],["host.memory.total",Number(D.memTotalMb)*1024*1024,"bytes"],["host.memory.available",Number(D.memAvailableMb)*1024*1024,"bytes"],["host.memory.cache",Number(D.memCacheMb)*1024*1024,"bytes"],["host.memory.used_percent",W,"percent"],["host.swap.used",Number(D.swapUsedMb)*1024*1024,"bytes"],["host.swap.total",Number(D.swapTotalMb)*1024*1024,"bytes"],["host.swap.used_percent",Y,"percent"],["host.disk.used_percent",Number(D.diskUsedPct),"percent"],["host.disk.used",Number(D.diskUsedGb)*1073741824,"bytes"],["host.disk.total",Number(D.diskTotalGb)*1073741824,"bytes"],["host.disk.inode_used_percent",Number(D.inodeUsedPct),"percent"],["host.network.rx",Number(D.networkRxBytes),"bytes"],["host.network.tx",Number(D.networkTxBytes),"bytes"],["host.network.rx_rate",Number(D.networkRxBytesPerSec),"bytes_per_second"],["host.network.tx_rate",Number(D.networkTxBytesPerSec),"bytes_per_second"],["host.network.rx_today",Number(D.networkRxBytesToday),"bytes"],["host.network.tx_today",Number(D.networkTxBytesToday),"bytes"],["host.network.rx_month",Number(D.networkRxBytesMonth),"bytes"],["host.network.tx_month",Number(D.networkTxBytesMonth),"bytes"],["host.processes",Number(D.processes),"count"],["host.uptime",Number(D.uptimeSeconds),"seconds"]];for(let[ne,he,te]of ee)if(Number.isFinite(he))i.push({...s,id:Rr("host",ne,n.toISOString()),kind:"metric",source:"host",name:ne,timestamp:n.toISOString(),value:he,unit:te});for(let ne of D.disks??[]){if(ne.usedPercent===null||!Number.isFinite(Number(ne.usedPercent)))continue;i.push({...s,id:Rr("host",`disk:${ne.path}`,n.toISOString()),kind:"metric",source:"host",name:"host.filesystem.used_percent",timestamp:n.toISOString(),value:Number(ne.usedPercent),unit:"percent",attributes:{path:String(ne.path),mounted:ne.mounted!==!1}})}for(let ne of k.siteHealth??[]){let he=String(ne.project??e.config.project.slug),te=String(ne.name),Pe=te.startsWith(`${he}:`)?te.slice(he.length+1):te,Xe=`site:${he}:${Pe}`,$e=La(e.controlPlane,e.projectId,e.environmentId,te),Gt={...s,resourceId:$e,source:Xe,timestamp:ne.checkedAt||n.toISOString(),host:ne.route,attributes:{project:he,site:Pe,route:String(ne.route),status:String(ne.status)}},it=[["site.health.up",ne.status==="live"?1:0,"boolean"],["site.http.status",Number(ne.httpStatus),"status"],["site.response.time",Number(ne.responseMs),"ms"]];if(ne.tlsDaysRemaining!=null)it.push(["site.tls.days_remaining",Number(ne.tlsDaysRemaining),"days"]);for(let[ke,He,Tt]of it)if(Number.isFinite(He))i.push({...Gt,id:Rr(Xe,ke,Gt.timestamp),kind:"metric",name:ke,value:He,unit:Tt})}}}}catch(k){o.push({source:c==="serverless"?"aws":"host",message:k instanceof Error?k.message:String(k)})}{let k=e.config.infrastructure?.compute?.monitoring,D=typeof k==="object"?k?.egressEndpoints:void 0,W=await eb(D,{now:n.toISOString()});o.push(...W.errors);for(let Y of W.metrics)i.push({...s,id:Rr(Y.attributes.source,Y.name,Y.timestamp),kind:"metric",source:`egress:${Y.attributes.source}`,name:Y.name,timestamp:Y.timestamp,value:Y.value,unit:Y.unit,attributes:Y.attributes})}if(!e.lightweight)try{let k=await wi(e.config,e.environment),D=new Ce(e.config,e.environment,{inventory:async()=>k});for(let W of k.workloads){let Y=La(e.controlPlane,e.projectId,e.environmentId,W.links.service),ee={...s,resourceId:Y,source:`runtime:${W.provider}`,timestamp:n.toISOString(),workloadId:W.id,releaseId:W.links.release,attributes:{status:W.status,provider:W.provider,service:W.links.service??""}};if(i.push({...ee,id:Rr(W.id,"health",n.toISOString()),kind:"metric",name:"health.up",value:W.status==="running"?1:0,unit:"boolean"}),i.push({...ee,id:Rr(W.id,"restarts",n.toISOString()),kind:"metric",name:"saturation.restarts",value:W.restartCount??0,unit:"count"}),W.resources?.memoryBytes!=null)i.push({...ee,id:Rr(W.id,"memory",n.toISOString()),kind:"metric",name:"runtime.memory.used",value:W.resources.memoryBytes,unit:"bytes"});if(!W.capabilities.logs.supported)continue;try{let ne=await D.logs(W.id,{limit:100,since:new Date(n.getTime()-300000)});for(let he of ne.lines)i.push(...tb({...s,resourceId:Y,source:`runtime:${W.provider}`,name:`${W.links.service??W.name}.log`,timestamp:he.timestamp,message:he.message,workloadId:W.id}))}catch(ne){o.push({source:`runtime:${W.provider}`,message:ne instanceof Error?ne.message:String(ne)})}}for(let W of k.sources.filter((Y)=>Y.status!=="fresh"))o.push({source:W.id,message:W.message??`Runtime source is ${W.status}.`})}catch(k){o.push({source:"runtime",message:k instanceof Error?k.message:String(k)})}if(!e.lightweight)for(let k of e.controlPlane.listEvents({projectId:e.projectId,limit:1000})){let D=k.payload;i.push({...s,id:`telemetry:event:${k.id}`,resourceId:k.resourceId,kind:"event",source:"control-plane",name:k.type,timestamp:k.createdAt,level:k.level,message:k.type,deploymentId:k.operationId,releaseId:typeof D.releaseId==="string"?D.releaseId:void 0,traceId:k.correlationId,attributes:D})}let u=i.filter((k)=>LT(k,r)).map((k)=>({...k,sampled:r.samplingRate<1&&(k.kind==="log"||k.kind==="trace"||k.kind==="request"||k.name.startsWith("request."))})),a=t.appendMany(u).length;if(NT.shouldRun(e.projectId,$T,!e.lightweight))t.enforceRetention(r,e.projectId);let f=t.status(e.projectId,e.environmentId,r.rawDays,r.samplingRate);for(let k of o)if(!f.some((D)=>D.source===k.source))f.push({source:k.source,freshness:"unavailable",samplingRate:r.samplingRate,retentionDays:r.rawDays,estimatedDailyBytes:0,message:k.message});let C=n.toISOString();return e.controlPlane.setSetting(`telemetry.collection:${e.projectId}:${e.environmentId??"all"}`,{generatedAt:C,errors:o,statuses:f,policy:r}),{collected:a,cached:!1,generatedAt:C,statuses:f,errors:o,policy:r}}async function li(e){let r=`${`${e.projectId}:${e.environmentId??"all"}:${e.environment}`}:${e.lightweight?"lightweight":"full"}`,n=H(e.config)==="serverless"?300000:60000,i=await ob.getOrCreate(r,n,!!e.force,()=>FT(e));return{...i.value,cached:i.cached}}function sb(e){ob.invalidate(`${e}:`)}function ab(e,t={}){let r=t.shell||(process.platform==="win32"?"powershell.exe":"bash"),n=Bun.spawn([r,"-i"],{stdin:"pipe",stdout:"pipe",stderr:"pipe",cwd:t.cwd,env:{...process.env,TERM:"xterm-256color",PS1:"\\w $ "}}),i=new TextDecoder,o=async(s)=>{if(!s)return;let c=s.getReader();try{for(;;){let{done:u,value:a}=await c.read();if(u)break;if(a)e(i.decode(a))}}catch{}};if(o(n.stdout),o(n.stderr),t.onExit)n.exited.then((s)=>t.onExit(s)).catch(()=>{});return{write(s){try{n.stdin.write(s),n.stdin.flush()}catch{}},close(){try{n.stdin.end()}catch{}try{n.kill()}catch{}}}}var HT="127.0.0.1",WT=7676,db=65536,vb="ts-cloud-dashboard-",ca=UT(JT(import.meta.url));function KT(e){try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function QT(e=kd(),t=KT){let r=0;for(let n of cb(e,{withFileTypes:!0})){if(!n.isDirectory()||!n.name.startsWith(vb))continue;let i=Et(e,n.name),o=n.name.match(/^ts-cloud-dashboard-(\d+)-/);if(o){let s=Number(o[1]);if(s===process.pid||t(s))continue}else if(cb(i).length>0)continue;gs(i,{recursive:!0,force:!0}),r+=1}return r}var YT={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".ico":"image/x-icon"};function b(e,t=200,r={}){return new Response(JSON.stringify(e,null,2),{status:t,headers:{"content-type":"application/json; charset=utf-8",...r}})}function XT(e,t,r,n){let i=new TextEncoder,o=Math.max(0,Math.floor(r)),s,c,u=!1,a=new ReadableStream({start(f){let C=()=>{if(u)return;if(u=!0,s?.(),c)clearInterval(c);n.removeEventListener("abort",C);try{f.close()}catch{}},k=(W)=>{if(u)return;if(W.reset)f.enqueue(i.encode(`event: reset
|
|
460
460
|
data: ${JSON.stringify({cursor:W.cursor,droppedBytes:W.droppedBytes})}
|
|
461
461
|
|
|
462
462
|
`));for(let Y of W.chunks.filter((ee)=>ee.cursor>o))o=Y.cursor,f.enqueue(i.encode(`id: ${Y.cursor}
|
|
@@ -474,38 +474,38 @@ data: ${JSON.stringify({cursor:o,at:new Date().toISOString()})}
|
|
|
474
474
|
${c}
|
|
475
475
|
${u}`);return null}return n}catch(i){if(n)gs(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 fA(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:$t(da(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 wb(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 hA(e,t){return wb(t).find((r)=>r.id===e)}function gb(e){if(e.length<=db)return e;return`${e.slice(0,db)}
|
|
476
476
|
|
|
477
|
-
[output truncated]`}async function mb(e,t,r){let n=e.getReader(),i=new TextDecoder,o="";while(!0){let{done:c,value:u}=await n.read();if(c)break;let a=i.decode(u,{stream:!0});if(o+=a,a)r?.(t,a)}let s=i.decode();if(s)o+=s,r?.(t,s);return o}async function ap(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([mb(r.stdout,"stdout",t.onOutput),mb(r.stderr,"stderr",t.onOutput),r.exited]);return{action:e.id,command:["cloud",...e.command].join(" "),exitCode:s,ok:s===0,stdout:gb(i),stderr:gb(o)}}finally{t.signal?.removeEventListener("abort",n)}}function yA(){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 bA=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 SA(e){let t=Fa(e);if(t&&t!==".html")return!1;let r=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(r==="/")return!1;return!bA.has(r)}var vA={"/":"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 fb(e,t){if(t.role==="admin")return!0;let r=Fa(e);if(r&&r!==".html")return!0;if(t.organizationSource==="legacy")return!SA(e);let n=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(n==="/access-denied")return!0;let i=vA[n];return!!i&&!!t.capabilities?.includes(i)}function wA(e,t){let r=decodeURIComponent(t).replace(/^\/+/,""),i=zT(r===""?"index.html":r);if(i.startsWith("..")||i.includes("/../"))return null;let o=Et(e,i);if(ao(o)&&!Sb(o).isDirectory())return o;if(!Fa(o)&&ao(`${o}.html`))return`${o}.html`;if(!Fa(o)&&ao(Et(o,"index.html")))return Et(o,"index.html");return null}async function hb(e,t){let r=wA(e,t);if(!r){let o=Et(e,"404.html");if(ao(o))return new Response(await Li(o),{status:404,headers:{"content-type":"text/html; charset=utf-8"}});return Rd("Not found",404)}if(Sb(r).isDirectory())return Rd("Not found",404);let n=await Li(r),i=YT[Fa(r)]??"application/octet-stream";return new Response(n,{headers:{"content-type":i}})}var Ad=["observe","backup","restore","restart","resize","version","rotate","expose","delete","logs","slow_queries","users","databases"],yb=new WeakMap;async function bb(e){let t=yb.get(e);if(t)return t;let r=await import("./chunk-4fkmd2ce.js"),n=new r.SpendStore(e),i={store:n,service:new r.SpendService(n),gate:new r.SpendGate(e)};return yb.set(e,i),i}async function dr(e={}){QT();let t=e.cwd??process.cwd(),r=e.host??HT,n=e.port??WT,i=e.cliEntry??process.argv[1];if(e.box)process.env.TS_CLOUD_DASHBOARD_BOX="1";await oA(t);let o=e.config??await Ji(),s=process.env.TS_CLOUD_DASHBOARD_DB_PASSWORD,c=A(o);if(s&&c&&!c.password)c.password=s;let u=o.infrastructure?.compute?.managedServices?.vitess;if(s&&u&&typeof u==="object"&&!u.password)u.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 f=Object.keys(o.environments??{}),C=nA(o,e.environment),k=sA(t),D=await ps(o,C),W=new Map([[C,D]]),Y=new Map([[C,Date.now()]]),ee=new Map([[C,Date.now()]]),ne=new Map,he=Math.min(300000,Math.max(5000,Number(process.env.TS_CLOUD_DASHBOARD_REFRESH_MS)||30000)),te=Math.min(1800000,Math.max(60000,Number(process.env.TS_CLOUD_DASHBOARD_SITE_REFRESH_MS)||300000)),Pe=H(o)!=="serverless",Xe=(I)=>{let Te=W.get(I);if(Te&&!ub(Y.get(I),Date.now(),he))return Promise.resolve(Te);let De=ne.get(I);if(De)return De;let Ie=!Pe||ub(ee.get(I),Date.now(),te),Ve=ps(o,I,{includeSiteHealth:Ie}).then((gt)=>{let L=W.get(I),Dr=Ie?gt:pA(L,gt);if(W.set(I,Dr),Y.set(I,Date.now()),Ie)ee.set(I,Date.now());if(L?._serverReachable!==Dr._serverReachable||L?._metricsStatus!==Dr._metricsStatus||(L?.sitesDetail?.length??0)!==(Dr.sitesDetail?.length??0))Fn();return Dr}).finally(()=>ne.delete(I));return ne.set(I,Ve),Ve},$e=Do(t),Gt=process.env.TS_CLOUD_DASHBOARD_TELEMETRY?.trim();if(e.box&&Gt!=="0"&&(Gt==="1"||!o.cloud?.attachTo)){let I=!1,Te=Date.now()+300000,De=async()=>{if(I)return;I=!0;try{let Ve=Date.now(),gt=Ve>=Te;if(gt)Te=Ve+300000;let L=a.environments.get(C);await li({controlPlane:a.store,projectId:a.project.id,environmentId:L?.id,config:o,environment:C,force:!0,lightweight:!0,includeSiteHealth:gt})}catch(Ve){if(e.verbose)console.warn(` ts-cloud dashboard: background telemetry collection failed: ${Ve instanceof Error?Ve.message:String(Ve)}`)}finally{I=!1}};De(),setInterval(()=>void De(),60000).unref?.()}let ke=new Map,He=new Map,Tt=new Set,Ei=0;function co(I,Te){if(I.role==="admin"&&!a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`))return I;let De=a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`),Ie=De?a.store.getMembershipForActor(a.organization.id,De.id):void 0;if(!Ie||Ie.status!=="active")return{...I,role:"member",sites:{},capabilities:[]};let Ve=a.store.listGrants(Ie.id),gt=a.store.resolveAuthorizationTarget(a.organization.id,Ie.scope)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),L=vn({membership:Ie,grants:Ve,target:gt});if(Ie.roleTemplate==="owner"||Ie.roleTemplate==="admin")return{...I,role:"admin",sites:{},organizationRole:Ie.roleTemplate,organizationSource:Ie.source,capabilities:L};let Dr=a.environments.get(Te),Wt={};for(let Ke of a.store.listResources(a.project.id,Dr?.id).filter((nt)=>nt.kind==="application")){let nt=a.store.resolveAuthorizationTarget(a.organization.id,{type:"resource",id:Ke.id});if(!nt||!re({membership:Ie,grants:Ve,capability:"project:read",target:nt}).allowed)continue;Wt[Ke.slug]=re({membership:Ie,grants:Ve,capability:"config:write",target:nt}).allowed?"owner":"collaborator"}return{...I,role:"member",sites:Wt,organizationRole:Ie.roleTemplate,organizationSource:Ie.source,capabilities:L}}function Fn(){Ei+=1,ke.clear();for(let I of Tt)gs(I,{recursive:!0,force:!0});Tt.clear()}let Ai=(I,Te)=>`${Te}:${I.role==="admin"?"admin":`member:${Object.entries(I.sites).sort(([De],[Ie])=>De.localeCompare(Ie)).map(([De,Ie])=>`${De}=${Ie}`).join(",")}`}:${[...I.capabilities??[]].sort().join(",")}`;async function ki(I,Te){let De=co(I,Te),Ie=Ai(De,Te),Ve=ke.get(Ie);if(Ve)return Ve;let gt=He.get(Ie);if(gt)return gt;let L=Ei,Dr=(async()=>{let Wt=W.get(Te)??await ps(o,Te);W.set(Te,Wt);let Ke={...Yl(Wt,{user:De,slug:o.project.slug}),viewer:{role:De.role,organizationRole:De.organizationRole,organizationSource:De.organizationSource,capabilities:De.capabilities??[]}},nt=await mA(t,Ke);if(nt&&L!==Ei)return gs(nt,{recursive:!0,force:!0}),$e?.uiRoot;if(nt)Tt.add(nt);let br=nt??$e?.uiRoot;if(br)ke.set(Ie,br);return br})();He.set(Ie,Dr);try{return await Dr}finally{He.delete(Ie)}}let Ri=await ki({username:"",passwordHash:"",role:"admin",sites:{}},C);if(!Ri)throw Error("ts-cloud dashboard UI not found. Run `bun run build` in ts-cloud or reinstall the package.");let Q=new WeakMap,ge=process.env.TS_CLOUD_DASHBOARD_TERMINAL!=="0",Ee=process.env.TS_CLOUD_DASHBOARD_AUTH==="0";if(Ee&&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=!Ee,Pt=fy(t),Jt=Re?Sy(t,process.env.TS_CLOUD_UI_USERNAME?.trim()||"admin"):void 0,we=new Le(a.store,{encryptionKey:x(t)}),st=new qe(a.store),rt=new Ot(a.store),ze=new ir(a.store,{encryptionKey:x(t)}),Pr=new ei(a.store),ms=new ri(a.store,{cwd:t}),Pi=new ti(a.store,{encryptionKey:x(t)}),At=new S(a.store,{workerId:`dashboard:${process.pid}`}),Dt=new rr(a.store),Bi=new nr(a.store,x(t)),po=new xr(a.store),ja=new qr(Dt,At,Bi),go=o.project?.region??"us-east-1",dp=x(t),on=new Lr(po,{encryptionKey:dp,backends:[new wt(a.store,dp),new _r(new K(go),go),new Or(new We(go),go),new $r]});await bn(on,a,o);let Pd=new fe(go),Ib={aws_rds:new qn(new Xn(Pd)),aws_aurora:new Gn(new Qn(Pd)),aws_elasticache:new Wn(new Yn(new oe(go))),server:new Kn(new ct),container:new Jn(new ct)},up=(I)=>Ib[I.provider],Kt=new ai(a.store),Bo=new Zr(Kt,At),lp=new ci(Bi),Cb={managed_database:new Rl(Dt,Pd),logical_database:new Ol(Dt,Bi),volume:new Nl,files:new Dl(t),control_plane:new $l(a.store,t),infrastructure:new Bl(new xa(go))},Eb=(I)=>Cb[I.resourceKind],Tb=(I)=>I.provider==="aws_backup"?void 0:lp,xd=new ft(a.store),Dd=[new Mt,new ln(R(t,"volumes"))],Fi=new cn(xd,Dd,At),ua=new xe(a.store),xi=new $n(ua,[new at("aws"),new at("hetzner"),new at("ssh")],At),mo=new Ln(a.store),pp=new Mn(mo,ua),Fo=new Un(a.store),gp=new Bn(Fo,At),ji=new jn(a.store),Od=new Vn(ji,At),mp=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((I)=>new zn(I,a.store,a.project.id,a.organization.id)),hr=new Yr(a.store),fp=new si(hr,{queue:At}),Ht=new Ze(a.store),fo=new Ye(a.store),Cn=new lt(a.store),Je=new yt(a.store,{encryptionKey:x(t)}),Ab=()=>bb(a.store);for(let I of a.environments.values())Qr(hr,o,{organization:a.organization,project:a.project,environment:I,resources:a.store.listResources(a.project.id,I.id)});let En=new vr(Je,{emailImpl:async(I)=>{let{email:Te}=await import("./chunk-kj1e4xvg.js");return Te.send(I)}}),hp=async(I)=>{let Te=dn(Je,a.project.id,I),De=[];for(let Ie of Te.filter((Ve)=>Ve.notify&&Ve.alert))De.push(...await En.deliverAll(En.enqueue(a.organization.id,Ie.alert,Ie.transition)));return De.push(...await En.deliverAll(En.enqueueRemindersAndEscalations(a.organization.id,Je.listAlerts(a.project.id,{environmentId:I,states:["firing"]})))),De.push(...await En.retryDue()),{evaluations:Te,deliveries:De}},_d=!1,kb=async()=>{if(_d)return;_d=!0;try{for(let I of a.environments.values())for(let Te of Je.listHealthChecks(a.project.id,I.id).filter((De)=>De.enabled)){let De=Je.listHealthResults(Te.id,1)[0];if(De&&Date.now()-new Date(De.checkedAt).getTime()<Te.intervalSeconds*1000)continue;let Ie=await new Be(Je).runAndEvaluate(Te);for(let Ve of Ie.evaluations.filter((gt)=>gt.notify&>.alert))await En.deliverAll(En.enqueue(a.organization.id,Ve.alert,Ve.transition))}}finally{_d=!1}},yp=setInterval(()=>{for(let I of a.environments.values())hp(I.id).catch((Te)=>console.error("ts-cloud alert evaluation failed:",Te))},60000);yp.unref?.();let bp=setInterval(()=>{kb().catch((I)=>console.error("ts-cloud health check evaluation failed:",I))},30000);bp.unref?.();let Sp=setInterval(()=>{try{fp.tick()}catch(I){console.error("ts-cloud scheduled job evaluation failed:",I)}},30000);Sp.unref?.();let vp=setInterval(()=>{try{Bo.enqueueDue(),Bo.enqueueRetention()}catch(I){console.error("ts-cloud backup policy evaluation failed:",I)}},30000);vp.unref?.(),Ht.cleanup();let wp=setInterval(()=>{try{Ht.cleanup()}catch(I){console.error("ts-cloud preview cleanup failed:",I)}},3600000);wp.unref?.();let Rb=e.queueWorker??!0,Pb=yA(),xb=async(I,Te)=>{let Ie=(I.environmentId?a.store.listEnvironments(I.projectId).find((Ve)=>Ve.id===I.environmentId):void 0)?.slug??String(C);if(Te.kind==="dashboard_operation"&&Te.operationId){let Ve=W.get(Ie)??D,gt=ni(Te.operationId,o,Ve);if(!gt||gt.danger||!["scheduler","backup","worker"].includes(gt.group))return{ok:!1,stderr:"The allowlisted dashboard operation is no longer available."};let L=await Jr(o,Ie,gt);return{ok:L.ok,stdout:L.stdout,stderr:L.stderr??L.error,retryable:/temporar|unavailable|timeout|network/i.test(L.stderr??L.error??""),output:{command:L.command??null,operation:L.operation}}}if(Te.kind==="serverless_scheduler"){let Ve=await op(o,Ie,"run");return{ok:Ve.ok,stdout:Ve.stdout,stderr:Ve.error,retryable:/temporar|unavailable|timeout|network/i.test(Ve.error??""),output:{command:Ve.command??null,operation:"serverless_scheduler"}}}return{ok:!1,stderr:`No safe executor is configured for ${Te.kind}.`}},Ua=Rb?new ys(At,{...Ec({store:a.store,execute:async(I,Te)=>{let De=Te.operation.input&&typeof Te.operation.input==="object"&&!Array.isArray(Te.operation.input)?Te.operation.input:{},Ie=De.source&&typeof De.source==="object"?De.source:void 0,Ve=t,gt,L,Dr;try{if(Ie?.bindingId&&Ie?.connectionId&&Ie?.commitSha){let Ke=ze.getBinding(String(Ie.bindingId)),nt=ze.getConnection(String(Ie.connectionId));if(!Ke||!nt||Ke.connectionId!==nt.id)throw Error("Queued source binding is no longer available");let mr=(Ke.repositoryId?ze.getRepository(Ke.repositoryId):ze.listRepositories(nt.id).find((Ss)=>Ss.fullName.toLowerCase()===Ke.repositoryFullName.toLowerCase()))?.cloneUrl;if(!mr&&nt.provider==="generic_ssh")mr=`git@${new URL(nt.host).hostname}:${Ke.repositoryFullName}.git`;if(!mr)mr=new URL(`/${Ke.repositoryFullName}.git`,nt.host.endsWith("/")?nt.host:`${nt.host}/`).href;let ye=Ke.deployKeyId?ze.getDeployKey(Ke.deployKeyId):void 0,Lt=ye&&Ke.deployKeyId?{...ye,privateKey:ze.getDeployPrivateKey(Ke.deployKeyId)}:void 0;if(["github","gitlab","bitbucket","gitea"].includes(nt.provider)&&I.target.previewId){let Ss=ko(nt,ze.getCredential(nt.id)),ae=Ht.previews.getInstance(I.target.previewId);Dr=async(Tn,Ja)=>{try{await Ss.setCommitStatus(Ke.repositoryFullName,String(Ie.commitSha),{state:Tn,url:ae?.url,description:Ja})}catch(vs){Te.log(`Could not publish source status: ${vs instanceof Error?vs.message:String(vs)}`,{stream:"stderr"})}},await Dr("pending",`Preview deployment started for ${String(Ie.commitSha).slice(0,12)}`)}gt=cp(Et(kd(),"ts-cloud-queued-source-")),Te.log(`Checking out immutable source commit ${Ie.commitSha}.`,{stream:"system"}),Ve=(await nl({remote:mr,binding:Ke,destination:Et(gt,"checkout"),ref:String(Ie.branch??Ke.defaultBranch),commitSha:String(Ie.commitSha)},{credential:ze.getCredential(nt.id),deployKey:Lt})).directory}if(Te.operation.kind!=="preview.destroy"){let Ke=I.target.previewId?Ht.previews.getInstance(I.target.previewId):void 0,nt=Ke?Ht.previews.getDefinition(Ke.definitionId):void 0,br=Te.operation.resourceId?a.store.getResource(Te.operation.resourceId):void 0;if(L=await on.resolve({projectId:a.project.id,environmentId:Te.operation.environmentId,resourceId:Te.operation.resourceId,functionId:br?.kind==="function"?br.id:void 0,previewId:Ke?.id,trustedPreview:!!Ke&&!Ke.fork,allowedPreviewSecrets:nt?.inheritedSecrets}),L.warnings.some((mr)=>mr.code==="missing_required"))throw Error(`Required deployment configuration is unavailable: ${L.warnings.filter((mr)=>mr.code==="missing_required").map((mr)=>mr.key).join(", ")}`);if(Te.operation.resourceId)for(let mr of Object.values(L.entries))po.setDependency({entryId:mr.id,resourceId:Te.operation.resourceId,injectionTarget:"environment",required:mr.required,requiresRedeploy:!0});Te.log(`Resolved configuration ${L.configurationHash.slice(0,18)} for ${Object.keys(L.values).length} keys.`,{stream:"system"})}let Wt=await ap(I,{cwd:Ve,cliEntry:i,signal:Te.signal,env:L?.values,onOutput:(Ke,nt)=>Te.log(nt,{stream:Ke,step:"execute",secrets:[...Pb,...Object.entries(L?.entries??{}).filter(([,br])=>br.kind==="secret").map(([br])=>L.values[br]).filter(Boolean)]})});if(Wt.ok&&Te.operation.resourceId&&L)for(let Ke of Object.values(L.entries))po.setDependency({entryId:Ke.id,resourceId:Te.operation.resourceId,injectionTarget:"environment",required:Ke.required,requiresRedeploy:!1,lastDeployedVersion:Ke.version});return await Dr?.(Wt.ok?"success":"failure",Wt.ok?`Preview is ready at ${String(Ie?.commitSha).slice(0,12)}`:`Preview deployment failed at ${String(Ie?.commitSha).slice(0,12)}`),Wt}catch(Wt){throw await Dr?.("error",`Preview deployment could not complete at ${String(Ie?.commitSha).slice(0,12)}`),Wt}finally{if(gt)gs(gt,{recursive:!0,force:!0})}}}),...Th({store:hr,executor:xb}),...uf({store:Dt,secrets:Bi,resolveAdapter:up}),...$m(ua,xi.drivers),...Vm(Fo,[new qu("aws","AWS regional execution requires an injected AwsRegionalTransport; topology and plans were preserved without provider mutation.")]),...rf({store:ji,cleanup:mp}),...Tc(xd,Dd),..._h({store:Kt,queue:At,resolveSource:Eb,resolveDestination:Tb,validateHealth:async(I,Te)=>{if(!I.healthCheckId)return{healthy:!0,mode:"adapter"};let De=Je.getHealthCheck(I.healthCheckId);if(!De||De.projectId!==I.projectId)return{healthy:!1,error:"Configured restore health check was not found."};let Ie=await new Be(Je).runAndEvaluate(De);return{healthy:Ie.result.status==="healthy",healthCheckId:De.id,healthResultId:Ie.result.id,target:Te}}}),...th({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,Te)=>{let De=Je.listHealthChecks(Te.projectId,Te.environmentId).find((Ve)=>Ve.enabled&&Ve.name===I&&(!Ve.resourceId||Ve.resourceId===Te.resourceId));if(!De)return{healthy:!1,message:`Named health gate ${I} was not found for this release.`};let Ie=await new Be(Je).runAndEvaluate(De);return{healthy:Ie.result.status==="healthy",evidence:{healthCheckId:De.id,healthResultId:Ie.result.id,status:Ie.result.status,timings:Ie.result.timings},message:Ie.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(ii(a),rd(rt,ue(a,String(C)),D),Jt)Ya(a,Jt.users),Iy(we,a,Jt.users);let Ft=vy({cwd:t,enabled:Re,secret:Pt,authentication:we,authorization:{store:a.store,organizationId:a.organization.id,projectId:a.project.id,defaultEnvironment:String(C)}}),Yt=new Ul,Ip=setInterval(()=>Yt.sweep(),60000);Ip.unref?.();let za=new Ma,Nd=new Ma(3,900000,900000),Va=new Ma(8,900000,900000),Cp=setInterval(()=>za.prune(),300000),Ep=setInterval(()=>Nd.prune(),300000),Tp=setInterval(()=>Va.prune(),300000);if(Cp.unref?.(),Ep.unref?.(),Tp.unref?.(),Re){if(Jt?.generated)console.warn(`
|
|
477
|
+
[output truncated]`}async function mb(e,t,r){let n=e.getReader(),i=new TextDecoder,o="";while(!0){let{done:c,value:u}=await n.read();if(c)break;let a=i.decode(u,{stream:!0});if(o+=a,a)r?.(t,a)}let s=i.decode();if(s)o+=s,r?.(t,s);return o}async function ap(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([mb(r.stdout,"stdout",t.onOutput),mb(r.stderr,"stderr",t.onOutput),r.exited]);return{action:e.id,command:["cloud",...e.command].join(" "),exitCode:s,ok:s===0,stdout:gb(i),stderr:gb(o)}}finally{t.signal?.removeEventListener("abort",n)}}function yA(){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 bA=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 SA(e){let t=Fa(e);if(t&&t!==".html")return!1;let r=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(r==="/")return!1;return!bA.has(r)}var vA={"/":"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 fb(e,t){if(t.role==="admin")return!0;let r=Fa(e);if(r&&r!==".html")return!0;if(t.organizationSource==="legacy")return!SA(e);let n=e.replace(/\.html$/,"").replace(/\/+$/,"")||"/";if(n==="/access-denied")return!0;let i=vA[n];return!!i&&!!t.capabilities?.includes(i)}function wA(e,t){let r=decodeURIComponent(t).replace(/^\/+/,""),i=zT(r===""?"index.html":r);if(i.startsWith("..")||i.includes("/../"))return null;let o=Et(e,i);if(ao(o)&&!Sb(o).isDirectory())return o;if(!Fa(o)&&ao(`${o}.html`))return`${o}.html`;if(!Fa(o)&&ao(Et(o,"index.html")))return Et(o,"index.html");return null}async function hb(e,t){let r=wA(e,t);if(!r){let o=Et(e,"404.html");if(ao(o))return new Response(await Li(o),{status:404,headers:{"content-type":"text/html; charset=utf-8"}});return Rd("Not found",404)}if(Sb(r).isDirectory())return Rd("Not found",404);let n=await Li(r),i=YT[Fa(r)]??"application/octet-stream";return new Response(n,{headers:{"content-type":i}})}var Ad=["observe","backup","restore","restart","resize","version","rotate","expose","delete","logs","slow_queries","users","databases"],yb=new WeakMap;async function bb(e){let t=yb.get(e);if(t)return t;let r=await import("./chunk-37gemrn2.js"),n=new r.SpendStore(e),i={store:n,service:new r.SpendService(n),gate:new r.SpendGate(e)};return yb.set(e,i),i}async function ur(e={}){QT();let t=e.cwd??process.cwd(),r=e.host??HT,n=e.port??WT,i=e.cliEntry??process.argv[1];if(e.box)process.env.TS_CLOUD_DASHBOARD_BOX="1";await oA(t);let o=e.config??await Ji(),s=process.env.TS_CLOUD_DASHBOARD_DB_PASSWORD,c=A(o);if(s&&c&&!c.password)c.password=s;let u=o.infrastructure?.compute?.managedServices?.vitess;if(s&&u&&typeof u==="object"&&!u.password)u.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 f=Object.keys(o.environments??{}),C=nA(o,e.environment),k=sA(t),D=await ps(o,C),W=new Map([[C,D]]),Y=new Map([[C,Date.now()]]),ee=new Map([[C,Date.now()]]),ne=new Map,he=Math.min(300000,Math.max(5000,Number(process.env.TS_CLOUD_DASHBOARD_REFRESH_MS)||30000)),te=Math.min(1800000,Math.max(60000,Number(process.env.TS_CLOUD_DASHBOARD_SITE_REFRESH_MS)||300000)),Pe=H(o)!=="serverless",Xe=(I)=>{let Te=W.get(I);if(Te&&!ub(Y.get(I),Date.now(),he))return Promise.resolve(Te);let De=ne.get(I);if(De)return De;let Ie=!Pe||ub(ee.get(I),Date.now(),te),Ve=ps(o,I,{includeSiteHealth:Ie}).then((gt)=>{let F=W.get(I),Dr=Ie?gt:pA(F,gt);if(W.set(I,Dr),Y.set(I,Date.now()),Ie)ee.set(I,Date.now());if(F?._serverReachable!==Dr._serverReachable||F?._metricsStatus!==Dr._metricsStatus||(F?.sitesDetail?.length??0)!==(Dr.sitesDetail?.length??0))Fn();return Dr}).finally(()=>ne.delete(I));return ne.set(I,Ve),Ve},$e=Do(t),Gt=process.env.TS_CLOUD_DASHBOARD_TELEMETRY?.trim();if(e.box&&Gt!=="0"&&(Gt==="1"||!o.cloud?.attachTo)){let I=!1,Te=Date.now()+300000,De=async()=>{if(I)return;I=!0;try{let Ve=Date.now(),gt=Ve>=Te;if(gt)Te=Ve+300000;let F=a.environments.get(C);await li({controlPlane:a.store,projectId:a.project.id,environmentId:F?.id,config:o,environment:C,force:!0,lightweight:!0,includeSiteHealth:gt})}catch(Ve){if(e.verbose)console.warn(` ts-cloud dashboard: background telemetry collection failed: ${Ve instanceof Error?Ve.message:String(Ve)}`)}finally{I=!1}};De(),setInterval(()=>void De(),60000).unref?.()}let ke=new Map,He=new Map,Tt=new Set,Ei=0;function co(I,Te){if(I.role==="admin"&&!a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`))return I;let De=a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`),Ie=De?a.store.getMembershipForActor(a.organization.id,De.id):void 0;if(!Ie||Ie.status!=="active")return{...I,role:"member",sites:{},capabilities:[]};let Ve=a.store.listGrants(Ie.id),gt=a.store.resolveAuthorizationTarget(a.organization.id,Ie.scope)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),F=vn({membership:Ie,grants:Ve,target:gt});if(Ie.roleTemplate==="owner"||Ie.roleTemplate==="admin")return{...I,role:"admin",sites:{},organizationRole:Ie.roleTemplate,organizationSource:Ie.source,capabilities:F};let Dr=a.environments.get(Te),Kt={};for(let Ke of a.store.listResources(a.project.id,Dr?.id).filter((nt)=>nt.kind==="application")){let nt=a.store.resolveAuthorizationTarget(a.organization.id,{type:"resource",id:Ke.id});if(!nt||!re({membership:Ie,grants:Ve,capability:"project:read",target:nt}).allowed)continue;Kt[Ke.slug]=re({membership:Ie,grants:Ve,capability:"config:write",target:nt}).allowed?"owner":"collaborator"}return{...I,role:"member",sites:Kt,organizationRole:Ie.roleTemplate,organizationSource:Ie.source,capabilities:F}}function Fn(){Ei+=1,ke.clear();for(let I of Tt)gs(I,{recursive:!0,force:!0});Tt.clear()}let Ai=(I,Te)=>`${Te}:${I.role==="admin"?"admin":`member:${Object.entries(I.sites).sort(([De],[Ie])=>De.localeCompare(Ie)).map(([De,Ie])=>`${De}=${Ie}`).join(",")}`}:${[...I.capabilities??[]].sort().join(",")}`;async function ki(I,Te){let De=co(I,Te),Ie=Ai(De,Te),Ve=ke.get(Ie);if(Ve)return Ve;let gt=He.get(Ie);if(gt)return gt;let F=Ei,Dr=(async()=>{let Kt=W.get(Te)??await ps(o,Te);W.set(Te,Kt);let Ke={...Yl(Kt,{user:De,slug:o.project.slug}),viewer:{role:De.role,organizationRole:De.organizationRole,organizationSource:De.organizationSource,capabilities:De.capabilities??[]}},nt=await mA(t,Ke);if(nt&&F!==Ei)return gs(nt,{recursive:!0,force:!0}),$e?.uiRoot;if(nt)Tt.add(nt);let Sr=nt??$e?.uiRoot;if(Sr)ke.set(Ie,Sr);return Sr})();He.set(Ie,Dr);try{return await Dr}finally{He.delete(Ie)}}let Ri=await ki({username:"",passwordHash:"",role:"admin",sites:{}},C);if(!Ri)throw Error("ts-cloud dashboard UI not found. Run `bun run build` in ts-cloud or reinstall the package.");let Q=new WeakMap,ge=process.env.TS_CLOUD_DASHBOARD_TERMINAL!=="0",Ee=process.env.TS_CLOUD_DASHBOARD_AUTH==="0";if(Ee&&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=!Ee,Pt=fy(t),Jt=Re?Sy(t,process.env.TS_CLOUD_UI_USERNAME?.trim()||"admin"):void 0,we=new Le(a.store,{encryptionKey:x(t)}),st=new Ge(a.store),rt=new Ot(a.store),ze=new or(a.store,{encryptionKey:x(t)}),Pr=new ei(a.store),ms=new ri(a.store,{cwd:t}),Pi=new ti(a.store,{encryptionKey:x(t)}),At=new S(a.store,{workerId:`dashboard:${process.pid}`}),Dt=new nr(a.store),Bi=new ir(a.store,x(t)),po=new xr(a.store),ja=new Gr(Dt,At,Bi),go=o.project?.region??"us-east-1",dp=x(t),on=new Lr(po,{encryptionKey:dp,backends:[new wt(a.store,dp),new _r(new K(go),go),new Or(new We(go),go),new $r]});await bn(on,a,o);let Pd=new fe(go),Ib={aws_rds:new Gn(new Xn(Pd)),aws_aurora:new qn(new Qn(Pd)),aws_elasticache:new Wn(new Yn(new oe(go))),server:new Kn(new ct),container:new Jn(new ct)},up=(I)=>Ib[I.provider],Qt=new ai(a.store),Bo=new Zr(Qt,At),lp=new ci(Bi),Cb={managed_database:new Rl(Dt,Pd),logical_database:new Ol(Dt,Bi),volume:new Nl,files:new Dl(t),control_plane:new $l(a.store,t),infrastructure:new Bl(new xa(go))},Eb=(I)=>Cb[I.resourceKind],Tb=(I)=>I.provider==="aws_backup"?void 0:lp,xd=new ft(a.store),Dd=[new Mt,new ln(R(t,"volumes"))],Fi=new cn(xd,Dd,At),ua=new xe(a.store),xi=new $n(ua,[new at("aws"),new at("hetzner"),new at("ssh")],At),mo=new Ln(a.store),pp=new Mn(mo,ua),Fo=new Un(a.store),gp=new Bn(Fo,At),ji=new jn(a.store),Od=new Vn(ji,At),mp=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((I)=>new zn(I,a.store,a.project.id,a.organization.id)),yr=new Yr(a.store),fp=new si(yr,{queue:At}),Wt=new Ze(a.store),fo=new Ye(a.store),Cn=new lt(a.store),Je=new yt(a.store,{encryptionKey:x(t)}),Ab=()=>bb(a.store);for(let I of a.environments.values())Qr(yr,o,{organization:a.organization,project:a.project,environment:I,resources:a.store.listResources(a.project.id,I.id)});let En=new Cr(Je,{emailImpl:async(I)=>{let{email:Te}=await import("./chunk-40963a0r.js");return Te.send(I)}}),hp=async(I)=>{let Te=dn(Je,a.project.id,I),De=[];for(let Ie of Te.filter((Ve)=>Ve.notify&&Ve.alert))De.push(...await En.deliverAll(En.enqueue(a.organization.id,Ie.alert,Ie.transition)));return De.push(...await En.deliverAll(En.enqueueRemindersAndEscalations(a.organization.id,Je.listAlerts(a.project.id,{environmentId:I,states:["firing"]})))),De.push(...await En.retryDue()),{evaluations:Te,deliveries:De}},_d=!1,kb=async()=>{if(_d)return;_d=!0;try{for(let I of a.environments.values())for(let Te of Je.listHealthChecks(a.project.id,I.id).filter((De)=>De.enabled)){let De=Je.listHealthResults(Te.id,1)[0];if(De&&Date.now()-new Date(De.checkedAt).getTime()<Te.intervalSeconds*1000)continue;let Ie=await new Be(Je).runAndEvaluate(Te);for(let Ve of Ie.evaluations.filter((gt)=>gt.notify&>.alert))await En.deliverAll(En.enqueue(a.organization.id,Ve.alert,Ve.transition))}}finally{_d=!1}},yp=setInterval(()=>{for(let I of a.environments.values())hp(I.id).catch((Te)=>console.error("ts-cloud alert evaluation failed:",Te))},60000);yp.unref?.();let bp=setInterval(()=>{kb().catch((I)=>console.error("ts-cloud health check evaluation failed:",I))},30000);bp.unref?.();let Sp=setInterval(()=>{try{fp.tick()}catch(I){console.error("ts-cloud scheduled job evaluation failed:",I)}},30000);Sp.unref?.();let vp=setInterval(()=>{try{Bo.enqueueDue(),Bo.enqueueRetention()}catch(I){console.error("ts-cloud backup policy evaluation failed:",I)}},30000);vp.unref?.(),Wt.cleanup();let wp=setInterval(()=>{try{Wt.cleanup()}catch(I){console.error("ts-cloud preview cleanup failed:",I)}},3600000);wp.unref?.();let Rb=e.queueWorker??!0,Pb=yA(),xb=async(I,Te)=>{let Ie=(I.environmentId?a.store.listEnvironments(I.projectId).find((Ve)=>Ve.id===I.environmentId):void 0)?.slug??String(C);if(Te.kind==="dashboard_operation"&&Te.operationId){let Ve=W.get(Ie)??D,gt=ni(Te.operationId,o,Ve);if(!gt||gt.danger||!["scheduler","backup","worker"].includes(gt.group))return{ok:!1,stderr:"The allowlisted dashboard operation is no longer available."};let F=await Jr(o,Ie,gt);return{ok:F.ok,stdout:F.stdout,stderr:F.stderr??F.error,retryable:/temporar|unavailable|timeout|network/i.test(F.stderr??F.error??""),output:{command:F.command??null,operation:F.operation}}}if(Te.kind==="serverless_scheduler"){let Ve=await op(o,Ie,"run");return{ok:Ve.ok,stdout:Ve.stdout,stderr:Ve.error,retryable:/temporar|unavailable|timeout|network/i.test(Ve.error??""),output:{command:Ve.command??null,operation:"serverless_scheduler"}}}return{ok:!1,stderr:`No safe executor is configured for ${Te.kind}.`}},Ua=Rb?new ys(At,{...Ec({store:a.store,execute:async(I,Te)=>{let De=Te.operation.input&&typeof Te.operation.input==="object"&&!Array.isArray(Te.operation.input)?Te.operation.input:{},Ie=De.source&&typeof De.source==="object"?De.source:void 0,Ve=t,gt,F,Dr;try{if(Ie?.bindingId&&Ie?.connectionId&&Ie?.commitSha){let Ke=ze.getBinding(String(Ie.bindingId)),nt=ze.getConnection(String(Ie.connectionId));if(!Ke||!nt||Ke.connectionId!==nt.id)throw Error("Queued source binding is no longer available");let mr=(Ke.repositoryId?ze.getRepository(Ke.repositoryId):ze.listRepositories(nt.id).find((Ss)=>Ss.fullName.toLowerCase()===Ke.repositoryFullName.toLowerCase()))?.cloneUrl;if(!mr&&nt.provider==="generic_ssh")mr=`git@${new URL(nt.host).hostname}:${Ke.repositoryFullName}.git`;if(!mr)mr=new URL(`/${Ke.repositoryFullName}.git`,nt.host.endsWith("/")?nt.host:`${nt.host}/`).href;let ye=Ke.deployKeyId?ze.getDeployKey(Ke.deployKeyId):void 0,Lt=ye&&Ke.deployKeyId?{...ye,privateKey:ze.getDeployPrivateKey(Ke.deployKeyId)}:void 0;if(["github","gitlab","bitbucket","gitea"].includes(nt.provider)&&I.target.previewId){let Ss=ko(nt,ze.getCredential(nt.id)),ae=Wt.previews.getInstance(I.target.previewId);Dr=async(Tn,Ja)=>{try{await Ss.setCommitStatus(Ke.repositoryFullName,String(Ie.commitSha),{state:Tn,url:ae?.url,description:Ja})}catch(vs){Te.log(`Could not publish source status: ${vs instanceof Error?vs.message:String(vs)}`,{stream:"stderr"})}},await Dr("pending",`Preview deployment started for ${String(Ie.commitSha).slice(0,12)}`)}gt=cp(Et(kd(),"ts-cloud-queued-source-")),Te.log(`Checking out immutable source commit ${Ie.commitSha}.`,{stream:"system"}),Ve=(await nl({remote:mr,binding:Ke,destination:Et(gt,"checkout"),ref:String(Ie.branch??Ke.defaultBranch),commitSha:String(Ie.commitSha)},{credential:ze.getCredential(nt.id),deployKey:Lt})).directory}if(Te.operation.kind!=="preview.destroy"){let Ke=I.target.previewId?Wt.previews.getInstance(I.target.previewId):void 0,nt=Ke?Wt.previews.getDefinition(Ke.definitionId):void 0,Sr=Te.operation.resourceId?a.store.getResource(Te.operation.resourceId):void 0;if(F=await on.resolve({projectId:a.project.id,environmentId:Te.operation.environmentId,resourceId:Te.operation.resourceId,functionId:Sr?.kind==="function"?Sr.id:void 0,previewId:Ke?.id,trustedPreview:!!Ke&&!Ke.fork,allowedPreviewSecrets:nt?.inheritedSecrets}),F.warnings.some((mr)=>mr.code==="missing_required"))throw Error(`Required deployment configuration is unavailable: ${F.warnings.filter((mr)=>mr.code==="missing_required").map((mr)=>mr.key).join(", ")}`);if(Te.operation.resourceId)for(let mr of Object.values(F.entries))po.setDependency({entryId:mr.id,resourceId:Te.operation.resourceId,injectionTarget:"environment",required:mr.required,requiresRedeploy:!0});Te.log(`Resolved configuration ${F.configurationHash.slice(0,18)} for ${Object.keys(F.values).length} keys.`,{stream:"system"})}let Kt=await ap(I,{cwd:Ve,cliEntry:i,signal:Te.signal,env:F?.values,onOutput:(Ke,nt)=>Te.log(nt,{stream:Ke,step:"execute",secrets:[...Pb,...Object.entries(F?.entries??{}).filter(([,Sr])=>Sr.kind==="secret").map(([Sr])=>F.values[Sr]).filter(Boolean)]})});if(Kt.ok&&Te.operation.resourceId&&F)for(let Ke of Object.values(F.entries))po.setDependency({entryId:Ke.id,resourceId:Te.operation.resourceId,injectionTarget:"environment",required:Ke.required,requiresRedeploy:!1,lastDeployedVersion:Ke.version});return await Dr?.(Kt.ok?"success":"failure",Kt.ok?`Preview is ready at ${String(Ie?.commitSha).slice(0,12)}`:`Preview deployment failed at ${String(Ie?.commitSha).slice(0,12)}`),Kt}catch(Kt){throw await Dr?.("error",`Preview deployment could not complete at ${String(Ie?.commitSha).slice(0,12)}`),Kt}finally{if(gt)gs(gt,{recursive:!0,force:!0})}}}),...Th({store:yr,executor:xb}),...uf({store:Dt,secrets:Bi,resolveAdapter:up}),...$m(ua,xi.drivers),...Vm(Fo,[new qu("aws","AWS regional execution requires an injected AwsRegionalTransport; topology and plans were preserved without provider mutation.")]),...rf({store:ji,cleanup:mp}),...Tc(xd,Dd),..._h({store:Qt,queue:At,resolveSource:Eb,resolveDestination:Tb,validateHealth:async(I,Te)=>{if(!I.healthCheckId)return{healthy:!0,mode:"adapter"};let De=Je.getHealthCheck(I.healthCheckId);if(!De||De.projectId!==I.projectId)return{healthy:!1,error:"Configured restore health check was not found."};let Ie=await new Be(Je).runAndEvaluate(De);return{healthy:Ie.result.status==="healthy",healthCheckId:De.id,healthResultId:Ie.result.id,target:Te}}}),...th({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,Te)=>{let De=Je.listHealthChecks(Te.projectId,Te.environmentId).find((Ve)=>Ve.enabled&&Ve.name===I&&(!Ve.resourceId||Ve.resourceId===Te.resourceId));if(!De)return{healthy:!1,message:`Named health gate ${I} was not found for this release.`};let Ie=await new Be(Je).runAndEvaluate(De);return{healthy:Ie.result.status==="healthy",evidence:{healthCheckId:De.id,healthResultId:Ie.result.id,status:Ie.result.status,timings:Ie.result.timings},message:Ie.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(ii(a),rd(rt,ue(a,String(C)),D),Jt)Ya(a,Jt.users),Iy(we,a,Jt.users);let Ft=vy({cwd:t,enabled:Re,secret:Pt,authentication:we,authorization:{store:a.store,organizationId:a.organization.id,projectId:a.project.id,defaultEnvironment:String(C)}}),Xt=new Ul,Ip=setInterval(()=>Xt.sweep(),60000);Ip.unref?.();let za=new Ma,Nd=new Ma(3,900000,900000),Va=new Ma(8,900000,900000),Cp=setInterval(()=>za.prune(),300000),Ep=setInterval(()=>Nd.prune(),300000),Tp=setInterval(()=>Va.prune(),300000);if(Cp.unref?.(),Ep.unref?.(),Tp.unref?.(),Re){if(Jt?.generated)console.warn(`
|
|
478
478
|
ts-cloud dashboard: created the first admin.
|
|
479
479
|
username: ${Jt.generated.username}
|
|
480
480
|
password: ${Jt.generated.password}
|
|
481
481
|
Saved (hashed) to ${yy()}. This password is shown once.
|
|
482
|
-
`)}else console.warn(" ts-cloud dashboard: authentication is DISABLED (TS_CLOUD_DASHBOARD_AUTH=0). Every request runs as an admin.");let ho=r!=="127.0.0.1"&&r!=="localhost",Md=(I)=>jT("sha256").update(`${Pt}:${I}`).digest("hex").slice(0,16),Db=vl({controlPlane:a.store,identities:st,sources:ze,applications:{drafts:Pr,artifacts:ms,registries:Pi}}),Ap=(I)=>I.headers.get("user-agent")?.trim().slice(0,256)||void 0,qa=(I,Te,De,Ie="local")=>we.createSession({identityId:I,authMethod:Ie,userAgent:Ap(Te),networkHint:Md(De)}),_e=(I)=>{let Te=a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`),De=Te?a.store.getMembershipForActor(a.organization.id,Te.id):void 0;return{actor:Te,membership:De,grants:De?a.store.listGrants(De.id):[]}},fs=(I,Te,De)=>{if(I.role==="admin")return!0;let Ie=a.store.getOperation(Te),Ve=_e(I);if(!Ie||!Ve.membership)return!1;let gt=Ie.resourceId?{type:"resource",id:Ie.resourceId}:Ie.environmentId?{type:"environment",id:Ie.environmentId}:Ie.projectId?{type:"project",id:Ie.projectId}:{type:"organization"},
|
|
482
|
+
`)}else console.warn(" ts-cloud dashboard: authentication is DISABLED (TS_CLOUD_DASHBOARD_AUTH=0). Every request runs as an admin.");let ho=r!=="127.0.0.1"&&r!=="localhost",Md=(I)=>jT("sha256").update(`${Pt}:${I}`).digest("hex").slice(0,16),Db=vl({controlPlane:a.store,identities:st,sources:ze,applications:{drafts:Pr,artifacts:ms,registries:Pi}}),Ap=(I)=>I.headers.get("user-agent")?.trim().slice(0,256)||void 0,qa=(I,Te,De,Ie="local")=>we.createSession({identityId:I,authMethod:Ie,userAgent:Ap(Te),networkHint:Md(De)}),_e=(I)=>{let Te=a.store.getActorByExternalId("user",`dashboard:${I.username.toLowerCase()}`),De=Te?a.store.getMembershipForActor(a.organization.id,Te.id):void 0;return{actor:Te,membership:De,grants:De?a.store.listGrants(De.id):[]}},fs=(I,Te,De)=>{if(I.role==="admin")return!0;let Ie=a.store.getOperation(Te),Ve=_e(I);if(!Ie||!Ve.membership)return!1;let gt=Ie.resourceId?{type:"resource",id:Ie.resourceId}:Ie.environmentId?{type:"environment",id:Ie.environmentId}:Ie.projectId?{type:"project",id:Ie.projectId}:{type:"organization"},F=a.store.resolveAuthorizationTarget(a.organization.id,gt);return!!F&&re({membership:Ve.membership,grants:Ve.grants,capability:De,target:F}).allowed},br=(I,Te,De)=>{if(I.role==="admin")return!0;let Ie=_e(I);if(!Ie.membership)return!1;let Ve=a.store.resolveAuthorizationTarget(a.organization.id,{type:"resource",id:Te});return!!Ve&&re({membership:Ie.membership,grants:Ie.grants,capability:De,target:Ve}).allowed},la=(I,Te,De)=>{if(I.role==="admin")return!0;let Ie=_e(I);if(!Ie.membership)return!1;let Ve=a.store.resolveAuthorizationTarget(a.organization.id,{type:"environment",id:Te});return!!Ve&&re({membership:Ie.membership,grants:Ie.grants,capability:De,target:Ve}).allowed},Ga=(I,Te)=>{if(I.role==="admin")return!0;let De=_e(I);if(!De.membership)return!1;let Ie=a.store.resolveAuthorizationTarget(a.organization.id,{type:"organization"});return!!Ie&&re({membership:De.membership,grants:De.grants,capability:Te,target:Ie}).allowed},bs=Bun.serve({hostname:r,port:n,idleTimeout:30,websocket:{open(I){if(!ge){I.send(`The web terminal is disabled (TS_CLOUD_DASHBOARD_TERMINAL=0).\r
|
|
483
483
|
`),I.close();return}let Te=ab((De)=>I.send(De),{cwd:t,onExit:()=>{try{I.close()}catch{}}});Q.set(I,Te),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,Te){Q.get(I)?.write(typeof Te==="string"?Te:new TextDecoder().decode(Te))},close(I){Q.get(I)?.close(),Q.delete(I)}},async fetch(I,Te){let De=Date.now(),Ie=I.clone(),Ve=I.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),gt=!["GET","HEAD","OPTIONS"].includes(I.method.toUpperCase()),
|
|
484
|
+
`)},message(I,Te){Q.get(I)?.write(typeof Te==="string"?Te:new TextDecoder().decode(Te))},close(I){Q.get(I)?.close(),Q.delete(I)}},async fetch(I,Te){let De=Date.now(),Ie=I.clone(),Ve=I.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),gt=!["GET","HEAD","OPTIONS"].includes(I.method.toUpperCase()),F=new URL(I.url),Kt=await(async()=>{let Ke=Te??bs,nt=rA(r,Ke.port??n),Sr=await Db(I,Md(Ke.requestIP(I)?.address??"unknown"));if(Sr)return Sr;let mr=F.searchParams.get("env"),ye=iA(f,C,mr),Lt=W.get(ye);if(!Lt)Lt=await Xe(ye);try{if(!cA(I))return b({ok:!1,error:"Cross-site requests are not allowed."},403);let jo=/^\/api\/source\/webhooks\/([A-Za-z0-9_-]{16,200})$/.exec(F.pathname);if(jo&&I.method==="POST"){let d=await kf({sources:ze,controlPlane:a.store,endpointToken:jo[1],headers:I.headers,rawBody:new Uint8Array(await I.arrayBuffer())});return b({accepted:d.accepted,duplicate:d.duplicate,status:d.status,operationIds:d.operations.map((l)=>l.id),message:d.message},d.accepted?202:404)}let Ss=/^\/auth\/oidc\/([a-z0-9-]+)\/(start|callback)$/.exec(F.pathname);if(Ss&&I.method==="GET"){let[,d,l]=Ss;if(!nt)return new Response(null,{status:302,headers:{location:"/login?sso_error=configuration"}});if(l==="start")try{let T=await qd(we,d,nt,F.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(F.searchParams.has("error")){let X=we.getOidcProviderBySlug(d),U=F.searchParams.get("state");if(X&&U)we.consumeOidcTransaction(X.id,U);throw Error("OIDC provider returned an authorization error")}let T=await Gd(we,{providerSlug:d,state:F.searchParams.get("state")??"",code:F.searchParams.get("code")??"",origin:nt},e.oidcFetch),M=Cy(we,a,t,T.identity);we.recordLogin(M.identity.id);let j=qa(M.identity.id,I,Ke.requestIP(I)?.address??"unknown","oidc");return Fn(),a.store.appendEvent({organizationId:a.organization.id,actorId:M.identity.actorId,type:"auth.login.succeeded",payload:{method:"oidc",provider:d,provisioned:M.provisioned}}),new Response(null,{status:302,headers:{location:T.returnPath,"cache-control":"no-store","set-cookie":ra(j.token,{secure:ho,maxAgeMs:bo})}})}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(F.pathname==="/api/invitations/accept"&&I.method==="POST"){let d=await ie(I),l=String(d.token??"").trim(),T=String(d.username??"").trim(),M=String(d.password??"");if(!l||!vd(T)||M.length<12)return b({ok:!1,error:"Invitation token, valid username, and a password of at least 12 characters are required."},422);let j=a.store.inspectInvitationToken(l);if(!j||j.state!=="pending")return b({ok:!1,error:j?`Invitation is ${j.state}`:"Invitation is invalid"},j?409:404);let X=Nn(nn(t),T),U=we.getIdentityByUsername(T);if(X&&!Ii(M,U?.passwordHash??X.passwordHash))return b({ok:!1,error:"That username already exists; enter its current password to continue."},401);let Z=we.getIdentityByEmail(j.email);if(Z&&Z.id!==U?.id)return b({ok:!1,error:"This invitation belongs to an existing account. Sign in with that account or ask an owner to resend it."},409);let me=Na(t,{username:T,password:X?void 0:M,name:typeof d.name==="string"?d.name:void 0,email:j.email,sites:X?.sites??{}}),le=er(a.store,me.user);try{let qe=a.store.acceptInvitation(l,le.id),be=U?we.setVerifiedEmail(U.id,qe.invitation.email):we.createIdentity({actorId:le.id,username:me.user.username,email:qe.invitation.email,emailVerified:!0,passwordHash:me.user.passwordHash}),Ne=qa(be.id,I,Ke.requestIP(I)?.address??"unknown");return Fn(),b({ok:!0,user:ia(me.user),organization:a.organization,membership:qe.membership},200,{"set-cookie":ra(Ne.token,{secure:ho,maxAgeMs:bo})})}catch(qe){if(!X)Ql(t,me.user.username);let be=qe instanceof Error?qe.message:"Invitation could not be accepted.";return b({ok:!1,error:be},be.includes("expired")||be.includes("revoked")||be.includes("accepted")?409:404)}}if(F.pathname==="/api/auth/password-reset/request"&&I.method==="POST"){let d=await ie(I),l=String(d.identifier??"").trim().toLowerCase(),T=Ke.requestIP(I)?.address??"unknown",M=Nd.check(l,T),j=l.includes("@")?we.getIdentityByEmail(l):we.getIdentityByUsername(l);if(M.allowed)Nd.recordFailure(l,T);if(M.allowed&&j?.email&&j.emailVerifiedAt&&!j.disabledAt){we.revokeActionTokens(j.id,"password_reset");let X=we.createActionToken(j.id,"password_reset"),U=`${F.origin}/reset-password?token=${encodeURIComponent(X.token)}`,Z=await ga(o,{to:j.email,subject:"Reset your ts-cloud password",text:`Reset your ts-cloud password: ${U}
|
|
485
485
|
|
|
486
|
-
This link expires in one hour and can be used once.`});a.store.appendEvent({organizationId:a.organization.id,actorId:F.actorId,type:"auth.password_reset.requested",payload:{delivered:Z}})}return b({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(L.pathname==="/api/auth/password-reset/complete"&&I.method==="POST"){let d=await ie(I),l=String(d.token??"").trim(),T=String(d.password??"");if(!l||T.length<12)return b({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let M=we.consumeActionToken(l,"password_reset"),F=$o(T),X=we.updatePassword(M.identityId,F);return Id(t,X.username,F),a.store.appendEvent({organizationId:a.organization.id,actorId:X.actorId,type:"auth.password_reset.completed"}),b({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":Sd({secure:ho})})}catch(M){let F=M instanceof Error?M.message:"Password reset failed.";return b({ok:!1,error:F.replace("Action token","Reset link")},F.includes("consumed")||F.includes("expired")?409:404)}}if(L.pathname==="/api/login"&&I.method==="POST"){let d=await ie(I),l=String(d.username??"").trim(),T=String(d.password??""),M=Ke.requestIP(I)?.address??"unknown",F=za.check(l,M);if(!F.allowed)return b({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((F.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(F.retryAfterSeconds??60)});let X=Nn(nn(t),l),j=we.getIdentityByUsername(l),Z=j?.passwordHash??X?.passwordHash??tA;if(!(Ii(T,Z)&&!!X&&!!j&&!j.disabledAt))return za.recordFailure(l,M),b({ok:!1,error:"Incorrect username or password."},401);if(Ey(we,a,j))return b({ok:!1,error:"Single sign-on is required for this account."},403);za.recordSuccess(l,M);let le=j,Ge=le.requiresPasswordUpgrade||oy(le.passwordHash);if(Ge){let Ne=$o(T);le=we.rehashPassword(le.id,Ne),Id(t,le.username,Ne)}if(we.recordLogin(le.id),we.getMfaFactor(le.id)?.state==="active"){let Ne=we.createMfaChallenge(le.id,"login");return a.store.appendEvent({organizationId:a.organization.id,actorId:le.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),b({ok:!0,mfaRequired:!0,challengeToken:Ne.token,passwordUpgraded:Ge})}let be=qa(le.id,I,M);return a.store.appendEvent({organizationId:a.organization.id,actorId:le.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),b({ok:!0,user:ia(X),passwordUpgraded:Ge},200,{"set-cookie":ra(be.token,{secure:ho,maxAgeMs:bo})})}if(L.pathname==="/api/auth/mfa/complete"&&I.method==="POST"){let d=await ie(I),l=String(d.challengeToken??"").trim(),T=String(d.code??"").trim(),M=Ke.requestIP(I)?.address??"unknown",X=we.inspectMfaChallengeToken(l,"login")?.identityId??"unknown-mfa",j=Va.check(X,M);if(!j.allowed)return b({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(j.retryAfterSeconds??60)});try{let Z=we.completeMfaChallenge(l,T,"login");Va.recordSuccess(X,M);let me=new Date().toISOString(),le=we.createSession({identityId:Z.identity.id,userAgent:Ap(I),networkHint:Md(M),mfaAt:me,recentAuthAt:me});return a.store.appendEvent({organizationId:a.organization.id,actorId:Z.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:Z.method}}),b({ok:!0},200,{"set-cookie":ra(le.token,{secure:ho,maxAgeMs:bo})})}catch{return Va.recordFailure(X,M),b({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(L.pathname==="/api/logout"&&I.method==="POST"){let d=Ft.resolveSession(I);if(d)we.revokeSession(d.identityId,d.id);let l=Sd({secure:ho});if(I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":l}});return b({ok:!0},200,{"set-cookie":l})}if(L.pathname==="/login"){let d=we.listOidcProviders(a.organization.id).map((l)=>({slug:l.slug,name:l.name}));return new Response(Ty(D?.mode==="serverless",d),{headers:{"content-type":"text/html; charset=utf-8"}})}if(L.pathname==="/forgot-password"||L.pathname==="/reset-password")return new Response(Ay(L.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(L.pathname==="/accept-invitation")return hb(Ri,L.pathname);let ae=Ft.resolveUser(I);if(!ae){if(!L.pathname.startsWith("/api/")&&I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return b({ok:!1,error:"Sign in to continue."},401)}let Tn=co(ae,ye);if(L.pathname==="/api/me"){let d=a.store.getActorByExternalId("user",`dashboard:${ae.username.toLowerCase()}`),l=d?a.store.getMembershipForActor(a.organization.id,d.id):void 0,T=a.store.resolveAuthorizationTarget(a.organization.id,l?.scope??{type:"project",id:a.project.id})??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id});return b({ok:!0,user:ia(ae),authEnabled:Re,organization:a.organization,membership:l,capabilities:vn({membership:l,grants:l?a.store.listGrants(l.id):[],target:T})})}if(L.pathname.startsWith("/api/")){let d=await wy(I,L.pathname),l=Ft.check(I,L.pathname,ae,d);if(!l.ok)return b({ok:!1,error:l.error},l.status??403);if(Re&&lA.has(`${I.method.toUpperCase()} ${L.pathname}`)){let T=Ft.resolveSession(I);if(!T||!we.isRecentlyAuthenticated(T))return b({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(L.pathname==="/api/auth/security"&&I.method==="GET"){let d=_e(ae),l=d.actor?we.getIdentityByActor(d.actor.id):void 0,T=Ft.resolveSession(I);return b({identity:l?{username:l.username,email:l.email,emailVerifiedAt:l.emailVerifiedAt,requiresPasswordUpgrade:l.requiresPasswordUpgrade,lastLoginAt:l.lastLoginAt}:void 0,currentSessionId:T?.id,sessions:l?we.listSessions(l.id,{includeInactive:!0}):[],mfa:l?{factor:we.getMfaFactor(l.id),recoveryCodesRemaining:we.remainingRecoveryCodes(l.id)}:void 0})}if(L.pathname==="/api/auth/oidc/providers"&&I.method==="GET")return b({providers:we.listOidcProviders(a.organization.id,{includeDisabled:!0}),callbackOrigin:nt,callbackPattern:nt?`${nt}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(L.pathname==="/api/auth/oidc/providers"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=l.actor?we.getIdentityByActor(l.actor.id):void 0,M=d.enforceSso===!0;if(M&&(!T?.emailVerifiedAt||we.remainingRecoveryCodes(T.id)<1))return b({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let F=Td(d.defaultRole),X=we.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:F&&F!=="owner"?F:void 0,enabled:d.enabled!==!1,enforceSso:M});return a.store.appendEvent({organizationId:a.organization.id,actorId:l.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:X.id,issuer:X.issuer,enabled:X.enabled,enforceSso:X.enforceSso}}),b({ok:!0,provider:X})}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"OIDC provider could not be saved."},422)}}if(L.pathname==="/api/auth/oidc/providers"&&I.method==="PATCH"){let d=await ie(I),l=we.getOidcProvider(String(d.id??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"OIDC provider was not found."},404);let T=_e(ae),M=we.setOidcProviderEnabled(l.id,d.enabled===!0);return a.store.appendEvent({organizationId:a.organization.id,actorId:T.actor?.id,type:M.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:l.id}}),b({ok:!0,provider:M})}if(L.pathname==="/api/automation"&&I.method==="GET"){let d=st.listServiceAccounts(a.organization.id,{includeDisabled:!0}).map((l)=>{let T=a.store.getMembershipForActor(a.organization.id,l.actorId),M=l.createdByActorId?a.store.getActor(l.createdByActorId):void 0,F=st.listTokens(l.id,{includeInactive:!0}).map((X)=>({...X,createdBy:X.createdByActorId?a.store.getActor(X.createdByActorId):void 0}));return{account:l,createdBy:M,membership:T,tokens:F}});return b({accounts:d,apiBaseUrl:`${L.origin}/api/v1`,openApiUrl:`${L.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(L.pathname==="/api/automation/service-accounts"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=Td(d.roleTemplate),M=Ba(d);if(!l.actor||!T||T==="owner"||!M)return b({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let F=st.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:M,createdByActorId:l.actor.id});return b({ok:!0,...F},201)}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"Service account could not be created."},422)}}if(L.pathname==="/api/automation/service-accounts"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=st.getServiceAccount(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Service account was not found."},404);return b({ok:!0,account:st.disableServiceAccount(T.id,l.actor?.id)})}if(L.pathname==="/api/automation/tokens"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=st.getServiceAccount(String(d.serviceAccountId??"")),M=Ba(d);if(!l.actor||!T||T.organizationId!==a.organization.id||!M||!Array.isArray(d.capabilities))return b({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let F=st.createToken({serviceAccountId:T.id,name:String(d.name??"API token"),capabilities:d.capabilities.map(String),scope:M,expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,createdByActorId:l.actor.id});return b({ok:!0,token:F.token,secret:F.secret,revealOnce:!0},201)}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"API token could not be created."},422)}}if(L.pathname==="/api/automation/tokens/rotate"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=st.getToken(String(d.id??"")),M=T?st.getServiceAccount(T.serviceAccountId):void 0;if(!l.actor||!T||M?.organizationId!==a.organization.id)return b({ok:!1,error:"API token was not found."},404);try{let F=st.rotateToken(T.id,l.actor.id);return b({ok:!0,token:F.token,secret:F.secret,revealOnce:!0,overlap:!0},201)}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"API token could not be rotated."},409)}}if(L.pathname==="/api/automation/tokens"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=st.getToken(String(d.id??"")),M=T?st.getServiceAccount(T.serviceAccountId):void 0;if(!T||M?.organizationId!==a.organization.id)return b({ok:!1,error:"API token was not found."},404);return b({ok:!0,token:st.revokeToken(T.id,l.actor?.id)})}if(L.pathname==="/api/onboarding"&&I.method==="GET"){let d=ze.listConnections(a.organization.id);return b({drafts:Pr.list(a.project.id),artifacts:ms.list(a.project.id),registries:Pi.list(a.organization.id),sourceConnections:d,repositories:d.flatMap((l)=>ze.listRepositories(l.id)),project:{id:a.project.id,slug:a.project.slug,name:a.project.name},environments:[...a.environments.values()].map((l)=>({id:l.id,slug:l.slug,name:l.name,kind:l.kind,region:l.region})),resources:a.store.listResources(a.project.id).filter((l)=>l.kind==="application").map((l)=>({id:l.id,slug:l.slug,name:l.name,environmentId:l.environmentId}))})}if(L.pathname==="/api/onboarding/detect"&&I.method==="POST"){let d=await ie(I);try{if(d.source?.kind==="git"){let M=ze.getConnection(String(d.source.connectionId??"")),F=ze.getRepository(String(d.source.repositoryId??""));if(!M||M.organizationId!==a.organization.id||!F||F.connectionId!==M.id)throw Error("Authorized Git repository was not found");let X=typeof d.source.deployKeyId==="string"?ze.getDeployKey(d.source.deployKeyId):void 0;if(X&&X.connectionId!==M.id)throw Error("Deploy key does not belong to this connection");let j=cp(Et(kd(),"ts-cloud-onboarding-git-"));try{let Z=await nl({remote:F.cloneUrl,destination:Et(j,"checkout"),ref:String(d.source.ref??F.defaultBranch),sparsePaths:Array.isArray(d.source.sparsePaths)?d.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:a.project.id,connectionId:M.id,repositoryId:F.id,repositoryFullName:F.fullName,defaultBranch:F.defaultBranch,monorepoRoot:String(d.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:d.source.submodules===!0,cloneDepth:1,deployKeyId:X?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:ze.getCredential(M.id),deployKey:X?{...X,privateKey:ze.getDeployPrivateKey(X.id)}:void 0,timeoutMs:120000});return b({ok:!0,commitSha:Z.commitSha,candidates:xt(Zn(Z.directory))})}finally{gs(j,{recursive:!0,force:!0})}}if(Array.isArray(d.files)){if(d.files.length>1e4)throw Error("Detection file-count limit exceeded");let M=d.files.map((F)=>({path:String(F.path??""),size:Number(F.size??0),content:typeof F.content==="string"?F.content.slice(0,262144):void 0}));return b({ok:!0,candidates:xt(M)})}let l=qT(t,String(d.root??".")),T=VT(t,l);if(T===".."||T.startsWith(`..${GT}`))throw Error("Detection root must stay inside the project");return b({ok:!0,candidates:xt(Zn(l))})}catch(l){return b({ok:!1,error:l instanceof Error?l.message:"Application detection failed."},422)}}if(L.pathname==="/api/onboarding/plan"&&I.method==="POST"){let d=await ie(I);try{return b({ok:!0,plan:de(d.draft,Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):[])})}catch(l){return b({ok:!1,error:l instanceof Error?l.message:"Application plan could not be generated."},422)}}if(L.pathname==="/api/onboarding/drafts"&&I.method==="POST"){let d=await ie(I),l=_e(ae);try{return b({ok:!0,draft:Pr.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:l.actor?.id})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Application draft could not be saved."},422)}}if(L.pathname==="/api/onboarding/drafts"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=Pr.get(String(d.id??""));if(!T||T.projectId!==a.project.id)return b({ok:!1,error:"Application draft was not found."},404);try{return b({ok:!0,draft:Pr.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:l.actor?.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Application draft could not be updated."},409)}}if(L.pathname==="/api/onboarding/artifacts"&&I.method==="POST"){let d=_e(ae);if(Number(I.headers.get("content-length")??0)>104857600)return b({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let T=new Uint8Array(await I.arrayBuffer());return b({ok:!0,artifact:ms.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 b({ok:!1,error:T instanceof Error?T.message:"Artifact could not be inspected."},422)}}if(L.pathname==="/api/onboarding/registries"&&I.method==="POST"){let d=await ie(I),l=_e(ae);try{return b({ok:!0,registry:Pi.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:l.actor?.id})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Registry connection could not be created."},422)}}if(L.pathname==="/api/onboarding/registries"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=Pi.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Registry connection was not found."},404);try{if(d.action==="test")return b({ok:!0,registry:await Pi.test(T.id,{image:typeof d.image==="string"?d.image:void 0})});if(d.action==="rotate")return b({ok:!0,registry:Pi.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:l.actor?.id})});return b({ok:!1,error:"Registry action must be test or rotate."},422)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Registry connection could not be updated."},422)}}if(L.pathname==="/api/onboarding/registries"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=Pi.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Registry connection was not found."},404);let M=Pr.list(a.project.id).filter((F)=>F.input.source.kind==="image"&&F.input.source.registryConnectionId===T.id||F.input.build.kind==="prebuilt_image"&&F.input.build.registryConnectionId===T.id);if(d.preview===!0)return b({ok:!0,preview:!0,affectedDrafts:M});return b({ok:!0,registry:Pi.disconnect(T.id,l.actor?.id),affectedDrafts:M})}if(L.pathname==="/api/onboarding/apply"&&I.method==="POST"){let d=await ie(I),l=_e(ae);try{let T=Wr({controlPlane:a.store,drafts:Pr,draftId:String(d.id??""),expectedVersion:Number(d.version),confirmEnvironment:String(d.confirmEnvironment??""),actorId:l.actor?.id});return b({ok:!0,resource:T.resource,operation:T.operation,plan:T.plan},202)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Application plan could not be applied."},422)}}if(L.pathname==="/api/sources"&&I.method==="GET"){let d=ze.listConnections(a.organization.id);return b({connections:d,bindings:ze.listBindings({projectId:a.project.id}),repositories:d.flatMap((l)=>ze.listRepositories(l.id)),deployKeys:d.flatMap((l)=>ze.listDeployKeys(l.id)),webhooks:d.flatMap((l)=>ze.listWebhooks(l.id)).map((l)=>({...l,deliveries:ze.listDeliveries(l.id,20)})),project:{id:a.project.id,slug:a.project.slug},environment:ue(a,String(ye)),resources:a.store.listResources(a.project.id,ue(a,String(ye)).environmentId).filter((l)=>l.kind==="application").map((l)=>({id:l.id,slug:l.slug,name:l.name}))})}if(L.pathname==="/api/sources/connections"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=String(d.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(T))return b({ok:!1,error:"A supported Git provider is required."},422);try{let M=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,F={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},X,j,Z;if(a.store.database.transaction(()=>{if(X=ze.createConnection({organizationId:a.organization.id,provider:T,name:String(d.name??T),host:String(d.host??F[T]??""),owner:typeof d.owner==="string"?d.owner:void 0,authKind:d.authKind,credential:M,grantedScopes:Array.isArray(d.grantedScopes)?d.grantedScopes.map(String):[],credentialExpiresAt:typeof d.credentialExpiresAt==="string"?d.credentialExpiresAt:void 0,createdByActorId:l.actor?.id}),typeof d.repositoryUrl==="string"&&typeof d.repositoryFullName==="string")j=ze.upsertRepository({connectionId:X.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")Z=ze.createDeployKey({connectionId:X.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:l.actor?.id})})(),d.test===!0)X=await il(ze,X.id,j?.id);return b({ok:!0,connection:X,repository:j,deployKey:Z},201)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source connection could not be created."},422)}}if(L.pathname==="/api/sources/connections"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=ze.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{if(d.action==="test")return b({ok:!0,connection:await il(ze,T.id,typeof d.repositoryId==="string"?d.repositoryId:void 0)});if(d.action==="rotate")return b({ok:!0,connection:ze.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:l.actor?.id})});return b({ok:!1,error:"Connection action must be test or rotate."},422)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source connection could not be updated."},422)}}if(L.pathname==="/api/sources/connections"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=ze.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);let M=ze.listBindings({connectionId:T.id,status:"active"});if(d.preview===!0)return b({ok:!0,preview:!0,affectedBindings:M});return b({ok:!0,...ze.disconnectConnection(T.id,l.actor?.id)})}if(L.pathname==="/api/sources/deploy-keys"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=ze.getConnection(String(d.connectionId??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b({ok:!0,deployKey:ze.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:l.actor?.id})},201)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Deploy key could not be stored."},422)}}if(L.pathname==="/api/sources/deploy-keys"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=ze.getDeployKey(String(d.id??"")),M=T?ze.getConnection(T.connectionId):void 0;if(!T||!M||M.organizationId!==a.organization.id)return b({ok:!1,error:"Deploy key was not found."},404);let F=ze.listBindings({connectionId:M.id}).filter((X)=>X.deployKeyId===T.id);if(d.preview===!0)return b({ok:!0,preview:!0,affectedBindings:F});return b({ok:!0,...ze.revokeDeployKey(T.id,l.actor?.id)})}if(L.pathname==="/api/sources/repositories/sync"&&I.method==="POST"){let d=await ie(I),l=ze.getConnection(String(d.connectionId??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b({ok:!0,repositories:await Gr(ze,String(d.connectionId??""),{search:typeof d.search==="string"?d.search:void 0})})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Repositories could not be synchronized."},422)}}if(L.pathname==="/api/sources/references"&&I.method==="GET"){let d=ze.getConnection(String(L.searchParams.get("connectionId")??""));if(!d||d.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b(await or(ze,{connectionId:String(L.searchParams.get("connectionId")??""),repository:String(L.searchParams.get("repository")??""),repositoryId:L.searchParams.get("repositoryId")??void 0,deployKeyId:L.searchParams.get("deployKeyId")??void 0,type:L.searchParams.get("type")==="tags"?"tags":"branches",cursor:L.searchParams.get("cursor")??void 0}))}catch(l){return b({ok:!1,error:l instanceof Error?l.message:"References could not be listed."},422)}}if(L.pathname==="/api/sources/bindings"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=ue(a,String(ye)),M=ze.getConnection(String(d.connectionId??""));if(!M||M.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b({ok:!0,binding:ze.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:l.actor?.id})},201)}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"Source binding could not be created."},422)}}if(L.pathname==="/api/sources/bindings"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=ze.getBinding(String(d.id??""));if(!T||T.projectId!==a.project.id)return b({ok:!1,error:"Source binding was not found."},404);try{return b({ok:!0,binding:ze.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:l.actor?.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source binding could not be updated."},409)}}if(L.pathname==="/api/sources/webhooks"&&I.method==="POST"){let d=await ie(I),l=ze.getConnection(String(d.connectionId??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{let T=ze.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}),M=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||nt,F=M?Nt(M,T.webhook):void 0,X=d.reconcile!==!1&&M?await sr(ze,T.webhook.id,M):T.webhook;return b({ok:!0,webhook:X,endpoint:F,endpointRevealOnce:!0},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Source webhook could not be created."},422)}}if(L.pathname==="/api/sources/webhooks"&&I.method==="PATCH"){let d=await ie(I),l=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||nt,T=ze.getWebhook(String(d.id??"")),M=T?ze.getConnection(T.connectionId):void 0;if(!T||!M||M.organizationId!==a.organization.id)return b({ok:!1,error:"Source webhook was not found."},404);if(!l)return b({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return b({ok:!0,webhook:await sr(ze,String(d.id??""),l)})}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"Source webhook could not be reconciled."},422)}}if(L.pathname==="/api/sources/webhooks"&&I.method==="DELETE"){let d=await ie(I),l=ze.getWebhook(String(d.id??"")),T=l?ze.getConnection(l.connectionId):void 0;if(!l||!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source webhook was not found."},404);try{return b({ok:!0,webhook:await Xi(ze,String(d.id??""))})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source webhook could not be removed."},422)}}if(L.pathname==="/api/security/posture"&&I.method==="GET"){let d=ue(a,String(ye)),l=rt.listFindings({...d,limit:500});return b({scope:d,summary:rt.summary(d.organizationId,d.projectId,d.environmentId),findings:l,scans:rt.listScanRuns({...d,limit:100}),policies:rt.listPolicies(d.organizationId).filter((T)=>!T.environmentId||T.environmentId===d.environmentId),waivers:l.flatMap((T)=>rt.listWaivers(T.id)),decisions:rt.listDecisions(d.environmentId,50),actors:a.store.listMemberships(a.organization.id).map((T)=>a.store.getActor(T.actorId)).filter(Boolean)})}if(L.pathname==="/api/security/export"&&I.method==="GET")return b(rt.exportPosture(a.organization.id));if(L.pathname==="/api/security/scan"&&I.method==="POST"){let d=ue(a,String(ye)),l=await new rs(rt).run(new Ra,{...d,artifactRoot:t}),T=rd(rt,d,Lt??{});return b({ok:!0,source:l,host:T,summary:rt.summary(d.organizationId,d.projectId,d.environmentId)})}if(L.pathname==="/api/security/review"&&I.method==="POST")try{let d=ue(a,String(ye));return b({ok:!0,...lr(rt,{scope:d,desiredConfigHash:a.project.desiredConfigHash})})}catch(d){return b({ok:!1,error:d instanceof Error?d.message:"Security change review failed."},409)}if(L.pathname==="/api/security/policies"&&I.method==="POST"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{let T=rt.createPolicy({organizationId:a.organization.id,environmentId:d.environmentId===null?void 0:String(d.environmentId??ue(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((M)=>({minimumSeverity:String(M.minimumSeverity),action:String(M.action),scannerId:M.scannerId?String(M.scannerId):void 0})):[],actorId:l.actor.id});return b({ok:!0,policy:T},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Security policy could not be created."},422)}}if(L.pathname==="/api/security/policies"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=rt.getPolicy(String(d.id??""));if(!l.actor||!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Security policy was not found."},404);try{return b({ok:!0,policy:rt.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((M)=>({minimumSeverity:String(M.minimumSeverity),action:String(M.action),scannerId:M.scannerId?String(M.scannerId):void 0})):void 0,enabled:typeof d.enabled==="boolean"?d.enabled:void 0,actorId:l.actor.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Security policy could not be updated."},409)}}if(L.pathname==="/api/security/waivers"&&I.method==="POST"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{return b({ok:!0,waiver:rt.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:l.actor.id})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be created."},422)}}if(L.pathname==="/api/security/waivers"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{return b({ok:!0,waiver:rt.revokeWaiver(String(d.id??""),l.actor.id)})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be revoked."},404)}}if(L.pathname==="/api/security/findings"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=rt.getFinding(String(d.id??""));if(!l.actor||!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Security finding was not found."},404);try{let M=d.action==="acknowledge"?rt.acknowledgeFinding(T.id,l.actor.id):rt.assignFinding(T.id,typeof d.ownerActorId==="string"&&d.ownerActorId?d.ownerActorId:void 0,l.actor.id);return b({ok:!0,finding:M})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Security finding could not be updated."},422)}}if(L.pathname==="/api/security/comments"&&I.method==="POST"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{return b({ok:!0,comment:rt.addComment({findingId:String(d.findingId??""),actorId:l.actor.id,body:String(d.body??""),referenceUrl:typeof d.referenceUrl==="string"?d.referenceUrl:void 0})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Comment could not be saved."},422)}}if(L.pathname==="/api/auth/sessions"&&I.method==="GET"){let d=Ft.resolveSession(I);return b({currentSessionId:d?.id,sessions:d?we.listSessions(d.identityId,{includeInactive:!0}):[]})}if(L.pathname==="/api/auth/sessions"&&I.method==="DELETE"){let d=await ie(I),l=Ft.resolveSession(I);if(!l)return b({ok:!1,error:"Sign in again to manage sessions."},401);let T=String(d.id??""),M=we.revokeSession(l.identityId,T),F=T===l.id&&M?{"set-cookie":Sd({secure:ho})}:void 0;return b({ok:M,signedOut:T===l.id&&M},M?200:404,F)}if(L.pathname==="/api/auth/sessions/revoke-others"&&I.method==="POST"){let d=Ft.resolveSession(I);if(!d)return b({ok:!1,error:"Sign in again to manage sessions."},401);return b({ok:!0,revoked:we.revokeOtherSessions(d.identityId,d.id)})}if(L.pathname==="/api/auth/password/change"&&I.method==="POST"){let d=await ie(I),l=String(d.currentPassword??""),T=String(d.password??""),M=_e(ae),F=M.actor?we.getIdentityByActor(M.actor.id):void 0;if(!F||!Ii(l,F.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);if(T.length<12)return b({ok:!1,error:"New password must be at least 12 characters."},422);if(Ii(T,F.passwordHash))return b({ok:!1,error:"Choose a different password."},409);let X=$o(T),j=we.updatePassword(F.id,X);Id(t,j.username,X);let Z=qa(j.id,I,Ke.requestIP(I)?.address??"unknown");return a.store.appendEvent({organizationId:a.organization.id,actorId:j.actorId,type:"auth.password.changed"}),b({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":ra(Z.token,{secure:ho,maxAgeMs:bo})})}if(L.pathname==="/api/auth/mfa/enroll"&&I.method==="POST"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M)return b({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Ii(String(d.password??""),M.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);try{let F=we.beginTotpEnrollment(M.id,{issuer:a.organization.name});return a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.mfa.enrollment.started"}),b({factor:F.factor,secret:F.secret,uri:F.uri})}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"MFA enrollment failed."},409)}}if(L.pathname==="/api/auth/mfa/verify"&&I.method==="POST"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M)return b({ok:!1,error:"Sign in again before enabling MFA."},401);try{let F=we.verifyTotpEnrollment(M.id,String(d.code??""));return we.markSessionStepUp(l.id,!0),a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:F.recoveryCodes.length}}),b(F)}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"MFA enrollment failed."},422)}}if(L.pathname==="/api/auth/mfa"&&I.method==="DELETE"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M||!Ii(String(d.password??""),M.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);let F=we.verifyMfaCode(M.id,String(d.code??""));if(!F.valid||!F.method)return b({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return we.disableMfa(M.id),we.revokeOtherSessions(M.id,l.id),we.markSessionStepUp(l.id),a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.mfa.disabled",payload:{method:F.method}}),b({ok:!0})}if(L.pathname==="/api/auth/step-up"&&I.method==="POST"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M||!Ii(String(d.password??""),M.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);let F=we.getMfaFactor(M.id);if(F?.state==="active"){if(!we.verifyMfaCode(M.id,String(d.code??"")).valid)return b({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let X=we.markSessionStepUp(l.id,F?.state==="active");return a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.step_up.succeeded",payload:{mfa:F?.state==="active"}}),b({ok:!0,recentAuthAt:X.recentAuthAt})}if(L.pathname==="/api/terminal"){if(!ge)return b({ok:!1,error:"The web terminal is disabled."},403);if(Ke.upgrade(I))return;return Rd("WebSocket upgrade failed",400)}if(L.pathname==="/api/health"){let d=a.store.health();return b({ok:!0,cwd:t,environment:ye,environments:f,uiRoot:await ki(ae,ye),liveData:ke.size>0,terminal:ge,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:d.schemaVersion,supportedSchemaVersion:d.supportedSchemaVersion,integrity:d.integrity,pendingRetryableOperations:d.pendingRetryableOperations}})}if(L.pathname==="/api/control-plane/operations"){let d=L.searchParams.get("state"),l=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0;return b({operations:a.store.listOperations({projectId:a.project.id,state:l,kind:L.searchParams.get("kind")??void 0,limit:Number(L.searchParams.get("limit"))||100})})}if(L.pathname==="/api/queue"&&I.method==="GET"){let d=L.searchParams.get("state"),l=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0,T=At.list({projectId:a.project.id,state:l,limit:Number(L.searchParams.get("limit"))||250}).filter((M)=>fs(ae,M.operation.id,"deployments:read")).map((M)=>{let F=M.operation.resourceId?a.store.getResource(M.operation.resourceId):void 0,X=M.operation.environmentId?a.store.listEnvironments(a.project.id).find((me)=>me.id===M.operation.environmentId):void 0,j=M.operation.actorId?a.store.getActor(M.operation.actorId):void 0,Z=M.operation.input;return{...M,target:F?{id:F.id,name:F.name,slug:F.slug,kind:F.kind}:X?{id:X.id,name:X.name,slug:X.slug,kind:"environment"}:{id:a.project.id,name:a.project.name,slug:a.project.slug,kind:"project"},actor:j?{id:j.id,name:j.displayName,kind:j.kind}:void 0,commit:Z.revision??Z.source?.commitSha??null}});return b({operations:T,concurrency:At.limits})}if(L.pathname==="/api/queue/logs"&&I.method==="GET"){let d=String(L.searchParams.get("id")??"");if(!fs(ae,d,"deployments:read"))return b({ok:!1,error:"Operation was not found in this scope."},404);let l=At.logs(d,{after:Number(L.searchParams.get("after"))||0,limit:Number(L.searchParams.get("limit"))||500});return b({entries:l,cursor:l.at(-1)?.sequence??(Number(L.searchParams.get("after"))||0),operation:a.store.getOperation(d)})}if(L.pathname==="/api/queue/stream"&&I.method==="GET"){let d=String(L.searchParams.get("id")??"");if(!fs(ae,d,"deployments:read"))return b({ok:!1,error:"Operation was not found in this scope."},404);let l=I.headers.get("last-event-id")?.trim(),T=Number(l||L.searchParams.get("after")||0),M=new TextEncoder,F,X=!1,j=new ReadableStream({start(Z){let me=()=>{if(X)return;let le=Ft.resolveUser(I);if(!le||!fs(le,d,"deployments:read")){if(X=!0,F)clearInterval(F);Z.close();return}let Ge=At.logs(d,{after:T,limit:500});for(let Ne of Ge)T=Ne.sequence,Z.enqueue(M.encode(`id: ${Ne.sequence}
|
|
486
|
+
This link expires in one hour and can be used once.`});a.store.appendEvent({organizationId:a.organization.id,actorId:j.actorId,type:"auth.password_reset.requested",payload:{delivered:Z}})}return b({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(F.pathname==="/api/auth/password-reset/complete"&&I.method==="POST"){let d=await ie(I),l=String(d.token??"").trim(),T=String(d.password??"");if(!l||T.length<12)return b({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let M=we.consumeActionToken(l,"password_reset"),j=$o(T),X=we.updatePassword(M.identityId,j);return Id(t,X.username,j),a.store.appendEvent({organizationId:a.organization.id,actorId:X.actorId,type:"auth.password_reset.completed"}),b({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":Sd({secure:ho})})}catch(M){let j=M instanceof Error?M.message:"Password reset failed.";return b({ok:!1,error:j.replace("Action token","Reset link")},j.includes("consumed")||j.includes("expired")?409:404)}}if(F.pathname==="/api/login"&&I.method==="POST"){let d=await ie(I),l=String(d.username??"").trim(),T=String(d.password??""),M=Ke.requestIP(I)?.address??"unknown",j=za.check(l,M);if(!j.allowed)return b({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((j.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(j.retryAfterSeconds??60)});let X=Nn(nn(t),l),U=we.getIdentityByUsername(l),Z=U?.passwordHash??X?.passwordHash??tA;if(!(Ii(T,Z)&&!!X&&!!U&&!U.disabledAt))return za.recordFailure(l,M),b({ok:!1,error:"Incorrect username or password."},401);if(Ey(we,a,U))return b({ok:!1,error:"Single sign-on is required for this account."},403);za.recordSuccess(l,M);let le=U,qe=le.requiresPasswordUpgrade||oy(le.passwordHash);if(qe){let Ne=$o(T);le=we.rehashPassword(le.id,Ne),Id(t,le.username,Ne)}if(we.recordLogin(le.id),we.getMfaFactor(le.id)?.state==="active"){let Ne=we.createMfaChallenge(le.id,"login");return a.store.appendEvent({organizationId:a.organization.id,actorId:le.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),b({ok:!0,mfaRequired:!0,challengeToken:Ne.token,passwordUpgraded:qe})}let be=qa(le.id,I,M);return a.store.appendEvent({organizationId:a.organization.id,actorId:le.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),b({ok:!0,user:ia(X),passwordUpgraded:qe},200,{"set-cookie":ra(be.token,{secure:ho,maxAgeMs:bo})})}if(F.pathname==="/api/auth/mfa/complete"&&I.method==="POST"){let d=await ie(I),l=String(d.challengeToken??"").trim(),T=String(d.code??"").trim(),M=Ke.requestIP(I)?.address??"unknown",X=we.inspectMfaChallengeToken(l,"login")?.identityId??"unknown-mfa",U=Va.check(X,M);if(!U.allowed)return b({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(U.retryAfterSeconds??60)});try{let Z=we.completeMfaChallenge(l,T,"login");Va.recordSuccess(X,M);let me=new Date().toISOString(),le=we.createSession({identityId:Z.identity.id,userAgent:Ap(I),networkHint:Md(M),mfaAt:me,recentAuthAt:me});return a.store.appendEvent({organizationId:a.organization.id,actorId:Z.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:Z.method}}),b({ok:!0},200,{"set-cookie":ra(le.token,{secure:ho,maxAgeMs:bo})})}catch{return Va.recordFailure(X,M),b({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(F.pathname==="/api/logout"&&I.method==="POST"){let d=Ft.resolveSession(I);if(d)we.revokeSession(d.identityId,d.id);let l=Sd({secure:ho});if(I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":l}});return b({ok:!0},200,{"set-cookie":l})}if(F.pathname==="/login"){let d=we.listOidcProviders(a.organization.id).map((l)=>({slug:l.slug,name:l.name}));return new Response(Ty(D?.mode==="serverless",d),{headers:{"content-type":"text/html; charset=utf-8"}})}if(F.pathname==="/forgot-password"||F.pathname==="/reset-password")return new Response(Ay(F.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(F.pathname==="/accept-invitation")return hb(Ri,F.pathname);let ae=Ft.resolveUser(I);if(!ae){if(!F.pathname.startsWith("/api/")&&I.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return b({ok:!1,error:"Sign in to continue."},401)}let Tn=co(ae,ye);if(F.pathname==="/api/me"){let d=a.store.getActorByExternalId("user",`dashboard:${ae.username.toLowerCase()}`),l=d?a.store.getMembershipForActor(a.organization.id,d.id):void 0,T=a.store.resolveAuthorizationTarget(a.organization.id,l?.scope??{type:"project",id:a.project.id})??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id});return b({ok:!0,user:ia(ae),authEnabled:Re,organization:a.organization,membership:l,capabilities:vn({membership:l,grants:l?a.store.listGrants(l.id):[],target:T})})}if(F.pathname.startsWith("/api/")){let d=await wy(I,F.pathname),l=Ft.check(I,F.pathname,ae,d);if(!l.ok)return b({ok:!1,error:l.error},l.status??403);if(Re&&lA.has(`${I.method.toUpperCase()} ${F.pathname}`)){let T=Ft.resolveSession(I);if(!T||!we.isRecentlyAuthenticated(T))return b({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(F.pathname==="/api/auth/security"&&I.method==="GET"){let d=_e(ae),l=d.actor?we.getIdentityByActor(d.actor.id):void 0,T=Ft.resolveSession(I);return b({identity:l?{username:l.username,email:l.email,emailVerifiedAt:l.emailVerifiedAt,requiresPasswordUpgrade:l.requiresPasswordUpgrade,lastLoginAt:l.lastLoginAt}:void 0,currentSessionId:T?.id,sessions:l?we.listSessions(l.id,{includeInactive:!0}):[],mfa:l?{factor:we.getMfaFactor(l.id),recoveryCodesRemaining:we.remainingRecoveryCodes(l.id)}:void 0})}if(F.pathname==="/api/auth/oidc/providers"&&I.method==="GET")return b({providers:we.listOidcProviders(a.organization.id,{includeDisabled:!0}),callbackOrigin:nt,callbackPattern:nt?`${nt}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(F.pathname==="/api/auth/oidc/providers"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=l.actor?we.getIdentityByActor(l.actor.id):void 0,M=d.enforceSso===!0;if(M&&(!T?.emailVerifiedAt||we.remainingRecoveryCodes(T.id)<1))return b({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let j=Td(d.defaultRole),X=we.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:j&&j!=="owner"?j:void 0,enabled:d.enabled!==!1,enforceSso:M});return a.store.appendEvent({organizationId:a.organization.id,actorId:l.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:X.id,issuer:X.issuer,enabled:X.enabled,enforceSso:X.enforceSso}}),b({ok:!0,provider:X})}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"OIDC provider could not be saved."},422)}}if(F.pathname==="/api/auth/oidc/providers"&&I.method==="PATCH"){let d=await ie(I),l=we.getOidcProvider(String(d.id??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"OIDC provider was not found."},404);let T=_e(ae),M=we.setOidcProviderEnabled(l.id,d.enabled===!0);return a.store.appendEvent({organizationId:a.organization.id,actorId:T.actor?.id,type:M.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:l.id}}),b({ok:!0,provider:M})}if(F.pathname==="/api/automation"&&I.method==="GET"){let d=st.listServiceAccounts(a.organization.id,{includeDisabled:!0}).map((l)=>{let T=a.store.getMembershipForActor(a.organization.id,l.actorId),M=l.createdByActorId?a.store.getActor(l.createdByActorId):void 0,j=st.listTokens(l.id,{includeInactive:!0}).map((X)=>({...X,createdBy:X.createdByActorId?a.store.getActor(X.createdByActorId):void 0}));return{account:l,createdBy:M,membership:T,tokens:j}});return b({accounts:d,apiBaseUrl:`${F.origin}/api/v1`,openApiUrl:`${F.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(F.pathname==="/api/automation/service-accounts"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=Td(d.roleTemplate),M=Ba(d);if(!l.actor||!T||T==="owner"||!M)return b({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let j=st.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:M,createdByActorId:l.actor.id});return b({ok:!0,...j},201)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"Service account could not be created."},422)}}if(F.pathname==="/api/automation/service-accounts"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=st.getServiceAccount(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Service account was not found."},404);return b({ok:!0,account:st.disableServiceAccount(T.id,l.actor?.id)})}if(F.pathname==="/api/automation/tokens"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=st.getServiceAccount(String(d.serviceAccountId??"")),M=Ba(d);if(!l.actor||!T||T.organizationId!==a.organization.id||!M||!Array.isArray(d.capabilities))return b({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let j=st.createToken({serviceAccountId:T.id,name:String(d.name??"API token"),capabilities:d.capabilities.map(String),scope:M,expiresAt:typeof d.expiresAt==="string"?d.expiresAt:void 0,createdByActorId:l.actor.id});return b({ok:!0,token:j.token,secret:j.secret,revealOnce:!0},201)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"API token could not be created."},422)}}if(F.pathname==="/api/automation/tokens/rotate"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=st.getToken(String(d.id??"")),M=T?st.getServiceAccount(T.serviceAccountId):void 0;if(!l.actor||!T||M?.organizationId!==a.organization.id)return b({ok:!1,error:"API token was not found."},404);try{let j=st.rotateToken(T.id,l.actor.id);return b({ok:!0,token:j.token,secret:j.secret,revealOnce:!0,overlap:!0},201)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"API token could not be rotated."},409)}}if(F.pathname==="/api/automation/tokens"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=st.getToken(String(d.id??"")),M=T?st.getServiceAccount(T.serviceAccountId):void 0;if(!T||M?.organizationId!==a.organization.id)return b({ok:!1,error:"API token was not found."},404);return b({ok:!0,token:st.revokeToken(T.id,l.actor?.id)})}if(F.pathname==="/api/onboarding"&&I.method==="GET"){let d=ze.listConnections(a.organization.id);return b({drafts:Pr.list(a.project.id),artifacts:ms.list(a.project.id),registries:Pi.list(a.organization.id),sourceConnections:d,repositories:d.flatMap((l)=>ze.listRepositories(l.id)),project:{id:a.project.id,slug:a.project.slug,name:a.project.name},environments:[...a.environments.values()].map((l)=>({id:l.id,slug:l.slug,name:l.name,kind:l.kind,region:l.region})),resources:a.store.listResources(a.project.id).filter((l)=>l.kind==="application").map((l)=>({id:l.id,slug:l.slug,name:l.name,environmentId:l.environmentId}))})}if(F.pathname==="/api/onboarding/detect"&&I.method==="POST"){let d=await ie(I);try{if(d.source?.kind==="git"){let M=ze.getConnection(String(d.source.connectionId??"")),j=ze.getRepository(String(d.source.repositoryId??""));if(!M||M.organizationId!==a.organization.id||!j||j.connectionId!==M.id)throw Error("Authorized Git repository was not found");let X=typeof d.source.deployKeyId==="string"?ze.getDeployKey(d.source.deployKeyId):void 0;if(X&&X.connectionId!==M.id)throw Error("Deploy key does not belong to this connection");let U=cp(Et(kd(),"ts-cloud-onboarding-git-"));try{let Z=await nl({remote:j.cloneUrl,destination:Et(U,"checkout"),ref:String(d.source.ref??j.defaultBranch),sparsePaths:Array.isArray(d.source.sparsePaths)?d.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:a.project.id,connectionId:M.id,repositoryId:j.id,repositoryFullName:j.fullName,defaultBranch:j.defaultBranch,monorepoRoot:String(d.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:d.source.submodules===!0,cloneDepth:1,deployKeyId:X?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:ze.getCredential(M.id),deployKey:X?{...X,privateKey:ze.getDeployPrivateKey(X.id)}:void 0,timeoutMs:120000});return b({ok:!0,commitSha:Z.commitSha,candidates:xt(Zn(Z.directory))})}finally{gs(U,{recursive:!0,force:!0})}}if(Array.isArray(d.files)){if(d.files.length>1e4)throw Error("Detection file-count limit exceeded");let M=d.files.map((j)=>({path:String(j.path??""),size:Number(j.size??0),content:typeof j.content==="string"?j.content.slice(0,262144):void 0}));return b({ok:!0,candidates:xt(M)})}let l=qT(t,String(d.root??".")),T=VT(t,l);if(T===".."||T.startsWith(`..${GT}`))throw Error("Detection root must stay inside the project");return b({ok:!0,candidates:xt(Zn(l))})}catch(l){return b({ok:!1,error:l instanceof Error?l.message:"Application detection failed."},422)}}if(F.pathname==="/api/onboarding/plan"&&I.method==="POST"){let d=await ie(I);try{return b({ok:!0,plan:de(d.draft,Array.isArray(d.suppliedSecretNames)?d.suppliedSecretNames.map(String):[])})}catch(l){return b({ok:!1,error:l instanceof Error?l.message:"Application plan could not be generated."},422)}}if(F.pathname==="/api/onboarding/drafts"&&I.method==="POST"){let d=await ie(I),l=_e(ae);try{return b({ok:!0,draft:Pr.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:l.actor?.id})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Application draft could not be saved."},422)}}if(F.pathname==="/api/onboarding/drafts"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=Pr.get(String(d.id??""));if(!T||T.projectId!==a.project.id)return b({ok:!1,error:"Application draft was not found."},404);try{return b({ok:!0,draft:Pr.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:l.actor?.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Application draft could not be updated."},409)}}if(F.pathname==="/api/onboarding/artifacts"&&I.method==="POST"){let d=_e(ae);if(Number(I.headers.get("content-length")??0)>104857600)return b({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let T=new Uint8Array(await I.arrayBuffer());return b({ok:!0,artifact:ms.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 b({ok:!1,error:T instanceof Error?T.message:"Artifact could not be inspected."},422)}}if(F.pathname==="/api/onboarding/registries"&&I.method==="POST"){let d=await ie(I),l=_e(ae);try{return b({ok:!0,registry:Pi.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:l.actor?.id})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Registry connection could not be created."},422)}}if(F.pathname==="/api/onboarding/registries"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=Pi.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Registry connection was not found."},404);try{if(d.action==="test")return b({ok:!0,registry:await Pi.test(T.id,{image:typeof d.image==="string"?d.image:void 0})});if(d.action==="rotate")return b({ok:!0,registry:Pi.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:l.actor?.id})});return b({ok:!1,error:"Registry action must be test or rotate."},422)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Registry connection could not be updated."},422)}}if(F.pathname==="/api/onboarding/registries"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=Pi.get(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Registry connection was not found."},404);let M=Pr.list(a.project.id).filter((j)=>j.input.source.kind==="image"&&j.input.source.registryConnectionId===T.id||j.input.build.kind==="prebuilt_image"&&j.input.build.registryConnectionId===T.id);if(d.preview===!0)return b({ok:!0,preview:!0,affectedDrafts:M});return b({ok:!0,registry:Pi.disconnect(T.id,l.actor?.id),affectedDrafts:M})}if(F.pathname==="/api/onboarding/apply"&&I.method==="POST"){let d=await ie(I),l=_e(ae);try{let T=Wr({controlPlane:a.store,drafts:Pr,draftId:String(d.id??""),expectedVersion:Number(d.version),confirmEnvironment:String(d.confirmEnvironment??""),actorId:l.actor?.id});return b({ok:!0,resource:T.resource,operation:T.operation,plan:T.plan},202)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Application plan could not be applied."},422)}}if(F.pathname==="/api/sources"&&I.method==="GET"){let d=ze.listConnections(a.organization.id);return b({connections:d,bindings:ze.listBindings({projectId:a.project.id}),repositories:d.flatMap((l)=>ze.listRepositories(l.id)),deployKeys:d.flatMap((l)=>ze.listDeployKeys(l.id)),webhooks:d.flatMap((l)=>ze.listWebhooks(l.id)).map((l)=>({...l,deliveries:ze.listDeliveries(l.id,20)})),project:{id:a.project.id,slug:a.project.slug},environment:ue(a,String(ye)),resources:a.store.listResources(a.project.id,ue(a,String(ye)).environmentId).filter((l)=>l.kind==="application").map((l)=>({id:l.id,slug:l.slug,name:l.name}))})}if(F.pathname==="/api/sources/connections"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=String(d.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(T))return b({ok:!1,error:"A supported Git provider is required."},422);try{let M=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,j={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},X,U,Z;if(a.store.database.transaction(()=>{if(X=ze.createConnection({organizationId:a.organization.id,provider:T,name:String(d.name??T),host:String(d.host??j[T]??""),owner:typeof d.owner==="string"?d.owner:void 0,authKind:d.authKind,credential:M,grantedScopes:Array.isArray(d.grantedScopes)?d.grantedScopes.map(String):[],credentialExpiresAt:typeof d.credentialExpiresAt==="string"?d.credentialExpiresAt:void 0,createdByActorId:l.actor?.id}),typeof d.repositoryUrl==="string"&&typeof d.repositoryFullName==="string")U=ze.upsertRepository({connectionId:X.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")Z=ze.createDeployKey({connectionId:X.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:l.actor?.id})})(),d.test===!0)X=await il(ze,X.id,U?.id);return b({ok:!0,connection:X,repository:U,deployKey:Z},201)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source connection could not be created."},422)}}if(F.pathname==="/api/sources/connections"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=ze.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{if(d.action==="test")return b({ok:!0,connection:await il(ze,T.id,typeof d.repositoryId==="string"?d.repositoryId:void 0)});if(d.action==="rotate")return b({ok:!0,connection:ze.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:l.actor?.id})});return b({ok:!1,error:"Connection action must be test or rotate."},422)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source connection could not be updated."},422)}}if(F.pathname==="/api/sources/connections"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=ze.getConnection(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);let M=ze.listBindings({connectionId:T.id,status:"active"});if(d.preview===!0)return b({ok:!0,preview:!0,affectedBindings:M});return b({ok:!0,...ze.disconnectConnection(T.id,l.actor?.id)})}if(F.pathname==="/api/sources/deploy-keys"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=ze.getConnection(String(d.connectionId??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b({ok:!0,deployKey:ze.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:l.actor?.id})},201)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Deploy key could not be stored."},422)}}if(F.pathname==="/api/sources/deploy-keys"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=ze.getDeployKey(String(d.id??"")),M=T?ze.getConnection(T.connectionId):void 0;if(!T||!M||M.organizationId!==a.organization.id)return b({ok:!1,error:"Deploy key was not found."},404);let j=ze.listBindings({connectionId:M.id}).filter((X)=>X.deployKeyId===T.id);if(d.preview===!0)return b({ok:!0,preview:!0,affectedBindings:j});return b({ok:!0,...ze.revokeDeployKey(T.id,l.actor?.id)})}if(F.pathname==="/api/sources/repositories/sync"&&I.method==="POST"){let d=await ie(I),l=ze.getConnection(String(d.connectionId??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b({ok:!0,repositories:await qr(ze,String(d.connectionId??""),{search:typeof d.search==="string"?d.search:void 0})})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Repositories could not be synchronized."},422)}}if(F.pathname==="/api/sources/references"&&I.method==="GET"){let d=ze.getConnection(String(F.searchParams.get("connectionId")??""));if(!d||d.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b(await sr(ze,{connectionId:String(F.searchParams.get("connectionId")??""),repository:String(F.searchParams.get("repository")??""),repositoryId:F.searchParams.get("repositoryId")??void 0,deployKeyId:F.searchParams.get("deployKeyId")??void 0,type:F.searchParams.get("type")==="tags"?"tags":"branches",cursor:F.searchParams.get("cursor")??void 0}))}catch(l){return b({ok:!1,error:l instanceof Error?l.message:"References could not be listed."},422)}}if(F.pathname==="/api/sources/bindings"&&I.method==="POST"){let d=await ie(I),l=_e(ae),T=ue(a,String(ye)),M=ze.getConnection(String(d.connectionId??""));if(!M||M.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{return b({ok:!0,binding:ze.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:l.actor?.id})},201)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"Source binding could not be created."},422)}}if(F.pathname==="/api/sources/bindings"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=ze.getBinding(String(d.id??""));if(!T||T.projectId!==a.project.id)return b({ok:!1,error:"Source binding was not found."},404);try{return b({ok:!0,binding:ze.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:l.actor?.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source binding could not be updated."},409)}}if(F.pathname==="/api/sources/webhooks"&&I.method==="POST"){let d=await ie(I),l=ze.getConnection(String(d.connectionId??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Source connection was not found."},404);try{let T=ze.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}),M=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||nt,j=M?Nt(M,T.webhook):void 0,X=d.reconcile!==!1&&M?await ar(ze,T.webhook.id,M):T.webhook;return b({ok:!0,webhook:X,endpoint:j,endpointRevealOnce:!0},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Source webhook could not be created."},422)}}if(F.pathname==="/api/sources/webhooks"&&I.method==="PATCH"){let d=await ie(I),l=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||nt,T=ze.getWebhook(String(d.id??"")),M=T?ze.getConnection(T.connectionId):void 0;if(!T||!M||M.organizationId!==a.organization.id)return b({ok:!1,error:"Source webhook was not found."},404);if(!l)return b({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return b({ok:!0,webhook:await ar(ze,String(d.id??""),l)})}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"Source webhook could not be reconciled."},422)}}if(F.pathname==="/api/sources/webhooks"&&I.method==="DELETE"){let d=await ie(I),l=ze.getWebhook(String(d.id??"")),T=l?ze.getConnection(l.connectionId):void 0;if(!l||!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Source webhook was not found."},404);try{return b({ok:!0,webhook:await Xi(ze,String(d.id??""))})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Source webhook could not be removed."},422)}}if(F.pathname==="/api/security/posture"&&I.method==="GET"){let d=ue(a,String(ye)),l=rt.listFindings({...d,limit:500});return b({scope:d,summary:rt.summary(d.organizationId,d.projectId,d.environmentId),findings:l,scans:rt.listScanRuns({...d,limit:100}),policies:rt.listPolicies(d.organizationId).filter((T)=>!T.environmentId||T.environmentId===d.environmentId),waivers:l.flatMap((T)=>rt.listWaivers(T.id)),decisions:rt.listDecisions(d.environmentId,50),actors:a.store.listMemberships(a.organization.id).map((T)=>a.store.getActor(T.actorId)).filter(Boolean)})}if(F.pathname==="/api/security/export"&&I.method==="GET")return b(rt.exportPosture(a.organization.id));if(F.pathname==="/api/security/scan"&&I.method==="POST"){let d=ue(a,String(ye)),l=await new rs(rt).run(new Ra,{...d,artifactRoot:t}),T=rd(rt,d,Lt??{});return b({ok:!0,source:l,host:T,summary:rt.summary(d.organizationId,d.projectId,d.environmentId)})}if(F.pathname==="/api/security/review"&&I.method==="POST")try{let d=ue(a,String(ye));return b({ok:!0,...dr(rt,{scope:d,desiredConfigHash:a.project.desiredConfigHash})})}catch(d){return b({ok:!1,error:d instanceof Error?d.message:"Security change review failed."},409)}if(F.pathname==="/api/security/policies"&&I.method==="POST"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{let T=rt.createPolicy({organizationId:a.organization.id,environmentId:d.environmentId===null?void 0:String(d.environmentId??ue(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((M)=>({minimumSeverity:String(M.minimumSeverity),action:String(M.action),scannerId:M.scannerId?String(M.scannerId):void 0})):[],actorId:l.actor.id});return b({ok:!0,policy:T},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Security policy could not be created."},422)}}if(F.pathname==="/api/security/policies"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=rt.getPolicy(String(d.id??""));if(!l.actor||!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Security policy was not found."},404);try{return b({ok:!0,policy:rt.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((M)=>({minimumSeverity:String(M.minimumSeverity),action:String(M.action),scannerId:M.scannerId?String(M.scannerId):void 0})):void 0,enabled:typeof d.enabled==="boolean"?d.enabled:void 0,actorId:l.actor.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Security policy could not be updated."},409)}}if(F.pathname==="/api/security/waivers"&&I.method==="POST"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{return b({ok:!0,waiver:rt.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:l.actor.id})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be created."},422)}}if(F.pathname==="/api/security/waivers"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{return b({ok:!0,waiver:rt.revokeWaiver(String(d.id??""),l.actor.id)})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Security waiver could not be revoked."},404)}}if(F.pathname==="/api/security/findings"&&I.method==="PATCH"){let d=await ie(I),l=_e(ae),T=rt.getFinding(String(d.id??""));if(!l.actor||!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Security finding was not found."},404);try{let M=d.action==="acknowledge"?rt.acknowledgeFinding(T.id,l.actor.id):rt.assignFinding(T.id,typeof d.ownerActorId==="string"&&d.ownerActorId?d.ownerActorId:void 0,l.actor.id);return b({ok:!0,finding:M})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Security finding could not be updated."},422)}}if(F.pathname==="/api/security/comments"&&I.method==="POST"){let d=await ie(I),l=_e(ae);if(!l.actor)return b({ok:!1,error:"An organization actor is required."},403);try{return b({ok:!0,comment:rt.addComment({findingId:String(d.findingId??""),actorId:l.actor.id,body:String(d.body??""),referenceUrl:typeof d.referenceUrl==="string"?d.referenceUrl:void 0})},201)}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Comment could not be saved."},422)}}if(F.pathname==="/api/auth/sessions"&&I.method==="GET"){let d=Ft.resolveSession(I);return b({currentSessionId:d?.id,sessions:d?we.listSessions(d.identityId,{includeInactive:!0}):[]})}if(F.pathname==="/api/auth/sessions"&&I.method==="DELETE"){let d=await ie(I),l=Ft.resolveSession(I);if(!l)return b({ok:!1,error:"Sign in again to manage sessions."},401);let T=String(d.id??""),M=we.revokeSession(l.identityId,T),j=T===l.id&&M?{"set-cookie":Sd({secure:ho})}:void 0;return b({ok:M,signedOut:T===l.id&&M},M?200:404,j)}if(F.pathname==="/api/auth/sessions/revoke-others"&&I.method==="POST"){let d=Ft.resolveSession(I);if(!d)return b({ok:!1,error:"Sign in again to manage sessions."},401);return b({ok:!0,revoked:we.revokeOtherSessions(d.identityId,d.id)})}if(F.pathname==="/api/auth/password/change"&&I.method==="POST"){let d=await ie(I),l=String(d.currentPassword??""),T=String(d.password??""),M=_e(ae),j=M.actor?we.getIdentityByActor(M.actor.id):void 0;if(!j||!Ii(l,j.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);if(T.length<12)return b({ok:!1,error:"New password must be at least 12 characters."},422);if(Ii(T,j.passwordHash))return b({ok:!1,error:"Choose a different password."},409);let X=$o(T),U=we.updatePassword(j.id,X);Id(t,U.username,X);let Z=qa(U.id,I,Ke.requestIP(I)?.address??"unknown");return a.store.appendEvent({organizationId:a.organization.id,actorId:U.actorId,type:"auth.password.changed"}),b({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":ra(Z.token,{secure:ho,maxAgeMs:bo})})}if(F.pathname==="/api/auth/mfa/enroll"&&I.method==="POST"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M)return b({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Ii(String(d.password??""),M.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);try{let j=we.beginTotpEnrollment(M.id,{issuer:a.organization.name});return a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.mfa.enrollment.started"}),b({factor:j.factor,secret:j.secret,uri:j.uri})}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"MFA enrollment failed."},409)}}if(F.pathname==="/api/auth/mfa/verify"&&I.method==="POST"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M)return b({ok:!1,error:"Sign in again before enabling MFA."},401);try{let j=we.verifyTotpEnrollment(M.id,String(d.code??""));return we.markSessionStepUp(l.id,!0),a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:j.recoveryCodes.length}}),b(j)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"MFA enrollment failed."},422)}}if(F.pathname==="/api/auth/mfa"&&I.method==="DELETE"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M||!Ii(String(d.password??""),M.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);let j=we.verifyMfaCode(M.id,String(d.code??""));if(!j.valid||!j.method)return b({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return we.disableMfa(M.id),we.revokeOtherSessions(M.id,l.id),we.markSessionStepUp(l.id),a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.mfa.disabled",payload:{method:j.method}}),b({ok:!0})}if(F.pathname==="/api/auth/step-up"&&I.method==="POST"){let d=await ie(I),l=Ft.resolveSession(I),T=_e(ae),M=T.actor?we.getIdentityByActor(T.actor.id):void 0;if(!l||!M||!Ii(String(d.password??""),M.passwordHash))return b({ok:!1,error:"Current password is incorrect."},401);let j=we.getMfaFactor(M.id);if(j?.state==="active"){if(!we.verifyMfaCode(M.id,String(d.code??"")).valid)return b({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let X=we.markSessionStepUp(l.id,j?.state==="active");return a.store.appendEvent({organizationId:a.organization.id,actorId:M.actorId,type:"auth.step_up.succeeded",payload:{mfa:j?.state==="active"}}),b({ok:!0,recentAuthAt:X.recentAuthAt})}if(F.pathname==="/api/terminal"){if(!ge)return b({ok:!1,error:"The web terminal is disabled."},403);if(Ke.upgrade(I))return;return Rd("WebSocket upgrade failed",400)}if(F.pathname==="/api/health"){let d=a.store.health();return b({ok:!0,cwd:t,environment:ye,environments:f,uiRoot:await ki(ae,ye),liveData:ke.size>0,terminal:ge,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:d.schemaVersion,supportedSchemaVersion:d.supportedSchemaVersion,integrity:d.integrity,pendingRetryableOperations:d.pendingRetryableOperations}})}if(F.pathname==="/api/control-plane/operations"){let d=F.searchParams.get("state"),l=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0;return b({operations:a.store.listOperations({projectId:a.project.id,state:l,kind:F.searchParams.get("kind")??void 0,limit:Number(F.searchParams.get("limit"))||100})})}if(F.pathname==="/api/queue"&&I.method==="GET"){let d=F.searchParams.get("state"),l=d&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(d)?d:void 0,T=At.list({projectId:a.project.id,state:l,limit:Number(F.searchParams.get("limit"))||250}).filter((M)=>fs(ae,M.operation.id,"deployments:read")).map((M)=>{let j=M.operation.resourceId?a.store.getResource(M.operation.resourceId):void 0,X=M.operation.environmentId?a.store.listEnvironments(a.project.id).find((me)=>me.id===M.operation.environmentId):void 0,U=M.operation.actorId?a.store.getActor(M.operation.actorId):void 0,Z=M.operation.input;return{...M,target:j?{id:j.id,name:j.name,slug:j.slug,kind:j.kind}:X?{id:X.id,name:X.name,slug:X.slug,kind:"environment"}:{id:a.project.id,name:a.project.name,slug:a.project.slug,kind:"project"},actor:U?{id:U.id,name:U.displayName,kind:U.kind}:void 0,commit:Z.revision??Z.source?.commitSha??null}});return b({operations:T,concurrency:At.limits})}if(F.pathname==="/api/queue/logs"&&I.method==="GET"){let d=String(F.searchParams.get("id")??"");if(!fs(ae,d,"deployments:read"))return b({ok:!1,error:"Operation was not found in this scope."},404);let l=At.logs(d,{after:Number(F.searchParams.get("after"))||0,limit:Number(F.searchParams.get("limit"))||500});return b({entries:l,cursor:l.at(-1)?.sequence??(Number(F.searchParams.get("after"))||0),operation:a.store.getOperation(d)})}if(F.pathname==="/api/queue/stream"&&I.method==="GET"){let d=String(F.searchParams.get("id")??"");if(!fs(ae,d,"deployments:read"))return b({ok:!1,error:"Operation was not found in this scope."},404);let l=I.headers.get("last-event-id")?.trim(),T=Number(l||F.searchParams.get("after")||0),M=new TextEncoder,j,X=!1,U=new ReadableStream({start(Z){let me=()=>{if(X)return;let le=Ft.resolveUser(I);if(!le||!fs(le,d,"deployments:read")){if(X=!0,j)clearInterval(j);Z.close();return}let qe=At.logs(d,{after:T,limit:500});for(let Ne of qe)T=Ne.sequence,Z.enqueue(M.encode(`id: ${Ne.sequence}
|
|
487
487
|
event: log
|
|
488
488
|
data: ${JSON.stringify(Ne)}
|
|
489
489
|
|
|
490
|
-
`));let be=a.store.getOperation(d);if(be&&["succeeded","failed","cancelled","timed_out"].includes(be.state)&&At.logs(d,{after:T,limit:1}).length===0){if(X=!0,
|
|
490
|
+
`));let be=a.store.getOperation(d);if(be&&["succeeded","failed","cancelled","timed_out"].includes(be.state)&&At.logs(d,{after:T,limit:1}).length===0){if(X=!0,j)clearInterval(j);Z.enqueue(M.encode(`event: complete
|
|
491
491
|
data: ${JSON.stringify({state:be.state,cursor:T})}
|
|
492
492
|
|
|
493
|
-
`)),Z.close()}};if(me(),!X)F=setInterval(me,500);I.signal.addEventListener("abort",()=>{if(X=!0,F)clearInterval(F);try{Z.close()}catch{}},{once:!0})},cancel(){if(X=!0,F)clearInterval(F)}});return new Response(j,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no"}})}if(L.pathname==="/api/queue/cancel"&&I.method==="POST"){let d=await ie(I),l=String(d.id??"");if(!fs(ae,l,"deployments:cancel"))return b({ok:!1,error:"Operation was not found or cannot be cancelled in this scope."},404);let T=Zt(a.store,ae);try{return b({ok:!0,operation:At.requestCancellation(l,T.id)})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Cancellation failed."},409)}}if(L.pathname==="/api/queue/retry"&&I.method==="POST"){let d=await ie(I),l=String(d.id??"");if(!fs(ae,l,"deployments:create"))return b({ok:!1,error:"Operation was not found or cannot be retried in this scope."},404);let T=Zt(a.store,ae);try{return b({ok:!0,operation:At.retry(l,String(d.errorClass??"manual"),{delayMs:Number(d.delayMs)||0,actorId:T.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Retry failed."},409)}}if(L.pathname==="/api/queue/settings"&&I.method==="GET")return b({concurrency:At.limits});if(L.pathname==="/api/queue/settings"&&I.method==="PATCH"){let d=await ie(I);if(d.confirm!=="update queue limits")return b({ok:!1,error:'Type "update queue limits" to confirm production concurrency changes.'},409);let l=Zt(a.store,ae);return b({ok:!0,concurrency:At.configureConcurrency(d.concurrency??{},{organizationId:a.organization.id,actorId:l.id})})}if(L.pathname==="/api/queue/history"&&I.method==="DELETE"){let d=await ie(I);if(d.confirm!=="clear completed")return b({ok:!1,error:'Type "clear completed" to confirm retained history cleanup.'},409);let l=Zt(a.store,ae);return b({ok:!0,deleted:At.clearCompleted({projectId:a.project.id,before:typeof d.before==="string"?d.before:void 0,actorId:l.id})})}if(L.pathname==="/api/previews"&&I.method==="GET"){let d=Ht.previews.listInstances({projectId:a.project.id}).filter((M)=>yr(ae,M.resourceId,"deployments:read")),l=Ht.previews.listDefinitions(a.project.id).filter((M)=>yr(ae,M.resourceId,"project:read")),T=a.store.listResources(a.project.id).filter((M)=>M.kind==="application"&&yr(ae,M.id,"project:read")).map((M)=>({id:M.id,slug:M.slug,name:M.name,environmentId:M.environmentId}));return b({previews:d,definitions:l,resources:T,environments:[...a.environments.values()]})}if(L.pathname==="/api/releases"&&I.method==="GET"){let d=[...a.environments.values()],l=a.store.listResources(a.project.id).filter((F)=>yr(ae,F.id,"deployments:read")),T=new Set(l.map((F)=>F.id)),M=Cn.releases.list({projectId:a.project.id}).filter((F)=>T.has(F.resourceId)).map((F)=>{let X=l.find((me)=>me.id===F.resourceId),j=d.find((me)=>me.id===F.environmentId),Z=F.previousReleaseId?Cn.releases.get(F.previousReleaseId):void 0;return{...F,resource:X?{id:X.id,name:X.name,slug:X.slug,provider:X.provider}:void 0,environment:j?{id:j.id,name:j.name,slug:j.slug,kind:j.kind}:void 0,artifact:Cn.releases.getArtifact(F.artifactId),transitions:Cn.releases.transitions(F.id),approvals:Cn.releases.approvals(F.id),previous:Z,comparison:Z?Cn.releases.compare(Z.id,F.id):void 0,capabilities:cr({kind:F.kind,provider:X?.provider,hasHealthGate:!!F.healthGate,replicas:Number(F.manifest?.replicas)||1})}});return b({releases:M,resources:l.map((F)=>({id:F.id,name:F.name,slug:F.slug,environmentId:F.environmentId,provider:F.provider})),environments:d})}if(L.pathname==="/api/releases/action"&&I.method==="POST"){let d=await ie(I),l=Cn.releases.get(String(d.id??"")),T=String(d.action??"");if(!l||!yr(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Release was not found in this scope."},404);let M=Zt(a.store,ae);try{if(T==="activate")return b({ok:!0,operation:Cn.enqueueActivation(l,{actorId:M.id})});if(T==="rollback"){let F=a.store.getResource(l.resourceId);if(d.confirm!==F?.slug)return b({ok:!1,error:`Type "${F?.slug??""}" to confirm rollback.`},409);return b({ok:!0,operation:Cn.enqueueRollback(l,{actorId:M.id,targetReleaseId:typeof d.targetReleaseId==="string"?d.targetReleaseId:void 0})})}if(T==="approve"){let F=a.store.listEnvironments(l.projectId).find((X)=>X.id===l.environmentId);if(d.confirm!==F?.slug)return b({ok:!1,error:`Type "${F?.slug??""}" to confirm the environment gate.`},409);return b({ok:!0,release:Cn.releases.approve(l.id,{actorId:M.id,decision:d.decision==="rejected"?"rejected":"approved",comment:typeof d.comment==="string"?d.comment:void 0})})}if(T==="pin")return b({ok:!0,release:Cn.releases.pin(l.id,d.pinned!==!1,typeof d.reason==="string"?d.reason:void 0)});if(T==="promote"){let F=a.store.getResource(String(d.targetResourceId??"")),X=F?a.store.listEnvironments(l.projectId).find((j)=>j.id===F.environmentId):void 0;if(!F||!X||!yr(ae,F.id,"deployments:create"))return b({ok:!1,error:"Promotion target was not found in this scope."},404);if(d.confirm!==X.slug)return b({ok:!1,error:`Type "${X.slug}" to confirm promotion.`},409);return b({ok:!0,release:Cn.releases.promote(l.id,{targetEnvironmentId:X.id,targetResourceId:F.id,config:d.config&&typeof d.config==="object"?d.config:{},strategy:typeof d.strategy==="string"?d.strategy:void 0,actorId:M.id,approvalRequired:d.approvalRequired===!0})})}return b({ok:!1,error:"Unsupported release action."},422)}catch(F){return b({ok:!1,error:F instanceof Error?F.message:"Release action failed."},409)}}if(L.pathname==="/api/compose"&&I.method==="GET"){let d=fo.applications.list({projectId:a.project.id}).filter((l)=>yr(ae,l.resourceId,"applications:read")).map((l)=>({...l,services:fo.applications.services(l.id)}));return b({applications:d,templates:Sr(),environments:[...a.environments.values()]})}if(L.pathname==="/api/compose/preview"&&I.method==="POST"){let d=await ie(I),l=String(d.environmentId??"");if(!la(ae,l,"applications:manage"))return b({ok:!1,error:"Environment was not found in this scope."},404);try{return b({ok:!0,result:fo.applications.preview(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:l})})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Compose could not be parsed."},422)}}if((L.pathname==="/api/compose/import"||L.pathname==="/api/compose/template")&&I.method==="POST"){let d=await ie(I),l=String(d.environmentId??"");if(!la(ae,l,"applications:manage"))return b({ok:!1,error:"Environment was not found in this scope."},404);let T=Zt(a.store,ae);try{let M=L.pathname.endsWith("/template")?fo.applications.fromTemplate(String(d.templateId??""),d.inputs&&typeof d.inputs==="object"?d.inputs:{},{name:String(d.name??""),projectId:a.project.id,environmentId:l,version:typeof d.templateVersion==="string"?d.templateVersion:void 0,createdByActorId:T.id}):fo.applications.import(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:l,createdByActorId:T.id});return b({ok:!0,application:M.application,diagnostics:M.parsed.diagnostics})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Compose application could not be saved."},422)}}if(L.pathname==="/api/compose/action"&&I.method==="POST"){let d=await ie(I),l=fo.applications.get(String(d.id??"")),T=String(d.action??""),M=T==="delete"||T==="stop"?"deployments:cancel":"deployments:create";if(!l||!yr(ae,l.resourceId,M))return b({ok:!1,error:"Compose application was not found in this scope."},404);try{let F=Zt(a.store,ae);return b({ok:!0,operation:fo.enqueue(l,T,{actorId:F.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(F){return b({ok:!1,error:F instanceof Error?F.message:"Compose operation could not be queued."},409)}}if((L.pathname==="/api/compose/logs"||L.pathname==="/api/compose/shell")&&I.method==="POST"){let d=await ie(I),l=fo.applications.get(String(d.id??"")),T=L.pathname.endsWith("/shell"),M=T?"runtime:terminal":"runtime:logs";if(!l||!yr(ae,l.resourceId,M))return b({ok:!1,error:"Compose service was not found in this scope."},404);let F=String(d.service??"");if(!l.manifest.spec.services[F])return b({ok:!1,error:"Compose service was not found."},404);if(T&&d.confirm!==F)return b({ok:!1,error:`Type "${F}" to run a service command.`},409);let X=a.store.listEnvironments(l.projectId).find((Z)=>Z.id===l.environmentId)?.slug;if(!X)return b({ok:!1,error:"Compose environment was not found."},404);let j=T?vi(l.manifest,F,Array.isArray(d.command)?d.command.map(String):["sh"]):Si(l.manifest,F,Number(d.lines)||200);return b(await ar(o,X,j))}if(L.pathname==="/api/previews/definitions"&&I.method==="POST"){let d=await ie(I),l=String(d.resourceId??"");if(!yr(ae,l,"config:write"))return b({ok:!1,error:"Application was not found in this scope."},404);let T=Zt(a.store,ae);try{return b({ok:!0,definition:Ht.previews.createDefinition({...d,projectId:a.project.id,resourceId:l,baseEnvironmentId:String(d.baseEnvironmentId??""),domainPattern:String(d.domainPattern??""),createdByActorId:T.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Preview policy could not be created."},409)}}if(L.pathname==="/api/previews/deploy"&&I.method==="POST"){let d=await ie(I),l=Ht.previews.getDefinition(String(d.definitionId??""));if(!l||!yr(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Preview policy was not found in this scope."},404);let T=Zt(a.store,ae);try{let M=Ht.previews.upsert({definitionId:l.id,sourceProvider:"dashboard",repository:"dashboard",branch:String(d.branch??""),pullRequestNumber:Number(d.pullRequestNumber)||void 0,commitSha:String(d.commitSha??""),createdByActorId:T.id});return b({ok:!0,preview:M.preview,operation:Ht.enqueueDeploy(M.preview,{created:M.created,actorId:T.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Preview could not be queued."},409)}}if(L.pathname==="/api/previews/destroy"&&I.method==="POST"){let d=await ie(I),l=Ht.previews.getInstance(String(d.id??""));if(!l||!yr(ae,l.resourceId,"deployments:cancel"))return b({ok:!1,error:"Preview was not found in this scope."},404);if(d.confirm!==l.name)return b({ok:!1,error:`Type "${l.name}" to confirm tagged teardown.`},409);let T=Zt(a.store,ae);return b({ok:!0,operation:Ht.enqueueDestroy(l,"dashboard",T.id)})}if(L.pathname==="/api/previews/extend"&&I.method==="POST"){let d=await ie(I),l=Ht.previews.getInstance(String(d.id??""));if(!l||!yr(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Preview was not found in this scope."},404);return b({ok:!0,preview:Ht.previews.extend(l.id,Number(d.hours))})}if(L.pathname==="/api/previews/rebuild"&&I.method==="POST"){let d=await ie(I),l=Ht.previews.getInstance(String(d.id??""));if(!l||!yr(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Preview was not found in this scope."},404);let T=Zt(a.store,ae);return b({ok:!0,operation:Ht.enqueueDeploy(l,{actorId:T.id,reason:"manual_rebuild"})})}if(L.pathname==="/api/previews/cleanup"&&I.method==="POST"){let d=await ie(I);if(!d.dryRun&&d.confirm!=="cleanup previews")return b({ok:!1,error:'Type "cleanup previews" to confirm teardown.'},409);let l=Zt(a.store,ae);return b({ok:!0,...Ht.cleanup({dryRun:d.dryRun===!0,maxAgeHours:Number(d.maxAgeHours)||void 0,keepCount:Number(d.keepCount)||void 0,actorId:l.id})})}if(L.pathname==="/api/control-plane/events")return b({events:a.store.listEvents({organizationId:a.organization.id,projectId:a.project.id,operationId:L.searchParams.get("operationId")??void 0,correlationId:L.searchParams.get("correlationId")??void 0,afterSequence:Number(L.searchParams.get("afterSequence"))||void 0,limit:Number(L.searchParams.get("limit"))||200})});if(L.pathname==="/api/search"){let d=String(L.searchParams.get("q")??"").trim().slice(0,128),l=Tn.role==="member"?new Set(Object.keys(Tn.sites)):void 0,T=d?oa(a.store,{projectId:a.project.id,query:d,allowedResourceSlugs:l,limit:Number(L.searchParams.get("limit"))||20}):[];return b({query:d,results:T,stale:!1})}if(L.pathname==="/api/search/preferences"&&I.method==="GET"){let d=`dashboard:${ae.username.toLowerCase()}`;return b({savedFilters:a.store.listSavedFilters(d),navigation:a.store.listNavigation(d)})}if(L.pathname==="/api/search/preferences"&&I.method==="POST"){let d=`dashboard:${ae.username.toLowerCase()}`,l=await ie(I),T=String(l.action??"");if(T==="save-filter")return b({savedFilter:a.store.saveFilter(d,String(l.name??""),String(l.routeId??""),l.query??{})});if(T==="favorite")return b({navigation:a.store.setFavorite(d,String(l.entityType??""),String(l.entityId??""),l.favorite!==!1)});if(T==="visit")return b({navigation:a.store.recordNavigation(d,String(l.entityType??""),String(l.entityId??""))});return b({ok:!1,error:"Unknown search preference action."},422)}if(L.pathname==="/api/search/preferences"&&I.method==="DELETE"){let d=`dashboard:${ae.username.toLowerCase()}`,l=await ie(I);return b({ok:a.store.deleteSavedFilter(d,String(l.id??""))})}if(L.pathname==="/api/organization"&&I.method==="GET"){let d=a.store.listMemberships(a.organization.id,{includeRevoked:!0}).map((l)=>{let T=a.store.getActor(l.actorId);return{...l,actor:T?{id:T.id,displayName:T.displayName,externalId:T.externalId,disabledAt:T.disabledAt}:void 0,grants:a.store.listGrants(l.id)}});return b({organization:a.organization,project:a.project,environments:a.store.listEnvironments(a.project.id),resources:a.store.listResources(a.project.id).map((l)=>({id:l.id,environmentId:l.environmentId,kind:l.kind,slug:l.slug,name:l.name})),memberships:d,invitations:a.store.listInvitations(a.organization.id)})}if(L.pathname==="/api/organization/invitations"&&I.method==="GET")return b({invitations:a.store.listInvitations(a.organization.id)});if(L.pathname==="/api/organization/invitations"&&I.method==="POST"){let d=await ie(I),l=Td(d.roleTemplate),T=Ba(d);if(!l||!T)return b({ok:!1,error:"Choose a valid role template and resource scope."},422);let M=_e(ae);if(!M.actor||!M.membership)return b({ok:!1,error:"Your organization membership is unavailable."},403);if(l==="owner"&&(!Ii(String(d.password??""),ae.passwordHash)||M.membership.roleTemplate!=="owner"))return b({ok:!1,error:"Owner invitations require an owner to re-enter their password."},401);try{let F=a.store.createInvitation({organizationId:a.organization.id,email:String(d.email??""),roleTemplate:l,scope:T,invitedByActorId:M.actor.id,expiresInMs:Number(d.expiresInMs)||void 0}),X=`${L.origin}/accept-invitation?token=${encodeURIComponent(F.token)}`,j=await ga(o,{to:F.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${X}
|
|
493
|
+
`)),Z.close()}};if(me(),!X)j=setInterval(me,500);I.signal.addEventListener("abort",()=>{if(X=!0,j)clearInterval(j);try{Z.close()}catch{}},{once:!0})},cancel(){if(X=!0,j)clearInterval(j)}});return new Response(U,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no"}})}if(F.pathname==="/api/queue/cancel"&&I.method==="POST"){let d=await ie(I),l=String(d.id??"");if(!fs(ae,l,"deployments:cancel"))return b({ok:!1,error:"Operation was not found or cannot be cancelled in this scope."},404);let T=er(a.store,ae);try{return b({ok:!0,operation:At.requestCancellation(l,T.id)})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Cancellation failed."},409)}}if(F.pathname==="/api/queue/retry"&&I.method==="POST"){let d=await ie(I),l=String(d.id??"");if(!fs(ae,l,"deployments:create"))return b({ok:!1,error:"Operation was not found or cannot be retried in this scope."},404);let T=er(a.store,ae);try{return b({ok:!0,operation:At.retry(l,String(d.errorClass??"manual"),{delayMs:Number(d.delayMs)||0,actorId:T.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Retry failed."},409)}}if(F.pathname==="/api/queue/settings"&&I.method==="GET")return b({concurrency:At.limits});if(F.pathname==="/api/queue/settings"&&I.method==="PATCH"){let d=await ie(I);if(d.confirm!=="update queue limits")return b({ok:!1,error:'Type "update queue limits" to confirm production concurrency changes.'},409);let l=er(a.store,ae);return b({ok:!0,concurrency:At.configureConcurrency(d.concurrency??{},{organizationId:a.organization.id,actorId:l.id})})}if(F.pathname==="/api/queue/history"&&I.method==="DELETE"){let d=await ie(I);if(d.confirm!=="clear completed")return b({ok:!1,error:'Type "clear completed" to confirm retained history cleanup.'},409);let l=er(a.store,ae);return b({ok:!0,deleted:At.clearCompleted({projectId:a.project.id,before:typeof d.before==="string"?d.before:void 0,actorId:l.id})})}if(F.pathname==="/api/previews"&&I.method==="GET"){let d=Wt.previews.listInstances({projectId:a.project.id}).filter((M)=>br(ae,M.resourceId,"deployments:read")),l=Wt.previews.listDefinitions(a.project.id).filter((M)=>br(ae,M.resourceId,"project:read")),T=a.store.listResources(a.project.id).filter((M)=>M.kind==="application"&&br(ae,M.id,"project:read")).map((M)=>({id:M.id,slug:M.slug,name:M.name,environmentId:M.environmentId}));return b({previews:d,definitions:l,resources:T,environments:[...a.environments.values()]})}if(F.pathname==="/api/releases"&&I.method==="GET"){let d=[...a.environments.values()],l=a.store.listResources(a.project.id).filter((j)=>br(ae,j.id,"deployments:read")),T=new Set(l.map((j)=>j.id)),M=Cn.releases.list({projectId:a.project.id}).filter((j)=>T.has(j.resourceId)).map((j)=>{let X=l.find((me)=>me.id===j.resourceId),U=d.find((me)=>me.id===j.environmentId),Z=j.previousReleaseId?Cn.releases.get(j.previousReleaseId):void 0;return{...j,resource:X?{id:X.id,name:X.name,slug:X.slug,provider:X.provider}:void 0,environment:U?{id:U.id,name:U.name,slug:U.slug,kind:U.kind}:void 0,artifact:Cn.releases.getArtifact(j.artifactId),transitions:Cn.releases.transitions(j.id),approvals:Cn.releases.approvals(j.id),previous:Z,comparison:Z?Cn.releases.compare(Z.id,j.id):void 0,capabilities:lr({kind:j.kind,provider:X?.provider,hasHealthGate:!!j.healthGate,replicas:Number(j.manifest?.replicas)||1})}});return b({releases:M,resources:l.map((j)=>({id:j.id,name:j.name,slug:j.slug,environmentId:j.environmentId,provider:j.provider})),environments:d})}if(F.pathname==="/api/releases/action"&&I.method==="POST"){let d=await ie(I),l=Cn.releases.get(String(d.id??"")),T=String(d.action??"");if(!l||!br(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Release was not found in this scope."},404);let M=er(a.store,ae);try{if(T==="activate")return b({ok:!0,operation:Cn.enqueueActivation(l,{actorId:M.id})});if(T==="rollback"){let j=a.store.getResource(l.resourceId);if(d.confirm!==j?.slug)return b({ok:!1,error:`Type "${j?.slug??""}" to confirm rollback.`},409);return b({ok:!0,operation:Cn.enqueueRollback(l,{actorId:M.id,targetReleaseId:typeof d.targetReleaseId==="string"?d.targetReleaseId:void 0})})}if(T==="approve"){let j=a.store.listEnvironments(l.projectId).find((X)=>X.id===l.environmentId);if(d.confirm!==j?.slug)return b({ok:!1,error:`Type "${j?.slug??""}" to confirm the environment gate.`},409);return b({ok:!0,release:Cn.releases.approve(l.id,{actorId:M.id,decision:d.decision==="rejected"?"rejected":"approved",comment:typeof d.comment==="string"?d.comment:void 0})})}if(T==="pin")return b({ok:!0,release:Cn.releases.pin(l.id,d.pinned!==!1,typeof d.reason==="string"?d.reason:void 0)});if(T==="promote"){let j=a.store.getResource(String(d.targetResourceId??"")),X=j?a.store.listEnvironments(l.projectId).find((U)=>U.id===j.environmentId):void 0;if(!j||!X||!br(ae,j.id,"deployments:create"))return b({ok:!1,error:"Promotion target was not found in this scope."},404);if(d.confirm!==X.slug)return b({ok:!1,error:`Type "${X.slug}" to confirm promotion.`},409);return b({ok:!0,release:Cn.releases.promote(l.id,{targetEnvironmentId:X.id,targetResourceId:j.id,config:d.config&&typeof d.config==="object"?d.config:{},strategy:typeof d.strategy==="string"?d.strategy:void 0,actorId:M.id,approvalRequired:d.approvalRequired===!0})})}return b({ok:!1,error:"Unsupported release action."},422)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"Release action failed."},409)}}if(F.pathname==="/api/compose"&&I.method==="GET"){let d=fo.applications.list({projectId:a.project.id}).filter((l)=>br(ae,l.resourceId,"applications:read")).map((l)=>({...l,services:fo.applications.services(l.id)}));return b({applications:d,templates:vr(),environments:[...a.environments.values()]})}if(F.pathname==="/api/compose/preview"&&I.method==="POST"){let d=await ie(I),l=String(d.environmentId??"");if(!la(ae,l,"applications:manage"))return b({ok:!1,error:"Environment was not found in this scope."},404);try{return b({ok:!0,result:fo.applications.preview(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:l})})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Compose could not be parsed."},422)}}if((F.pathname==="/api/compose/import"||F.pathname==="/api/compose/template")&&I.method==="POST"){let d=await ie(I),l=String(d.environmentId??"");if(!la(ae,l,"applications:manage"))return b({ok:!1,error:"Environment was not found in this scope."},404);let T=er(a.store,ae);try{let M=F.pathname.endsWith("/template")?fo.applications.fromTemplate(String(d.templateId??""),d.inputs&&typeof d.inputs==="object"?d.inputs:{},{name:String(d.name??""),projectId:a.project.id,environmentId:l,version:typeof d.templateVersion==="string"?d.templateVersion:void 0,createdByActorId:T.id}):fo.applications.import(String(d.source??""),{name:String(d.name??""),slug:typeof d.slug==="string"?d.slug:void 0,projectId:a.project.id,environmentId:l,createdByActorId:T.id});return b({ok:!0,application:M.application,diagnostics:M.parsed.diagnostics})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Compose application could not be saved."},422)}}if(F.pathname==="/api/compose/action"&&I.method==="POST"){let d=await ie(I),l=fo.applications.get(String(d.id??"")),T=String(d.action??""),M=T==="delete"||T==="stop"?"deployments:cancel":"deployments:create";if(!l||!br(ae,l.resourceId,M))return b({ok:!1,error:"Compose application was not found in this scope."},404);try{let j=er(a.store,ae);return b({ok:!0,operation:fo.enqueue(l,T,{actorId:j.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(j){return b({ok:!1,error:j instanceof Error?j.message:"Compose operation could not be queued."},409)}}if((F.pathname==="/api/compose/logs"||F.pathname==="/api/compose/shell")&&I.method==="POST"){let d=await ie(I),l=fo.applications.get(String(d.id??"")),T=F.pathname.endsWith("/shell"),M=T?"runtime:terminal":"runtime:logs";if(!l||!br(ae,l.resourceId,M))return b({ok:!1,error:"Compose service was not found in this scope."},404);let j=String(d.service??"");if(!l.manifest.spec.services[j])return b({ok:!1,error:"Compose service was not found."},404);if(T&&d.confirm!==j)return b({ok:!1,error:`Type "${j}" to run a service command.`},409);let X=a.store.listEnvironments(l.projectId).find((Z)=>Z.id===l.environmentId)?.slug;if(!X)return b({ok:!1,error:"Compose environment was not found."},404);let U=T?vi(l.manifest,j,Array.isArray(d.command)?d.command.map(String):["sh"]):Si(l.manifest,j,Number(d.lines)||200);return b(await cr(o,X,U))}if(F.pathname==="/api/previews/definitions"&&I.method==="POST"){let d=await ie(I),l=String(d.resourceId??"");if(!br(ae,l,"config:write"))return b({ok:!1,error:"Application was not found in this scope."},404);let T=er(a.store,ae);try{return b({ok:!0,definition:Wt.previews.createDefinition({...d,projectId:a.project.id,resourceId:l,baseEnvironmentId:String(d.baseEnvironmentId??""),domainPattern:String(d.domainPattern??""),createdByActorId:T.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Preview policy could not be created."},409)}}if(F.pathname==="/api/previews/deploy"&&I.method==="POST"){let d=await ie(I),l=Wt.previews.getDefinition(String(d.definitionId??""));if(!l||!br(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Preview policy was not found in this scope."},404);let T=er(a.store,ae);try{let M=Wt.previews.upsert({definitionId:l.id,sourceProvider:"dashboard",repository:"dashboard",branch:String(d.branch??""),pullRequestNumber:Number(d.pullRequestNumber)||void 0,commitSha:String(d.commitSha??""),createdByActorId:T.id});return b({ok:!0,preview:M.preview,operation:Wt.enqueueDeploy(M.preview,{created:M.created,actorId:T.id})})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Preview could not be queued."},409)}}if(F.pathname==="/api/previews/destroy"&&I.method==="POST"){let d=await ie(I),l=Wt.previews.getInstance(String(d.id??""));if(!l||!br(ae,l.resourceId,"deployments:cancel"))return b({ok:!1,error:"Preview was not found in this scope."},404);if(d.confirm!==l.name)return b({ok:!1,error:`Type "${l.name}" to confirm tagged teardown.`},409);let T=er(a.store,ae);return b({ok:!0,operation:Wt.enqueueDestroy(l,"dashboard",T.id)})}if(F.pathname==="/api/previews/extend"&&I.method==="POST"){let d=await ie(I),l=Wt.previews.getInstance(String(d.id??""));if(!l||!br(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Preview was not found in this scope."},404);return b({ok:!0,preview:Wt.previews.extend(l.id,Number(d.hours))})}if(F.pathname==="/api/previews/rebuild"&&I.method==="POST"){let d=await ie(I),l=Wt.previews.getInstance(String(d.id??""));if(!l||!br(ae,l.resourceId,"deployments:create"))return b({ok:!1,error:"Preview was not found in this scope."},404);let T=er(a.store,ae);return b({ok:!0,operation:Wt.enqueueDeploy(l,{actorId:T.id,reason:"manual_rebuild"})})}if(F.pathname==="/api/previews/cleanup"&&I.method==="POST"){let d=await ie(I);if(!d.dryRun&&d.confirm!=="cleanup previews")return b({ok:!1,error:'Type "cleanup previews" to confirm teardown.'},409);let l=er(a.store,ae);return b({ok:!0,...Wt.cleanup({dryRun:d.dryRun===!0,maxAgeHours:Number(d.maxAgeHours)||void 0,keepCount:Number(d.keepCount)||void 0,actorId:l.id})})}if(F.pathname==="/api/control-plane/events")return b({events:a.store.listEvents({organizationId:a.organization.id,projectId:a.project.id,operationId:F.searchParams.get("operationId")??void 0,correlationId:F.searchParams.get("correlationId")??void 0,afterSequence:Number(F.searchParams.get("afterSequence"))||void 0,limit:Number(F.searchParams.get("limit"))||200})});if(F.pathname==="/api/search"){let d=String(F.searchParams.get("q")??"").trim().slice(0,128),l=Tn.role==="member"?new Set(Object.keys(Tn.sites)):void 0,T=d?oa(a.store,{projectId:a.project.id,query:d,allowedResourceSlugs:l,limit:Number(F.searchParams.get("limit"))||20}):[];return b({query:d,results:T,stale:!1})}if(F.pathname==="/api/search/preferences"&&I.method==="GET"){let d=`dashboard:${ae.username.toLowerCase()}`;return b({savedFilters:a.store.listSavedFilters(d),navigation:a.store.listNavigation(d)})}if(F.pathname==="/api/search/preferences"&&I.method==="POST"){let d=`dashboard:${ae.username.toLowerCase()}`,l=await ie(I),T=String(l.action??"");if(T==="save-filter")return b({savedFilter:a.store.saveFilter(d,String(l.name??""),String(l.routeId??""),l.query??{})});if(T==="favorite")return b({navigation:a.store.setFavorite(d,String(l.entityType??""),String(l.entityId??""),l.favorite!==!1)});if(T==="visit")return b({navigation:a.store.recordNavigation(d,String(l.entityType??""),String(l.entityId??""))});return b({ok:!1,error:"Unknown search preference action."},422)}if(F.pathname==="/api/search/preferences"&&I.method==="DELETE"){let d=`dashboard:${ae.username.toLowerCase()}`,l=await ie(I);return b({ok:a.store.deleteSavedFilter(d,String(l.id??""))})}if(F.pathname==="/api/organization"&&I.method==="GET"){let d=a.store.listMemberships(a.organization.id,{includeRevoked:!0}).map((l)=>{let T=a.store.getActor(l.actorId);return{...l,actor:T?{id:T.id,displayName:T.displayName,externalId:T.externalId,disabledAt:T.disabledAt}:void 0,grants:a.store.listGrants(l.id)}});return b({organization:a.organization,project:a.project,environments:a.store.listEnvironments(a.project.id),resources:a.store.listResources(a.project.id).map((l)=>({id:l.id,environmentId:l.environmentId,kind:l.kind,slug:l.slug,name:l.name})),memberships:d,invitations:a.store.listInvitations(a.organization.id)})}if(F.pathname==="/api/organization/invitations"&&I.method==="GET")return b({invitations:a.store.listInvitations(a.organization.id)});if(F.pathname==="/api/organization/invitations"&&I.method==="POST"){let d=await ie(I),l=Td(d.roleTemplate),T=Ba(d);if(!l||!T)return b({ok:!1,error:"Choose a valid role template and resource scope."},422);let M=_e(ae);if(!M.actor||!M.membership)return b({ok:!1,error:"Your organization membership is unavailable."},403);if(l==="owner"&&(!Ii(String(d.password??""),ae.passwordHash)||M.membership.roleTemplate!=="owner"))return b({ok:!1,error:"Owner invitations require an owner to re-enter their password."},401);try{let j=a.store.createInvitation({organizationId:a.organization.id,email:String(d.email??""),roleTemplate:l,scope:T,invitedByActorId:M.actor.id,expiresInMs:Number(d.expiresInMs)||void 0}),X=`${F.origin}/accept-invitation?token=${encodeURIComponent(j.token)}`,U=await ga(o,{to:j.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${X}
|
|
494
494
|
|
|
495
|
-
This link expires ${
|
|
495
|
+
This link expires ${j.invitation.expiresAt} and can be used once.`});return b({invitation:j.invitation,token:j.token,acceptUrl:X,delivered:U},201)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:"Invitation could not be created."},422)}}if(F.pathname==="/api/organization/invitations"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae);try{return b({invitation:a.store.revokeInvitation(String(d.id??""),l.actor?.id)})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Invitation could not be revoked."},409)}}if(F.pathname==="/api/organization/invitations/resend"&&I.method==="POST"){let d=await ie(I),l=_e(ae);try{let T=a.store.reissueInvitation(String(d.id??""),l.actor?.id),M=`${F.origin}/accept-invitation?token=${encodeURIComponent(T.token)}`,j=await ga(o,{to:T.invitation.email,subject:"Your ts-cloud organization invitation",text:`Accept your ts-cloud invitation: ${M}
|
|
496
496
|
|
|
497
|
-
This replacement link expires ${T.invitation.expiresAt} and can be used once.`});return b({invitation:T.invitation,token:T.token,acceptUrl:M,delivered:F})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Invitation could not be resent."},409)}}if(L.pathname==="/api/organization/memberships"&&I.method==="PATCH"){let d=await ie(I),l=a.store.getMembership(String(d.id??"")),T=Td(d.roleTemplate),M=Ba(d);if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Membership was not found."},404);if(!T||!M)return b({ok:!1,error:"Choose a valid role template and resource scope."},422);let F=_e(ae);if((l.roleTemplate==="owner"||T==="owner")&&(!Ii(String(d.password??""),ae.passwordHash)||F.membership?.roleTemplate!=="owner"))return b({ok:!1,error:"Ownership changes require an owner to re-enter their password."},401);let j=a.store.resolveAuthorizationTarget(a.organization.id,M)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),Z=a.store.listGrants(l.id),me=vn({membership:l,grants:Z,target:j}),le={...l,roleTemplate:T,scope:M},Ge=vn({membership:le,grants:Z,target:j}),be={gained:Ge.filter((Ne)=>!me.includes(Ne)),lost:me.filter((Ne)=>!Ge.includes(Ne))};if(d.preview===!0)return b({membership:l,proposed:{roleTemplate:T,scope:M},accessDiff:be});if(String(d.confirm??"")!==l.id)return b({ok:!1,error:`Confirm this change with membership ID ${l.id}.`,accessDiff:be},409);try{return b({membership:a.store.updateMembership({id:l.id,roleTemplate:T,scope:M,actorId:F.actor?.id}),accessDiff:be})}catch(Ne){return b({ok:!1,error:Ne instanceof Error?Ne.message:"Membership could not be updated."},409)}}if(L.pathname==="/api/organization/memberships"&&I.method==="DELETE"){let d=await ie(I),l=a.store.getMembership(String(d.id??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Membership was not found."},404);if(String(d.confirm??"")!==l.id)return b({ok:!1,error:`Confirm removal with membership ID ${l.id}.`},409);let T=_e(ae);if(l.roleTemplate==="owner"&&(T.membership?.roleTemplate!=="owner"||!Ii(String(d.password??""),ae.passwordHash)))return b({ok:!1,error:"Removing an owner requires an owner to re-enter their current password."},401);try{return b({membership:a.store.revokeMembership(l.id,T.actor?.id)})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Membership could not be removed."},409)}}if(L.pathname==="/api/organization/grants"&&I.method==="POST"){let d=await ie(I),l=String(d.capability??""),T=d.effect==="deny"?"deny":d.effect==="allow"?"allow":void 0,M=Ba(d),F=_e(ae);if(!T||!M||!ce.includes(l))return b({ok:!1,error:"Choose a valid capability, effect, and resource scope."},422);try{return b({grant:a.store.upsertGrant({organizationId:a.organization.id,membershipId:String(d.membershipId??""),effect:T,capability:l,scope:M,actorId:F.actor?.id})},201)}catch(X){return b({ok:!1,error:X instanceof Error?X.message:"Grant could not be created."},422)}}if(L.pathname==="/api/organization/grants"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=a.store.getGrant(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Grant was not found."},404);return b({ok:a.store.removeGrant(T.id,l.actor?.id)})}if(L.pathname==="/api/tags"&&I.method==="GET")return b({tags:a.store.listTags(a.project.id),assignments:a.store.listResourceTags(a.project.id)});if(L.pathname==="/api/tags"&&I.method==="POST"){let d=await ie(I),l=a.store.upsertTag(a.project.id,String(d.name??""),String(d.color??"#5a8be0"));if(d.resourceId)a.store.assignTag(String(d.resourceId),l.id);return b({tag:l},201)}if(L.pathname==="/api/tags"&&I.method==="DELETE"){let d=await ie(I);return a.store.removeTag(String(d.resourceId??""),String(d.tagId??"")),b({ok:!0})}if(L.pathname==="/"&&!fb(L.pathname,Tn))return new Response(null,{status:302,headers:{location:`/server/sites?env=${encodeURIComponent(ye)}`}});if(L.pathname==="/"&&Lt?.mode==="serverless")return new Response(null,{status:302,headers:{location:`/serverless?env=${encodeURIComponent(ye)}`}});let Ja=ky(L.pathname);if(Ja)return new Response(null,{status:308,headers:{location:`${Ja}?env=${encodeURIComponent(ye)}`}});if(L.pathname==="/api/env"&&I.method==="POST"){let d=await ie(I),l=String(d.env??"");if(!f.includes(l))return b({ok:!1,error:`Unknown environment '${l}'.`,environments:f},404);return b({ok:!0,environment:l,environments:f,href:`?env=${encodeURIComponent(l)}`})}if(L.pathname==="/api/config"){let d={...fA(o),environment:ye,environments:f};return b(Py(d,Tn))}if(L.pathname==="/api/ssh-keys"&&I.method==="GET")return b({configPath:k,keys:$t(da(o))});if(L.pathname==="/api/ssh-keys"&&I.method==="POST"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=await Li(k,"utf8"),T=da(o),M=fc({configText:l,name:String(d.name??""),publicKey:String(d.publicKey??""),existingKeys:T});return await ls(k,M),lb(o,[...T,{name:String(d.name??"").trim(),publicKey:String(d.publicKey??"").trim().replace(/\s+/g," ")}]),b({ok:!0,configPath:k,keys:$t(da(o))})}if(L.pathname==="/api/ssh-keys"&&I.method==="DELETE"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??L.searchParams.get("name")??""),T=await Li(k,"utf8"),M=da(o),F=hc({configText:T,name:l,existingKeys:M});return await ls(k,F),lb(o,M.filter((X)=>X.name!==l.trim())),b({ok:!0,configPath:k,keys:$t(da(o))})}if(L.pathname==="/api/firewall"&&I.method==="GET")return b({configPath:k,alwaysOpen:[22,80,443],ports:sp(o)});if(L.pathname==="/api/firewall"&&I.method==="POST"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=Number(d.port);if(!$a(l))return b({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=sp(o),M=await Li(k,"utf8");try{await ls(k,$y(M,l,T))}catch(j){return b({ok:!1,error:j?.message??String(j)},422)}let F=us([...T,l]);pb(o,F);let X=d.apply===!1?null:await ar(o,ye,`ufw allow ${l}/tcp`).catch((j)=>({ok:!1,error:String(j?.message??j)}));return b({ok:!0,configPath:k,ports:F,apply:X})}if(L.pathname==="/api/firewall"&&I.method==="DELETE"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=Number(d.port??L.searchParams.get("port"));if(!$a(l))return b({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=sp(o),M=await Li(k,"utf8");await ls(k,Ly(M,l,T));let F=us(T.filter((j)=>j!==l));pb(o,F);let X=d.apply===!1?null:await ar(o,ye,`ufw delete allow ${l}/tcp`).catch((j)=>({ok:!1,error:String(j?.message??j)}));return b({ok:!0,configPath:k,ports:F,apply:X})}if(L.pathname==="/api/sites"&&I.method==="POST"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??"").trim(),T=String(d.root??"").trim();if(!l||!T)return b({ok:!1,error:"Site name and root are required."},422);let M={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(M.port!==void 0&&(!Number.isInteger(M.port)||M.port<1||M.port>65535))return b({ok:!1,error:"Port must be a number between 1 and 65535."},422);let F=await Li(k,"utf8"),X=On({configText:F,name:l,root:M.root,domain:M.domain,path:M.path,deploy:M.deploy,build:M.build,start:M.start,port:M.port,type:M.type});return await ls(k,X),aA(o,l,Object.fromEntries(Object.entries(M).filter(([,j])=>j!==void 0))),Lt=await ps(o,ye),W.set(ye,Lt),b({ok:!0,configPath:k,site:l,data:Lt})}if(L.pathname==="/api/sites"&&I.method==="DELETE"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??L.searchParams.get("name")??"").trim();if(!l||!o.sites?.[l])return b({ok:!1,error:`Site '${l}' was not found.`},404);let T=await Li(k,"utf8");return await ls(k,Sm({configText:T,name:l})),delete o.sites[l],Lt=await ps(o,ye),W.set(ye,Lt),b({ok:!0,configPath:k,site:l,data:Lt})}if(L.pathname==="/api/sites"&&I.method==="PATCH"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??"").trim(),T=o.sites?.[l];if(!l||!T)return b({ok:!1,error:`Site '${l}' was not found.`},404);if(Tn.role==="member"){let X=Oy(d);if(!X.ok)return b({ok:!1,error:X.error},403);let j=_y({siteName:l,body:d,sites:o.sites??{},ownSites:Object.keys(Tn.sites)});if(!j.ok)return b({ok:!1,error:j.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 b({ok:!1,error:"Port must be a number between 1 and 65535."},422);if(typeof d.domain==="string"&&d.domain.trim()&&!_u(d.domain.trim()))return b({ok:!1,error:`Domain '${d.domain.trim()}' is not a valid hostname.`},422);let M=await Li(k,"utf8"),F=(X,j)=>{M=vm({configText:M,siteName:l,key:X,valueText:j})};if(d.ssl!==void 0)F("ssl",wm(d.ssl)),T.ssl=d.ssl;if(d.env!==void 0&&d.env&&typeof d.env==="object")F("env",Cm(d.env)),T.env=d.env;if(d.aliases!==void 0&&Array.isArray(d.aliases)){let X=d.aliases.map((j)=>String(j));F("aliases",Em(X)),T.aliases=X.map((j)=>j.trim().toLowerCase()).filter(Boolean)}if(d.redirects!==void 0&&d.redirects&&typeof d.redirects==="object")F("redirects",Tm(d.redirects)),T.redirects=d.redirects;for(let X of["domain","path","build","start","type","root","php"])if(typeof d[X]==="string"&&d[X].trim())F(X,Im(String(d[X]).trim())),T[X]=String(d[X]).trim();if(d.port!==void 0&&d.port!==null&&d.port!=="")F("port",String(Number(d.port))),T.port=Number(d.port);return await ls(k,M),Lt=await ps(o,ye),W.set(ye,Lt),b({ok:!0,configPath:k,site:l,data:Lt})}if(L.pathname==="/api/sites/deploy"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim();if(!l||!o.sites?.[l])return b({ok:!1,error:`Site '${l}' was not found.`},404);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to deploy this site.`},409);let T=ue(a,String(ye));await new rs(rt).run(new Ra,{...T,artifactRoot:t}),rd(rt,T,Lt??{});let M=lr(rt,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(M.decision.outcome==="block")return b({ok:!1,error:`Deployment blocked by security policy: ${M.decision.explanation}`,securityReview:M},409);let F={id:`deploy:${l}`,label:`Deploy ${l}`,description:`Deploy the ${l} site for ${ye}.`,command:["deploy","--env",ye,"--site",l,"--yes"],mutates:!0},X=await zi({controlPlane:a,environment:ye,actor:ae,kind:"dashboard.site.deploy",resourceSlug:l,input:{site:l},execute:()=>ap(F,{cwd:t,cliEntry:i})});return b({...X.result,controlPlaneOperation:X.operation,securityReview:M})}if(L.pathname==="/api/actions")return b(wb(ye));if(L.pathname==="/api/server/operations")return b(Kr(o,Lt));if(L.pathname==="/api/runtime/workloads"&&I.method==="GET"){let d=await wi(o,ye);return b(d)}if(L.pathname==="/api/runtime/logs"&&I.method==="GET"){let d=String(L.searchParams.get("workload")??"");if(!d)return b({ok:!1,error:"A workload query parameter is required."},422);let l=Math.min(1000,Math.max(1,Number(L.searchParams.get("limit"))||200));try{return b(await new Ce(o,ye).logs(d,{limit:l}))}catch(T){return b({ok:!1,error:String(T?.message??T)},404)}}if(L.pathname==="/api/runtime/log-sessions"&&I.method==="POST"){let d=await ie(I),l=String(d.workloadId??"");if(!l)return b({ok:!1,error:"A workloadId is required."},422);let T=await wi(o,ye),M=T.workloads.find((j)=>j.id===l);if(!M)return b({ok:!1,error:"Workload was not found in the current project and environment."},404);if(!M.capabilities.logs.supported)return b({ok:!1,error:M.capabilities.logs.reason??"Logs are unsupported for this workload."},409);let F=new Ce(o,ye,{inventory:async()=>T}),X=Yt.create("logs",l);return(async()=>{let j=new Date(Date.now()-Math.min(3600000,Math.max(1000,Number(d.sinceMs)||60000)));try{for(let Z=0;Z<200&&!Yt.signal(X.id)?.aborted;Z++){let me=await F.logs(l,{limit:Math.min(500,Math.max(1,Number(d.limit)||200)),since:j});for(let le of me.lines)if(Yt.append(X.id,`${le.timestamp?`${le.timestamp} `:""}${le.message}
|
|
498
|
-
`),le.timestamp)
|
|
499
|
-
`,"system"),Z.stdout)Yt.append(j.id,Z.stdout,"stdout");if(Z.stderr)Yt.append(j.id,Z.stderr,"stderr");Yt.close(j.id,Z.ok?"complete":"failed",Z.error)}).catch((Z)=>{let me=Z instanceof Error?Z.message:String(Z);Yt.append(j.id,me,"stderr"),Yt.close(j.id,"failed",me)}),b({ok:!0,session:j,streamUrl:`/api/runtime/exec-stream?id=${encodeURIComponent(j.id)}&workload=${encodeURIComponent(l)}`},202)}if(L.pathname==="/api/runtime/files/read"&&I.method==="POST"){let d=await ie(I),l=await wi(o,ye),T=Ft.resolveSession(I),M=await new Ce(o,ye,{inventory:async()=>l}).readFile({workloadId:String(d.workloadId??""),path:String(d.path??""),confirm:String(d.confirm??""),recentAuth:!Re||!!T&&we.isRecentlyAuthenticated(T)});return b(M,M.ok?200:409)}if(L.pathname==="/api/runtime/files/write"&&I.method==="POST"){let d=await ie(I),l=await wi(o,ye),T=String(d.workloadId??""),M=l.workloads.find((Z)=>Z.id===T);if(!M)return b({ok:!1,error:"Workload was not found in the current project and environment."},404);let F=Ft.resolveSession(I),X=new Ce(o,ye,{inventory:async()=>l}),j=await zi({controlPlane:a,environment:ye,actor:ae,kind:"runtime.file.write",resourceSlug:M.links.service,input:{workloadId:T,provider:M.provider,path:String(d.path??""),bytes:Buffer.from(String(d.contentBase64??""),"base64").byteLength},execute:()=>X.writeFile({workloadId:T,path:String(d.path??""),contentBase64:String(d.contentBase64??""),confirm:String(d.confirm??""),recentAuth:!Re||!!F&&we.isRecentlyAuthenticated(F)})});return b({...j.result,controlPlaneOperation:j.operation},j.result.ok?200:409)}if(L.pathname==="/api/runtime/operations"&&I.method==="POST"){let d=await ie(I),l=String(d.workloadId??""),T=String(d.action??"");if(!l||!["start","stop","restart","redeploy","scale","inspect"].includes(T))return b({ok:!1,error:"A valid workloadId and lifecycle action are required."},422);let M=await wi(o,ye),F=M.workloads.find((me)=>me.id===l);if(!F)return b({ok:!1,error:"Workload was not found in the current project and environment."},404);let X=Ft.resolveSession(I),j=new Ce(o,ye,{inventory:async()=>M}),Z=await zi({controlPlane:a,environment:ye,actor:ae,kind:`runtime.${T}`,resourceSlug:F.links.service,input:{workloadId:l,provider:F.provider,action:T,replicas:d.replicas==null?null:Number(d.replicas)},execute:()=>j.run({workloadId:l,action:T,replicas:d.replicas==null?void 0:Number(d.replicas),confirm:String(d.confirm??""),recentAuth:!Re||!!X&&we.isRecentlyAuthenticated(X)})});return b({...Z.result,controlPlaneOperation:Z.operation},Z.result.ok?200:409)}if(L.pathname.startsWith("/api/protection")){let d=ae.role==="admin"||Ga(ae,"security:read"),l=ae.role==="admin"||Ga(ae,"security:manage");if(!d)return b({ok:!1,error:"Protection controls require security:read."},403);let{ProtectionControlStore:T,describePosture:M}=await import("./chunk-nnrta1g9.js"),F=new T(a.store),X=()=>{if(!l)throw Error("Changing protection controls requires security:manage.")};if(L.pathname==="/api/protection"&&I.method==="GET"){let j=F.current();return b({ok:!0,posture:M(j),controls:j,raw:F.raw()})}if(L.pathname==="/api/protection/attack-mode"&&I.method==="POST"){X();let j=await ie(I);if(j.enabled===!1)return b({ok:!0,disabled:F.disableAttackMode()});return b({ok:!0,control:F.enableAttackMode({hours:j.hours==null?void 0:Number(j.hours),reason:String(j.reason??"Enabled from the dashboard."),actorId:_e(ae).actor?.id})})}if(L.pathname==="/api/protection/pause"&&I.method==="POST"){X();let j=await ie(I);if(j.enabled===!1)return b({ok:!0,resumed:F.resumeMitigations()});return b({ok:!0,control:F.pauseMitigations({hours:j.hours==null?void 0:Number(j.hours),reason:String(j.reason??""),actorId:_e(ae).actor?.id})})}if(L.pathname==="/api/protection/ip-rules"&&I.method==="GET")return b({ok:!0,ipRules:F.current().ipRules});if(L.pathname==="/api/protection/ip-rules"&&(I.method==="POST"||I.method==="DELETE")){X();let j=await ie(I),Z=j.list==="allow"?"allow":"block",me=I.method==="POST"?F.addIpRule(Z,String(j.cidr??"")):F.removeIpRule(Z,String(j.cidr??""));return b({ok:!0,ipRules:me})}return b({ok:!1,error:"Protection endpoint was not found."},404)}if(L.pathname.startsWith("/api/spend/")||L.pathname==="/api/usage"){let d=await Ab(),{store:l,service:T,gate:M}=d,F=ae.role==="admin"||Ga(ae,"billing:read"),X=ae.role==="admin"||Ga(ae,"billing:manage");if(!F)return b({ok:!1,error:"Spend data requires the billing:read capability."},403);let j=a.environments.get(ye),Z={organizationId:a.organization.id,projectId:a.project.id,environmentId:j?.id},me=()=>{if(!X)throw Error("Changing a budget requires the billing:manage capability.")};if(L.pathname==="/api/usage"&&I.method==="GET")return b({ok:!0,...T.usageReport({organizationId:Z.organizationId,projectId:Z.projectId,period:L.searchParams.get("period")??"monthly",timezone:L.searchParams.get("timezone")??void 0})});if(L.pathname==="/api/spend/budgets"&&I.method==="GET")return b({ok:!0,budgets:l.listBudgets({organizationId:Z.organizationId,projectId:Z.projectId}).map((le)=>({...le,status:T.status(le)}))});if(L.pathname==="/api/spend/budgets"&&I.method==="POST"){me();let le=await ie(I),Ge=String(le.scope??"project"),be=l.createBudget({organizationId:Z.organizationId,projectId:Ge==="organization"?void 0:Z.projectId,environmentId:Ge==="environment"?Z.environmentId:void 0,name:String(le.name??"").trim(),period:le.period??"monthly",timezone:le.timezone?String(le.timezone):void 0,softLimitCents:le.softLimitCents==null?void 0:Math.round(Number(le.softLimitCents)),hardLimitCents:le.hardLimitCents==null?void 0:Math.round(Number(le.hardLimitCents)),graceSeconds:le.graceSeconds==null?void 0:Number(le.graceSeconds),dryRun:le.dryRun!==!1});return b({ok:!0,budget:be})}if(L.pathname==="/api/spend/budgets"&&I.method==="PATCH"){me();let le=await ie(I),Ge=String(le.id??""),be=l.getBudget(Ge);if(!be||be.organizationId!==Z.organizationId)return b({ok:!1,error:"Budget was not found."},404);return b({ok:!0,budget:l.updateBudget(Ge,{softLimitCents:le.softLimitCents==null?be.softLimitCents:Math.round(Number(le.softLimitCents)),hardLimitCents:le.hardLimitCents==null?be.hardLimitCents:Math.round(Number(le.hardLimitCents)),enabled:le.enabled==null?be.enabled:le.enabled===!0,dryRun:le.dryRun==null?be.dryRun:le.dryRun===!0},le.expectedVersion==null?void 0:Number(le.expectedVersion))})}if(L.pathname==="/api/spend/budgets"&&I.method==="DELETE"){me();let le=await ie(I),Ge=String(le.id??""),be=l.getBudget(Ge);if(!be||be.organizationId!==Z.organizationId)return b({ok:!1,error:"Budget was not found."},404);let Ne=M.closeBudget(Ge);return l.deleteBudget(Ge),b({ok:!0,deleted:!0,lifted:Ne})}if(L.pathname==="/api/spend/check"&&I.method==="POST"){me();let le=await ie(I),{SpendRunner:Ge}=await import("./chunk-4fkmd2ce.js"),be=new Ge({controlPlane:a.store,store:l,alerts:Je});if(le.apply!==!0){let Se=l.budgetsForScope(Z.organizationId,Z.projectId,Z.environmentId);return b({ok:!0,applied:!1,preview:Se.map((Ae)=>T.status(Ae))})}let Ne=await be.run({...Z,environmentKind:j?.kind});return b({ok:!0,applied:!0,result:Ne})}if(L.pathname==="/api/spend/enforcement"&&I.method==="GET")return b({ok:!0,enforcement:M.listUnder({organizationId:Z.organizationId})});if(L.pathname==="/api/spend/release"&&I.method==="POST"){me();let le=await ie(I),Ge=M.close(String(le.budgetId??""),le.action);return b({ok:Ge,released:Ge,note:Ge?"The next spend cycle re-applies this if spend is still over the threshold.":"That action was not in force."})}if(L.pathname==="/api/spend/anomalies"&&I.method==="GET")return b({ok:!0,anomalies:l.listAnomalies({organizationId:Z.organizationId,projectId:Z.projectId,unacknowledgedOnly:L.searchParams.get("unacknowledged")==="true"})});if(L.pathname==="/api/spend/anomalies/acknowledge"&&I.method==="POST"){me();let le=await ie(I);return b({ok:!0,acknowledged:l.acknowledgeAnomaly(String(le.id??""))})}return b({ok:!1,error:"Spend endpoint was not found."},404)}if(L.pathname.startsWith("/api/health/")||L.pathname.startsWith("/api/alerts")||L.pathname.startsWith("/api/notifications/")){let d=a.environments.get(ye),l=a.store.listResources(a.project.id,d?.id),T=ae.role==="admin"||!!d&&la(ae,d.id,"runtime:read")?l:l.filter((j)=>yr(ae,j.id,"runtime:read")),M=(j)=>!j||T.some((Z)=>Z.id===j),F=(j)=>{if(!j)return;let Z=l.find((me)=>me.id===j||me.slug===j);if(!Z)throw Error("Alert resource was not found.");if(!M(Z.id))throw Error("Alert resource is outside your authorized scope.");return Z.id},X=_e(ae).actor;if(L.pathname==="/api/health/checks"&&I.method==="GET")return b({ok:!0,checks:Je.listHealthChecks(a.project.id,d?.id).filter((j)=>M(j.resourceId)).map((j)=>({...j,results:Je.listHealthResults(j.id,20)}))});if(L.pathname==="/api/health/checks"&&I.method==="POST"){let j=await ie(I),Z=String(j.kind??"http");if(Z==="command"&&ae.role!=="admin")return b({ok:!1,error:"Command health checks require an administrator."},403);let me={method:String(j.config?.method??"GET").toUpperCase().slice(0,10),path:j.config?.path?String(j.config.path).slice(0,500):void 0,port:j.config?.port==null?void 0:Number(j.config.port),command:Array.isArray(j.config?.command)?j.config.command.map(String).slice(0,20):void 0,expectedStatuses:Array.isArray(j.config?.expectedStatuses)?j.config.expectedStatuses.map(Number).filter(Number.isInteger).slice(0,20):void 0,expectedBody:j.config?.expectedBody?String(j.config.expectedBody).slice(0,500):void 0};return b({ok:!0,check:Je.createHealthCheck({projectId:a.project.id,environmentId:d?.id,resourceId:F(j.resourceId??j.resource),name:String(j.name??""),kind:Z,target:String(j.target??""),config:me,intervalSeconds:Number(j.intervalSeconds)||60,timeoutSeconds:Number(j.timeoutSeconds)||10,failureThreshold:Number(j.failureThreshold)||3,recoveryThreshold:Number(j.recoveryThreshold)||2,regions:Array.isArray(j.regions)?j.regions.map(String):["local"],enabled:j.enabled!==!1})},201)}if(L.pathname==="/api/health/checks"&&I.method==="PATCH"){let j=await ie(I),Z=Je.getHealthCheck(String(j.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Health check was not found."},404);return b({ok:!0,check:Je.setHealthCheckEnabled(Z.id,j.enabled!==!1)})}if(L.pathname==="/api/health/checks/test"&&I.method==="POST"){let j=await ie(I),Z=Je.getHealthCheck(String(j.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Health check was not found."},404);return b({ok:!0,productionIncidentCreated:!1,result:await new Be(Je).probe(Z)})}if(L.pathname==="/api/health/checks/run"&&I.method==="POST"){let j=await ie(I),Z=Je.getHealthCheck(String(j.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Health check was not found."},404);let me=await new Be(Je).runAndEvaluate(Z),le=[];for(let Ge of me.evaluations.filter((be)=>be.notify&&be.alert)){let be=En.enqueue(a.organization.id,Ge.alert,Ge.transition);le.push(...await En.deliverAll(be))}return b({ok:!0,...me,deliveries:le})}if(L.pathname==="/api/alerts/rules"&&I.method==="GET")return b({ok:!0,rules:Je.listRules(a.project.id,d?.id).filter((j)=>M(j.resourceId))});if(L.pathname==="/api/alerts/rules"&&I.method==="POST"){let j=await ie(I),Z=j.healthCheckId?Je.getHealthCheck(String(j.healthCheckId)):void 0;if(j.healthCheckId&&(!Z||!M(Z.resourceId)))return b({ok:!1,error:"Health check was not found."},404);return b({ok:!0,rule:Je.createRule({projectId:a.project.id,environmentId:d?.id,resourceId:F(j.resourceId??j.resource)??Z?.resourceId,healthCheckId:Z?.id,name:String(j.name??""),signal:String(j.signal??(Z?"health":"")),operator:String(j.operator??(Z?"unhealthy":"gt")),threshold:j.threshold==null?void 0:Number(j.threshold),recoveryThreshold:j.recoveryThreshold==null?void 0:Number(j.recoveryThreshold),windowMs:Number(j.windowMs)||300000,consecutive:Number(j.consecutive)||Z?.failureThreshold||3,recoveryConsecutive:Number(j.recoveryConsecutive)||Z?.recoveryThreshold||2,noDataPolicy:["ignore","pending","firing"].includes(String(j.noDataPolicy))?j.noDataPolicy:"pending",severity:["info","warning","critical"].includes(String(j.severity))?j.severity:"warning",groupBy:Array.isArray(j.groupBy)?j.groupBy.map(String):[],labels:j.labels&&typeof j.labels==="object"?j.labels:{},enabled:j.enabled!==!1})},201)}if(L.pathname==="/api/alerts/rules"&&I.method==="PATCH"){let j=await ie(I),Z=Je.getRule(String(j.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Alert rule was not found."},404);return b({ok:!0,rule:Je.setRuleEnabled(Z.id,j.enabled!==!1)})}if(L.pathname==="/api/alerts/evaluate"&&I.method==="POST")return b({ok:!0,...await hp(d?.id)});if(L.pathname==="/api/alerts"&&I.method==="GET")return b({ok:!0,alerts:Je.listAlerts(a.project.id,{environmentId:d?.id,states:L.searchParams.getAll("state").length?L.searchParams.getAll("state"):void 0,limit:Number(L.searchParams.get("limit"))||200}).filter((j)=>M(j.resourceId)).map((j)=>({...j,deliveries:Je.listDeliveries({alertId:j.id,limit:50})}))});if(L.pathname==="/api/alerts/action"&&I.method==="POST"){let j=await ie(I),Z=Je.getAlert(String(j.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Alert was not found."},404);let me=String(j.action??"");if(me==="acknowledge")return b({ok:!0,alert:Je.acknowledge(Z.id,X?.id??"")});if(me==="assign")return b({ok:!0,alert:Je.assign(Z.id,j.ownerActorId==="me"?X?.id:j.ownerActorId?String(j.ownerActorId):void 0,X?.id)});if(me==="silence"){if(ae.role!=="admin")return b({ok:!1,error:"Silencing production alerts requires an administrator."},403);let le=Ft.resolveSession(I);if(Re&&(!le||!we.isRecentlyAuthenticated(le)))return b({ok:!1,error:"Recent authentication is required to silence alerts.",stepUpRequired:!0},401);return b({ok:!0,alert:Je.silenceAlert(Z.id,String(j.until??""),X?.id)})}return b({ok:!1,error:"Action must be acknowledge, assign, or silence."},422)}if(L.pathname==="/api/alerts/silences"&&I.method==="POST"){let j=await ie(I);return b({ok:!0,id:Je.createSilence({projectId:a.project.id,environmentId:d?.id,resourceId:F(j.resourceId??j.resource),matcher:j.matcher,reason:String(j.reason??""),startsAt:String(j.startsAt??new Date().toISOString()),endsAt:String(j.endsAt??""),timezone:String(j.timezone??"UTC"),actorId:X?.id})},201)}if(L.pathname==="/api/notifications/channels"&&I.method==="GET")return b({ok:!0,channels:Je.listChannels(a.organization.id)});if(L.pathname==="/api/notifications/channels"&&I.method==="POST"){let j=await ie(I),Z=String(j.kind??""),me=Z==="email"?{to:j.config?.to,from:j.config?.from}:Z==="telegram"?{chatId:String(j.config?.chatId??"")}:{};return b({ok:!0,channel:Je.createChannel({organizationId:a.organization.id,name:String(j.name??""),kind:Z,config:me,credential:j.credential?String(j.credential):void 0,actorId:X?.id})},201)}if(L.pathname==="/api/notifications/channels"&&I.method==="PATCH"){let j=await ie(I),Z=String(j.id??"");if(j.credential)return b({ok:!0,channel:Je.rotateChannel(Z,String(j.credential))});let me=String(j.status??"paused");if(!["active","paused","disabled"].includes(me))return b({ok:!1,error:"Channel status must be active, paused, or disabled."},422);return b({ok:!0,channel:Je.setChannelStatus(Z,me)})}if(L.pathname==="/api/notifications/channels/test"&&I.method==="POST"){let j=await ie(I);return b({ok:!0,productionIncidentCreated:!1,result:await En.testChannel(String(j.id??""))})}if(L.pathname==="/api/notifications/routes"&&I.method==="GET")return b({ok:!0,routes:Je.listRoutes(a.organization.id)});if(L.pathname==="/api/notifications/routes"&&I.method==="POST"){let j=await ie(I),Z=Array.isArray(j.channelIds)?j.channelIds.map(String):[];if(Z.some((me)=>Je.getChannel(me)?.organizationId!==a.organization.id))return b({ok:!1,error:"Route contains an unavailable channel."},422);return b({ok:!0,route:Je.createRoute({organizationId:a.organization.id,name:String(j.name??""),priority:Number(j.priority)||0,matcher:j.matcher&&typeof j.matcher==="object"?j.matcher:{},channelIds:Z,quietHours:j.quietHours,groupWaitSeconds:Number(j.groupWaitSeconds)||30,reminderSeconds:j.reminderSeconds==null?void 0:Number(j.reminderSeconds),escalation:Array.isArray(j.escalation)?j.escalation:[],template:j.template?String(j.template):void 0,rateLimitPerMinute:Number(j.rateLimitPerMinute)||60,enabled:j.enabled!==!1})},201)}if(L.pathname==="/api/notifications/routes"&&I.method==="PATCH"){let j=await ie(I),Z=Je.getRoute(String(j.id??""));if(!Z||Z.organizationId!==a.organization.id)return b({ok:!1,error:"Notification route was not found."},404);return b({ok:!0,route:Je.setRouteEnabled(Z.id,j.enabled!==!1)})}if(L.pathname==="/api/notifications/routes/preview"&&I.method==="POST"){let j=await ie(I),me=(j.alertId?Je.getAlert(String(j.alertId)):void 0)??{id:"preview",ruleId:"preview",projectId:a.project.id,environmentId:d?.id,resourceId:F(j.resourceId??j.resource),dedupKey:"preview",groupKey:String(j.groupKey??"default"),state:"firing",severity:["info","warning","critical"].includes(String(j.severity))?j.severity:"warning",title:String(j.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 b({ok:!0,productionIncidentCreated:!1,matches:En.preview(a.organization.id,me,String(j.eventType??"firing")).map((le)=>({route:le.route,channels:le.channels,quiet:le.quiet}))})}if(L.pathname==="/api/notifications/deliveries"&&I.method==="GET")return b({ok:!0,deliveries:Je.listDeliveries({alertId:L.searchParams.get("alertId")??void 0,states:L.searchParams.getAll("state"),limit:Number(L.searchParams.get("limit"))||200})});if(L.pathname==="/api/notifications/deliveries/retry"&&I.method==="POST"){let j=await ie(I),Z=Je.getDelivery(String(j.id??""));if(!Z)return b({ok:!1,error:"Delivery was not found."},404);return Je.updateDelivery(Z.id,{state:"retrying",attempt:Math.max(0,Z.attempt-1),nextAttemptAt:new Date().toISOString()}),b({ok:!0,delivery:await En.deliver(Z.id)})}}if(L.pathname.startsWith("/api/jobs")||L.pathname.startsWith("/api/workers")){let d=a.environments.get(ye),l=a.store.listResources(a.project.id,d?.id),M=ae.role==="admin"||!!d&&la(ae,d.id,"automation:read")?l:l.filter((Se)=>yr(ae,Se.id,"automation:read")),F=(Se)=>!Se||M.some((Ae)=>Ae.id===Se),X=_e(ae).actor,j=W.get(ye)??D,Z=Kr(o,j),me=Z.filter((Se)=>!Se.danger&&["scheduler","backup","worker"].includes(Se.group)),le=H(o),Ge=()=>{let Se=Ft.resolveSession(I);return!Re||!!Se&&we.isRecentlyAuthenticated(Se)},be=(Se)=>{if(!Se||typeof Se!=="object"||Array.isArray(Se))return{};let Ae=Object.entries(Se).slice(0,50);if(Ae.some(([,Qe])=>typeof Qe!=="string"||!/^(?:secret|ssm|arn|env):\/\//.test(Qe)))throw Error("Job payload values must be secret or environment references, never inline values.");return Object.fromEntries(Ae)},Ne=(Se,Ae,Qe)=>a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,resourceId:Qe,actorId:X?.id,type:`job.${Se}`,payload:Ae});if(L.pathname==="/api/jobs/preview"&&I.method==="POST"){let Se=await ie(I);try{return b({ok:!0,productionExecutionCreated:!1,preview:ut(String(Se.expression??""),String(Se.timezone??"UTC"),new Date(Se.from?String(Se.from):Date.now()),Number(Se.count)||5)})}catch(Ae){return b({ok:!1,error:Ae instanceof Error?Ae.message:"Schedule preview could not be generated.",productionExecutionCreated:!1},422)}}if(L.pathname==="/api/jobs"&&I.method==="GET")return b({ok:!0,jobs:hr.list(a.project.id,{environmentId:d?.id}).filter((Se)=>F(Se.resourceId)).map((Se)=>({...Se,preview:ut(Se.normalizedExpression,Se.timezone,new Date,5),capability:oi(Se),lastExecution:hr.listExecutions(Se.id,1)[0]}))});if(L.pathname==="/api/jobs"&&I.method==="POST"){let Se=await ie(I),Ae=String(Se.provider??(le==="serverless"?"eventbridge":"server")),Qe=le==="serverless"?"eventbridge":"server";if(Ae!==Qe)return b({ok:!1,error:`${le} environments accept ${Qe} schedules through this adapter.`},422);let ot=Se.operationId?String(Se.operationId):void 0;if(Ae==="server"&&(!ot||!me.some((Xt)=>Xt.id===ot)))return b({ok:!1,error:"Server jobs require an allowlisted operation target."},422);let St=oi({provider:Ae,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(!St.supported)return b({ok:!1,error:St.notes.join(" ")},422);let mn=Se.resourceId?l.find((Xt)=>Xt.id===Se.resourceId||Xt.slug===Se.resourceId):void 0;if(Se.resourceId&&(!mn||!F(mn.id)))return b({ok:!1,error:"Job resource was not found."},404);try{let Xt=Ae==="server"?{kind:"dashboard_operation",operationId:ot}:{kind:"serverless_scheduler",action:"run"},yo=hr.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:mn?.id,name:String(Se.name??""),provider:Ae,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:Xt,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:X?.id,observedState:{},reconciliationStatus:"pending"});return Ne("created",{jobId:yo.id,provider:yo.provider,expression:yo.normalizedExpression},yo.resourceId),b({ok:!0,job:yo,capability:St},201)}catch(Xt){return b({ok:!1,error:Xt instanceof Error?Xt.message:"Scheduled job could not be created."},422)}}if(L.pathname==="/api/jobs"&&I.method==="PATCH"){let Se=await ie(I),Ae=hr.get(String(Se.id??""));if(!Ae||!F(Ae.resourceId))return b({ok:!1,error:"Scheduled job was not found."},404);if(Ae.origin==="config")return b({ok:!1,error:"Config-defined schedules must be edited in cloud.config.ts and reconciled."},409);let Qe=Se.missedRunPolicy==null?void 0:String(Se.missedRunPolicy),ot=Se.overlapPolicy==null?void 0:String(Se.overlapPolicy);if(Qe&&!["skip","catch_up"].includes(Qe))return b({ok:!1,error:"Missed-run policy must be skip or catch_up."},422);if(ot&&!["allow","forbid","replace"].includes(ot))return b({ok:!1,error:"Overlap policy must be allow, forbid, or replace."},422);try{let St=hr.updateSchedule(Ae.id,{expression:Se.expression?String(Se.expression):void 0,timezone:Se.timezone?String(Se.timezone):void 0,missedRunPolicy:Qe,overlapPolicy:ot,timeoutSeconds:Se.timeoutSeconds==null?void 0:Number(Se.timeoutSeconds)});return Ne("updated",{jobId:St.id,expression:St.normalizedExpression,version:St.version},St.resourceId),b({ok:!0,job:St})}catch(St){return b({ok:!1,error:St instanceof Error?St.message:"Scheduled job could not be updated."},422)}}if(L.pathname==="/api/jobs/action"&&I.method==="POST"){let Se=await ie(I),Ae=hr.get(String(Se.id??""));if(!Ae||!F(Ae.resourceId))return b({ok:!1,error:"Scheduled job was not found."},404);let Qe=String(Se.action??"");if(Qe==="run"){let ot=fp.enqueue(Ae,{trigger:"manual",actorId:X?.id});return Ne("run_queued",{jobId:Ae.id,executionId:ot.id},Ae.resourceId),b({ok:!0,execution:ot},202)}if(["disable","delete"].includes(Qe)&&d?.kind==="production"){if(String(Se.confirm??"")!==Qe)return b({ok:!1,error:`Type "${Qe}" to confirm this production change.`},409);if(!Ge())return b({ok:!1,error:"Recent authentication is required for this production change.",stepUpRequired:!0},401)}if(Qe==="enable"||Qe==="disable"){let ot=hr.setEnabled(Ae.id,Qe==="enable");return Ne(Qe==="enable"?"enabled":"disabled",{jobId:Ae.id},Ae.resourceId),b({ok:!0,job:ot})}if(Qe==="delete")try{return hr.remove(Ae.id),Ne("deleted",{jobId:Ae.id,name:Ae.name},Ae.resourceId),b({ok:!0,deleted:Ae.id})}catch(ot){return b({ok:!1,error:ot instanceof Error?ot.message:"Scheduled job could not be deleted."},409)}return b({ok:!1,error:"Action must be run, enable, disable, or delete."},422)}if(L.pathname==="/api/jobs/history"&&I.method==="GET"){let Se=hr.get(String(L.searchParams.get("jobId")??""));if(!Se||!F(Se.resourceId))return b({ok:!1,error:"Scheduled job was not found."},404);return b({ok:!0,executions:hr.listExecutions(Se.id,Number(L.searchParams.get("limit"))||100).map((Ae)=>({...Ae,logs:Ae.operationId?At.logs(Ae.operationId,{limit:500}):[]}))})}if(L.pathname==="/api/jobs/reconcile"&&I.method==="POST"){if(!d)return b({ok:!1,error:"Environment was not found."},404);let Se=Qr(hr,o,{organization:a.organization,project:a.project,environment:d,resources:l});return Ne("reconciled",Se),b({ok:!0,reconciliation:Se})}if(L.pathname==="/api/workers"&&I.method==="GET"){let Se=Array.isArray(j.workersDetail??j.workers)?j.workersDetail??j.workers:[];return b({ok:!0,workers:hr.listWorkers(a.project.id,d?.id).filter((Ae)=>F(Ae.resourceId)).map((Ae)=>{let Qe=Se.find((ot)=>ot.name===Ae.name||ot.site===Ae.target.site);return Qe?{...Ae,observedState:{...Ae.observedState,status:Qe.status??"configured",currentJob:Qe.currentJob??null,failures:Number(Qe.failed??Qe.failures)||0,processed:Number(Qe.processed)||0}}:Ae})})}if(L.pathname==="/api/workers/action"&&I.method==="POST"){let Se=await ie(I),Ae=hr.getWorker(String(Se.id??""));if(!Ae||!F(Ae.resourceId))return b({ok:!1,error:"Worker was not found."},404);let Qe=String(Se.action??"");if(Qe==="restart"){if(String(Se.confirm??"")!==Ae.name)return b({ok:!1,error:`Type "${Ae.name}" to restart this worker.`},409);let ot=Z.find((Xt)=>Xt.id===Ae.target.operationId);if(!ot)return b({ok:!1,error:"The allowlisted worker restart operation is unavailable."},409);let St=await Jr(o,ye,ot),mn=hr.reconcileWorker(Ae.id,St.ok?"in_sync":"unavailable",{...Ae.observedState,lastRestartAt:new Date().toISOString(),command:St.command??null,error:St.error??St.stderr??null});return Ne("worker_restarted",{workerId:Ae.id,ok:St.ok},Ae.resourceId),b({...St,worker:mn},St.ok?200:409)}if(Qe==="scale")return b({ok:!1,error:Ae.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 b({ok:!1,error:"Action must be restart or scale."},422)}}if(L.pathname.startsWith("/api/telemetry/")){let d=a.environments.get(ye),l=new tt(a.store),T=a.store.listResources(a.project.id,d?.id),M=["/api/telemetry/query","/api/telemetry/tail","/api/telemetry/export","/api/telemetry/saved-queries","/api/telemetry/refresh"].includes(L.pathname)?"runtime:logs":"runtime:read",F=ae.role==="admin"||!!d&&la(ae,d.id,M),X=F?T:T.filter((be)=>yr(ae,be.id,M)),j=(be)=>Zy(X,F,be),Z=(be)=>{let Ne=new Date,Se={"1h":3600000,"6h":21600000,"24h":86400000,"7d":604800000,"30d":2592000000},Ae=String(be.to??Ne.toISOString()),Qe=String(be.from??new Date(new Date(Ae).getTime()-(Se[String(be.range??"1h")]??Se["1h"])).toISOString()),ot=(mn)=>{let Xt=(Array.isArray(mn)?mn:String(mn??"").split(",")).map(String).filter(Boolean);return Xt.length?Xt:void 0},St=ot(be.kinds)?.filter((mn)=>["metric","log","trace","request","event"].includes(mn));return{projectId:a.project.id,environmentId:d?.id,resourceIds:j(be.resources),kinds:St,names:ot(be.names),sources:ot(be.sources),levels:ot(be.levels),from:Qe,to:Ae,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}},me=Object.fromEntries(L.searchParams.entries()),le=(be=!1)=>li({controlPlane:a.store,projectId:a.project.id,environmentId:d?.id,config:o,environment:ye,force:be,lightweight:!be}),Ge=()=>{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??et(a.store,a.project.id)}};if(L.pathname==="/api/telemetry/status"&&I.method==="GET"){le(!1);let be=Ge(),Ne=F?be.statuses:l.status(a.project.id,d?.id,be.policy.rawDays,be.policy.samplingRate,X.map((Ae)=>Ae.id)),Se=Ne.reduce((Ae,Qe)=>Ae+Qe.estimatedDailyBytes*30,0);return b({ok:!0,generatedAt:be.generatedAt,cached:be.cached,sources:Ne,errors:F?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:Ti(Se,be.policy),costEstimateConfigured:be.policy.estimatedStorageUsdPerGbMonth>0})}if(L.pathname==="/api/telemetry/settings"&&I.method==="GET")return b({ok:!0,policy:et(a.store,a.project.id)});if(L.pathname==="/api/telemetry/settings"&&I.method==="PATCH"){let be=Ci(a.store,a.project.id,await ie(I));return sb(a.project.id),b({ok:!0,policy:be})}if(L.pathname==="/api/telemetry/query"&&I.method==="GET"){le(!1);let be=Ge();return b({ok:!0,collection:{generatedAt:be.generatedAt,cached:be.cached},...l.query(Z(me))})}if(L.pathname==="/api/telemetry/tail"&&I.method==="GET"){le(!1);let be=new TextEncoder,Ne=new Date,Se=Z({...me,kinds:me.kinds||"log,request,event,trace",from:me.from||new Date(Ne.getTime()-120000).toISOString(),to:Ne.toISOString(),limit:Math.min(1000,Number(me.limit)||200),cursor:void 0}),Ae=I.headers.get("last-event-id")||String(me.cursor??"")||void 0,Qe,ot=!1,St=!1,mn=new ReadableStream({start(Xt){let yo=()=>{if(ot)return;if(ot=!0,Qe)clearInterval(Qe);I.signal.removeEventListener("abort",yo);try{Xt.close()}catch{}},Rp=async()=>{if(ot||St)return;St=!0;try{let Uo=l.tail({...Se,to:new Date(Date.now()+1000).toISOString()},Ae);for(let Pp of Uo.records)Ae=uo(Pp)??Ae,Xt.enqueue(be.encode(`id: ${Ae??""}
|
|
497
|
+
This replacement link expires ${T.invitation.expiresAt} and can be used once.`});return b({invitation:T.invitation,token:T.token,acceptUrl:M,delivered:j})}catch(T){return b({ok:!1,error:T instanceof Error?T.message:"Invitation could not be resent."},409)}}if(F.pathname==="/api/organization/memberships"&&I.method==="PATCH"){let d=await ie(I),l=a.store.getMembership(String(d.id??"")),T=Td(d.roleTemplate),M=Ba(d);if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Membership was not found."},404);if(!T||!M)return b({ok:!1,error:"Choose a valid role template and resource scope."},422);let j=_e(ae);if((l.roleTemplate==="owner"||T==="owner")&&(!Ii(String(d.password??""),ae.passwordHash)||j.membership?.roleTemplate!=="owner"))return b({ok:!1,error:"Ownership changes require an owner to re-enter their password."},401);let U=a.store.resolveAuthorizationTarget(a.organization.id,M)??a.store.resolveAuthorizationTarget(a.organization.id,{type:"project",id:a.project.id}),Z=a.store.listGrants(l.id),me=vn({membership:l,grants:Z,target:U}),le={...l,roleTemplate:T,scope:M},qe=vn({membership:le,grants:Z,target:U}),be={gained:qe.filter((Ne)=>!me.includes(Ne)),lost:me.filter((Ne)=>!qe.includes(Ne))};if(d.preview===!0)return b({membership:l,proposed:{roleTemplate:T,scope:M},accessDiff:be});if(String(d.confirm??"")!==l.id)return b({ok:!1,error:`Confirm this change with membership ID ${l.id}.`,accessDiff:be},409);try{return b({membership:a.store.updateMembership({id:l.id,roleTemplate:T,scope:M,actorId:j.actor?.id}),accessDiff:be})}catch(Ne){return b({ok:!1,error:Ne instanceof Error?Ne.message:"Membership could not be updated."},409)}}if(F.pathname==="/api/organization/memberships"&&I.method==="DELETE"){let d=await ie(I),l=a.store.getMembership(String(d.id??""));if(!l||l.organizationId!==a.organization.id)return b({ok:!1,error:"Membership was not found."},404);if(String(d.confirm??"")!==l.id)return b({ok:!1,error:`Confirm removal with membership ID ${l.id}.`},409);let T=_e(ae);if(l.roleTemplate==="owner"&&(T.membership?.roleTemplate!=="owner"||!Ii(String(d.password??""),ae.passwordHash)))return b({ok:!1,error:"Removing an owner requires an owner to re-enter their current password."},401);try{return b({membership:a.store.revokeMembership(l.id,T.actor?.id)})}catch(M){return b({ok:!1,error:M instanceof Error?M.message:"Membership could not be removed."},409)}}if(F.pathname==="/api/organization/grants"&&I.method==="POST"){let d=await ie(I),l=String(d.capability??""),T=d.effect==="deny"?"deny":d.effect==="allow"?"allow":void 0,M=Ba(d),j=_e(ae);if(!T||!M||!ce.includes(l))return b({ok:!1,error:"Choose a valid capability, effect, and resource scope."},422);try{return b({grant:a.store.upsertGrant({organizationId:a.organization.id,membershipId:String(d.membershipId??""),effect:T,capability:l,scope:M,actorId:j.actor?.id})},201)}catch(X){return b({ok:!1,error:X instanceof Error?X.message:"Grant could not be created."},422)}}if(F.pathname==="/api/organization/grants"&&I.method==="DELETE"){let d=await ie(I),l=_e(ae),T=a.store.getGrant(String(d.id??""));if(!T||T.organizationId!==a.organization.id)return b({ok:!1,error:"Grant was not found."},404);return b({ok:a.store.removeGrant(T.id,l.actor?.id)})}if(F.pathname==="/api/tags"&&I.method==="GET")return b({tags:a.store.listTags(a.project.id),assignments:a.store.listResourceTags(a.project.id)});if(F.pathname==="/api/tags"&&I.method==="POST"){let d=await ie(I),l=a.store.upsertTag(a.project.id,String(d.name??""),String(d.color??"#5a8be0"));if(d.resourceId)a.store.assignTag(String(d.resourceId),l.id);return b({tag:l},201)}if(F.pathname==="/api/tags"&&I.method==="DELETE"){let d=await ie(I);return a.store.removeTag(String(d.resourceId??""),String(d.tagId??"")),b({ok:!0})}if(F.pathname==="/"&&!fb(F.pathname,Tn))return new Response(null,{status:302,headers:{location:`/server/sites?env=${encodeURIComponent(ye)}`}});if(F.pathname==="/"&&Lt?.mode==="serverless")return new Response(null,{status:302,headers:{location:`/serverless?env=${encodeURIComponent(ye)}`}});let Ja=ky(F.pathname);if(Ja)return new Response(null,{status:308,headers:{location:`${Ja}?env=${encodeURIComponent(ye)}`}});if(F.pathname==="/api/env"&&I.method==="POST"){let d=await ie(I),l=String(d.env??"");if(!f.includes(l))return b({ok:!1,error:`Unknown environment '${l}'.`,environments:f},404);return b({ok:!0,environment:l,environments:f,href:`?env=${encodeURIComponent(l)}`})}if(F.pathname==="/api/config"){let d={...fA(o),environment:ye,environments:f};return b(Py(d,Tn))}if(F.pathname==="/api/ssh-keys"&&I.method==="GET")return b({configPath:k,keys:$t(da(o))});if(F.pathname==="/api/ssh-keys"&&I.method==="POST"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=await Li(k,"utf8"),T=da(o),M=fc({configText:l,name:String(d.name??""),publicKey:String(d.publicKey??""),existingKeys:T});return await ls(k,M),lb(o,[...T,{name:String(d.name??"").trim(),publicKey:String(d.publicKey??"").trim().replace(/\s+/g," ")}]),b({ok:!0,configPath:k,keys:$t(da(o))})}if(F.pathname==="/api/ssh-keys"&&I.method==="DELETE"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??F.searchParams.get("name")??""),T=await Li(k,"utf8"),M=da(o),j=hc({configText:T,name:l,existingKeys:M});return await ls(k,j),lb(o,M.filter((X)=>X.name!==l.trim())),b({ok:!0,configPath:k,keys:$t(da(o))})}if(F.pathname==="/api/firewall"&&I.method==="GET")return b({configPath:k,alwaysOpen:[22,80,443],ports:sp(o)});if(F.pathname==="/api/firewall"&&I.method==="POST"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=Number(d.port);if(!$a(l))return b({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=sp(o),M=await Li(k,"utf8");try{await ls(k,$y(M,l,T))}catch(U){return b({ok:!1,error:U?.message??String(U)},422)}let j=us([...T,l]);pb(o,j);let X=d.apply===!1?null:await cr(o,ye,`ufw allow ${l}/tcp`).catch((U)=>({ok:!1,error:String(U?.message??U)}));return b({ok:!0,configPath:k,ports:j,apply:X})}if(F.pathname==="/api/firewall"&&I.method==="DELETE"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=Number(d.port??F.searchParams.get("port"));if(!$a(l))return b({ok:!1,error:"Port must be an integer between 1 and 65535."},422);let T=sp(o),M=await Li(k,"utf8");await ls(k,Ly(M,l,T));let j=us(T.filter((U)=>U!==l));pb(o,j);let X=d.apply===!1?null:await cr(o,ye,`ufw delete allow ${l}/tcp`).catch((U)=>({ok:!1,error:String(U?.message??U)}));return b({ok:!0,configPath:k,ports:j,apply:X})}if(F.pathname==="/api/sites"&&I.method==="POST"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??"").trim(),T=String(d.root??"").trim();if(!l||!T)return b({ok:!1,error:"Site name and root are required."},422);let M={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(M.port!==void 0&&(!Number.isInteger(M.port)||M.port<1||M.port>65535))return b({ok:!1,error:"Port must be a number between 1 and 65535."},422);let j=await Li(k,"utf8"),X=On({configText:j,name:l,root:M.root,domain:M.domain,path:M.path,deploy:M.deploy,build:M.build,start:M.start,port:M.port,type:M.type});return await ls(k,X),aA(o,l,Object.fromEntries(Object.entries(M).filter(([,U])=>U!==void 0))),Lt=await ps(o,ye),W.set(ye,Lt),b({ok:!0,configPath:k,site:l,data:Lt})}if(F.pathname==="/api/sites"&&I.method==="DELETE"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??F.searchParams.get("name")??"").trim();if(!l||!o.sites?.[l])return b({ok:!1,error:`Site '${l}' was not found.`},404);let T=await Li(k,"utf8");return await ls(k,Sm({configText:T,name:l})),delete o.sites[l],Lt=await ps(o,ye),W.set(ye,Lt),b({ok:!0,configPath:k,site:l,data:Lt})}if(F.pathname==="/api/sites"&&I.method==="PATCH"){if(!k)return b({ok:!1,error:"No cloud config file was found in this checkout."},404);let d=await ie(I),l=String(d.name??"").trim(),T=o.sites?.[l];if(!l||!T)return b({ok:!1,error:`Site '${l}' was not found.`},404);if(Tn.role==="member"){let X=Oy(d);if(!X.ok)return b({ok:!1,error:X.error},403);let U=_y({siteName:l,body:d,sites:o.sites??{},ownSites:Object.keys(Tn.sites)});if(!U.ok)return b({ok:!1,error:U.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 b({ok:!1,error:"Port must be a number between 1 and 65535."},422);if(typeof d.domain==="string"&&d.domain.trim()&&!_u(d.domain.trim()))return b({ok:!1,error:`Domain '${d.domain.trim()}' is not a valid hostname.`},422);let M=await Li(k,"utf8"),j=(X,U)=>{M=vm({configText:M,siteName:l,key:X,valueText:U})};if(d.ssl!==void 0)j("ssl",wm(d.ssl)),T.ssl=d.ssl;if(d.env!==void 0&&d.env&&typeof d.env==="object")j("env",Cm(d.env)),T.env=d.env;if(d.aliases!==void 0&&Array.isArray(d.aliases)){let X=d.aliases.map((U)=>String(U));j("aliases",Em(X)),T.aliases=X.map((U)=>U.trim().toLowerCase()).filter(Boolean)}if(d.redirects!==void 0&&d.redirects&&typeof d.redirects==="object")j("redirects",Tm(d.redirects)),T.redirects=d.redirects;for(let X of["domain","path","build","start","type","root","php"])if(typeof d[X]==="string"&&d[X].trim())j(X,Im(String(d[X]).trim())),T[X]=String(d[X]).trim();if(d.port!==void 0&&d.port!==null&&d.port!=="")j("port",String(Number(d.port))),T.port=Number(d.port);return await ls(k,M),Lt=await ps(o,ye),W.set(ye,Lt),b({ok:!0,configPath:k,site:l,data:Lt})}if(F.pathname==="/api/sites/deploy"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim();if(!l||!o.sites?.[l])return b({ok:!1,error:`Site '${l}' was not found.`},404);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to deploy this site.`},409);let T=ue(a,String(ye));await new rs(rt).run(new Ra,{...T,artifactRoot:t}),rd(rt,T,Lt??{});let M=dr(rt,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(M.decision.outcome==="block")return b({ok:!1,error:`Deployment blocked by security policy: ${M.decision.explanation}`,securityReview:M},409);let j={id:`deploy:${l}`,label:`Deploy ${l}`,description:`Deploy the ${l} site for ${ye}.`,command:["deploy","--env",ye,"--site",l,"--yes"],mutates:!0},X=await zi({controlPlane:a,environment:ye,actor:ae,kind:"dashboard.site.deploy",resourceSlug:l,input:{site:l},execute:()=>ap(j,{cwd:t,cliEntry:i})});return b({...X.result,controlPlaneOperation:X.operation,securityReview:M})}if(F.pathname==="/api/actions")return b(wb(ye));if(F.pathname==="/api/server/operations")return b(Kr(o,Lt));if(F.pathname==="/api/runtime/workloads"&&I.method==="GET"){let d=await wi(o,ye);return b(d)}if(F.pathname==="/api/runtime/logs"&&I.method==="GET"){let d=String(F.searchParams.get("workload")??"");if(!d)return b({ok:!1,error:"A workload query parameter is required."},422);let l=Math.min(1000,Math.max(1,Number(F.searchParams.get("limit"))||200));try{return b(await new Ce(o,ye).logs(d,{limit:l}))}catch(T){return b({ok:!1,error:String(T?.message??T)},404)}}if(F.pathname==="/api/runtime/log-sessions"&&I.method==="POST"){let d=await ie(I),l=String(d.workloadId??"");if(!l)return b({ok:!1,error:"A workloadId is required."},422);let T=await wi(o,ye),M=T.workloads.find((U)=>U.id===l);if(!M)return b({ok:!1,error:"Workload was not found in the current project and environment."},404);if(!M.capabilities.logs.supported)return b({ok:!1,error:M.capabilities.logs.reason??"Logs are unsupported for this workload."},409);let j=new Ce(o,ye,{inventory:async()=>T}),X=Xt.create("logs",l);return(async()=>{let U=new Date(Date.now()-Math.min(3600000,Math.max(1000,Number(d.sinceMs)||60000)));try{for(let Z=0;Z<200&&!Xt.signal(X.id)?.aborted;Z++){let me=await j.logs(l,{limit:Math.min(500,Math.max(1,Number(d.limit)||200)),since:U});for(let le of me.lines)if(Xt.append(X.id,`${le.timestamp?`${le.timestamp} `:""}${le.message}
|
|
498
|
+
`),le.timestamp)U=new Date(Math.max(U.getTime(),new Date(le.timestamp).getTime()+1));await Bun.sleep(3000)}if(!Xt.signal(X.id)?.aborted)Xt.close(X.id,"complete")}catch(Z){Xt.append(X.id,Z instanceof Error?Z.message:String(Z),"stderr"),Xt.close(X.id,"failed",Z instanceof Error?Z.message:String(Z))}})(),b({ok:!0,session:X,streamUrl:`/api/runtime/log-stream?id=${encodeURIComponent(X.id)}&workload=${encodeURIComponent(l)}`},201)}if((F.pathname==="/api/runtime/log-stream"||F.pathname==="/api/runtime/exec-stream")&&I.method==="GET"){let d=String(F.searchParams.get("id")??""),l=String(F.searchParams.get("workload")??""),T=Number(I.headers.get("last-event-id")??F.searchParams.get("after")??0)||0,M=Xt.read(d,l,T),j=F.pathname.includes("exec")?"exec":"logs";if(!M||M.kind!==j)return b({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return XT(Xt,M,T,I.signal)}if((F.pathname==="/api/runtime/log-sessions"||F.pathname==="/api/runtime/exec-sessions")&&I.method==="DELETE"){let d=await ie(I),l=Xt.cancel(String(d.id??""),String(d.workloadId??""));if(!l)return b({ok:!1,error:"Runtime stream was not found in this workload scope."},404);return b({ok:!0,session:l})}if(F.pathname==="/api/runtime/exec-sessions"&&I.method==="POST"){let d=await ie(I),l=String(d.workloadId??""),T=await wi(o,ye),M=T.workloads.find((Z)=>Z.id===l);if(!M)return b({ok:!1,error:"Workload was not found in the current project and environment."},404);let j=Ft.resolveSession(I),X=new Ce(o,ye,{inventory:async()=>T}),U=Xt.create("exec",l);return zi({controlPlane:a,environment:ye,actor:ae,kind:"runtime.exec",resourceSlug:M.links.service,input:{workloadId:l,provider:M.provider,preset:d.preset?String(d.preset):null,freeForm:!!String(d.command??"").trim()},execute:()=>X.exec({workloadId:l,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||!!j&&we.isRecentlyAuthenticated(j)})}).then(({result:Z,operation:me})=>{if(Xt.append(U.id,`operation ${me.id}
|
|
499
|
+
`,"system"),Z.stdout)Xt.append(U.id,Z.stdout,"stdout");if(Z.stderr)Xt.append(U.id,Z.stderr,"stderr");Xt.close(U.id,Z.ok?"complete":"failed",Z.error)}).catch((Z)=>{let me=Z instanceof Error?Z.message:String(Z);Xt.append(U.id,me,"stderr"),Xt.close(U.id,"failed",me)}),b({ok:!0,session:U,streamUrl:`/api/runtime/exec-stream?id=${encodeURIComponent(U.id)}&workload=${encodeURIComponent(l)}`},202)}if(F.pathname==="/api/runtime/files/read"&&I.method==="POST"){let d=await ie(I),l=await wi(o,ye),T=Ft.resolveSession(I),M=await new Ce(o,ye,{inventory:async()=>l}).readFile({workloadId:String(d.workloadId??""),path:String(d.path??""),confirm:String(d.confirm??""),recentAuth:!Re||!!T&&we.isRecentlyAuthenticated(T)});return b(M,M.ok?200:409)}if(F.pathname==="/api/runtime/files/write"&&I.method==="POST"){let d=await ie(I),l=await wi(o,ye),T=String(d.workloadId??""),M=l.workloads.find((Z)=>Z.id===T);if(!M)return b({ok:!1,error:"Workload was not found in the current project and environment."},404);let j=Ft.resolveSession(I),X=new Ce(o,ye,{inventory:async()=>l}),U=await zi({controlPlane:a,environment:ye,actor:ae,kind:"runtime.file.write",resourceSlug:M.links.service,input:{workloadId:T,provider:M.provider,path:String(d.path??""),bytes:Buffer.from(String(d.contentBase64??""),"base64").byteLength},execute:()=>X.writeFile({workloadId:T,path:String(d.path??""),contentBase64:String(d.contentBase64??""),confirm:String(d.confirm??""),recentAuth:!Re||!!j&&we.isRecentlyAuthenticated(j)})});return b({...U.result,controlPlaneOperation:U.operation},U.result.ok?200:409)}if(F.pathname==="/api/runtime/operations"&&I.method==="POST"){let d=await ie(I),l=String(d.workloadId??""),T=String(d.action??"");if(!l||!["start","stop","restart","redeploy","scale","inspect"].includes(T))return b({ok:!1,error:"A valid workloadId and lifecycle action are required."},422);let M=await wi(o,ye),j=M.workloads.find((me)=>me.id===l);if(!j)return b({ok:!1,error:"Workload was not found in the current project and environment."},404);let X=Ft.resolveSession(I),U=new Ce(o,ye,{inventory:async()=>M}),Z=await zi({controlPlane:a,environment:ye,actor:ae,kind:`runtime.${T}`,resourceSlug:j.links.service,input:{workloadId:l,provider:j.provider,action:T,replicas:d.replicas==null?null:Number(d.replicas)},execute:()=>U.run({workloadId:l,action:T,replicas:d.replicas==null?void 0:Number(d.replicas),confirm:String(d.confirm??""),recentAuth:!Re||!!X&&we.isRecentlyAuthenticated(X)})});return b({...Z.result,controlPlaneOperation:Z.operation},Z.result.ok?200:409)}if(F.pathname.startsWith("/api/protection")){let d=ae.role==="admin"||Ga(ae,"security:read"),l=ae.role==="admin"||Ga(ae,"security:manage");if(!d)return b({ok:!1,error:"Protection controls require security:read."},403);let{ProtectionControlStore:T,describePosture:M}=await import("./chunk-pntcdh4x.js"),j=new T(a.store),X=()=>{if(!l)throw Error("Changing protection controls requires security:manage.")};if(F.pathname==="/api/protection"&&I.method==="GET"){let U=j.current();return b({ok:!0,posture:M(U),controls:U,raw:j.raw()})}if(F.pathname==="/api/protection/attack-mode"&&I.method==="POST"){X();let U=await ie(I);if(U.enabled===!1)return b({ok:!0,disabled:j.disableAttackMode()});return b({ok:!0,control:j.enableAttackMode({hours:U.hours==null?void 0:Number(U.hours),reason:String(U.reason??"Enabled from the dashboard."),actorId:_e(ae).actor?.id})})}if(F.pathname==="/api/protection/pause"&&I.method==="POST"){X();let U=await ie(I);if(U.enabled===!1)return b({ok:!0,resumed:j.resumeMitigations()});return b({ok:!0,control:j.pauseMitigations({hours:U.hours==null?void 0:Number(U.hours),reason:String(U.reason??""),actorId:_e(ae).actor?.id})})}if(F.pathname==="/api/protection/ip-rules"&&I.method==="GET")return b({ok:!0,ipRules:j.current().ipRules});if(F.pathname==="/api/protection/ip-rules"&&(I.method==="POST"||I.method==="DELETE")){X();let U=await ie(I),Z=U.list==="allow"?"allow":"block",me=I.method==="POST"?j.addIpRule(Z,String(U.cidr??"")):j.removeIpRule(Z,String(U.cidr??""));return b({ok:!0,ipRules:me})}return b({ok:!1,error:"Protection endpoint was not found."},404)}if(F.pathname.startsWith("/api/spend/")||F.pathname==="/api/usage"){let d=await Ab(),{store:l,service:T,gate:M}=d,j=ae.role==="admin"||Ga(ae,"billing:read"),X=ae.role==="admin"||Ga(ae,"billing:manage");if(!j)return b({ok:!1,error:"Spend data requires the billing:read capability."},403);let U=a.environments.get(ye),Z={organizationId:a.organization.id,projectId:a.project.id,environmentId:U?.id},me=()=>{if(!X)throw Error("Changing a budget requires the billing:manage capability.")};if(F.pathname==="/api/usage"&&I.method==="GET")return b({ok:!0,...T.usageReport({organizationId:Z.organizationId,projectId:Z.projectId,period:F.searchParams.get("period")??"monthly",timezone:F.searchParams.get("timezone")??void 0})});if(F.pathname==="/api/spend/budgets"&&I.method==="GET")return b({ok:!0,budgets:l.listBudgets({organizationId:Z.organizationId,projectId:Z.projectId}).map((le)=>({...le,status:T.status(le)}))});if(F.pathname==="/api/spend/budgets"&&I.method==="POST"){me();let le=await ie(I),qe=String(le.scope??"project"),be=l.createBudget({organizationId:Z.organizationId,projectId:qe==="organization"?void 0:Z.projectId,environmentId:qe==="environment"?Z.environmentId:void 0,name:String(le.name??"").trim(),period:le.period??"monthly",timezone:le.timezone?String(le.timezone):void 0,softLimitCents:le.softLimitCents==null?void 0:Math.round(Number(le.softLimitCents)),hardLimitCents:le.hardLimitCents==null?void 0:Math.round(Number(le.hardLimitCents)),graceSeconds:le.graceSeconds==null?void 0:Number(le.graceSeconds),dryRun:le.dryRun!==!1});return b({ok:!0,budget:be})}if(F.pathname==="/api/spend/budgets"&&I.method==="PATCH"){me();let le=await ie(I),qe=String(le.id??""),be=l.getBudget(qe);if(!be||be.organizationId!==Z.organizationId)return b({ok:!1,error:"Budget was not found."},404);return b({ok:!0,budget:l.updateBudget(qe,{softLimitCents:le.softLimitCents==null?be.softLimitCents:Math.round(Number(le.softLimitCents)),hardLimitCents:le.hardLimitCents==null?be.hardLimitCents:Math.round(Number(le.hardLimitCents)),enabled:le.enabled==null?be.enabled:le.enabled===!0,dryRun:le.dryRun==null?be.dryRun:le.dryRun===!0},le.expectedVersion==null?void 0:Number(le.expectedVersion))})}if(F.pathname==="/api/spend/budgets"&&I.method==="DELETE"){me();let le=await ie(I),qe=String(le.id??""),be=l.getBudget(qe);if(!be||be.organizationId!==Z.organizationId)return b({ok:!1,error:"Budget was not found."},404);let Ne=M.closeBudget(qe);return l.deleteBudget(qe),b({ok:!0,deleted:!0,lifted:Ne})}if(F.pathname==="/api/spend/check"&&I.method==="POST"){me();let le=await ie(I),{SpendRunner:qe}=await import("./chunk-37gemrn2.js"),be=new qe({controlPlane:a.store,store:l,alerts:Je});if(le.apply!==!0){let Se=l.budgetsForScope(Z.organizationId,Z.projectId,Z.environmentId);return b({ok:!0,applied:!1,preview:Se.map((Ae)=>T.status(Ae))})}let Ne=await be.run({...Z,environmentKind:U?.kind});return b({ok:!0,applied:!0,result:Ne})}if(F.pathname==="/api/spend/enforcement"&&I.method==="GET")return b({ok:!0,enforcement:M.listUnder({organizationId:Z.organizationId})});if(F.pathname==="/api/spend/release"&&I.method==="POST"){me();let le=await ie(I),qe=M.close(String(le.budgetId??""),le.action);return b({ok:qe,released:qe,note:qe?"The next spend cycle re-applies this if spend is still over the threshold.":"That action was not in force."})}if(F.pathname==="/api/spend/anomalies"&&I.method==="GET")return b({ok:!0,anomalies:l.listAnomalies({organizationId:Z.organizationId,projectId:Z.projectId,unacknowledgedOnly:F.searchParams.get("unacknowledged")==="true"})});if(F.pathname==="/api/spend/anomalies/acknowledge"&&I.method==="POST"){me();let le=await ie(I);return b({ok:!0,acknowledged:l.acknowledgeAnomaly(String(le.id??""))})}return b({ok:!1,error:"Spend endpoint was not found."},404)}if(F.pathname.startsWith("/api/health/")||F.pathname.startsWith("/api/alerts")||F.pathname.startsWith("/api/notifications/")){let d=a.environments.get(ye),l=a.store.listResources(a.project.id,d?.id),T=ae.role==="admin"||!!d&&la(ae,d.id,"runtime:read")?l:l.filter((U)=>br(ae,U.id,"runtime:read")),M=(U)=>!U||T.some((Z)=>Z.id===U),j=(U)=>{if(!U)return;let Z=l.find((me)=>me.id===U||me.slug===U);if(!Z)throw Error("Alert resource was not found.");if(!M(Z.id))throw Error("Alert resource is outside your authorized scope.");return Z.id},X=_e(ae).actor;if(F.pathname==="/api/health/checks"&&I.method==="GET")return b({ok:!0,checks:Je.listHealthChecks(a.project.id,d?.id).filter((U)=>M(U.resourceId)).map((U)=>({...U,results:Je.listHealthResults(U.id,20)}))});if(F.pathname==="/api/health/checks"&&I.method==="POST"){let U=await ie(I),Z=String(U.kind??"http");if(Z==="command"&&ae.role!=="admin")return b({ok:!1,error:"Command health checks require an administrator."},403);let me={method:String(U.config?.method??"GET").toUpperCase().slice(0,10),path:U.config?.path?String(U.config.path).slice(0,500):void 0,port:U.config?.port==null?void 0:Number(U.config.port),command:Array.isArray(U.config?.command)?U.config.command.map(String).slice(0,20):void 0,expectedStatuses:Array.isArray(U.config?.expectedStatuses)?U.config.expectedStatuses.map(Number).filter(Number.isInteger).slice(0,20):void 0,expectedBody:U.config?.expectedBody?String(U.config.expectedBody).slice(0,500):void 0};return b({ok:!0,check:Je.createHealthCheck({projectId:a.project.id,environmentId:d?.id,resourceId:j(U.resourceId??U.resource),name:String(U.name??""),kind:Z,target:String(U.target??""),config:me,intervalSeconds:Number(U.intervalSeconds)||60,timeoutSeconds:Number(U.timeoutSeconds)||10,failureThreshold:Number(U.failureThreshold)||3,recoveryThreshold:Number(U.recoveryThreshold)||2,regions:Array.isArray(U.regions)?U.regions.map(String):["local"],enabled:U.enabled!==!1})},201)}if(F.pathname==="/api/health/checks"&&I.method==="PATCH"){let U=await ie(I),Z=Je.getHealthCheck(String(U.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Health check was not found."},404);return b({ok:!0,check:Je.setHealthCheckEnabled(Z.id,U.enabled!==!1)})}if(F.pathname==="/api/health/checks/test"&&I.method==="POST"){let U=await ie(I),Z=Je.getHealthCheck(String(U.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Health check was not found."},404);return b({ok:!0,productionIncidentCreated:!1,result:await new Be(Je).probe(Z)})}if(F.pathname==="/api/health/checks/run"&&I.method==="POST"){let U=await ie(I),Z=Je.getHealthCheck(String(U.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Health check was not found."},404);let me=await new Be(Je).runAndEvaluate(Z),le=[];for(let qe of me.evaluations.filter((be)=>be.notify&&be.alert)){let be=En.enqueue(a.organization.id,qe.alert,qe.transition);le.push(...await En.deliverAll(be))}return b({ok:!0,...me,deliveries:le})}if(F.pathname==="/api/alerts/rules"&&I.method==="GET")return b({ok:!0,rules:Je.listRules(a.project.id,d?.id).filter((U)=>M(U.resourceId))});if(F.pathname==="/api/alerts/rules"&&I.method==="POST"){let U=await ie(I),Z=U.healthCheckId?Je.getHealthCheck(String(U.healthCheckId)):void 0;if(U.healthCheckId&&(!Z||!M(Z.resourceId)))return b({ok:!1,error:"Health check was not found."},404);return b({ok:!0,rule:Je.createRule({projectId:a.project.id,environmentId:d?.id,resourceId:j(U.resourceId??U.resource)??Z?.resourceId,healthCheckId:Z?.id,name:String(U.name??""),signal:String(U.signal??(Z?"health":"")),operator:String(U.operator??(Z?"unhealthy":"gt")),threshold:U.threshold==null?void 0:Number(U.threshold),recoveryThreshold:U.recoveryThreshold==null?void 0:Number(U.recoveryThreshold),windowMs:Number(U.windowMs)||300000,consecutive:Number(U.consecutive)||Z?.failureThreshold||3,recoveryConsecutive:Number(U.recoveryConsecutive)||Z?.recoveryThreshold||2,noDataPolicy:["ignore","pending","firing"].includes(String(U.noDataPolicy))?U.noDataPolicy:"pending",severity:["info","warning","critical"].includes(String(U.severity))?U.severity:"warning",groupBy:Array.isArray(U.groupBy)?U.groupBy.map(String):[],labels:U.labels&&typeof U.labels==="object"?U.labels:{},enabled:U.enabled!==!1})},201)}if(F.pathname==="/api/alerts/rules"&&I.method==="PATCH"){let U=await ie(I),Z=Je.getRule(String(U.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Alert rule was not found."},404);return b({ok:!0,rule:Je.setRuleEnabled(Z.id,U.enabled!==!1)})}if(F.pathname==="/api/alerts/evaluate"&&I.method==="POST")return b({ok:!0,...await hp(d?.id)});if(F.pathname==="/api/alerts"&&I.method==="GET")return b({ok:!0,alerts:Je.listAlerts(a.project.id,{environmentId:d?.id,states:F.searchParams.getAll("state").length?F.searchParams.getAll("state"):void 0,limit:Number(F.searchParams.get("limit"))||200}).filter((U)=>M(U.resourceId)).map((U)=>({...U,deliveries:Je.listDeliveries({alertId:U.id,limit:50})}))});if(F.pathname==="/api/alerts/action"&&I.method==="POST"){let U=await ie(I),Z=Je.getAlert(String(U.id??""));if(!Z||!M(Z.resourceId))return b({ok:!1,error:"Alert was not found."},404);let me=String(U.action??"");if(me==="acknowledge")return b({ok:!0,alert:Je.acknowledge(Z.id,X?.id??"")});if(me==="assign")return b({ok:!0,alert:Je.assign(Z.id,U.ownerActorId==="me"?X?.id:U.ownerActorId?String(U.ownerActorId):void 0,X?.id)});if(me==="silence"){if(ae.role!=="admin")return b({ok:!1,error:"Silencing production alerts requires an administrator."},403);let le=Ft.resolveSession(I);if(Re&&(!le||!we.isRecentlyAuthenticated(le)))return b({ok:!1,error:"Recent authentication is required to silence alerts.",stepUpRequired:!0},401);return b({ok:!0,alert:Je.silenceAlert(Z.id,String(U.until??""),X?.id)})}return b({ok:!1,error:"Action must be acknowledge, assign, or silence."},422)}if(F.pathname==="/api/alerts/silences"&&I.method==="POST"){let U=await ie(I);return b({ok:!0,id:Je.createSilence({projectId:a.project.id,environmentId:d?.id,resourceId:j(U.resourceId??U.resource),matcher:U.matcher,reason:String(U.reason??""),startsAt:String(U.startsAt??new Date().toISOString()),endsAt:String(U.endsAt??""),timezone:String(U.timezone??"UTC"),actorId:X?.id})},201)}if(F.pathname==="/api/notifications/channels"&&I.method==="GET")return b({ok:!0,channels:Je.listChannels(a.organization.id)});if(F.pathname==="/api/notifications/channels"&&I.method==="POST"){let U=await ie(I),Z=String(U.kind??""),me=Z==="email"?{to:U.config?.to,from:U.config?.from}:Z==="telegram"?{chatId:String(U.config?.chatId??"")}:{};return b({ok:!0,channel:Je.createChannel({organizationId:a.organization.id,name:String(U.name??""),kind:Z,config:me,credential:U.credential?String(U.credential):void 0,actorId:X?.id})},201)}if(F.pathname==="/api/notifications/channels"&&I.method==="PATCH"){let U=await ie(I),Z=String(U.id??"");if(U.credential)return b({ok:!0,channel:Je.rotateChannel(Z,String(U.credential))});let me=String(U.status??"paused");if(!["active","paused","disabled"].includes(me))return b({ok:!1,error:"Channel status must be active, paused, or disabled."},422);return b({ok:!0,channel:Je.setChannelStatus(Z,me)})}if(F.pathname==="/api/notifications/channels/test"&&I.method==="POST"){let U=await ie(I);return b({ok:!0,productionIncidentCreated:!1,result:await En.testChannel(String(U.id??""))})}if(F.pathname==="/api/notifications/routes"&&I.method==="GET")return b({ok:!0,routes:Je.listRoutes(a.organization.id)});if(F.pathname==="/api/notifications/routes"&&I.method==="POST"){let U=await ie(I),Z=Array.isArray(U.channelIds)?U.channelIds.map(String):[];if(Z.some((me)=>Je.getChannel(me)?.organizationId!==a.organization.id))return b({ok:!1,error:"Route contains an unavailable channel."},422);return b({ok:!0,route:Je.createRoute({organizationId:a.organization.id,name:String(U.name??""),priority:Number(U.priority)||0,matcher:U.matcher&&typeof U.matcher==="object"?U.matcher:{},channelIds:Z,quietHours:U.quietHours,groupWaitSeconds:Number(U.groupWaitSeconds)||30,reminderSeconds:U.reminderSeconds==null?void 0:Number(U.reminderSeconds),escalation:Array.isArray(U.escalation)?U.escalation:[],template:U.template?String(U.template):void 0,rateLimitPerMinute:Number(U.rateLimitPerMinute)||60,enabled:U.enabled!==!1})},201)}if(F.pathname==="/api/notifications/routes"&&I.method==="PATCH"){let U=await ie(I),Z=Je.getRoute(String(U.id??""));if(!Z||Z.organizationId!==a.organization.id)return b({ok:!1,error:"Notification route was not found."},404);return b({ok:!0,route:Je.setRouteEnabled(Z.id,U.enabled!==!1)})}if(F.pathname==="/api/notifications/routes/preview"&&I.method==="POST"){let U=await ie(I),me=(U.alertId?Je.getAlert(String(U.alertId)):void 0)??{id:"preview",ruleId:"preview",projectId:a.project.id,environmentId:d?.id,resourceId:j(U.resourceId??U.resource),dedupKey:"preview",groupKey:String(U.groupKey??"default"),state:"firing",severity:["info","warning","critical"].includes(String(U.severity))?U.severity:"warning",title:String(U.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 b({ok:!0,productionIncidentCreated:!1,matches:En.preview(a.organization.id,me,String(U.eventType??"firing")).map((le)=>({route:le.route,channels:le.channels,quiet:le.quiet}))})}if(F.pathname==="/api/notifications/deliveries"&&I.method==="GET")return b({ok:!0,deliveries:Je.listDeliveries({alertId:F.searchParams.get("alertId")??void 0,states:F.searchParams.getAll("state"),limit:Number(F.searchParams.get("limit"))||200})});if(F.pathname==="/api/notifications/deliveries/retry"&&I.method==="POST"){let U=await ie(I),Z=Je.getDelivery(String(U.id??""));if(!Z)return b({ok:!1,error:"Delivery was not found."},404);return Je.updateDelivery(Z.id,{state:"retrying",attempt:Math.max(0,Z.attempt-1),nextAttemptAt:new Date().toISOString()}),b({ok:!0,delivery:await En.deliver(Z.id)})}}if(F.pathname.startsWith("/api/jobs")||F.pathname.startsWith("/api/workers")){let d=a.environments.get(ye),l=a.store.listResources(a.project.id,d?.id),M=ae.role==="admin"||!!d&&la(ae,d.id,"automation:read")?l:l.filter((Se)=>br(ae,Se.id,"automation:read")),j=(Se)=>!Se||M.some((Ae)=>Ae.id===Se),X=_e(ae).actor,U=W.get(ye)??D,Z=Kr(o,U),me=Z.filter((Se)=>!Se.danger&&["scheduler","backup","worker"].includes(Se.group)),le=H(o),qe=()=>{let Se=Ft.resolveSession(I);return!Re||!!Se&&we.isRecentlyAuthenticated(Se)},be=(Se)=>{if(!Se||typeof Se!=="object"||Array.isArray(Se))return{};let Ae=Object.entries(Se).slice(0,50);if(Ae.some(([,Qe])=>typeof Qe!=="string"||!/^(?:secret|ssm|arn|env):\/\//.test(Qe)))throw Error("Job payload values must be secret or environment references, never inline values.");return Object.fromEntries(Ae)},Ne=(Se,Ae,Qe)=>a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,resourceId:Qe,actorId:X?.id,type:`job.${Se}`,payload:Ae});if(F.pathname==="/api/jobs/preview"&&I.method==="POST"){let Se=await ie(I);try{return b({ok:!0,productionExecutionCreated:!1,preview:ut(String(Se.expression??""),String(Se.timezone??"UTC"),new Date(Se.from?String(Se.from):Date.now()),Number(Se.count)||5)})}catch(Ae){return b({ok:!1,error:Ae instanceof Error?Ae.message:"Schedule preview could not be generated.",productionExecutionCreated:!1},422)}}if(F.pathname==="/api/jobs"&&I.method==="GET")return b({ok:!0,jobs:yr.list(a.project.id,{environmentId:d?.id}).filter((Se)=>j(Se.resourceId)).map((Se)=>({...Se,preview:ut(Se.normalizedExpression,Se.timezone,new Date,5),capability:oi(Se),lastExecution:yr.listExecutions(Se.id,1)[0]}))});if(F.pathname==="/api/jobs"&&I.method==="POST"){let Se=await ie(I),Ae=String(Se.provider??(le==="serverless"?"eventbridge":"server")),Qe=le==="serverless"?"eventbridge":"server";if(Ae!==Qe)return b({ok:!1,error:`${le} environments accept ${Qe} schedules through this adapter.`},422);let ot=Se.operationId?String(Se.operationId):void 0;if(Ae==="server"&&(!ot||!me.some((Zt)=>Zt.id===ot)))return b({ok:!1,error:"Server jobs require an allowlisted operation target."},422);let St=oi({provider:Ae,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(!St.supported)return b({ok:!1,error:St.notes.join(" ")},422);let mn=Se.resourceId?l.find((Zt)=>Zt.id===Se.resourceId||Zt.slug===Se.resourceId):void 0;if(Se.resourceId&&(!mn||!j(mn.id)))return b({ok:!1,error:"Job resource was not found."},404);try{let Zt=Ae==="server"?{kind:"dashboard_operation",operationId:ot}:{kind:"serverless_scheduler",action:"run"},yo=yr.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:mn?.id,name:String(Se.name??""),provider:Ae,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:Zt,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:X?.id,observedState:{},reconciliationStatus:"pending"});return Ne("created",{jobId:yo.id,provider:yo.provider,expression:yo.normalizedExpression},yo.resourceId),b({ok:!0,job:yo,capability:St},201)}catch(Zt){return b({ok:!1,error:Zt instanceof Error?Zt.message:"Scheduled job could not be created."},422)}}if(F.pathname==="/api/jobs"&&I.method==="PATCH"){let Se=await ie(I),Ae=yr.get(String(Se.id??""));if(!Ae||!j(Ae.resourceId))return b({ok:!1,error:"Scheduled job was not found."},404);if(Ae.origin==="config")return b({ok:!1,error:"Config-defined schedules must be edited in cloud.config.ts and reconciled."},409);let Qe=Se.missedRunPolicy==null?void 0:String(Se.missedRunPolicy),ot=Se.overlapPolicy==null?void 0:String(Se.overlapPolicy);if(Qe&&!["skip","catch_up"].includes(Qe))return b({ok:!1,error:"Missed-run policy must be skip or catch_up."},422);if(ot&&!["allow","forbid","replace"].includes(ot))return b({ok:!1,error:"Overlap policy must be allow, forbid, or replace."},422);try{let St=yr.updateSchedule(Ae.id,{expression:Se.expression?String(Se.expression):void 0,timezone:Se.timezone?String(Se.timezone):void 0,missedRunPolicy:Qe,overlapPolicy:ot,timeoutSeconds:Se.timeoutSeconds==null?void 0:Number(Se.timeoutSeconds)});return Ne("updated",{jobId:St.id,expression:St.normalizedExpression,version:St.version},St.resourceId),b({ok:!0,job:St})}catch(St){return b({ok:!1,error:St instanceof Error?St.message:"Scheduled job could not be updated."},422)}}if(F.pathname==="/api/jobs/action"&&I.method==="POST"){let Se=await ie(I),Ae=yr.get(String(Se.id??""));if(!Ae||!j(Ae.resourceId))return b({ok:!1,error:"Scheduled job was not found."},404);let Qe=String(Se.action??"");if(Qe==="run"){let ot=fp.enqueue(Ae,{trigger:"manual",actorId:X?.id});return Ne("run_queued",{jobId:Ae.id,executionId:ot.id},Ae.resourceId),b({ok:!0,execution:ot},202)}if(["disable","delete"].includes(Qe)&&d?.kind==="production"){if(String(Se.confirm??"")!==Qe)return b({ok:!1,error:`Type "${Qe}" to confirm this production change.`},409);if(!qe())return b({ok:!1,error:"Recent authentication is required for this production change.",stepUpRequired:!0},401)}if(Qe==="enable"||Qe==="disable"){let ot=yr.setEnabled(Ae.id,Qe==="enable");return Ne(Qe==="enable"?"enabled":"disabled",{jobId:Ae.id},Ae.resourceId),b({ok:!0,job:ot})}if(Qe==="delete")try{return yr.remove(Ae.id),Ne("deleted",{jobId:Ae.id,name:Ae.name},Ae.resourceId),b({ok:!0,deleted:Ae.id})}catch(ot){return b({ok:!1,error:ot instanceof Error?ot.message:"Scheduled job could not be deleted."},409)}return b({ok:!1,error:"Action must be run, enable, disable, or delete."},422)}if(F.pathname==="/api/jobs/history"&&I.method==="GET"){let Se=yr.get(String(F.searchParams.get("jobId")??""));if(!Se||!j(Se.resourceId))return b({ok:!1,error:"Scheduled job was not found."},404);return b({ok:!0,executions:yr.listExecutions(Se.id,Number(F.searchParams.get("limit"))||100).map((Ae)=>({...Ae,logs:Ae.operationId?At.logs(Ae.operationId,{limit:500}):[]}))})}if(F.pathname==="/api/jobs/reconcile"&&I.method==="POST"){if(!d)return b({ok:!1,error:"Environment was not found."},404);let Se=Qr(yr,o,{organization:a.organization,project:a.project,environment:d,resources:l});return Ne("reconciled",Se),b({ok:!0,reconciliation:Se})}if(F.pathname==="/api/workers"&&I.method==="GET"){let Se=Array.isArray(U.workersDetail??U.workers)?U.workersDetail??U.workers:[];return b({ok:!0,workers:yr.listWorkers(a.project.id,d?.id).filter((Ae)=>j(Ae.resourceId)).map((Ae)=>{let Qe=Se.find((ot)=>ot.name===Ae.name||ot.site===Ae.target.site);return Qe?{...Ae,observedState:{...Ae.observedState,status:Qe.status??"configured",currentJob:Qe.currentJob??null,failures:Number(Qe.failed??Qe.failures)||0,processed:Number(Qe.processed)||0}}:Ae})})}if(F.pathname==="/api/workers/action"&&I.method==="POST"){let Se=await ie(I),Ae=yr.getWorker(String(Se.id??""));if(!Ae||!j(Ae.resourceId))return b({ok:!1,error:"Worker was not found."},404);let Qe=String(Se.action??"");if(Qe==="restart"){if(String(Se.confirm??"")!==Ae.name)return b({ok:!1,error:`Type "${Ae.name}" to restart this worker.`},409);let ot=Z.find((Zt)=>Zt.id===Ae.target.operationId);if(!ot)return b({ok:!1,error:"The allowlisted worker restart operation is unavailable."},409);let St=await Jr(o,ye,ot),mn=yr.reconcileWorker(Ae.id,St.ok?"in_sync":"unavailable",{...Ae.observedState,lastRestartAt:new Date().toISOString(),command:St.command??null,error:St.error??St.stderr??null});return Ne("worker_restarted",{workerId:Ae.id,ok:St.ok},Ae.resourceId),b({...St,worker:mn},St.ok?200:409)}if(Qe==="scale")return b({ok:!1,error:Ae.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 b({ok:!1,error:"Action must be restart or scale."},422)}}if(F.pathname.startsWith("/api/telemetry/")){let d=a.environments.get(ye),l=new tt(a.store),T=a.store.listResources(a.project.id,d?.id),M=["/api/telemetry/query","/api/telemetry/tail","/api/telemetry/export","/api/telemetry/saved-queries","/api/telemetry/refresh"].includes(F.pathname)?"runtime:logs":"runtime:read",j=ae.role==="admin"||!!d&&la(ae,d.id,M),X=j?T:T.filter((be)=>br(ae,be.id,M)),U=(be)=>Zy(X,j,be),Z=(be)=>{let Ne=new Date,Se={"1h":3600000,"6h":21600000,"24h":86400000,"7d":604800000,"30d":2592000000},Ae=String(be.to??Ne.toISOString()),Qe=String(be.from??new Date(new Date(Ae).getTime()-(Se[String(be.range??"1h")]??Se["1h"])).toISOString()),ot=(mn)=>{let Zt=(Array.isArray(mn)?mn:String(mn??"").split(",")).map(String).filter(Boolean);return Zt.length?Zt:void 0},St=ot(be.kinds)?.filter((mn)=>["metric","log","trace","request","event"].includes(mn));return{projectId:a.project.id,environmentId:d?.id,resourceIds:U(be.resources),kinds:St,names:ot(be.names),sources:ot(be.sources),levels:ot(be.levels),from:Qe,to:Ae,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}},me=Object.fromEntries(F.searchParams.entries()),le=(be=!1)=>li({controlPlane:a.store,projectId:a.project.id,environmentId:d?.id,config:o,environment:ye,force:be,lightweight:!be}),qe=()=>{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??et(a.store,a.project.id)}};if(F.pathname==="/api/telemetry/status"&&I.method==="GET"){le(!1);let be=qe(),Ne=j?be.statuses:l.status(a.project.id,d?.id,be.policy.rawDays,be.policy.samplingRate,X.map((Ae)=>Ae.id)),Se=Ne.reduce((Ae,Qe)=>Ae+Qe.estimatedDailyBytes*30,0);return b({ok:!0,generatedAt:be.generatedAt,cached:be.cached,sources:Ne,errors:j?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:Ti(Se,be.policy),costEstimateConfigured:be.policy.estimatedStorageUsdPerGbMonth>0})}if(F.pathname==="/api/telemetry/settings"&&I.method==="GET")return b({ok:!0,policy:et(a.store,a.project.id)});if(F.pathname==="/api/telemetry/settings"&&I.method==="PATCH"){let be=Ci(a.store,a.project.id,await ie(I));return sb(a.project.id),b({ok:!0,policy:be})}if(F.pathname==="/api/telemetry/query"&&I.method==="GET"){le(!1);let be=qe();return b({ok:!0,collection:{generatedAt:be.generatedAt,cached:be.cached},...l.query(Z(me))})}if(F.pathname==="/api/telemetry/tail"&&I.method==="GET"){le(!1);let be=new TextEncoder,Ne=new Date,Se=Z({...me,kinds:me.kinds||"log,request,event,trace",from:me.from||new Date(Ne.getTime()-120000).toISOString(),to:Ne.toISOString(),limit:Math.min(1000,Number(me.limit)||200),cursor:void 0}),Ae=I.headers.get("last-event-id")||String(me.cursor??"")||void 0,Qe,ot=!1,St=!1,mn=new ReadableStream({start(Zt){let yo=()=>{if(ot)return;if(ot=!0,Qe)clearInterval(Qe);I.signal.removeEventListener("abort",yo);try{Zt.close()}catch{}},Rp=async()=>{if(ot||St)return;St=!0;try{let Uo=l.tail({...Se,to:new Date(Date.now()+1000).toISOString()},Ae);for(let Pp of Uo.records)Ae=uo(Pp)??Ae,Zt.enqueue(be.encode(`id: ${Ae??""}
|
|
500
500
|
event: record
|
|
501
501
|
data: ${JSON.stringify(Pp)}
|
|
502
502
|
|
|
503
|
-
`));if(Uo.cursor)Ae=Uo.cursor}catch(Uo){
|
|
503
|
+
`));if(Uo.cursor)Ae=Uo.cursor}catch(Uo){Zt.enqueue(be.encode(`event: error
|
|
504
504
|
data: ${JSON.stringify({message:Uo instanceof Error?Uo.message:String(Uo)})}
|
|
505
505
|
|
|
506
|
-
`))}finally{St=!1}};Rp(),Qe=setInterval(()=>{if(Rp(),!ot)
|
|
506
|
+
`))}finally{St=!1}};Rp(),Qe=setInterval(()=>{if(Rp(),!ot)Zt.enqueue(be.encode(`event: heartbeat
|
|
507
507
|
data: ${JSON.stringify({cursor:Ae,at:new Date().toISOString()})}
|
|
508
508
|
|
|
509
|
-
`))},5000),Qe.unref?.(),I.signal.addEventListener("abort",yo,{once:!0})},cancel(){if(ot=!0,Qe)clearInterval(Qe)}});return new Response(mn,{headers:{"cache-control":"no-cache, no-transform",connection:"keep-alive","content-type":"text/event-stream; charset=utf-8","x-accel-buffering":"no"}})}if(
|
|
510
|
-
`);return new Response(Qe,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(L.pathname==="/api/telemetry/saved-queries"&&I.method==="GET"){let be=_e(ae);return b({ok:!0,queries:l.listSavedQueries(a.project.id,be.actor?.id)})}if(L.pathname==="/api/telemetry/saved-queries"&&I.method==="POST"){let be=await ie(I),Ne=_e(ae);return b({ok:!0,query:l.saveQuery(a.project.id,Ne.actor?.id,String(be.name??""),Z(be.query??be))},201)}if(L.pathname==="/api/telemetry/saved-queries"&&I.method==="DELETE"){let be=await ie(I),Ne=_e(ae),Se=l.deleteSavedQuery(a.project.id,Ne.actor?.id,String(be.id??""));return b({ok:Se},Se?200:404)}}if(L.pathname.startsWith("/api/configuration")){let d=a.environments.get(ye),l=ae.role==="admin"||!!Tn.capabilities?.includes("secrets:read"),T=ae.role==="admin"||!!Tn.capabilities?.includes("secrets:write"),M={projectId:a.project.id,environmentId:d?.id},F={"cache-control":"no-store"};if(L.pathname==="/api/configuration"&&I.method==="GET"){let X=Object.fromEntries(L.searchParams),j=X.scopeType||X.scopeId?sa(X,M):void 0,Z=["variable","secret"].includes(String(X.kind))?X.kind:void 0,me=j?.type==="preview"?Ht.previews.getInstance(j.id):void 0,le=me?Ht.previews.getDefinition(me.definitionId):void 0,Ge=j?await on.resolve({projectId:a.project.id,environmentId:j.environmentId,resourceId:j.resourceId,functionId:j.type==="function"?j.id:void 0,previewId:j.previewId,trustedPreview:!!me&&!me.fork,allowedPreviewSecrets:le?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:l}):void 0,be=a.store.listResources(a.project.id);return b({ok:!0,entries:on.list({projectId:a.project.id,scope:j,kind:Z,search:X.search,canReadSecretMetadata:l}),effectiveEntries:Ge?Object.values(Ge.entries).filter((Ne)=>!Z||Ne.kind===Z).filter((Ne)=>!X.search||Ne.key.toLowerCase().includes(String(X.search).toLowerCase())):[],configurationHash:Ge?.configurationHash,warnings:Ge?.warnings??[],scopes:{project:a.project,environments:a.store.listEnvironments(a.project.id),resources:be.filter((Ne)=>Ne.kind!=="function"),functions:be.filter((Ne)=>Ne.kind==="function"),previews:Ht.previews.listInstances({projectId:a.project.id}).filter((Ne)=>Ne.status!=="destroyed").map((Ne)=>({id:Ne.id,name:Ne.name,environmentId:Ne.baseEnvironmentId,resourceId:Ne.resourceId,fork:Ne.fork,status:Ne.status}))}},200,F)}if(L.pathname==="/api/configuration/export"&&I.method==="GET"){let X=sa(Object.fromEntries(L.searchParams),M);return new Response(on.exportVariables({projectId:a.project.id,scope:X}),{headers:{...F,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(L.pathname==="/api/configuration/plan"&&I.method==="POST"){let X=await ie(I),j=sa(X,M),Z=X.values&&typeof X.values==="object"&&!Array.isArray(X.values)?Object.fromEntries(Object.entries(X.values).map(([me,le])=>[me,String(le)])):{};return b({ok:!0,plan:on.plan({projectId:a.project.id,scope:j,values:Z,removeMissing:X.removeMissing===!0})},200,F)}if(L.pathname==="/api/configuration"&&I.method==="POST"){let X=await ie(I),j=sa(X,M),Z=X.kind==="secret"?"secret":"variable",me=String(X.key??"");if(Z==="secret"&&!T)return b({ok:!1,error:"Secret write permission is required."},403,F);try{let le=await on.set({organizationId:a.organization.id,projectId:a.project.id,scope:j,key:me,kind:Z,value:X.value==null?void 0:String(X.value),reference:X.reference==null?void 0:String(X.reference),backend:X.backend,required:X.required===!0,expectedVersion:X.expectedVersion==null?void 0:Number(X.expectedVersion),confirmed:String(X.confirm??"")===me,idempotencyKey:I.headers.get("idempotency-key")??X.idempotencyKey,actorId:_e(ae).actor?.id});return b({ok:!0,entry:on.list({projectId:a.project.id,scope:j,canReadSecretMetadata:l}).find((Ge)=>Ge.id===le.entry.id),mutation:le.mutation,warnings:le.warnings},le.mutation.added.length?201:200,F)}catch(le){return b({ok:!1,error:le instanceof Error?le.message:String(le)},409,F)}}if(L.pathname==="/api/configuration/import"&&I.method==="POST"){let X=await ie(I),j=sa(X,M),Z=Array.isArray(X.secretKeys)?X.secretKeys.map(String):[];if(Z.length&&!T)return b({ok:!1,error:"Secret write permission is required."},403,F);try{let me=await on.importDotenv({organizationId:a.organization.id,projectId:a.project.id,scope:j,source:String(X.source??""),secretKeys:Z,backend:X.backend,confirmed:X.confirm==="import",idempotencyKey:I.headers.get("idempotency-key")??X.idempotencyKey,actorId:_e(ae).actor?.id});return b({ok:me.document.valid,diagnostics:me.document.diagnostics,mutation:me.mutation,warnings:me.warnings},me.document.valid?200:422,F)}catch(me){return b({ok:!1,error:me instanceof Error?me.message:String(me)},409,F)}}if(L.pathname==="/api/configuration/dependencies"&&I.method==="POST"){let X=await ie(I),j=po.get(String(X.entryId??"")),Z=a.store.getResource(String(X.resourceId??""));if(!j||j.projectId!==a.project.id||!Z||Z.projectId!==a.project.id)return b({ok:!1,error:"Configuration entry or dependent resource was not found."},404,F);return b({ok:!0,dependency:po.setDependency({entryId:j.id,resourceId:Z.id,injectionTarget:["native_reference","file"].includes(String(X.injectionTarget))?X.injectionTarget:"environment",required:X.required!==!1,requiresRedeploy:X.requiresRedeploy!==!1,lastDeployedVersion:X.lastDeployedVersion==null?void 0:Number(X.lastDeployedVersion)})},200,F)}if(L.pathname==="/api/configuration/transfer"&&I.method==="POST"){let X=await ie(I),j=po.get(String(X.id??"")),Z=sa({...X,scopeType:X.targetScopeType,scopeId:X.targetScopeId},M);if(!j||j.projectId!==a.project.id)return b({ok:!1,error:"Configuration entry was not found."},404,F);if(j.kind==="secret"&&!T)return b({ok:!1,error:"Secret write permission is required."},403,F);try{let me=await on.transfer({entryId:j.id,targetScope:Z,mode:X.mode==="move"?"move":"copy",confirmed:X.confirm===j.key,actorId:_e(ae).actor?.id,idempotencyKey:I.headers.get("idempotency-key")??X.idempotencyKey});return b({ok:!0,entry:on.list({projectId:a.project.id,scope:Z,canReadSecretMetadata:l}).find((le)=>le.id===me.entry.id),mutation:me.mutation},200,F)}catch(me){return b({ok:!1,error:me instanceof Error?me.message:String(me)},409,F)}}if(L.pathname==="/api/configuration/bulk"&&I.method==="POST"){let X=await ie(I),j=Array.isArray(X.ids)?X.ids.map(String).slice(0,500):[],Z=j.map((le)=>po.get(le)).filter((le)=>!!le&&le.projectId===a.project.id);if(Z.length!==j.length)return b({ok:!1,error:"One or more configuration entries were not found."},404,F);if(Z.some((le)=>le.kind==="secret")&&!T)return b({ok:!1,error:"Secret write permission is required."},403,F);if(X.action!=="delete"||X.confirm!=="bulk")return b({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,F);let me=[];try{for(let le of Z)me.push(await on.remove({entryId:le.id,expectedVersion:le.version,confirmed:!0,actorId:_e(ae).actor?.id}));return b({ok:!0,removed:me.flatMap((le)=>le.removed),affectedResourceIds:[...new Set(me.flatMap((le)=>le.affectedResourceIds))].sort()},200,F)}catch(le){return b({ok:!1,error:le instanceof Error?le.message:String(le),partial:me.flatMap((Ge)=>Ge.removed)},409,F)}}if(L.pathname==="/api/configuration/reveal"&&I.method==="POST"){let X=await ie(I),j=Ft.resolveSession(I);try{return b({ok:!0,value:await on.reveal({entryId:String(X.id??""),canRevealSecrets:l,recentlyAuthenticated:!Re||!!j&&we.isRecentlyAuthenticated(j),actorId:_e(ae).actor?.id})},200,F)}catch(Z){return b({ok:!1,error:Z instanceof Error?Z.message:String(Z)},403,F)}}if(L.pathname==="/api/configuration"&&I.method==="DELETE"){let X=await ie(I),j=po.get(String(X.id??""));if(j?.kind==="secret"&&!T)return b({ok:!1,error:"Secret write permission is required."},403,F);if(!j||j.projectId!==a.project.id)return b({ok:!1,error:"Configuration entry was not found."},404,F);try{return b({ok:!0,mutation:await on.remove({entryId:j.id,expectedVersion:Number(X.expectedVersion),confirmed:String(X.confirm??"")===j.key,actorId:_e(ae).actor?.id})},200,F)}catch(Z){return b({ok:!1,error:Z instanceof Error?Z.message:String(Z)},409,F)}}}if(L.pathname.startsWith("/api/fleet")){let d=_e(ae).actor?.id,l=(T,M=409)=>b({ok:!1,error:T instanceof Error?T.message:String(T)},M,{"cache-control":"no-store"});if(L.pathname==="/api/fleet"&&I.method==="GET")return b({ok:!0,servers:ua.list(a.project.id),resources:a.store.listResources(a.project.id),operations:At.list({projectId:a.project.id,limit:200}).filter((T)=>T.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(L.pathname==="/api/fleet"&&I.method==="POST"){let T=await ie(I);try{return b({ok:!0,server:xi.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(M){return l(M,422)}}if(L.pathname==="/api/fleet/action"&&I.method==="POST"){let T=await ie(I),M=String(T.id??""),F=String(T.action??"");try{if(F==="test")return b({ok:!0,server:await xi.test(M)});if(F==="validate")return b({ok:!0,server:await xi.validate(M)});if(F==="review_host_key")return b({ok:!0,server:xi.reviewHostKey(M,String(T.fingerprint??""))});if(F==="bootstrap")return b({ok:!0,...xi.bootstrap(M,T.confirmed===!0)},T.confirmed===!0?202:200);if(F==="heartbeat")return b({ok:!0,server:xi.heartbeat(M,{usage:T.usage&&typeof T.usage==="object"?T.usage:{}})});if(F==="drain")return b({ok:!0,server:xi.drain(M,T.completed===!0)});if(F==="uncordon")return b({ok:!0,server:xi.uncordon(M)});if(F==="archive")return b({ok:!0,server:xi.archive(M,String(T.confirmation??""))});return l("Unsupported fleet action.",422)}catch(X){return l(X)}}}if(L.pathname.startsWith("/api/capacity")){let d=(l,T=409)=>b({ok:!1,error:l instanceof Error?l.message:String(l)},T,{"cache-control":"no-store"});if(L.pathname==="/api/capacity"&&I.method==="GET")return b({ok:!0,pools:mo.listPools(a.project.id),placements:mo.listPlacements(a.project.id),servers:ua.list(a.project.id)},200,{"cache-control":"no-store"});if(L.pathname==="/api/capacity"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,pool:mo.createPool({organizationId:a.organization.id,projectId:a.project.id,name:String(l.name??""),purpose:String(l.purpose??"application"),backend:String(l.backend??"server"),region:l.region?String(l.region):void 0,architecture:l.architecture?String(l.architecture):void 0,labels:l.labels&&typeof l.labels==="object"?l.labels:{},requiredServerLabels:l.requiredServerLabels&&typeof l.requiredServerLabels==="object"?l.requiredServerLabels:{},toleratedTaints:Array.isArray(l.toleratedTaints)?l.toleratedTaints.map(String):[],capacity:l.capacity&&typeof l.capacity==="object"?l.capacity:{},maxWorkloads:Number(l.maxWorkloads??10),costWeight:Number(l.costWeight??1),spreadKey:l.spreadKey?String(l.spreadKey):void 0,concurrency:Number(l.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(T){return d(T,422)}}if(L.pathname==="/api/capacity/member"&&I.method==="POST"){let l=await ie(I);try{return mo.addMember(String(l.poolId??""),String(l.serverId??"")),b({ok:!0,pool:mo.getPool(String(l.poolId??""))})}catch(T){return d(T,422)}}if(L.pathname==="/api/capacity/explain"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,decisions:pp.explain(a.project.id,{purpose:String(l.purpose??"application"),resources:l.resources&&typeof l.resources==="object"?l.resources:{},region:l.region?String(l.region):void 0,architecture:l.architecture?String(l.architecture):void 0,labels:l.labels&&typeof l.labels==="object"?l.labels:{}})})}catch(T){return d(T,422)}}if(L.pathname==="/api/capacity/action"&&I.method==="POST"){let l=await ie(I);try{if(l.action==="drain")return b({ok:!0,...pp.drainPool(String(l.poolId??""))});if(l.action==="enable")return b({ok:!0,pool:mo.updatePool(String(l.poolId??""),{status:"active"})});if(l.action==="disable")return b({ok:!0,pool:mo.updatePool(String(l.poolId??""),{status:"disabled"})});return d("Unsupported capacity action.",422)}catch(T){return d(T,422)}}}if(L.pathname.startsWith("/api/regions")){let d=(l,T=409)=>b({ok:!1,error:l instanceof Error?l.message:String(l)},T,{"cache-control":"no-store"});if(L.pathname==="/api/regions"&&I.method==="GET")return b({ok:!0,topologies:Fo.list(a.project.id).map((l)=>({topology:l,targets:Fo.targets(l.id),channels:Fo.channels(l.id),route:Fo.route(l.id),executions:Fo.executions(l.id)}))},200,{"cache-control":"no-store"});if(L.pathname==="/api/regions"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,topology:gp.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:a.environments.get(ye)?.id,name:String(l.name??""),hostname:String(l.hostname??""),regions:Array.isArray(l.regions)?l.regions:[],trafficPolicy:l.trafficPolicy==="weighted"||l.trafficPolicy==="latency"?l.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(l.replicate)?l.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(l.maxLagSeconds??30),retainOnDestroy:l.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:l.cdnEnabled===!0,wafEnabled:l.wafEnabled===!0})},201)}catch(T){return d(T,422)}}if(L.pathname==="/api/regions/action"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,...gp.enqueue({topologyId:String(l.topologyId??""),kind:String(l.action??""),targetRegion:l.targetRegion?String(l.targetRegion):void 0,revision:l.revision?String(l.revision):void 0,manifest:l.manifest&&typeof l.manifest==="object"?l.manifest:{},confirmation:l.confirmation?String(l.confirmation):void 0,deleteData:l.deleteData===!0})},202)}catch(T){return d(T,422)}}}if(L.pathname.startsWith("/api/maintenance")){let d=(l,T=409)=>b({ok:!1,error:l instanceof Error?l.message:String(l)},T,{"cache-control":"no-store"});if(L.pathname==="/api/maintenance"&&I.method==="GET")return b({ok:!0,manifests:ji.manifests(a.organization.id),windows:ji.windows(a.project.id),campaigns:ji.campaigns(a.project.id).map((l)=>({campaign:l,targets:ji.targets(l.id)})),cleanups:ji.cleanups(a.project.id),drills:ji.drills(a.project.id)},200,{"cache-control":"no-store"});if(L.pathname==="/api/maintenance/cleanup-preview"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,plan:await Od.previewCleanup({projectId:a.project.id,kind:String(l.kind??"operations"),criteria:{olderThanDays:Number(l.olderThanDays??30)}},mp)},201)}catch(T){return d(T,422)}}if(L.pathname==="/api/maintenance/cleanup-apply"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,...Od.enqueueCleanup(String(l.planId??""),String(l.confirmation??""))},202)}catch(T){return d(T,422)}}if(L.pathname==="/api/maintenance/drill"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,drill:ji.createDrill({projectId:a.project.id,scenario:String(l.scenario??"control_plane"),isolatedTarget:String(l.isolatedTarget??""),expectedRpoMinutes:Number(l.expectedRpoMinutes??60),expectedRtoMinutes:Number(l.expectedRtoMinutes??30),recoveryPointId:l.recoveryPointId?String(l.recoveryPointId):void 0,topologyId:l.topologyId?String(l.topologyId):void 0})},201)}catch(T){return d(T,422)}}if(L.pathname==="/api/maintenance/drill-run"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,...Od.enqueueDrill(String(l.drillId??""))},202)}catch(T){return d(T,422)}}}if(L.pathname.startsWith("/api/volumes")){let d=a.environments.get(ye),l=_e(ae).actor?.id,T=(M,F=409)=>b({ok:!1,error:M instanceof Error?M.message:String(M)},F,{"cache-control":"no-store"});if(L.pathname==="/api/volumes"&&I.method==="GET"){let M=xd.inventory(a.project.id,d?.id),F=a.store.listResources(a.project.id,d?.id).map((X)=>({id:X.id,name:X.name,slug:X.slug,kind:X.kind,provider:X.provider,providerId:X.providerId}));return b({ok:!0,volumes:M,resources:F,operations:At.list({projectId:a.project.id,limit:100}).filter((X)=>X.operation.kind.startsWith("volume.")),recoveryPoints:Kt.listRecoveryPoints(a.project.id).filter((X)=>X.kind==="volume"),providers:Dd.map((X)=>({provider:X.provider,type:X.type,capabilities:X.capabilities()}))},200,{"cache-control":"no-store"})}if(L.pathname==="/api/volumes"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:M.resourceId?String(M.resourceId):void 0,name:String(M.name??""),provider:String(M.provider??"docker"),type:M.type==="docker"?"docker":M.type,capacityBytes:M.capacityBytes==null?void 0:Number(M.capacityBytes),filesystem:M.filesystem?String(M.filesystem):void 0,encrypted:M.encrypted===!0,desiredState:M.desiredState&&typeof M.desiredState==="object"?M.desiredState:{},actorId:l})},202,{"cache-control":"no-store"})}catch(F){return T(F,422)}}if(L.pathname==="/api/volumes/attach"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.attach(String(M.volumeId??""),{resourceId:String(M.resourceId??""),targetPath:String(M.targetPath??""),readOnly:M.readOnly===!0,uid:M.uid==null?void 0:Number(M.uid),gid:M.gid==null?void 0:Number(M.gid),mode:M.mode?String(M.mode):void 0,propagation:M.propagation,driverOptions:M.driverOptions&&typeof M.driverOptions==="object"?M.driverOptions:{},actorId:l})},202)}catch(F){return T(F,422)}}if(L.pathname==="/api/volumes/detach"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.detach(String(M.volumeId??""),String(M.attachmentId??""),{force:M.force===!0,drained:M.drained===!0,unmounted:M.unmounted===!0,confirmation:M.confirmation?String(M.confirmation):void 0,actorId:l})},202)}catch(F){return T(F)}}if(L.pathname==="/api/volumes/resize"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.resize(String(M.volumeId??""),Number(M.capacityBytes),{drained:M.drained===!0,actorId:l})},202)}catch(F){return T(F,422)}}if(L.pathname==="/api/volumes/snapshot"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.snapshot(String(M.volumeId??""),{name:M.name?String(M.name):void 0,actorId:l})},202)}catch(F){return T(F,422)}}if(L.pathname==="/api/volumes/restore"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.restore(String(M.snapshotId??""),{name:String(M.name??""),actorId:l})},202)}catch(F){return T(F,422)}}if(L.pathname==="/api/volumes/discover"&&I.method==="POST")try{return b({ok:!0,volumes:await Fi.discover({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,actorId:l})})}catch(M){return T(M,502)}if(L.pathname==="/api/volumes/adopt"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,volume:Fi.adopt(String(M.volumeId??""),{name:String(M.name??""),actorId:l})})}catch(F){return T(F,422)}}if(L.pathname==="/api/volumes"&&I.method==="DELETE"){let M=await ie(I),F=Ft.resolveSession(I);try{return b({ok:!0,...Fi.delete(String(M.volumeId??""),{recentAuthAt:!Re||F&&we.isRecentlyAuthenticated(F)?new Date().toISOString():void 0,confirmation:M.confirmation?String(M.confirmation):void 0,backupOverride:M.backupOverride===!0,backupOverrideConfirmation:M.backupOverrideConfirmation?String(M.backupOverrideConfirmation):void 0,actorId:l})},202)}catch(X){return T(X)}}}if(L.pathname==="/api/backups"&&I.method==="GET"){let d=a.environments.get(ye),l=Kt.listPolicies(a.project.id,d?.id),T=new Set(l.map((Z)=>Z.id)),M=Kt.listRecoveryPoints(a.project.id).filter((Z)=>!Z.policyId||T.has(Z.policyId)),F=Kt.listJobs(a.project.id).filter((Z)=>!Z.policyId||T.has(Z.policyId)),X=(Z)=>({...Z,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!Z.credentialRef,clientEncryptionConfigured:!!Z.encryptionKeyRef}),j=await Promise.all(Kt.listDestinations(a.project.id).map(async(Z)=>({...X(Z),credentialStatus:await Oh(Z,Bi)})));return b({ok:!0,destinations:j,policies:l,recoveryPoints:M,jobs:F,coverage:Kt.coverage(a.project.id).filter((Z)=>T.has(Z.policy.id)),resources:d?a.store.listResources(a.project.id,d.id).map((Z)=>({id:Z.id,name:Z.name,slug:Z.slug,kind:Z.kind})):[]})}if(L.pathname==="/api/backups/destinations"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim(),T=String(d.provider??""),M=String(d.encryption??"provider"),F=`secret://data-services/backups/${a.project.id}/${l}`,X=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(T))return b({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(M))return b({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let j,Z;if(d.credentials&&typeof d.credentials==="object"&&!Array.isArray(d.credentials))j=`${F}/credentials`,await Bi.put(j,JSON.stringify(d.credentials)),X.push(j);if(M!=="provider"){let le=String(d.encryptionKey??"");if(le.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");Z=`${F}/encryption-key`,await Bi.put(Z,le),X.push(Z)}let me=Kt.createDestination({organizationId:a.organization.id,projectId:a.project.id,name:l,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):go,forcePathStyle:d.forcePathStyle===!0,credentialRef:j,encryption:M,encryptionKeyRef:Z,immutability:d.immutability&&typeof d.immutability==="object"&&!Array.isArray(d.immutability)?d.immutability:{},status:"untested"});return b({ok:!0,destination:{...me,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!j,clientEncryptionConfigured:!!Z}},201)}catch(j){for(let Z of X)await Bi.remove(Z).catch(()=>{});return b({ok:!1,error:j instanceof Error?j.message:String(j)},422)}}if(L.pathname==="/api/backups/destinations/test"&&I.method==="POST"){let d=await ie(I),l=Kt.getDestination(String(d.id??""));if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Backup destination was not found."},404);if(l.provider==="aws_backup")return b({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await lp.test(l),b({ok:!0,destination:Kt.recordDestinationTest(l.id,{ok:!0})})}catch(T){let M=T instanceof Error?T.message:String(T);return Kt.recordDestinationTest(l.id,{ok:!1,error:M}),b({ok:!1,error:M},502)}}if(L.pathname==="/api/backups/policies"&&I.method==="POST"){let d=await ie(I),l=a.environments.get(ye),T=Kt.getDestination(String(d.destinationId??"")),M=String(d.resourceKind??""),F=d.dataServiceId?String(d.dataServiceId):void 0,X=F?Dt.get(F):void 0,j=d.resourceId?String(d.resourceId):void 0,Z=j?a.store.getResource(j):void 0;if(!l)return b({ok:!1,error:"Environment was not found."},404);if(!T||T.projectId!==a.project.id)return b({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(M))return b({ok:!1,error:"A supported backup resource kind is required."},422);if(F&&(!X||X.projectId!==a.project.id||X.environmentId!==l.id))return b({ok:!1,error:"Data service was not found in this environment."},404);if(j&&(!Z||Z.projectId!==a.project.id||Z.environmentId!==l.id))return b({ok:!1,error:"Resource was not found in this environment."},404);if(M==="managed_database"&&!X)return b({ok:!1,error:"Managed database policies require a data service."},422);if(M==="logical_database"&&(!X||!["container","server"].includes(X.provider)))return b({ok:!1,error:"Logical database policies require an on-box data service."},422);if(M==="volume"&&(!Z||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(d.volumeName??""))))return b({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let me=Array.isArray(d.includePatterns)?d.includePatterns.map(String).filter(Boolean):[];if(M==="files"&&(!Z||!me.length))return b({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(M==="control_plane"&&T.encryption==="provider")return b({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(M==="infrastructure"&&(T.provider!=="aws_backup"||!me.some((le)=>le.startsWith("resource:arn:"))||!me.some((le)=>le.startsWith("role:arn:"))))return b({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let le=Kt.createPolicy({organizationId:a.organization.id,projectId:a.project.id,environmentId:l.id,resourceId:j,dataServiceId:F,destinationId:T.id,name:String(d.name??"").trim(),resourceKind:M,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:M==="volume"?[String(d.volumeName),...me]:me,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 b({ok:!0,policy:le},201)}catch(le){return b({ok:!1,error:le instanceof Error?le.message:String(le)},422)}}if(L.pathname==="/api/backups/run"&&I.method==="POST"){let d=await ie(I),l=Kt.getPolicy(String(d.policyId??"")),T=a.environments.get(ye);if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Backup policy was not found in this environment."},404);try{let M=Bo.enqueueBackup(l,new Date().toISOString(),_e(ae).actor?.id);return b({ok:!0,job:M},202)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:String(M)},409)}}if(L.pathname==="/api/backups/verify"&&I.method==="POST"){let d=await ie(I),l=Kt.getRecoveryPoint(String(d.recoveryPointId??""));if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Recovery point was not found."},404);return b({ok:!0,job:Bo.enqueueVerification(l)},202)}if(L.pathname==="/api/backups/restore"&&I.method==="POST"){let d=await ie(I),l=Kt.getRecoveryPoint(String(d.recoveryPointId??"")),T=d.mode==="in_place"?"in_place":"isolated",M=d.target&&typeof d.target==="object"&&!Array.isArray(d.target)?{...d.target,inPlace:T==="in_place"}:{inPlace:T==="in_place"},F=Ft.resolveSession(I),X={mode:T,target:M,targetName:String(d.targetName??""),confirm:d.confirm?String(d.confirm):void 0,recentAuth:!Re||!!F&&we.isRecentlyAuthenticated(F),downtimeAcknowledged:d.downtimeAcknowledged===!0,safetyBackupId:d.safetyBackupId?String(d.safetyBackupId):void 0};if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Recovery point was not found."},404);if(d.drill===!0&&T!=="isolated")return b({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let j=Bo.planRestore(l,X);if(d.execute!==!0)return b({ok:!0,plan:j,executionCreated:!1});let Z=Bo.enqueueRestore(l,{...X,drill:d.drill===!0,actorId:_e(ae).actor?.id});return b({ok:!0,plan:j,job:Z},202)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:String(j)},409)}}if(L.pathname==="/api/backups/recovery-points"&&I.method==="POST"){let d=await ie(I),l=Kt.getRecoveryPoint(String(d.id??""));if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Recovery point was not found."},404);if(d.held==null&&d.pinned==null)return b({ok:!1,error:"held or pinned must be provided."},422);return b({ok:!0,recoveryPoint:Kt.updateRecoveryPoint(l.id,{held:d.held==null?l.held:d.held===!0,pinned:d.pinned==null?l.pinned:d.pinned===!0})})}if(L.pathname==="/api/backups/retention"&&I.method==="POST")return b({ok:!0,jobs:Bo.enqueueRetention()},202);if(L.pathname==="/api/data-services/capabilities"&&I.method==="GET"){let d=String(L.searchParams.get("engine")??""),l=String(L.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(d)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(l))return b({ok:!1,error:"A supported engine and provider are required."},422);return b({ok:!0,engine:d,provider:l,capabilities:tr(d,l)})}if(L.pathname==="/api/data-services"&&I.method==="GET"){let d=a.environments.get(ye),l=Dt.list(a.project.id,d?.id).map((T)=>{let M=Dt.credential(T.id);return{...T,credentialRef:void 0,credential:M?{configured:!0,username:M.username,version:M.version,rotatedAt:M.rotatedAt}:void 0,dependencies:Dt.dependencies(T.id).map((F)=>({resourceId:F.resourceId,requiresRedeploy:F.requiresRedeploy}))}});return b({ok:!0,services:l})}if(L.pathname==="/api/data-services/preview"&&I.method==="POST"){let d=await ie(I);if(d.id){let M=Dt.get(String(d.id)),F=a.environments.get(ye),X=String(d.action??"");if(!M||M.projectId!==a.project.id||M.environmentId!==F?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!Ad.includes(X))return b({ok:!1,error:`Action must be one of: ${Ad.join(", ")}.`},422);try{return b({ok:!0,plan:ja.plan(M,X,d.changes??{})})}catch(j){return b({ok:!1,error:j instanceof Error?j.message:String(j)},422)}}let l=String(d.engine??""),T=String(d.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(l)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return b({ok:!1,error:"A supported engine and provider are required."},422);return b({ok:!0,capabilities:tr(l,T),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(L.pathname==="/api/data-services"&&I.method==="POST"){let d=await ie(I),l=String(d.engine??""),T=String(d.provider??""),M=a.environments.get(ye),F=_e(ae);if(!M)return b({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(l)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return b({ok:!1,error:"A supported engine and provider are required."},422);let X={organizationId:a.organization.id,projectId:a.project.id,environmentId:M.id,resourceId:d.resourceId?String(d.resourceId):void 0,name:String(d.name??"").trim(),engine:l,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:F.actor?.id,username:d.username?String(d.username):void 0};try{if(d.adopt===!0){let Z=Dt.create({...X,status:"adopted",credentialRef:void 0});return b({ok:!0,service:Z,readOnly:!0},201)}if(!up({provider:T,engine:l}))return b({ok:!1,error:`No ${T}/${l} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let j=await ja.create(X);return b({ok:!0,service:j.service,operationId:j.operationId,oneTimeCredential:j.credential},201)}catch(j){return b({ok:!1,error:j instanceof Error?j.message:String(j)},422)}}if(L.pathname==="/api/data-services/connections"&&I.method==="GET"){let d=Dt.get(String(L.searchParams.get("id")??"")),l=a.environments.get(ye);if(!d||d.projectId!==a.project.id||d.environmentId!==l?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);let T=typeof d.observedState.endpoint==="string"?d.observedState.endpoint:void 0,M=typeof d.observedState.readerEndpoint==="string"?d.observedState.readerEndpoint:void 0,F=Number(d.observedState.port)||(d.engine==="postgres"?5432:d.engine==="redis"?6379:d.engine==="mongodb"?27017:d.engine==="libsql"?8080:3306),X=typeof d.observedState.database==="string"?d.observedState.database:void 0,j=typeof d.observedState.tls==="boolean"?d.observedState.tls:d.provider.startsWith("aws_"),Z=[...T?[{type:d.publicExposure?"external":"internal",host:T,port:F,database:X,tls:j}]:[],...M?[{type:"internal",host:M,port:F,database:X,tls:j}]:[],{type:"tunnel",host:T??d.placement,port:F,database:X,tls:j}];return b({ok:!0,serviceId:d.id,guidance:Hn(d,Z)})}if(L.pathname==="/api/data-services/action"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye),M=String(d.action??"");if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!Ad.includes(M))return b({ok:!1,error:`Action must be one of: ${Ad.join(", ")}.`},422);let F=d.changes&&typeof d.changes==="object"&&!Array.isArray(d.changes)?d.changes:{};try{let X=ja.plan(l,M,F);if(d.execute!==!0)return b({ok:!0,plan:X,productionExecutionCreated:!1});let j=ja.enqueue(l,M,F,_e(ae).actor?.id);return b({ok:!0,plan:X,operationId:j},202)}catch(X){return b({ok:!1,error:X instanceof Error?X.message:String(X)},409)}}if(L.pathname==="/api/data-services/dependencies"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye),M=a.store.getResource(String(d.resourceId??""));if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!M||M.projectId!==a.project.id||M.environmentId!==T?.id)return b({ok:!1,error:"Dependent resource was not found in this environment."},404);if(d.remove===!0)return b({ok:Dt.removeDependency(l.id,M.id)});return Dt.addDependency({serviceId:l.id,resourceId:M.id,secretRef:l.credentialRef??`secret://data-services/${l.projectId}/${l.name}`,requiresRedeploy:d.requiresRedeploy!==!1}),b({ok:!0,dependencies:Dt.dependencies(l.id).map((F)=>({resourceId:F.resourceId,requiresRedeploy:F.requiresRedeploy}))})}if(L.pathname==="/api/data-services/management"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye);if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(l.origin!=="adopted"||d.reviewed!==!0||d.confirm!==l.name)return b({ok:!1,error:`Enabling management requires reviewed=true and typing ${l.name}.`},409);return b({ok:!0,service:Dt.update(l.id,l.version,{managementEnabled:!0})})}if(L.pathname==="/api/data-services/reveal"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye),M=l?Dt.credential(l.id):void 0;if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!M)return b({ok:!1,error:"No managed credential is configured."},404);return b({ok:!0,credential:{username:M.username,password:await Bi.resolve(M.secretRef),version:M.version}},200,{"cache-control":"no-store"})}if(L.pathname==="/api/databases"&&I.method==="GET")return b(await Rm(o,ye));if(L.pathname==="/api/databases"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim();if(!Yi(l))return b({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return b({...await Pm(o,ye,l),name:l})}if(L.pathname==="/api/databases/vitess"&&I.method==="GET"){let d=await _m(o,ye);return b({...d,unhealthy:Nm(d.tablets),missingPrimary:Mm(d)})}if(L.pathname==="/api/databases/vitess/provision"&&I.method==="POST"){let d=await ie(I);try{return b(await my(o,ye,{keyspace:String(d.keyspace??""),username:String(d.username??""),password:String(d.password??""),sharded:d.sharded===!0,confirm:String(d.confirm??"")}))}catch(l){return b({ok:!1,error:l instanceof Error?l.message:String(l)},422)}}if(L.pathname==="/api/databases/vitess/migrations"&&I.method==="GET"){let d=L.searchParams.get("keyspace")??void 0;return b(await py(o,ye,d))}if(L.pathname==="/api/databases/vitess/migrations/action"&&I.method==="POST"){let d=await ie(I),l=String(d.uuid??"").trim(),T=String(d.action??"");if(!["retry","cancel","cleanup","complete"].includes(T))return b({ok:!1,error:"Unknown migration action."},422);return b(await gy(o,ye,l,T))}if(L.pathname==="/api/databases/vitess/keyspaces"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim(),T=d.sharded===!0;return b(await dy(o,ye,l,{sharded:T}))}if(L.pathname==="/api/databases/vitess/vschema"&&I.method==="POST"){let d=await ie(I),l=String(d.keyspace??"").trim(),T=typeof d.vschema==="string"?d.vschema:JSON.stringify(d.vschema??null);return b(await uy(o,ye,l,T))}if(L.pathname==="/api/databases/vitess/schema"&&I.method==="POST"){let d=await ie(I),l=String(d.sql??"");return b(await ly(o,ye,l))}if(L.pathname==="/api/databases/vitess/install-client"&&I.method==="POST")return b(await cy(o,ye));if(L.pathname==="/api/databases/backups"&&I.method==="GET")return b(await Om(o,ye));if(L.pathname==="/api/databases/backup"&&I.method==="POST"){let d=await ie(I),l=String(d.database??"").trim();if(!Yi(l))return b({ok:!1,error:"Database name must be a valid identifier."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to back up this database.`},409);return b(await Dm(o,ye,l))}if(L.pathname==="/api/databases/users"&&I.method==="POST"){let d=await ie(I),l=String(d.username??"").trim(),T=String(d.password??""),M=String(d.database??"").trim()||void 0,F=d.access==="readonly"?"readonly":"all";if(!Yi(l))return b({ok:!1,error:"Username must be a valid identifier."},422);if(!T)return b({ok:!1,error:"Password is required."},422);if(M&&!Yi(M))return b({ok:!1,error:"Database must be a valid identifier."},422);return b({...await xm(o,ye,{username:l,password:T,database:M,access:F}),username:l})}if(L.pathname==="/api/dashboard-data")return Lt=W.get(ye)??await Xe(ye),Xe(ye),b(Yl(Lt,{user:Tn,slug:o.project.slug}));if(L.pathname==="/api/users"&&I.method==="GET")return b({ok:!0,users:nn(t).map(ia)});if(L.pathname==="/api/users"&&I.method==="POST"){let d=await ie(I),l=String(d.username??"").trim();if(!vd(l))return b({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:{},M=new Set(Object.keys(o.sites??{})),F={};for(let[Z,me]of Object.entries(T)){if(!M.has(Z))return b({ok:!1,error:`Site '${Z}' was not found.`},404);if(me!=="owner"&&me!=="collaborator")return b({ok:!1,error:`Unknown site role '${me}'. Use 'owner' or 'collaborator'.`},422);F[Z]=me}let X=typeof d.password==="string"&&d.password.trim()?d.password.trim():void 0;if(X&&X.length<12)return b({ok:!1,error:"Password must be at least 12 characters."},422);let j=Na(t,{username:l,password:X,name:typeof d.name==="string"?d.name:void 0,sites:F});return Ya(a,nn(t)),Fn(),b({ok:!0,user:ia(j.user),password:j.password})}if(L.pathname==="/api/users"&&I.method==="DELETE"){let d=await ie(I),l=String(d.username??"").trim();if(l.toLowerCase()===ae.username.toLowerCase())return b({ok:!1,error:"You cannot remove your own account."},409);let T=Nn(nn(t),l),M=T?a.store.getActorByExternalId("user",`dashboard:${T.username.toLowerCase()}`):void 0,F=M?a.store.getMembershipForActor(a.organization.id,M.id):void 0;if(F&&F.source!=="legacy")return b({ok:!1,error:"Organization members must be removed from Organization access."},409);let X=Ql(t,l);if(!X.ok)return b(X,409);return Ya(a,nn(t)),ke.clear(),b({ok:!0,username:l})}if(L.pathname==="/api/actions/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=d.action?hA(d.action,ye):void 0;if(!l)return b({ok:!1,error:"Unknown dashboard action."},404);if(l.mutates&&d.confirm!==l.confirm)return b({ok:!1,error:`Type "${l.confirm}" to run this action.`},409);let T=await zi({controlPlane:a,environment:ye,actor:ae,kind:`dashboard.action.${l.id}`,input:{action:l.id},execute:()=>ap(l,{cwd:t,cliEntry:i})});return b({...T.result,controlPlaneOperation:T.operation})}if(L.pathname==="/api/server/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=d.operation?ni(d.operation,o,Lt):void 0;if(!l)return b({ok:!1,error:"Unknown or unavailable server operation."},404);if(l.mutates&&d.confirm!==l.confirm)return b({ok:!1,error:`Type "${l.confirm}" to run this operation.`},409);let T=ue(a,String(ye));await new rs(rt).run(new Ra,{...T,artifactRoot:t});let M=lr(rt,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(M.decision.outcome==="block")return b({ok:!1,error:`Operation blocked by security policy: ${M.decision.explanation}`,securityReview:M},409);let F=await zi({controlPlane:a,environment:ye,actor:ae,kind:`dashboard.server.${l.id}`,resourceSlug:l.target,input:{operation:l.id,target:l.target,to:d.to??null},execute:()=>Jr(o,ye,l,{to:d.to})});return b({...F.result,controlPlaneOperation:F.operation,securityReview:M})}if(L.pathname==="/api/server/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return b({ok:!1,error:'Type "run" to execute this command on the server.'},409);let l=await zi({controlPlane:a,environment:ye,actor:ae,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>ar(o,ye,String(d.command??""))});return b({...l.result,controlPlaneOperation:l.operation})}if(L.pathname==="/api/serverless/operations")return b(rp(o,ye,Lt));if(L.pathname==="/api/serverless/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=d.operation?jy(d.operation,o,ye,Lt):void 0;if(!l)return b({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(l.mutates&&d.confirm!==l.confirm)return b({ok:!1,error:`Type "${l.confirm}" to run this operation.`},409);let T=await zi({controlPlane:a,environment:ye,actor:ae,kind:`dashboard.serverless.${l.id}`,input:{operation:l.id,min:d.min??null,max:d.max??null},execute:()=>Uy(o,ye,l,{min:d.min,max:d.max})});return Lt=await ps(o,ye),W.set(ye,Lt),b({...T.result,controlPlaneOperation:T.operation})}if(L.pathname==="/api/serverless/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return b({ok:!1,error:'Type "run" to execute this command.'},409);return b(await zy(o,ye,String(d.command??"")))}if(L.pathname==="/api/serverless/dlq"&&I.method==="GET"){let d=Number(L.searchParams.get("max"))||10;return b(await Vy(o,ye,d))}if(L.pathname==="/api/serverless/dlq/redrive"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="redrive")return b({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return b(await qy(o,ye,{max:d.max,targetQueue:d.targetQueue}))}if(L.pathname==="/api/serverless/dlq/purge"&&I.method==="POST"){if((await I.json().catch(()=>({}))).confirm!=="purge")return b({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return b(await Gy(o,ye))}if(L.pathname==="/api/serverless/secrets"&&I.method==="GET")return b({secrets:Jy(o,ye)});if(L.pathname==="/api/serverless/secrets"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.secretId??"").trim();if(!l)return b({ok:!1,error:"A secret id is required."},422);if(typeof d.value!=="string"||d.value==="")return b({ok:!1,error:"A non-empty value is required."},422);return b(await Hy(o,ye,l,d.value))}if(L.pathname==="/api/serverless/secrets"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),l=String(d.secretId??"").trim();if(!l)return b({ok:!1,error:"A secret id is required."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to delete this secret.`},409);return b(await Wy(o,ye,l))}if(L.pathname==="/api/serverless/functions/config"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.mode??"").trim();if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to update this function.`},409);return b(await Ky(o,ye,l,{memory:d.memory,timeout:d.timeout}))}if(L.pathname==="/api/serverless/alarms"&&I.method==="GET")return b(await Qy(o,ye));if(L.pathname==="/api/serverless/alarms"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.preset??"").trim(),T=Number(d.threshold);if(!l)return b({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(T))return b({ok:!1,error:"A numeric threshold is required."},422);return b(await Yy(o,ye,l,T))}if(L.pathname==="/api/serverless/alarms"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),l=String(d.name??"").trim();if(!l)return b({ok:!1,error:"An alarm name is required."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to delete this alarm.`},409);return b(await Xy(o,ye,l))}if(L.pathname==="/api/serverless/traces"&&I.method==="GET"){let d=Number(L.searchParams.get("minutes"))||30;return b(await Ed(o,ye,d))}if(L.pathname==="/api/serverless/scheduler"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.action??"").trim();if(l!=="enable"&&l!=="disable"&&l!=="run")return b({ok:!1,error:"Unknown scheduler action."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to ${l} the scheduler.`},409);return b(await op(o,ye,l))}if(!fb(L.pathname,Tn))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(ye)}`}});let vs=await ki(ae,ye);if(!vs)return Rd("ts-cloud dashboard UI is unavailable.",503);return hb(vs,L.pathname)}catch(jo){if(e.verbose)console.error(jo);return b({ok:!1,error:jo?.message??String(jo)},500)}})();if(!Wt)return Wt;if(gt&&(L.pathname.startsWith("/api/")||L.pathname.startsWith("/auth/"))){let Ke;if((Ie.headers.get("content-type")||"").includes("application/json"))Ke=await Ie.json().catch(()=>{return});let br=Ft.resolveUser(I),mr=br?_e(br).actor:void 0;a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,actorId:mr?.id,correlationId:Ve,type:Wt.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:Wt.status<400?"info":"warning",payload:eA(I.method,L.pathname,Ke,Wt.status,Date.now()-De)})}return Wt.headers.set("x-request-id",Ve),Wt}});Ua?.start();let Ob=e.spendLoop??!0,kp;if(Ob)(async()=>{let{SpendRunner:I,SpendLoopLease:Te,startSpendLoop:De}=await import("./chunk-4fkmd2ce.js"),{store:Ie}=await bb(a.store),Ve=new I({controlPlane:a.store,store:Ie,alerts:Je});kp=De(Ve,{lease:new Te(a.store,{owner:`dashboard:${process.pid}`}),onError:(gt)=>console.error(`[ts-cloud] spend cycle failed: ${gt instanceof Error?gt.message:String(gt)}`)})})();let _b=bs.stop.bind(bs);return bs.stop=(I)=>{clearInterval(Cp),clearInterval(Ep),clearInterval(Tp),clearInterval(Ip),clearInterval(wp),clearInterval(yp),clearInterval(bp),clearInterval(Sp),clearInterval(vp),Fn(),Yt.clear(),Ua?.stop(),kp?.();let Te=_b(I);if(Ua)Ua.settled().finally(()=>a.store.close());else a.store.close();return Te},{server:bs,url:`http://${r}:${bs.port}/`}}
|
|
511
|
-
export{Le,x,xn,y,_n,Ji,On,ss,Hr,at,xe,$n,Ln,Mn,Un,Bn,jn,Vn,zn,oe,
|
|
509
|
+
`))},5000),Qe.unref?.(),I.signal.addEventListener("abort",yo,{once:!0})},cancel(){if(ot=!0,Qe)clearInterval(Qe)}});return new Response(mn,{headers:{"cache-control":"no-cache, no-transform",connection:"keep-alive","content-type":"text/event-stream; charset=utf-8","x-accel-buffering":"no"}})}if(F.pathname==="/api/telemetry/series"&&I.method==="GET"){le(!1);let be=qe(),Ne=["sum","avg","min","max","count","p50","p90","p95","p99"].includes(String(me.aggregation))?me.aggregation:"avg",Se=Z({...me,kinds:"metric",limit:5000}),Ae=l.series({...Se,bucketMs:Number(me.bucketMs)||60000,aggregation:Ne,timezone:String(me.timezone??"UTC"),compareFrom:me.compareFrom,compareTo:me.compareTo});return b({ok:!0,collection:{generatedAt:be.generatedAt,cached:be.cached},query:{aggregation:Ne,bucketMs:Number(me.bucketMs)||60000,timezone:String(me.timezone??"UTC")},series:Ae})}if(F.pathname==="/api/telemetry/refresh"&&I.method==="POST")return b({ok:!0,...await le(!0)});if(F.pathname==="/api/telemetry/export"&&I.method==="POST"){let be=await ie(I);await le(!1);let Ne=l.query({...Z(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:Z(be),...Ne},null,2),{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.json"',"content-type":"application/json; charset=utf-8"}});let Ae=["timestamp","kind","source","name","level","value","unit","message","traceId","requestId","deploymentId","releaseId","workloadId"],Qe=[Ae.join(","),...Ne.records.map((ot)=>Ae.map((St)=>`"${String(ot[St]??"").replaceAll('"','""')}"`).join(","))].join(`
|
|
510
|
+
`);return new Response(Qe,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(F.pathname==="/api/telemetry/saved-queries"&&I.method==="GET"){let be=_e(ae);return b({ok:!0,queries:l.listSavedQueries(a.project.id,be.actor?.id)})}if(F.pathname==="/api/telemetry/saved-queries"&&I.method==="POST"){let be=await ie(I),Ne=_e(ae);return b({ok:!0,query:l.saveQuery(a.project.id,Ne.actor?.id,String(be.name??""),Z(be.query??be))},201)}if(F.pathname==="/api/telemetry/saved-queries"&&I.method==="DELETE"){let be=await ie(I),Ne=_e(ae),Se=l.deleteSavedQuery(a.project.id,Ne.actor?.id,String(be.id??""));return b({ok:Se},Se?200:404)}}if(F.pathname.startsWith("/api/configuration")){let d=a.environments.get(ye),l=ae.role==="admin"||!!Tn.capabilities?.includes("secrets:read"),T=ae.role==="admin"||!!Tn.capabilities?.includes("secrets:write"),M={projectId:a.project.id,environmentId:d?.id},j={"cache-control":"no-store"};if(F.pathname==="/api/configuration"&&I.method==="GET"){let X=Object.fromEntries(F.searchParams),U=X.scopeType||X.scopeId?sa(X,M):void 0,Z=["variable","secret"].includes(String(X.kind))?X.kind:void 0,me=U?.type==="preview"?Wt.previews.getInstance(U.id):void 0,le=me?Wt.previews.getDefinition(me.definitionId):void 0,qe=U?await on.resolve({projectId:a.project.id,environmentId:U.environmentId,resourceId:U.resourceId,functionId:U.type==="function"?U.id:void 0,previewId:U.previewId,trustedPreview:!!me&&!me.fork,allowedPreviewSecrets:le?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:l}):void 0,be=a.store.listResources(a.project.id);return b({ok:!0,entries:on.list({projectId:a.project.id,scope:U,kind:Z,search:X.search,canReadSecretMetadata:l}),effectiveEntries:qe?Object.values(qe.entries).filter((Ne)=>!Z||Ne.kind===Z).filter((Ne)=>!X.search||Ne.key.toLowerCase().includes(String(X.search).toLowerCase())):[],configurationHash:qe?.configurationHash,warnings:qe?.warnings??[],scopes:{project:a.project,environments:a.store.listEnvironments(a.project.id),resources:be.filter((Ne)=>Ne.kind!=="function"),functions:be.filter((Ne)=>Ne.kind==="function"),previews:Wt.previews.listInstances({projectId:a.project.id}).filter((Ne)=>Ne.status!=="destroyed").map((Ne)=>({id:Ne.id,name:Ne.name,environmentId:Ne.baseEnvironmentId,resourceId:Ne.resourceId,fork:Ne.fork,status:Ne.status}))}},200,j)}if(F.pathname==="/api/configuration/export"&&I.method==="GET"){let X=sa(Object.fromEntries(F.searchParams),M);return new Response(on.exportVariables({projectId:a.project.id,scope:X}),{headers:{...j,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(F.pathname==="/api/configuration/plan"&&I.method==="POST"){let X=await ie(I),U=sa(X,M),Z=X.values&&typeof X.values==="object"&&!Array.isArray(X.values)?Object.fromEntries(Object.entries(X.values).map(([me,le])=>[me,String(le)])):{};return b({ok:!0,plan:on.plan({projectId:a.project.id,scope:U,values:Z,removeMissing:X.removeMissing===!0})},200,j)}if(F.pathname==="/api/configuration"&&I.method==="POST"){let X=await ie(I),U=sa(X,M),Z=X.kind==="secret"?"secret":"variable",me=String(X.key??"");if(Z==="secret"&&!T)return b({ok:!1,error:"Secret write permission is required."},403,j);try{let le=await on.set({organizationId:a.organization.id,projectId:a.project.id,scope:U,key:me,kind:Z,value:X.value==null?void 0:String(X.value),reference:X.reference==null?void 0:String(X.reference),backend:X.backend,required:X.required===!0,expectedVersion:X.expectedVersion==null?void 0:Number(X.expectedVersion),confirmed:String(X.confirm??"")===me,idempotencyKey:I.headers.get("idempotency-key")??X.idempotencyKey,actorId:_e(ae).actor?.id});return b({ok:!0,entry:on.list({projectId:a.project.id,scope:U,canReadSecretMetadata:l}).find((qe)=>qe.id===le.entry.id),mutation:le.mutation,warnings:le.warnings},le.mutation.added.length?201:200,j)}catch(le){return b({ok:!1,error:le instanceof Error?le.message:String(le)},409,j)}}if(F.pathname==="/api/configuration/import"&&I.method==="POST"){let X=await ie(I),U=sa(X,M),Z=Array.isArray(X.secretKeys)?X.secretKeys.map(String):[];if(Z.length&&!T)return b({ok:!1,error:"Secret write permission is required."},403,j);try{let me=await on.importDotenv({organizationId:a.organization.id,projectId:a.project.id,scope:U,source:String(X.source??""),secretKeys:Z,backend:X.backend,confirmed:X.confirm==="import",idempotencyKey:I.headers.get("idempotency-key")??X.idempotencyKey,actorId:_e(ae).actor?.id});return b({ok:me.document.valid,diagnostics:me.document.diagnostics,mutation:me.mutation,warnings:me.warnings},me.document.valid?200:422,j)}catch(me){return b({ok:!1,error:me instanceof Error?me.message:String(me)},409,j)}}if(F.pathname==="/api/configuration/dependencies"&&I.method==="POST"){let X=await ie(I),U=po.get(String(X.entryId??"")),Z=a.store.getResource(String(X.resourceId??""));if(!U||U.projectId!==a.project.id||!Z||Z.projectId!==a.project.id)return b({ok:!1,error:"Configuration entry or dependent resource was not found."},404,j);return b({ok:!0,dependency:po.setDependency({entryId:U.id,resourceId:Z.id,injectionTarget:["native_reference","file"].includes(String(X.injectionTarget))?X.injectionTarget:"environment",required:X.required!==!1,requiresRedeploy:X.requiresRedeploy!==!1,lastDeployedVersion:X.lastDeployedVersion==null?void 0:Number(X.lastDeployedVersion)})},200,j)}if(F.pathname==="/api/configuration/transfer"&&I.method==="POST"){let X=await ie(I),U=po.get(String(X.id??"")),Z=sa({...X,scopeType:X.targetScopeType,scopeId:X.targetScopeId},M);if(!U||U.projectId!==a.project.id)return b({ok:!1,error:"Configuration entry was not found."},404,j);if(U.kind==="secret"&&!T)return b({ok:!1,error:"Secret write permission is required."},403,j);try{let me=await on.transfer({entryId:U.id,targetScope:Z,mode:X.mode==="move"?"move":"copy",confirmed:X.confirm===U.key,actorId:_e(ae).actor?.id,idempotencyKey:I.headers.get("idempotency-key")??X.idempotencyKey});return b({ok:!0,entry:on.list({projectId:a.project.id,scope:Z,canReadSecretMetadata:l}).find((le)=>le.id===me.entry.id),mutation:me.mutation},200,j)}catch(me){return b({ok:!1,error:me instanceof Error?me.message:String(me)},409,j)}}if(F.pathname==="/api/configuration/bulk"&&I.method==="POST"){let X=await ie(I),U=Array.isArray(X.ids)?X.ids.map(String).slice(0,500):[],Z=U.map((le)=>po.get(le)).filter((le)=>!!le&&le.projectId===a.project.id);if(Z.length!==U.length)return b({ok:!1,error:"One or more configuration entries were not found."},404,j);if(Z.some((le)=>le.kind==="secret")&&!T)return b({ok:!1,error:"Secret write permission is required."},403,j);if(X.action!=="delete"||X.confirm!=="bulk")return b({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,j);let me=[];try{for(let le of Z)me.push(await on.remove({entryId:le.id,expectedVersion:le.version,confirmed:!0,actorId:_e(ae).actor?.id}));return b({ok:!0,removed:me.flatMap((le)=>le.removed),affectedResourceIds:[...new Set(me.flatMap((le)=>le.affectedResourceIds))].sort()},200,j)}catch(le){return b({ok:!1,error:le instanceof Error?le.message:String(le),partial:me.flatMap((qe)=>qe.removed)},409,j)}}if(F.pathname==="/api/configuration/reveal"&&I.method==="POST"){let X=await ie(I),U=Ft.resolveSession(I);try{return b({ok:!0,value:await on.reveal({entryId:String(X.id??""),canRevealSecrets:l,recentlyAuthenticated:!Re||!!U&&we.isRecentlyAuthenticated(U),actorId:_e(ae).actor?.id})},200,j)}catch(Z){return b({ok:!1,error:Z instanceof Error?Z.message:String(Z)},403,j)}}if(F.pathname==="/api/configuration"&&I.method==="DELETE"){let X=await ie(I),U=po.get(String(X.id??""));if(U?.kind==="secret"&&!T)return b({ok:!1,error:"Secret write permission is required."},403,j);if(!U||U.projectId!==a.project.id)return b({ok:!1,error:"Configuration entry was not found."},404,j);try{return b({ok:!0,mutation:await on.remove({entryId:U.id,expectedVersion:Number(X.expectedVersion),confirmed:String(X.confirm??"")===U.key,actorId:_e(ae).actor?.id})},200,j)}catch(Z){return b({ok:!1,error:Z instanceof Error?Z.message:String(Z)},409,j)}}}if(F.pathname.startsWith("/api/fleet")){let d=_e(ae).actor?.id,l=(T,M=409)=>b({ok:!1,error:T instanceof Error?T.message:String(T)},M,{"cache-control":"no-store"});if(F.pathname==="/api/fleet"&&I.method==="GET")return b({ok:!0,servers:ua.list(a.project.id),resources:a.store.listResources(a.project.id),operations:At.list({projectId:a.project.id,limit:200}).filter((T)=>T.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(F.pathname==="/api/fleet"&&I.method==="POST"){let T=await ie(I);try{return b({ok:!0,server:xi.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(M){return l(M,422)}}if(F.pathname==="/api/fleet/action"&&I.method==="POST"){let T=await ie(I),M=String(T.id??""),j=String(T.action??"");try{if(j==="test")return b({ok:!0,server:await xi.test(M)});if(j==="validate")return b({ok:!0,server:await xi.validate(M)});if(j==="review_host_key")return b({ok:!0,server:xi.reviewHostKey(M,String(T.fingerprint??""))});if(j==="bootstrap")return b({ok:!0,...xi.bootstrap(M,T.confirmed===!0)},T.confirmed===!0?202:200);if(j==="heartbeat")return b({ok:!0,server:xi.heartbeat(M,{usage:T.usage&&typeof T.usage==="object"?T.usage:{}})});if(j==="drain")return b({ok:!0,server:xi.drain(M,T.completed===!0)});if(j==="uncordon")return b({ok:!0,server:xi.uncordon(M)});if(j==="archive")return b({ok:!0,server:xi.archive(M,String(T.confirmation??""))});return l("Unsupported fleet action.",422)}catch(X){return l(X)}}}if(F.pathname.startsWith("/api/capacity")){let d=(l,T=409)=>b({ok:!1,error:l instanceof Error?l.message:String(l)},T,{"cache-control":"no-store"});if(F.pathname==="/api/capacity"&&I.method==="GET")return b({ok:!0,pools:mo.listPools(a.project.id),placements:mo.listPlacements(a.project.id),servers:ua.list(a.project.id)},200,{"cache-control":"no-store"});if(F.pathname==="/api/capacity"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,pool:mo.createPool({organizationId:a.organization.id,projectId:a.project.id,name:String(l.name??""),purpose:String(l.purpose??"application"),backend:String(l.backend??"server"),region:l.region?String(l.region):void 0,architecture:l.architecture?String(l.architecture):void 0,labels:l.labels&&typeof l.labels==="object"?l.labels:{},requiredServerLabels:l.requiredServerLabels&&typeof l.requiredServerLabels==="object"?l.requiredServerLabels:{},toleratedTaints:Array.isArray(l.toleratedTaints)?l.toleratedTaints.map(String):[],capacity:l.capacity&&typeof l.capacity==="object"?l.capacity:{},maxWorkloads:Number(l.maxWorkloads??10),costWeight:Number(l.costWeight??1),spreadKey:l.spreadKey?String(l.spreadKey):void 0,concurrency:Number(l.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(T){return d(T,422)}}if(F.pathname==="/api/capacity/member"&&I.method==="POST"){let l=await ie(I);try{return mo.addMember(String(l.poolId??""),String(l.serverId??"")),b({ok:!0,pool:mo.getPool(String(l.poolId??""))})}catch(T){return d(T,422)}}if(F.pathname==="/api/capacity/explain"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,decisions:pp.explain(a.project.id,{purpose:String(l.purpose??"application"),resources:l.resources&&typeof l.resources==="object"?l.resources:{},region:l.region?String(l.region):void 0,architecture:l.architecture?String(l.architecture):void 0,labels:l.labels&&typeof l.labels==="object"?l.labels:{}})})}catch(T){return d(T,422)}}if(F.pathname==="/api/capacity/action"&&I.method==="POST"){let l=await ie(I);try{if(l.action==="drain")return b({ok:!0,...pp.drainPool(String(l.poolId??""))});if(l.action==="enable")return b({ok:!0,pool:mo.updatePool(String(l.poolId??""),{status:"active"})});if(l.action==="disable")return b({ok:!0,pool:mo.updatePool(String(l.poolId??""),{status:"disabled"})});return d("Unsupported capacity action.",422)}catch(T){return d(T,422)}}}if(F.pathname.startsWith("/api/regions")){let d=(l,T=409)=>b({ok:!1,error:l instanceof Error?l.message:String(l)},T,{"cache-control":"no-store"});if(F.pathname==="/api/regions"&&I.method==="GET")return b({ok:!0,topologies:Fo.list(a.project.id).map((l)=>({topology:l,targets:Fo.targets(l.id),channels:Fo.channels(l.id),route:Fo.route(l.id),executions:Fo.executions(l.id)}))},200,{"cache-control":"no-store"});if(F.pathname==="/api/regions"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,topology:gp.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:a.environments.get(ye)?.id,name:String(l.name??""),hostname:String(l.hostname??""),regions:Array.isArray(l.regions)?l.regions:[],trafficPolicy:l.trafficPolicy==="weighted"||l.trafficPolicy==="latency"?l.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(l.replicate)?l.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(l.maxLagSeconds??30),retainOnDestroy:l.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:l.cdnEnabled===!0,wafEnabled:l.wafEnabled===!0})},201)}catch(T){return d(T,422)}}if(F.pathname==="/api/regions/action"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,...gp.enqueue({topologyId:String(l.topologyId??""),kind:String(l.action??""),targetRegion:l.targetRegion?String(l.targetRegion):void 0,revision:l.revision?String(l.revision):void 0,manifest:l.manifest&&typeof l.manifest==="object"?l.manifest:{},confirmation:l.confirmation?String(l.confirmation):void 0,deleteData:l.deleteData===!0})},202)}catch(T){return d(T,422)}}}if(F.pathname.startsWith("/api/maintenance")){let d=(l,T=409)=>b({ok:!1,error:l instanceof Error?l.message:String(l)},T,{"cache-control":"no-store"});if(F.pathname==="/api/maintenance"&&I.method==="GET")return b({ok:!0,manifests:ji.manifests(a.organization.id),windows:ji.windows(a.project.id),campaigns:ji.campaigns(a.project.id).map((l)=>({campaign:l,targets:ji.targets(l.id)})),cleanups:ji.cleanups(a.project.id),drills:ji.drills(a.project.id)},200,{"cache-control":"no-store"});if(F.pathname==="/api/maintenance/cleanup-preview"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,plan:await Od.previewCleanup({projectId:a.project.id,kind:String(l.kind??"operations"),criteria:{olderThanDays:Number(l.olderThanDays??30)}},mp)},201)}catch(T){return d(T,422)}}if(F.pathname==="/api/maintenance/cleanup-apply"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,...Od.enqueueCleanup(String(l.planId??""),String(l.confirmation??""))},202)}catch(T){return d(T,422)}}if(F.pathname==="/api/maintenance/drill"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,drill:ji.createDrill({projectId:a.project.id,scenario:String(l.scenario??"control_plane"),isolatedTarget:String(l.isolatedTarget??""),expectedRpoMinutes:Number(l.expectedRpoMinutes??60),expectedRtoMinutes:Number(l.expectedRtoMinutes??30),recoveryPointId:l.recoveryPointId?String(l.recoveryPointId):void 0,topologyId:l.topologyId?String(l.topologyId):void 0})},201)}catch(T){return d(T,422)}}if(F.pathname==="/api/maintenance/drill-run"&&I.method==="POST"){let l=await ie(I);try{return b({ok:!0,...Od.enqueueDrill(String(l.drillId??""))},202)}catch(T){return d(T,422)}}}if(F.pathname.startsWith("/api/volumes")){let d=a.environments.get(ye),l=_e(ae).actor?.id,T=(M,j=409)=>b({ok:!1,error:M instanceof Error?M.message:String(M)},j,{"cache-control":"no-store"});if(F.pathname==="/api/volumes"&&I.method==="GET"){let M=xd.inventory(a.project.id,d?.id),j=a.store.listResources(a.project.id,d?.id).map((X)=>({id:X.id,name:X.name,slug:X.slug,kind:X.kind,provider:X.provider,providerId:X.providerId}));return b({ok:!0,volumes:M,resources:j,operations:At.list({projectId:a.project.id,limit:100}).filter((X)=>X.operation.kind.startsWith("volume.")),recoveryPoints:Qt.listRecoveryPoints(a.project.id).filter((X)=>X.kind==="volume"),providers:Dd.map((X)=>({provider:X.provider,type:X.type,capabilities:X.capabilities()}))},200,{"cache-control":"no-store"})}if(F.pathname==="/api/volumes"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.create({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,resourceId:M.resourceId?String(M.resourceId):void 0,name:String(M.name??""),provider:String(M.provider??"docker"),type:M.type==="docker"?"docker":M.type,capacityBytes:M.capacityBytes==null?void 0:Number(M.capacityBytes),filesystem:M.filesystem?String(M.filesystem):void 0,encrypted:M.encrypted===!0,desiredState:M.desiredState&&typeof M.desiredState==="object"?M.desiredState:{},actorId:l})},202,{"cache-control":"no-store"})}catch(j){return T(j,422)}}if(F.pathname==="/api/volumes/attach"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.attach(String(M.volumeId??""),{resourceId:String(M.resourceId??""),targetPath:String(M.targetPath??""),readOnly:M.readOnly===!0,uid:M.uid==null?void 0:Number(M.uid),gid:M.gid==null?void 0:Number(M.gid),mode:M.mode?String(M.mode):void 0,propagation:M.propagation,driverOptions:M.driverOptions&&typeof M.driverOptions==="object"?M.driverOptions:{},actorId:l})},202)}catch(j){return T(j,422)}}if(F.pathname==="/api/volumes/detach"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.detach(String(M.volumeId??""),String(M.attachmentId??""),{force:M.force===!0,drained:M.drained===!0,unmounted:M.unmounted===!0,confirmation:M.confirmation?String(M.confirmation):void 0,actorId:l})},202)}catch(j){return T(j)}}if(F.pathname==="/api/volumes/resize"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.resize(String(M.volumeId??""),Number(M.capacityBytes),{drained:M.drained===!0,actorId:l})},202)}catch(j){return T(j,422)}}if(F.pathname==="/api/volumes/snapshot"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.snapshot(String(M.volumeId??""),{name:M.name?String(M.name):void 0,actorId:l})},202)}catch(j){return T(j,422)}}if(F.pathname==="/api/volumes/restore"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,...Fi.restore(String(M.snapshotId??""),{name:String(M.name??""),actorId:l})},202)}catch(j){return T(j,422)}}if(F.pathname==="/api/volumes/discover"&&I.method==="POST")try{return b({ok:!0,volumes:await Fi.discover({organizationId:a.organization.id,projectId:a.project.id,environmentId:d?.id,actorId:l})})}catch(M){return T(M,502)}if(F.pathname==="/api/volumes/adopt"&&I.method==="POST"){let M=await ie(I);try{return b({ok:!0,volume:Fi.adopt(String(M.volumeId??""),{name:String(M.name??""),actorId:l})})}catch(j){return T(j,422)}}if(F.pathname==="/api/volumes"&&I.method==="DELETE"){let M=await ie(I),j=Ft.resolveSession(I);try{return b({ok:!0,...Fi.delete(String(M.volumeId??""),{recentAuthAt:!Re||j&&we.isRecentlyAuthenticated(j)?new Date().toISOString():void 0,confirmation:M.confirmation?String(M.confirmation):void 0,backupOverride:M.backupOverride===!0,backupOverrideConfirmation:M.backupOverrideConfirmation?String(M.backupOverrideConfirmation):void 0,actorId:l})},202)}catch(X){return T(X)}}}if(F.pathname==="/api/backups"&&I.method==="GET"){let d=a.environments.get(ye),l=Qt.listPolicies(a.project.id,d?.id),T=new Set(l.map((Z)=>Z.id)),M=Qt.listRecoveryPoints(a.project.id).filter((Z)=>!Z.policyId||T.has(Z.policyId)),j=Qt.listJobs(a.project.id).filter((Z)=>!Z.policyId||T.has(Z.policyId)),X=(Z)=>({...Z,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!Z.credentialRef,clientEncryptionConfigured:!!Z.encryptionKeyRef}),U=await Promise.all(Qt.listDestinations(a.project.id).map(async(Z)=>({...X(Z),credentialStatus:await Oh(Z,Bi)})));return b({ok:!0,destinations:U,policies:l,recoveryPoints:M,jobs:j,coverage:Qt.coverage(a.project.id).filter((Z)=>T.has(Z.policy.id)),resources:d?a.store.listResources(a.project.id,d.id).map((Z)=>({id:Z.id,name:Z.name,slug:Z.slug,kind:Z.kind})):[]})}if(F.pathname==="/api/backups/destinations"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim(),T=String(d.provider??""),M=String(d.encryption??"provider"),j=`secret://data-services/backups/${a.project.id}/${l}`,X=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(T))return b({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(M))return b({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let U,Z;if(d.credentials&&typeof d.credentials==="object"&&!Array.isArray(d.credentials))U=`${j}/credentials`,await Bi.put(U,JSON.stringify(d.credentials)),X.push(U);if(M!=="provider"){let le=String(d.encryptionKey??"");if(le.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");Z=`${j}/encryption-key`,await Bi.put(Z,le),X.push(Z)}let me=Qt.createDestination({organizationId:a.organization.id,projectId:a.project.id,name:l,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):go,forcePathStyle:d.forcePathStyle===!0,credentialRef:U,encryption:M,encryptionKeyRef:Z,immutability:d.immutability&&typeof d.immutability==="object"&&!Array.isArray(d.immutability)?d.immutability:{},status:"untested"});return b({ok:!0,destination:{...me,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!U,clientEncryptionConfigured:!!Z}},201)}catch(U){for(let Z of X)await Bi.remove(Z).catch(()=>{});return b({ok:!1,error:U instanceof Error?U.message:String(U)},422)}}if(F.pathname==="/api/backups/destinations/test"&&I.method==="POST"){let d=await ie(I),l=Qt.getDestination(String(d.id??""));if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Backup destination was not found."},404);if(l.provider==="aws_backup")return b({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await lp.test(l),b({ok:!0,destination:Qt.recordDestinationTest(l.id,{ok:!0})})}catch(T){let M=T instanceof Error?T.message:String(T);return Qt.recordDestinationTest(l.id,{ok:!1,error:M}),b({ok:!1,error:M},502)}}if(F.pathname==="/api/backups/policies"&&I.method==="POST"){let d=await ie(I),l=a.environments.get(ye),T=Qt.getDestination(String(d.destinationId??"")),M=String(d.resourceKind??""),j=d.dataServiceId?String(d.dataServiceId):void 0,X=j?Dt.get(j):void 0,U=d.resourceId?String(d.resourceId):void 0,Z=U?a.store.getResource(U):void 0;if(!l)return b({ok:!1,error:"Environment was not found."},404);if(!T||T.projectId!==a.project.id)return b({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(M))return b({ok:!1,error:"A supported backup resource kind is required."},422);if(j&&(!X||X.projectId!==a.project.id||X.environmentId!==l.id))return b({ok:!1,error:"Data service was not found in this environment."},404);if(U&&(!Z||Z.projectId!==a.project.id||Z.environmentId!==l.id))return b({ok:!1,error:"Resource was not found in this environment."},404);if(M==="managed_database"&&!X)return b({ok:!1,error:"Managed database policies require a data service."},422);if(M==="logical_database"&&(!X||!["container","server"].includes(X.provider)))return b({ok:!1,error:"Logical database policies require an on-box data service."},422);if(M==="volume"&&(!Z||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(d.volumeName??""))))return b({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let me=Array.isArray(d.includePatterns)?d.includePatterns.map(String).filter(Boolean):[];if(M==="files"&&(!Z||!me.length))return b({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(M==="control_plane"&&T.encryption==="provider")return b({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(M==="infrastructure"&&(T.provider!=="aws_backup"||!me.some((le)=>le.startsWith("resource:arn:"))||!me.some((le)=>le.startsWith("role:arn:"))))return b({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let le=Qt.createPolicy({organizationId:a.organization.id,projectId:a.project.id,environmentId:l.id,resourceId:U,dataServiceId:j,destinationId:T.id,name:String(d.name??"").trim(),resourceKind:M,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:M==="volume"?[String(d.volumeName),...me]:me,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 b({ok:!0,policy:le},201)}catch(le){return b({ok:!1,error:le instanceof Error?le.message:String(le)},422)}}if(F.pathname==="/api/backups/run"&&I.method==="POST"){let d=await ie(I),l=Qt.getPolicy(String(d.policyId??"")),T=a.environments.get(ye);if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Backup policy was not found in this environment."},404);try{let M=Bo.enqueueBackup(l,new Date().toISOString(),_e(ae).actor?.id);return b({ok:!0,job:M},202)}catch(M){return b({ok:!1,error:M instanceof Error?M.message:String(M)},409)}}if(F.pathname==="/api/backups/verify"&&I.method==="POST"){let d=await ie(I),l=Qt.getRecoveryPoint(String(d.recoveryPointId??""));if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Recovery point was not found."},404);return b({ok:!0,job:Bo.enqueueVerification(l)},202)}if(F.pathname==="/api/backups/restore"&&I.method==="POST"){let d=await ie(I),l=Qt.getRecoveryPoint(String(d.recoveryPointId??"")),T=d.mode==="in_place"?"in_place":"isolated",M=d.target&&typeof d.target==="object"&&!Array.isArray(d.target)?{...d.target,inPlace:T==="in_place"}:{inPlace:T==="in_place"},j=Ft.resolveSession(I),X={mode:T,target:M,targetName:String(d.targetName??""),confirm:d.confirm?String(d.confirm):void 0,recentAuth:!Re||!!j&&we.isRecentlyAuthenticated(j),downtimeAcknowledged:d.downtimeAcknowledged===!0,safetyBackupId:d.safetyBackupId?String(d.safetyBackupId):void 0};if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Recovery point was not found."},404);if(d.drill===!0&&T!=="isolated")return b({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let U=Bo.planRestore(l,X);if(d.execute!==!0)return b({ok:!0,plan:U,executionCreated:!1});let Z=Bo.enqueueRestore(l,{...X,drill:d.drill===!0,actorId:_e(ae).actor?.id});return b({ok:!0,plan:U,job:Z},202)}catch(U){return b({ok:!1,error:U instanceof Error?U.message:String(U)},409)}}if(F.pathname==="/api/backups/recovery-points"&&I.method==="POST"){let d=await ie(I),l=Qt.getRecoveryPoint(String(d.id??""));if(!l||l.projectId!==a.project.id)return b({ok:!1,error:"Recovery point was not found."},404);if(d.held==null&&d.pinned==null)return b({ok:!1,error:"held or pinned must be provided."},422);return b({ok:!0,recoveryPoint:Qt.updateRecoveryPoint(l.id,{held:d.held==null?l.held:d.held===!0,pinned:d.pinned==null?l.pinned:d.pinned===!0})})}if(F.pathname==="/api/backups/retention"&&I.method==="POST")return b({ok:!0,jobs:Bo.enqueueRetention()},202);if(F.pathname==="/api/data-services/capabilities"&&I.method==="GET"){let d=String(F.searchParams.get("engine")??""),l=String(F.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(d)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(l))return b({ok:!1,error:"A supported engine and provider are required."},422);return b({ok:!0,engine:d,provider:l,capabilities:rr(d,l)})}if(F.pathname==="/api/data-services"&&I.method==="GET"){let d=a.environments.get(ye),l=Dt.list(a.project.id,d?.id).map((T)=>{let M=Dt.credential(T.id);return{...T,credentialRef:void 0,credential:M?{configured:!0,username:M.username,version:M.version,rotatedAt:M.rotatedAt}:void 0,dependencies:Dt.dependencies(T.id).map((j)=>({resourceId:j.resourceId,requiresRedeploy:j.requiresRedeploy}))}});return b({ok:!0,services:l})}if(F.pathname==="/api/data-services/preview"&&I.method==="POST"){let d=await ie(I);if(d.id){let M=Dt.get(String(d.id)),j=a.environments.get(ye),X=String(d.action??"");if(!M||M.projectId!==a.project.id||M.environmentId!==j?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!Ad.includes(X))return b({ok:!1,error:`Action must be one of: ${Ad.join(", ")}.`},422);try{return b({ok:!0,plan:ja.plan(M,X,d.changes??{})})}catch(U){return b({ok:!1,error:U instanceof Error?U.message:String(U)},422)}}let l=String(d.engine??""),T=String(d.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(l)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return b({ok:!1,error:"A supported engine and provider are required."},422);return b({ok:!0,capabilities:rr(l,T),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(F.pathname==="/api/data-services"&&I.method==="POST"){let d=await ie(I),l=String(d.engine??""),T=String(d.provider??""),M=a.environments.get(ye),j=_e(ae);if(!M)return b({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(l)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(T))return b({ok:!1,error:"A supported engine and provider are required."},422);let X={organizationId:a.organization.id,projectId:a.project.id,environmentId:M.id,resourceId:d.resourceId?String(d.resourceId):void 0,name:String(d.name??"").trim(),engine:l,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:j.actor?.id,username:d.username?String(d.username):void 0};try{if(d.adopt===!0){let Z=Dt.create({...X,status:"adopted",credentialRef:void 0});return b({ok:!0,service:Z,readOnly:!0},201)}if(!up({provider:T,engine:l}))return b({ok:!1,error:`No ${T}/${l} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let U=await ja.create(X);return b({ok:!0,service:U.service,operationId:U.operationId,oneTimeCredential:U.credential},201)}catch(U){return b({ok:!1,error:U instanceof Error?U.message:String(U)},422)}}if(F.pathname==="/api/data-services/connections"&&I.method==="GET"){let d=Dt.get(String(F.searchParams.get("id")??"")),l=a.environments.get(ye);if(!d||d.projectId!==a.project.id||d.environmentId!==l?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);let T=typeof d.observedState.endpoint==="string"?d.observedState.endpoint:void 0,M=typeof d.observedState.readerEndpoint==="string"?d.observedState.readerEndpoint:void 0,j=Number(d.observedState.port)||(d.engine==="postgres"?5432:d.engine==="redis"?6379:d.engine==="mongodb"?27017:d.engine==="libsql"?8080:3306),X=typeof d.observedState.database==="string"?d.observedState.database:void 0,U=typeof d.observedState.tls==="boolean"?d.observedState.tls:d.provider.startsWith("aws_"),Z=[...T?[{type:d.publicExposure?"external":"internal",host:T,port:j,database:X,tls:U}]:[],...M?[{type:"internal",host:M,port:j,database:X,tls:U}]:[],{type:"tunnel",host:T??d.placement,port:j,database:X,tls:U}];return b({ok:!0,serviceId:d.id,guidance:Hn(d,Z)})}if(F.pathname==="/api/data-services/action"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye),M=String(d.action??"");if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!Ad.includes(M))return b({ok:!1,error:`Action must be one of: ${Ad.join(", ")}.`},422);let j=d.changes&&typeof d.changes==="object"&&!Array.isArray(d.changes)?d.changes:{};try{let X=ja.plan(l,M,j);if(d.execute!==!0)return b({ok:!0,plan:X,productionExecutionCreated:!1});let U=ja.enqueue(l,M,j,_e(ae).actor?.id);return b({ok:!0,plan:X,operationId:U},202)}catch(X){return b({ok:!1,error:X instanceof Error?X.message:String(X)},409)}}if(F.pathname==="/api/data-services/dependencies"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye),M=a.store.getResource(String(d.resourceId??""));if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!M||M.projectId!==a.project.id||M.environmentId!==T?.id)return b({ok:!1,error:"Dependent resource was not found in this environment."},404);if(d.remove===!0)return b({ok:Dt.removeDependency(l.id,M.id)});return Dt.addDependency({serviceId:l.id,resourceId:M.id,secretRef:l.credentialRef??`secret://data-services/${l.projectId}/${l.name}`,requiresRedeploy:d.requiresRedeploy!==!1}),b({ok:!0,dependencies:Dt.dependencies(l.id).map((j)=>({resourceId:j.resourceId,requiresRedeploy:j.requiresRedeploy}))})}if(F.pathname==="/api/data-services/management"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye);if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(l.origin!=="adopted"||d.reviewed!==!0||d.confirm!==l.name)return b({ok:!1,error:`Enabling management requires reviewed=true and typing ${l.name}.`},409);return b({ok:!0,service:Dt.update(l.id,l.version,{managementEnabled:!0})})}if(F.pathname==="/api/data-services/reveal"&&I.method==="POST"){let d=await ie(I),l=Dt.get(String(d.id??"")),T=a.environments.get(ye),M=l?Dt.credential(l.id):void 0;if(!l||l.projectId!==a.project.id||l.environmentId!==T?.id)return b({ok:!1,error:"Data service was not found in this environment."},404);if(!M)return b({ok:!1,error:"No managed credential is configured."},404);return b({ok:!0,credential:{username:M.username,password:await Bi.resolve(M.secretRef),version:M.version}},200,{"cache-control":"no-store"})}if(F.pathname==="/api/databases"&&I.method==="GET")return b(await Rm(o,ye));if(F.pathname==="/api/databases"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim();if(!Yi(l))return b({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return b({...await Pm(o,ye,l),name:l})}if(F.pathname==="/api/databases/vitess"&&I.method==="GET"){let d=await _m(o,ye);return b({...d,unhealthy:Nm(d.tablets),missingPrimary:Mm(d)})}if(F.pathname==="/api/databases/vitess/provision"&&I.method==="POST"){let d=await ie(I);try{return b(await my(o,ye,{keyspace:String(d.keyspace??""),username:String(d.username??""),password:String(d.password??""),sharded:d.sharded===!0,confirm:String(d.confirm??"")}))}catch(l){return b({ok:!1,error:l instanceof Error?l.message:String(l)},422)}}if(F.pathname==="/api/databases/vitess/migrations"&&I.method==="GET"){let d=F.searchParams.get("keyspace")??void 0;return b(await py(o,ye,d))}if(F.pathname==="/api/databases/vitess/migrations/action"&&I.method==="POST"){let d=await ie(I),l=String(d.uuid??"").trim(),T=String(d.action??"");if(!["retry","cancel","cleanup","complete"].includes(T))return b({ok:!1,error:"Unknown migration action."},422);return b(await gy(o,ye,l,T))}if(F.pathname==="/api/databases/vitess/keyspaces"&&I.method==="POST"){let d=await ie(I),l=String(d.name??"").trim(),T=d.sharded===!0;return b(await dy(o,ye,l,{sharded:T}))}if(F.pathname==="/api/databases/vitess/vschema"&&I.method==="POST"){let d=await ie(I),l=String(d.keyspace??"").trim(),T=typeof d.vschema==="string"?d.vschema:JSON.stringify(d.vschema??null);return b(await uy(o,ye,l,T))}if(F.pathname==="/api/databases/vitess/schema"&&I.method==="POST"){let d=await ie(I),l=String(d.sql??"");return b(await ly(o,ye,l))}if(F.pathname==="/api/databases/vitess/install-client"&&I.method==="POST")return b(await cy(o,ye));if(F.pathname==="/api/databases/backups"&&I.method==="GET")return b(await Om(o,ye));if(F.pathname==="/api/databases/backup"&&I.method==="POST"){let d=await ie(I),l=String(d.database??"").trim();if(!Yi(l))return b({ok:!1,error:"Database name must be a valid identifier."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to back up this database.`},409);return b(await Dm(o,ye,l))}if(F.pathname==="/api/databases/users"&&I.method==="POST"){let d=await ie(I),l=String(d.username??"").trim(),T=String(d.password??""),M=String(d.database??"").trim()||void 0,j=d.access==="readonly"?"readonly":"all";if(!Yi(l))return b({ok:!1,error:"Username must be a valid identifier."},422);if(!T)return b({ok:!1,error:"Password is required."},422);if(M&&!Yi(M))return b({ok:!1,error:"Database must be a valid identifier."},422);return b({...await xm(o,ye,{username:l,password:T,database:M,access:j}),username:l})}if(F.pathname==="/api/dashboard-data")return Lt=W.get(ye)??await Xe(ye),Xe(ye),b(Yl(Lt,{user:Tn,slug:o.project.slug}));if(F.pathname==="/api/users"&&I.method==="GET")return b({ok:!0,users:nn(t).map(ia)});if(F.pathname==="/api/users"&&I.method==="POST"){let d=await ie(I),l=String(d.username??"").trim();if(!vd(l))return b({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:{},M=new Set(Object.keys(o.sites??{})),j={};for(let[Z,me]of Object.entries(T)){if(!M.has(Z))return b({ok:!1,error:`Site '${Z}' was not found.`},404);if(me!=="owner"&&me!=="collaborator")return b({ok:!1,error:`Unknown site role '${me}'. Use 'owner' or 'collaborator'.`},422);j[Z]=me}let X=typeof d.password==="string"&&d.password.trim()?d.password.trim():void 0;if(X&&X.length<12)return b({ok:!1,error:"Password must be at least 12 characters."},422);let U=Na(t,{username:l,password:X,name:typeof d.name==="string"?d.name:void 0,sites:j});return Ya(a,nn(t)),Fn(),b({ok:!0,user:ia(U.user),password:U.password})}if(F.pathname==="/api/users"&&I.method==="DELETE"){let d=await ie(I),l=String(d.username??"").trim();if(l.toLowerCase()===ae.username.toLowerCase())return b({ok:!1,error:"You cannot remove your own account."},409);let T=Nn(nn(t),l),M=T?a.store.getActorByExternalId("user",`dashboard:${T.username.toLowerCase()}`):void 0,j=M?a.store.getMembershipForActor(a.organization.id,M.id):void 0;if(j&&j.source!=="legacy")return b({ok:!1,error:"Organization members must be removed from Organization access."},409);let X=Ql(t,l);if(!X.ok)return b(X,409);return Ya(a,nn(t)),ke.clear(),b({ok:!0,username:l})}if(F.pathname==="/api/actions/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=d.action?hA(d.action,ye):void 0;if(!l)return b({ok:!1,error:"Unknown dashboard action."},404);if(l.mutates&&d.confirm!==l.confirm)return b({ok:!1,error:`Type "${l.confirm}" to run this action.`},409);let T=await zi({controlPlane:a,environment:ye,actor:ae,kind:`dashboard.action.${l.id}`,input:{action:l.id},execute:()=>ap(l,{cwd:t,cliEntry:i})});return b({...T.result,controlPlaneOperation:T.operation})}if(F.pathname==="/api/server/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=d.operation?ni(d.operation,o,Lt):void 0;if(!l)return b({ok:!1,error:"Unknown or unavailable server operation."},404);if(l.mutates&&d.confirm!==l.confirm)return b({ok:!1,error:`Type "${l.confirm}" to run this operation.`},409);let T=ue(a,String(ye));await new rs(rt).run(new Ra,{...T,artifactRoot:t});let M=dr(rt,{scope:T,desiredConfigHash:a.project.desiredConfigHash});if(M.decision.outcome==="block")return b({ok:!1,error:`Operation blocked by security policy: ${M.decision.explanation}`,securityReview:M},409);let j=await zi({controlPlane:a,environment:ye,actor:ae,kind:`dashboard.server.${l.id}`,resourceSlug:l.target,input:{operation:l.id,target:l.target,to:d.to??null},execute:()=>Jr(o,ye,l,{to:d.to})});return b({...j.result,controlPlaneOperation:j.operation,securityReview:M})}if(F.pathname==="/api/server/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return b({ok:!1,error:'Type "run" to execute this command on the server.'},409);let l=await zi({controlPlane:a,environment:ye,actor:ae,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>cr(o,ye,String(d.command??""))});return b({...l.result,controlPlaneOperation:l.operation})}if(F.pathname==="/api/serverless/operations")return b(rp(o,ye,Lt));if(F.pathname==="/api/serverless/operations/run"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=d.operation?jy(d.operation,o,ye,Lt):void 0;if(!l)return b({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(l.mutates&&d.confirm!==l.confirm)return b({ok:!1,error:`Type "${l.confirm}" to run this operation.`},409);let T=await zi({controlPlane:a,environment:ye,actor:ae,kind:`dashboard.serverless.${l.id}`,input:{operation:l.id,min:d.min??null,max:d.max??null},execute:()=>Uy(o,ye,l,{min:d.min,max:d.max})});return Lt=await ps(o,ye),W.set(ye,Lt),b({...T.result,controlPlaneOperation:T.operation})}if(F.pathname==="/api/serverless/command"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="run")return b({ok:!1,error:'Type "run" to execute this command.'},409);return b(await zy(o,ye,String(d.command??"")))}if(F.pathname==="/api/serverless/dlq"&&I.method==="GET"){let d=Number(F.searchParams.get("max"))||10;return b(await Vy(o,ye,d))}if(F.pathname==="/api/serverless/dlq/redrive"&&I.method==="POST"){let d=await I.json().catch(()=>({}));if(d.confirm!=="redrive")return b({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return b(await qy(o,ye,{max:d.max,targetQueue:d.targetQueue}))}if(F.pathname==="/api/serverless/dlq/purge"&&I.method==="POST"){if((await I.json().catch(()=>({}))).confirm!=="purge")return b({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return b(await Gy(o,ye))}if(F.pathname==="/api/serverless/secrets"&&I.method==="GET")return b({secrets:Jy(o,ye)});if(F.pathname==="/api/serverless/secrets"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.secretId??"").trim();if(!l)return b({ok:!1,error:"A secret id is required."},422);if(typeof d.value!=="string"||d.value==="")return b({ok:!1,error:"A non-empty value is required."},422);return b(await Hy(o,ye,l,d.value))}if(F.pathname==="/api/serverless/secrets"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),l=String(d.secretId??"").trim();if(!l)return b({ok:!1,error:"A secret id is required."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to delete this secret.`},409);return b(await Wy(o,ye,l))}if(F.pathname==="/api/serverless/functions/config"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.mode??"").trim();if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to update this function.`},409);return b(await Ky(o,ye,l,{memory:d.memory,timeout:d.timeout}))}if(F.pathname==="/api/serverless/alarms"&&I.method==="GET")return b(await Qy(o,ye));if(F.pathname==="/api/serverless/alarms"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.preset??"").trim(),T=Number(d.threshold);if(!l)return b({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(T))return b({ok:!1,error:"A numeric threshold is required."},422);return b(await Yy(o,ye,l,T))}if(F.pathname==="/api/serverless/alarms"&&I.method==="DELETE"){let d=await I.json().catch(()=>({})),l=String(d.name??"").trim();if(!l)return b({ok:!1,error:"An alarm name is required."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to delete this alarm.`},409);return b(await Xy(o,ye,l))}if(F.pathname==="/api/serverless/traces"&&I.method==="GET"){let d=Number(F.searchParams.get("minutes"))||30;return b(await Ed(o,ye,d))}if(F.pathname==="/api/serverless/scheduler"&&I.method==="POST"){let d=await I.json().catch(()=>({})),l=String(d.action??"").trim();if(l!=="enable"&&l!=="disable"&&l!=="run")return b({ok:!1,error:"Unknown scheduler action."},422);if(d.confirm!==l)return b({ok:!1,error:`Type "${l}" to ${l} the scheduler.`},409);return b(await op(o,ye,l))}if(!fb(F.pathname,Tn))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(ye)}`}});let vs=await ki(ae,ye);if(!vs)return Rd("ts-cloud dashboard UI is unavailable.",503);return hb(vs,F.pathname)}catch(jo){if(e.verbose)console.error(jo);return b({ok:!1,error:jo?.message??String(jo)},500)}})();if(!Kt)return Kt;if(gt&&(F.pathname.startsWith("/api/")||F.pathname.startsWith("/auth/"))){let Ke;if((Ie.headers.get("content-type")||"").includes("application/json"))Ke=await Ie.json().catch(()=>{return});let Sr=Ft.resolveUser(I),mr=Sr?_e(Sr).actor:void 0;a.store.appendEvent({organizationId:a.organization.id,projectId:a.project.id,actorId:mr?.id,correlationId:Ve,type:Kt.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:Kt.status<400?"info":"warning",payload:eA(I.method,F.pathname,Ke,Kt.status,Date.now()-De)})}return Kt.headers.set("x-request-id",Ve),Kt}});Ua?.start();let Ob=e.spendLoop??!0,kp;if(Ob)(async()=>{let{SpendRunner:I,SpendLoopLease:Te,startSpendLoop:De}=await import("./chunk-37gemrn2.js"),{store:Ie}=await bb(a.store),Ve=new I({controlPlane:a.store,store:Ie,alerts:Je});kp=De(Ve,{lease:new Te(a.store,{owner:`dashboard:${process.pid}`}),onError:(gt)=>console.error(`[ts-cloud] spend cycle failed: ${gt instanceof Error?gt.message:String(gt)}`)})})();let _b=bs.stop.bind(bs);return bs.stop=(I)=>{clearInterval(Cp),clearInterval(Ep),clearInterval(Tp),clearInterval(Ip),clearInterval(wp),clearInterval(yp),clearInterval(bp),clearInterval(Sp),clearInterval(vp),Fn(),Xt.clear(),Ua?.stop(),kp?.();let Te=_b(I);if(Ua)Ua.settled().finally(()=>a.store.close());else a.store.close();return Te},{server:bs,url:`http://${r}:${bs.port}/`}}
|
|
511
|
+
export{Le,x,xn,y,_n,Ji,On,ss,Hr,at,xe,$n,Ln,Mn,Un,Bn,jn,Vn,zn,oe,rr,nr,Hn,Gr,Gn,qn,Wn,Kn,Jn,Xn,Qn,Yn,ct,ir,or,Nt,qr,sr,ar,Xi,xt,Zn,de,ei,ti,ri,Wr,Kr,ni,Jr,cr,lr,lt,_t,Ot,Xr,ue,ii,lc,dc,dr,uc,G,Qi,Ge,dt,ut,oi,Qr,si,Yr,ai,ci,Zr,as,pe,ve,Me,Ce,li,ur};
|