@stacksjs/ts-cloud 0.16.79 → 0.16.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/bin/{chunk-fgnvksyx.js → chunk-6kx0fddd.js} +1 -1
  2. package/dist/bin/{chunk-grx14tmn.js → chunk-b074y2np.js} +1 -1
  3. package/dist/bin/{chunk-vgcscxh1.js → chunk-f0djc6da.js} +1 -1
  4. package/dist/bin/{chunk-2wkw8qy0.js → chunk-jhydr9dp.js} +1 -1
  5. package/dist/bin/chunk-m1w3p30q.js +1 -0
  6. package/dist/bin/chunk-qssb91v3.js +11 -0
  7. package/dist/bin/cli.js +7 -7
  8. package/dist/bin/dashboard-server.js +1 -1
  9. package/dist/{chunk-wy0bqg1v.js → chunk-kjkkh11z.js} +1 -1
  10. package/dist/{chunk-p9cm5ynz.js → chunk-z52n96sa.js} +67 -65
  11. package/dist/deploy/index.js +1 -1
  12. package/dist/drivers/index.js +1 -1
  13. package/dist/drivers/shared/backups.test.d.ts +1 -0
  14. package/dist/index.js +1 -1
  15. package/dist/ui/404.html +1 -1
  16. package/dist/ui/accept-invitation.html +1 -1
  17. package/dist/ui/access-denied.html +1 -1
  18. package/dist/ui/account/automation.html +5 -5
  19. package/dist/ui/account/security.html +2 -2
  20. package/dist/ui/applications/compose.html +6 -6
  21. package/dist/ui/applications/new.html +2 -2
  22. package/dist/ui/data/backups.html +6 -6
  23. package/dist/ui/data/services.html +6 -6
  24. package/dist/ui/data/volumes.html +5 -5
  25. package/dist/ui/index.html +6 -6
  26. package/dist/ui/infrastructure/topology.html +6 -6
  27. package/dist/ui/integrations.html +1 -1
  28. package/dist/ui/operations/alerts.html +6 -6
  29. package/dist/ui/operations/configuration.html +6 -6
  30. package/dist/ui/operations/jobs.html +5 -5
  31. package/dist/ui/operations/maintenance.html +5 -5
  32. package/dist/ui/operations/observability.html +5 -5
  33. package/dist/ui/operations/previews.html +5 -5
  34. package/dist/ui/operations/queue.html +5 -5
  35. package/dist/ui/operations/regions.html +5 -5
  36. package/dist/ui/operations/releases.html +5 -5
  37. package/dist/ui/operations/spend.html +5 -5
  38. package/dist/ui/operations/workloads.html +5 -5
  39. package/dist/ui/security.html +2 -2
  40. package/dist/ui/server/actions.html +5 -5
  41. package/dist/ui/server/activity.html +1 -1
  42. package/dist/ui/server/capacity.html +5 -5
  43. package/dist/ui/server/database.html +6 -6
  44. package/dist/ui/server/deployments.html +6 -6
  45. package/dist/ui/server/diagnostics.html +2 -2
  46. package/dist/ui/server/firewall.html +6 -6
  47. package/dist/ui/server/fleet.html +6 -6
  48. package/dist/ui/server/logs.html +6 -6
  49. package/dist/ui/server/metrics.html +6 -6
  50. package/dist/ui/server/security.html +2 -2
  51. package/dist/ui/server/services.html +2 -2
  52. package/dist/ui/server/sites.html +6 -6
  53. package/dist/ui/server/ssh-keys.html +6 -6
  54. package/dist/ui/server/team.html +6 -6
  55. package/dist/ui/server/terminal.html +2 -2
  56. package/dist/ui/serverless/alarms.html +6 -6
  57. package/dist/ui/serverless/assets.html +1 -1
  58. package/dist/ui/serverless/cost.html +2 -2
  59. package/dist/ui/serverless/data.html +6 -6
  60. package/dist/ui/serverless/deployments.html +2 -2
  61. package/dist/ui/serverless/firewall.html +1 -1
  62. package/dist/ui/serverless/functions.html +6 -6
  63. package/dist/ui/serverless/logs.html +6 -6
  64. package/dist/ui/serverless/metrics.html +2 -2
  65. package/dist/ui/serverless/queues.html +6 -6
  66. package/dist/ui/serverless/secrets.html +6 -6
  67. package/dist/ui/serverless/traces.html +6 -6
  68. package/dist/ui/serverless.html +6 -6
  69. package/package.json +3 -3
  70. package/dist/bin/chunk-nzky7rgv.js +0 -1
  71. package/dist/bin/chunk-ps0pzqm0.js +0 -9
@@ -1,4 +1,4 @@
1
- import{ua,ze,I,H,A,U,$e,rr}from"./chunk-wayhpmn7.js";import{ce,Tn,re,En,h,Br,la}from"./chunk-fhqjr3ba.js";import{Be,S,ps,hr,gi,fi,rn,Sc,Ft,nn,gt,Ke,Fe,Je,vc,ht,yr,je,Xe,hi,yi,to,ro,Qe,on,vr,yt,m,uo,Rs,Is}from"./chunk-jcehsvnm.js";import{Jt,Xt,p}from"./chunk-540wkkhs.js";import{v}from"./chunk-4vtyjj7c.js";import{g}from"./chunk-gqstb8zn.js";import{W,w,R,Tt,Po,Et,fn}from"./chunk-ps0pzqm0.js";import{Ze,Er,yo,O,mn,zc,Hc,zt,Ii,Pi}from"./chunk-2wkw8qy0.js";import{Vo}from"./chunk-0r8k7qth.js";import{fe}from"./chunk-0e7y7q0t.js";import{Ps,Ds}from"./chunk-vgcscxh1.js";import{Or,Pt,$r,Lr,Mr,Ur,Cn}from"./chunk-0zydd9s4.js";import{ae,q,Ti}from"./chunk-06hwds44.js";import{E}from"./chunk-tf5tf414.js";import{V}from"./chunk-y5gx3dq2.js";import{D}from"./chunk-6xx24qev.js";import{J,ea,ta,qo,Wt,z,ra}from"./chunk-0v5q5sh0.js";import{Js}from"./chunk-kyqe19mh.js";import{bn}from"./chunk-ma0d990n.js";import{L,x,aa}from"./chunk-gbbcp2bw.js";import{createCipheriv as Fb,createDecipheriv as jb,createHash as Bp,randomBytes as zi}from"node:crypto";import{createHmac as Lb,timingSafeEqual as Bb}from"node:crypto";var Bd="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function Wa(e){let t=0,r=0,n="";for(let i of e){r=r<<8|i,t+=8;while(t>=5)n+=Bd[r>>>t-5&31],t-=5}if(t>0)n+=Bd[r<<5-t&31];return n}function Op(e){let t=e.toUpperCase().replace(/[^A-Z2-7]/g,""),r=0,n=0,i=[];for(let o of t){let s=Bd.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 _p(e,t,r=6){let n=Buffer.alloc(8);n.writeBigUInt64BE(BigInt(t));let i=Lb("sha1",Op(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 Ka(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(_p(e,s+c));if(o.length===u.length&&Bb(o,u))return s+c}return}function Fd(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 Fp=1800000,vo=43200000,jp=3600000,Up=300000,zp=600000;function yn(e){return typeof e==="string"?e:void 0}function Vp(e){if(typeof e!=="string")return{};try{return JSON.parse(e)}catch{return{}}}function Ub(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 jd(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 zb(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 Vb(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 qb(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 Gb(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 Nn(e){return Bp("sha256").update(e).digest("hex")}function ga(e){return{id:String(e.id),actorId:String(e.actor_id),username:String(e.username),email:yn(e.email),emailVerifiedAt:yn(e.email_verified_at),passwordHash:String(e.password_hash),credentialVersion:Number(e.credential_version),requiresPasswordUpgrade:Number(e.requires_password_upgrade)===1,disabledAt:yn(e.disabled_at),lastLoginAt:yn(e.last_login_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Np(e,t){let r=yn(e.consumed_at),n=String(e.expires_at);return{id:String(e.id),identityId:String(e.identity_id),type:String(e.type),metadata:Vp(e.metadata),expiresAt:n,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":n<=t?"expired":"pending"}}function Ud(e,t){let r=yn(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:yn(e.user_agent),networkHint:yn(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:yn(e.mfa_at),revokedAt:r,state:r?"revoked":n<=t||i<=t?"expired":"active"}}function $p(e){let t=yn(e.verified_at),r=yn(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 zd(e,t){let r=yn(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 Mp(e){let t=Vp(e);return Array.isArray(t)?t.filter((r)=>typeof r==="string"):[]}function Qa(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:Mp(e.scopes),allowedDomains:Mp(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 Lp(e,t){let r=yn(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 Jb(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 Me{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?Bp("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=zi(12),r=Fb("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=jb("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=Ub(e.username),r=jd(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)
1
+ import{ua,ze,I,H,A,U,$e,rr}from"./chunk-wayhpmn7.js";import{ce,Tn,re,En,h,Br,la}from"./chunk-fhqjr3ba.js";import{Be,S,ps,hr,gi,fi,rn,Sc,Ft,nn,gt,Ke,Fe,Je,vc,ht,yr,je,Xe,hi,yi,to,ro,Qe,on,vr,yt,m,uo,Rs,Is}from"./chunk-jcehsvnm.js";import{Jt,Xt,p}from"./chunk-540wkkhs.js";import{v}from"./chunk-4vtyjj7c.js";import{g}from"./chunk-gqstb8zn.js";import{W,w,R,Tt,Po,Et,fn}from"./chunk-qssb91v3.js";import{Ze,Er,yo,O,mn,zc,Hc,zt,Ii,Pi}from"./chunk-jhydr9dp.js";import{Vo}from"./chunk-0r8k7qth.js";import{fe}from"./chunk-0e7y7q0t.js";import{Ps,Ds}from"./chunk-f0djc6da.js";import{Or,Pt,$r,Lr,Mr,Ur,Cn}from"./chunk-0zydd9s4.js";import{ae,q,Ti}from"./chunk-06hwds44.js";import{E}from"./chunk-tf5tf414.js";import{V}from"./chunk-y5gx3dq2.js";import{D}from"./chunk-6xx24qev.js";import{J,ea,ta,qo,Wt,z,ra}from"./chunk-0v5q5sh0.js";import{Js}from"./chunk-kyqe19mh.js";import{bn}from"./chunk-ma0d990n.js";import{L,x,aa}from"./chunk-gbbcp2bw.js";import{createCipheriv as Fb,createDecipheriv as jb,createHash as Bp,randomBytes as zi}from"node:crypto";import{createHmac as Lb,timingSafeEqual as Bb}from"node:crypto";var Bd="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function Wa(e){let t=0,r=0,n="";for(let i of e){r=r<<8|i,t+=8;while(t>=5)n+=Bd[r>>>t-5&31],t-=5}if(t>0)n+=Bd[r<<5-t&31];return n}function Op(e){let t=e.toUpperCase().replace(/[^A-Z2-7]/g,""),r=0,n=0,i=[];for(let o of t){let s=Bd.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 _p(e,t,r=6){let n=Buffer.alloc(8);n.writeBigUInt64BE(BigInt(t));let i=Lb("sha1",Op(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 Ka(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(_p(e,s+c));if(o.length===u.length&&Bb(o,u))return s+c}return}function Fd(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 Fp=1800000,vo=43200000,jp=3600000,Up=300000,zp=600000;function yn(e){return typeof e==="string"?e:void 0}function Vp(e){if(typeof e!=="string")return{};try{return JSON.parse(e)}catch{return{}}}function Ub(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 jd(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 zb(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 Vb(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 qb(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 Gb(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 Nn(e){return Bp("sha256").update(e).digest("hex")}function ga(e){return{id:String(e.id),actorId:String(e.actor_id),username:String(e.username),email:yn(e.email),emailVerifiedAt:yn(e.email_verified_at),passwordHash:String(e.password_hash),credentialVersion:Number(e.credential_version),requiresPasswordUpgrade:Number(e.requires_password_upgrade)===1,disabledAt:yn(e.disabled_at),lastLoginAt:yn(e.last_login_at),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Np(e,t){let r=yn(e.consumed_at),n=String(e.expires_at);return{id:String(e.id),identityId:String(e.identity_id),type:String(e.type),metadata:Vp(e.metadata),expiresAt:n,consumedAt:r,createdAt:String(e.created_at),state:r?"consumed":n<=t?"expired":"pending"}}function Ud(e,t){let r=yn(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:yn(e.user_agent),networkHint:yn(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:yn(e.mfa_at),revokedAt:r,state:r?"revoked":n<=t||i<=t?"expired":"active"}}function $p(e){let t=yn(e.verified_at),r=yn(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 zd(e,t){let r=yn(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 Mp(e){let t=Vp(e);return Array.isArray(t)?t.filter((r)=>typeof r==="string"):[]}function Qa(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:Mp(e.scopes),allowedDomains:Mp(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 Lp(e,t){let r=yn(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 Jb(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 Me{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?Bp("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=zi(12),r=Fb("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=jb("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=Ub(e.username),r=jd(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?ga(t):void 0}getIdentityByActor(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE actor_id = ?").get(e);return t?ga(t):void 0}getIdentityByUsername(e){let t=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE username = ? COLLATE NOCASE").get(e.trim());return t?ga(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?ga(t):void 0}listIdentities(){return this.controlPlane.database.query("SELECT * FROM auth_identities ORDER BY username COLLATE NOCASE").all().map(ga)}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=jd(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=zi(32).toString("base64url"),i=this.idFn(),o=this.now(),s=new Date(this.nowFn().getTime()+Math.min(86400000,Math.max(60000,r.ttlMs??jp))).toISOString();return this.run("INSERT INTO auth_action_tokens (id, identity_id, type, token_hash, metadata, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[i,e,t,Nn(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?Np(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(Nn(e),t);if(!r)throw Error("Action token is invalid");let n=Np(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=zi(32).toString("base64url"),i=`v2.${r}.${n}`,o=this.now(),s=Math.min(86400000,Math.max(60000,e.idleTtlMs??Fp)),c=Math.min(2592000000,Math.max(s,e.absoluteTtlMs??vo));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)
@@ -1 +1 @@
1
- import{Pi}from"./chunk-2wkw8qy0.js";import"./chunk-9ktyfegk.js";import"./chunk-ps0pzqm0.js";import"./chunk-0r8k7qth.js";import"./chunk-4vtyjj7c.js";import"./chunk-gqstb8zn.js";import"./chunk-540wkkhs.js";import"./chunk-wayhpmn7.js";import"./chunk-33shhgye.js";export{Pi as resolveServerDashboardData};
1
+ import{Pi}from"./chunk-jhydr9dp.js";import"./chunk-9ktyfegk.js";import"./chunk-qssb91v3.js";import"./chunk-0r8k7qth.js";import"./chunk-4vtyjj7c.js";import"./chunk-gqstb8zn.js";import"./chunk-540wkkhs.js";import"./chunk-wayhpmn7.js";import"./chunk-33shhgye.js";export{Pi as resolveServerDashboardData};
@@ -1,3 +1,3 @@
1
- import{W,w,R,xi,js,Ht,Xc,Qc}from"./chunk-ps0pzqm0.js";function g(e){return`'${e.split("'").join("'\\''")}'`}function p(e){let r=e.user||"root",t=e.script.join(`
1
+ import{W,w,R,xi,js,Ht,Xc,Qc}from"./chunk-qssb91v3.js";function g(e){return`'${e.split("'").join("'\\''")}'`}function p(e){let r=e.user||"root",t=e.script.join(`
2
2
  `),s=r==="root"?'bash -l "$TS_CLOUD_RECIPE"':`runuser -l ${g(r)} -c "bash $TS_CLOUD_RECIPE"`;return["set -uo pipefail",`echo "__TS_CLOUD_RECIPE_BEGIN__ ${e.name} (user=${r})"`,"TS_CLOUD_RECIPE=$(mktemp)",`cat > "$TS_CLOUD_RECIPE" <<'TS_CLOUD_RECIPE_EOF'`,t,"TS_CLOUD_RECIPE_EOF",'chmod +r "$TS_CLOUD_RECIPE"',s,"TS_CLOUD_RC=$?",'rm -f "$TS_CLOUD_RECIPE"',`echo "__TS_CLOUD_RECIPE_END__ ${e.name} exit=$TS_CLOUD_RC"`,"exit $TS_CLOUD_RC"]}var c={info:()=>{},warn:()=>{},error:()=>{},step:()=>{},success:()=>{}};async function u(e){return await e.driver.findComputeTargets({slug:e.slug,environment:e.environment,role:e.role||"app"})}async function Ps(e,r){let t=e.logger||c,s=await u(e);if(s.length===0)return{success:!1,error:`No '${e.role||"app"}' servers found for ${e.slug}/${e.environment}.`};let n=W(e.slug,r.siteName),o=Ht(n,r.to||"unused"),a=r.onlyIfLive?f(o.current,r.siteName,r.onlyIfLive):[];if(r.dryRun){let l=await e.driver.runRemoteDeploy({targets:s,commands:["set -uo pipefail",...a,...Xc(o,r.to?{to:r.to}:{})],comment:`ts-cloud rollback plan ${e.slug}/${r.siteName}`,tags:{Project:e.slug,Environment:e.environment,Role:e.role||"app"}});return{success:l.success,error:l.error,perInstance:l.perInstance}}let m=["set -euo pipefail",...a,...Qc(o,{...r.to?{to:r.to}:{},unitBase:`${e.slug}-${r.siteName}`})];if(r.site&&w(r.site)==="server-php")m.push(`(cd ${R} && pantry restart php-fpm)`,`if [ -f ${o.current}/artisan ]; then (cd ${o.current} && TS_CLOUD_RB_ENV=$(cd ${R} && pantry env) && eval "$TS_CLOUD_RB_ENV" && php artisan queue:restart); fi`);t.step(`Rolling back ${r.siteName}${r.to?` to ${r.to}`:" to the previous release"} on ${s.length} server(s)...`);let i=await e.driver.runRemoteDeploy({targets:s,commands:m,comment:`ts-cloud rollback ${e.slug}/${r.siteName}`,tags:{Project:e.slug,Environment:e.environment,Role:e.role||"app"}});if(!i.success)t.error(`Rollback failed: ${i.error||"unknown error"}`);else t.success(`Rolled back ${r.siteName}.`);return{success:i.success,error:i.error,perInstance:i.perInstance}}function f(e,r,t){let s=t.replace(/[^0-9A-Za-z._-]/g,"");return[`TS_CLOUD_LIVE_ID=$(basename "$(readlink -f ${e} 2>/dev/null)" 2>/dev/null || true)`,`if [ -z "$TS_CLOUD_LIVE_ID" ] || [ "$TS_CLOUD_LIVE_ID" = "." ]; then echo "${r}: no live release here; left alone"; exit 0; fi`,`case "${s}" in "$TS_CLOUD_LIVE_ID"*) ;; *) echo "${r} serves $TS_CLOUD_LIVE_ID, not ${s}; left alone"; exit 0 ;; esac`]}async function pm(e,r){let t=await u(e);if(t.length===0)return{success:!1,error:`No '${e.role||"app"}' servers found for ${e.slug}/${e.environment}.`};let s=js(W(e.slug,r.siteName)),n=Math.max(1,r.limit??20),o=[`[ -f ${s} ] && tail -n ${n} ${s} || echo "no deploy history for ${r.siteName}"`],a=await e.driver.runRemoteDeploy({targets:t,commands:o,comment:`ts-cloud deploy:history ${e.slug}/${r.siteName}`,tags:{Project:e.slug,Environment:e.environment,Role:e.role||"app"}});return{success:a.success,error:a.error,perInstance:a.perInstance}}async function mm(e,r){let t=e.logger||c,s=await u(e);if(s.length===0)return{success:!1,error:`No '${e.role||"app"}' servers found for ${e.slug}/${e.environment}.`};t.step(`Running recipe '${r.name}' as ${r.user||"root"} on ${s.length} server(s)...`);let n=await e.driver.runRemoteDeploy({targets:s,commands:p({name:r.name,script:r.script,user:r.user}),comment:`ts-cloud recipe ${r.name}`,tags:{Project:e.slug,Environment:e.environment,Role:e.role||"app"}});if(!n.success)t.error(`Recipe '${r.name}' failed: ${n.error||"unknown error"}`);else t.success(`Recipe '${r.name}' completed.`);return{success:n.success,error:n.error,perInstance:n.perInstance}}async function Ds(e,r){let t=e.logger||c;if(!r.database?.name)return{success:!1,error:"No appDatabase configured to restore."};let s=await u(e);if(s.length===0)return{success:!1,error:`No '${e.role||"app"}' servers found for ${e.slug}/${e.environment}.`};t.step(`Restoring database '${r.database.name}'${r.from?` from ${r.from}`:" from the latest backup"} on ${s.length} server(s)...`);let n=await e.driver.runRemoteDeploy({targets:s,commands:xi(r.database,{from:r.from}),comment:`ts-cloud db:restore ${e.slug}/${r.database.name}`,tags:{Project:e.slug,Environment:e.environment,Role:e.role||"app"}});if(!n.success)t.error(`Restore failed: ${n.error||"unknown error"}`);else t.success(`Restored ${r.database.name}.`);return{success:n.success,error:n.error,perInstance:n.perInstance}}
3
3
  export{Ps,pm,mm,Ds};
@@ -1,4 +1,4 @@
1
- import{p}from"./chunk-540wkkhs.js";import{pa,I,A,ne,jr,ga,Jo,le,U,T,er,Vr}from"./chunk-wayhpmn7.js";import{v}from"./chunk-4vtyjj7c.js";import{Q}from"./chunk-9ktyfegk.js";import{g}from"./chunk-gqstb8zn.js";import{W,ki,Us,w,R,Tt,Ve,it,Io,Ni,Do,wt,Kc,ko,No,_i,xo,Oi,Ht,Vs,Jc,$i,zs,Hs,Gs,qs,_o,hn,Ws,yn,Ks,Oo}from"./chunk-ps0pzqm0.js";import{zo,Ho,Ys}from"./chunk-0r8k7qth.js";import{Ms}from"./chunk-k3cyh23p.js";import{Pr}from"./chunk-hhbmtgkq.js";import{bn}from"./chunk-ma0d990n.js";import{el}from"./chunk-hyrvmjq0.js";class Ze{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new p}async putParameter(e){let t={Name:e.Name,Value:e.Value};if(e.Type)t.Type=e.Type;if(e.Description)t.Description=e.Description;if(e.KeyId)t.KeyId=e.KeyId;if(e.Overwrite!==void 0)t.Overwrite=e.Overwrite;if(e.AllowedPattern)t.AllowedPattern=e.AllowedPattern;if(e.Tags&&e.Tags.length>0)t.Tags=e.Tags;if(e.Tier)t.Tier=e.Tier;if(e.DataType)t.DataType=e.DataType;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.PutParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Version:r.Version,Tier:r.Tier}}async getParameter(e){let t={Name:e.Name};if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameter:r.Parameter?this.parseParameter(r.Parameter):void 0}}async getParameters(e){let t={Names:e.Names};if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>this.parseParameter(n)),InvalidParameters:r.InvalidParameters}}async getParametersByPath(e){let t={Path:e.Path};if(e.Recursive!==void 0)t.Recursive=e.Recursive;if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;if(e.MaxResults)t.MaxResults=e.MaxResults;if(e.NextToken)t.NextToken=e.NextToken;if(e.ParameterFilters&&e.ParameterFilters.length>0)t.ParameterFilters=e.ParameterFilters;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParametersByPath","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>this.parseParameter(n)),NextToken:r.NextToken}}async deleteParameter(e){let t={Name:e.Name};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async deleteParameters(e){let t={Names:e},r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{DeletedParameters:r.DeletedParameters,InvalidParameters:r.InvalidParameters}}async describeParameters(e){let t={};if(e?.Filters&&e.Filters.length>0)t.Filters=e.Filters;if(e?.ParameterFilters&&e.ParameterFilters.length>0)t.ParameterFilters=e.ParameterFilters;if(e?.MaxResults)t.MaxResults=e.MaxResults;if(e?.NextToken)t.NextToken=e.NextToken;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DescribeParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>this.parseParameter(n)),NextToken:r.NextToken}}async getParameterHistory(e){let t={Name:e.Name};if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;if(e.MaxResults)t.MaxResults=e.MaxResults;if(e.NextToken)t.NextToken=e.NextToken;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameterHistory","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>({Name:n.Name,Type:n.Type,KeyId:n.KeyId,LastModifiedDate:n.LastModifiedDate,LastModifiedUser:n.LastModifiedUser,Description:n.Description,Value:n.Value,Version:n.Version,Labels:n.Labels,Tier:n.Tier})),NextToken:r.NextToken}}async labelParameterVersion(e){let t={Name:e.Name,Labels:e.Labels};if(e.ParameterVersion!==void 0)t.ParameterVersion=e.ParameterVersion;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.LabelParameterVersion","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{InvalidLabels:r.InvalidLabels,ParameterVersion:r.ParameterVersion}}async addTagsToResource(e){let t={ResourceType:e.ResourceType,ResourceId:e.ResourceId,Tags:e.Tags};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.AddTagsToResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async removeTagsFromResource(e){let t={ResourceType:e.ResourceType,ResourceId:e.ResourceId,TagKeys:e.TagKeys};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.RemoveTagsFromResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async listTagsForResource(e){let t={ResourceType:e.ResourceType,ResourceId:e.ResourceId};return{TagList:(await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListTagsForResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})).TagList}}async setString(e,t,r){return this.putParameter({Name:e,Value:t,Type:"String",Description:r?.description,Overwrite:r?.overwrite??!0,Tags:r?.tags})}async setSecureString(e,t,r){return this.putParameter({Name:e,Value:t,Type:"SecureString",Description:r?.description,Overwrite:r?.overwrite??!0,KeyId:r?.kmsKeyId,Tags:r?.tags})}async getValue(e){return(await this.getParameter({Name:e,WithDecryption:!0})).Parameter?.Value}async getAllByPath(e,t=!0){let r=[],n;do{let s=await this.getParametersByPath({Path:e,Recursive:t,WithDecryption:!0,NextToken:n});if(s.Parameters)r.push(...s.Parameters);n=s.NextToken}while(n);return r}parseParameter(e){return{Name:e.Name,Type:e.Type,Value:e.Value,Version:e.Version,LastModifiedDate:e.LastModifiedDate,ARN:e.ARN,DataType:e.DataType,Description:e.Description,AllowedPattern:e.AllowedPattern,KeyId:e.KeyId,Tier:e.Tier}}async sendCommand(e){if(!e.InstanceIds&&!e.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let t={DocumentName:e.DocumentName};if(e.InstanceIds)t.InstanceIds=e.InstanceIds;if(e.Targets)t.Targets=e.Targets;if(e.Parameters)t.Parameters=e.Parameters;if(e.TimeoutSeconds)t.TimeoutSeconds=e.TimeoutSeconds;if(e.Comment)t.Comment=e.Comment;if(e.OutputS3BucketName)t.OutputS3BucketName=e.OutputS3BucketName;if(e.OutputS3KeyPrefix)t.OutputS3KeyPrefix=e.OutputS3KeyPrefix;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.SendCommand","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{CommandId:r.Command?.CommandId,Status:r.Command?.Status,StatusDetails:r.Command?.StatusDetails}}async getCommandInvocation(e){let t={CommandId:e.CommandId,InstanceId:e.InstanceId},r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetCommandInvocation","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Status:r.Status,StatusDetails:r.StatusDetails,StandardOutputContent:r.StandardOutputContent,StandardErrorContent:r.StandardErrorContent,ResponseCode:r.ResponseCode}}async runShellCommand(e,t,r){let n=await this.sendCommand({InstanceIds:[e],DocumentName:"AWS-RunShellScript",Parameters:{commands:t},TimeoutSeconds:r?.timeoutSeconds||600});if(!n.CommandId)return{success:!1,error:"Failed to send command"};if(r?.waitForCompletion===!1)return{success:!0,status:"Pending"};let s=r?.pollIntervalMs||2000,i=r?.maxWaitMs||300000,o=Date.now();while(Date.now()-o<i){await new Promise((a)=>setTimeout(a,s));try{let a=await this.getCommandInvocation({CommandId:n.CommandId,InstanceId:e});if(a.Status==="Success")return{success:!0,output:a.StandardOutputContent,error:a.StandardErrorContent,status:a.Status};if(a.Status==="Failed"||a.Status==="Cancelled"||a.Status==="TimedOut")return{success:!1,output:a.StandardOutputContent,error:a.StandardErrorContent||a.StatusDetails,status:a.Status}}catch(a){if(!a.message?.includes("InvocationDoesNotExist"))return{success:!1,error:a.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations(e){let t={CommandId:e.CommandId};if(e.Details)t.Details=!0;return((await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListCommandInvocations","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})).CommandInvocations||[]).map((s)=>({InstanceId:s.InstanceId,Status:s.Status,StatusDetails:s.StatusDetails,StandardOutputContent:s.CommandPlugins?.[0]?.Output,StandardErrorContent:s.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags(e){let t=Object.entries(e.tags).map(([c,l])=>({Key:`tag:${c}`,Values:[l]})),r=await this.sendCommand({Targets:t,DocumentName:"AWS-RunShellScript",Parameters:{commands:e.commands},TimeoutSeconds:e.timeoutSeconds||600,Comment:e.comment});if(!r.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let n=e.pollIntervalMs||3000,s=e.maxWaitMs||600000,i=Date.now(),o=new Set(["Success","Failed","Cancelled","TimedOut"]),a=[];while(Date.now()-i<s){await new Promise((c)=>setTimeout(c,n));try{if(a=await this.listCommandInvocations({CommandId:r.CommandId,Details:!0}),a.length===0)continue;if(a.every((l)=>o.has(l.Status||""))){let l=a.map((d)=>({instanceId:d.InstanceId,status:d.Status||"Unknown",output:d.StandardOutputContent,error:d.StandardErrorContent||d.StatusDetails})),u=a.every((d)=>d.Status==="Success");return{success:u,instanceCount:a.length,perInstance:l,error:u?void 0:"One or more instances reported a non-success status"}}}catch(c){if(!c.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:c.message}}}return{success:!1,instanceCount:a.length,perInstance:a.map((c)=>({instanceId:c.InstanceId,status:c.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}function ks(e={}){let t=new Set;for(let r of Object.values(e)){if(!r.domain)continue;if(!(r.redirect||r.deploy==="server"||r.start))continue;t.add(r.domain);for(let n of r.aliases??[]){let s=String(n).trim().toLowerCase();if(s)t.add(s)}}return t}function Dr(e){return e.replace(/\.$/,"").toLowerCase()}function La(e,t,r){let n=Dr(e.name),s=Dr(t),i=Dr(r),o=i===s?"@":i.endsWith(`.${s}`)?i.slice(0,-(s.length+1)):i;return n===i||n===o||o==="@"&&(n===""||n===s)}async function ka(e,t,r,n,s="A"){let i=await e.listRecords(t);if(!i.success)return[`could not list ${s} records: ${i.message||"unknown provider error"}`];let o=i.records.filter((l)=>l.type===s&&La(l,t,r)),a=o.findIndex((l)=>l.content===n);if(o.length<=1||a===-1)return[];let c=[];for(let[l,u]of o.entries()){if(l===a)continue;let d=await e.deleteRecord(t,u);if(!d.success)c.push(`could not remove stale ${u.name} ${s} ${u.content}: ${d.message||"unknown provider error"}`)}return c}function me(e){if(!e)return;let t=e.trim();if(!t)return;if(!t.includes("/"))return t;let[r]=t.split("/");if(!r.endsWith("::"))return r||void 0;return`${r}1`}var Na=new Set(["mail","smtp","imap","mx"]);function po(e){return!Na.has(e.split(".")[0]??"")}async function Ei(e){let{provider:t,zone:r,fqdn:n,ipv4:s,ipv6:i,ttl:o=600}=e,a={published:[],warnings:[]},c=[{type:"A",content:s}];if(i&&po(n))c.push({type:"AAAA",content:i});for(let{type:l,content:u}of c){let d=await t.upsertRecord(r,{name:n,type:l,content:u,ttl:o});if(d?.success===!1){a.warnings.push(`${n} → ${u} failed: ${d.error||d.message||"unknown error"}`);continue}if(a.warnings.push(...(await ka(t,r,n,u,l)).map((m)=>`${n} cleanup: ${m}`)),await mo(t,r,n,u,l))a.published.push({fqdn:n,type:l,content:u});else a.warnings.push(`${n} → ${u} reported success at ${t.name} but no matching ${l} record exists — create it manually: ${l} ${n} → ${u}`)}return a}async function mo(e,t,r,n,s){try{if(typeof e?.listRecords!=="function")return!0;let i=await e.listRecords(t);if(!i?.success||!Array.isArray(i.records))return!0;return i.records.some((o)=>{let a=typeof o?.name==="string"?o.name.replace(/\.$/,""):"";return o?.type===s&&a===r&&o?.content===n})}catch{return!0}}import{readFileSync as Bs}from"node:fs";import{join as Rc}from"node:path";function Lr(e){return(Buffer.isBuffer(e)?e.toString("utf8"):typeof e==="string"?e:"").replace(/(^|\n)(\s*(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*=).*$/gm,"$1$2[redacted]").replace(/encrypted:[A-Za-z0-9+/=]+/g,"encrypted:[redacted]").trim().slice(-8000)}function Pt(e,t){let r=Lr(e?.stderr),n=/line (\d+): syntax error/.exec(r);if(!n)return"";let s=Number(n[1]),i=t.split(`
1
+ import{p}from"./chunk-540wkkhs.js";import{pa,I,A,ne,jr,ga,Jo,le,U,T,er,Vr}from"./chunk-wayhpmn7.js";import{v}from"./chunk-4vtyjj7c.js";import{Q}from"./chunk-9ktyfegk.js";import{g}from"./chunk-gqstb8zn.js";import{W,ki,Us,w,R,Tt,Ve,it,Io,Ni,Do,wt,Kc,ko,No,_i,xo,Oi,Ht,Vs,Jc,$i,zs,Hs,Gs,qs,_o,hn,Ws,yn,Ks,Oo}from"./chunk-qssb91v3.js";import{zo,Ho,Ys}from"./chunk-0r8k7qth.js";import{Ms}from"./chunk-k3cyh23p.js";import{Pr}from"./chunk-hhbmtgkq.js";import{bn}from"./chunk-ma0d990n.js";import{el}from"./chunk-hyrvmjq0.js";class Ze{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new p}async putParameter(e){let t={Name:e.Name,Value:e.Value};if(e.Type)t.Type=e.Type;if(e.Description)t.Description=e.Description;if(e.KeyId)t.KeyId=e.KeyId;if(e.Overwrite!==void 0)t.Overwrite=e.Overwrite;if(e.AllowedPattern)t.AllowedPattern=e.AllowedPattern;if(e.Tags&&e.Tags.length>0)t.Tags=e.Tags;if(e.Tier)t.Tier=e.Tier;if(e.DataType)t.DataType=e.DataType;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.PutParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Version:r.Version,Tier:r.Tier}}async getParameter(e){let t={Name:e.Name};if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameter:r.Parameter?this.parseParameter(r.Parameter):void 0}}async getParameters(e){let t={Names:e.Names};if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>this.parseParameter(n)),InvalidParameters:r.InvalidParameters}}async getParametersByPath(e){let t={Path:e.Path};if(e.Recursive!==void 0)t.Recursive=e.Recursive;if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;if(e.MaxResults)t.MaxResults=e.MaxResults;if(e.NextToken)t.NextToken=e.NextToken;if(e.ParameterFilters&&e.ParameterFilters.length>0)t.ParameterFilters=e.ParameterFilters;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParametersByPath","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>this.parseParameter(n)),NextToken:r.NextToken}}async deleteParameter(e){let t={Name:e.Name};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async deleteParameters(e){let t={Names:e},r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{DeletedParameters:r.DeletedParameters,InvalidParameters:r.InvalidParameters}}async describeParameters(e){let t={};if(e?.Filters&&e.Filters.length>0)t.Filters=e.Filters;if(e?.ParameterFilters&&e.ParameterFilters.length>0)t.ParameterFilters=e.ParameterFilters;if(e?.MaxResults)t.MaxResults=e.MaxResults;if(e?.NextToken)t.NextToken=e.NextToken;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DescribeParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>this.parseParameter(n)),NextToken:r.NextToken}}async getParameterHistory(e){let t={Name:e.Name};if(e.WithDecryption!==void 0)t.WithDecryption=e.WithDecryption;if(e.MaxResults)t.MaxResults=e.MaxResults;if(e.NextToken)t.NextToken=e.NextToken;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameterHistory","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Parameters:r.Parameters?.map((n)=>({Name:n.Name,Type:n.Type,KeyId:n.KeyId,LastModifiedDate:n.LastModifiedDate,LastModifiedUser:n.LastModifiedUser,Description:n.Description,Value:n.Value,Version:n.Version,Labels:n.Labels,Tier:n.Tier})),NextToken:r.NextToken}}async labelParameterVersion(e){let t={Name:e.Name,Labels:e.Labels};if(e.ParameterVersion!==void 0)t.ParameterVersion=e.ParameterVersion;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.LabelParameterVersion","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{InvalidLabels:r.InvalidLabels,ParameterVersion:r.ParameterVersion}}async addTagsToResource(e){let t={ResourceType:e.ResourceType,ResourceId:e.ResourceId,Tags:e.Tags};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.AddTagsToResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async removeTagsFromResource(e){let t={ResourceType:e.ResourceType,ResourceId:e.ResourceId,TagKeys:e.TagKeys};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.RemoveTagsFromResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async listTagsForResource(e){let t={ResourceType:e.ResourceType,ResourceId:e.ResourceId};return{TagList:(await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListTagsForResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})).TagList}}async setString(e,t,r){return this.putParameter({Name:e,Value:t,Type:"String",Description:r?.description,Overwrite:r?.overwrite??!0,Tags:r?.tags})}async setSecureString(e,t,r){return this.putParameter({Name:e,Value:t,Type:"SecureString",Description:r?.description,Overwrite:r?.overwrite??!0,KeyId:r?.kmsKeyId,Tags:r?.tags})}async getValue(e){return(await this.getParameter({Name:e,WithDecryption:!0})).Parameter?.Value}async getAllByPath(e,t=!0){let r=[],n;do{let s=await this.getParametersByPath({Path:e,Recursive:t,WithDecryption:!0,NextToken:n});if(s.Parameters)r.push(...s.Parameters);n=s.NextToken}while(n);return r}parseParameter(e){return{Name:e.Name,Type:e.Type,Value:e.Value,Version:e.Version,LastModifiedDate:e.LastModifiedDate,ARN:e.ARN,DataType:e.DataType,Description:e.Description,AllowedPattern:e.AllowedPattern,KeyId:e.KeyId,Tier:e.Tier}}async sendCommand(e){if(!e.InstanceIds&&!e.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let t={DocumentName:e.DocumentName};if(e.InstanceIds)t.InstanceIds=e.InstanceIds;if(e.Targets)t.Targets=e.Targets;if(e.Parameters)t.Parameters=e.Parameters;if(e.TimeoutSeconds)t.TimeoutSeconds=e.TimeoutSeconds;if(e.Comment)t.Comment=e.Comment;if(e.OutputS3BucketName)t.OutputS3BucketName=e.OutputS3BucketName;if(e.OutputS3KeyPrefix)t.OutputS3KeyPrefix=e.OutputS3KeyPrefix;let r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.SendCommand","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{CommandId:r.Command?.CommandId,Status:r.Command?.Status,StatusDetails:r.Command?.StatusDetails}}async getCommandInvocation(e){let t={CommandId:e.CommandId,InstanceId:e.InstanceId},r=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetCommandInvocation","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)});return{Status:r.Status,StatusDetails:r.StatusDetails,StandardOutputContent:r.StandardOutputContent,StandardErrorContent:r.StandardErrorContent,ResponseCode:r.ResponseCode}}async runShellCommand(e,t,r){let n=await this.sendCommand({InstanceIds:[e],DocumentName:"AWS-RunShellScript",Parameters:{commands:t},TimeoutSeconds:r?.timeoutSeconds||600});if(!n.CommandId)return{success:!1,error:"Failed to send command"};if(r?.waitForCompletion===!1)return{success:!0,status:"Pending"};let s=r?.pollIntervalMs||2000,i=r?.maxWaitMs||300000,o=Date.now();while(Date.now()-o<i){await new Promise((a)=>setTimeout(a,s));try{let a=await this.getCommandInvocation({CommandId:n.CommandId,InstanceId:e});if(a.Status==="Success")return{success:!0,output:a.StandardOutputContent,error:a.StandardErrorContent,status:a.Status};if(a.Status==="Failed"||a.Status==="Cancelled"||a.Status==="TimedOut")return{success:!1,output:a.StandardOutputContent,error:a.StandardErrorContent||a.StatusDetails,status:a.Status}}catch(a){if(!a.message?.includes("InvocationDoesNotExist"))return{success:!1,error:a.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations(e){let t={CommandId:e.CommandId};if(e.Details)t.Details=!0;return((await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListCommandInvocations","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})).CommandInvocations||[]).map((s)=>({InstanceId:s.InstanceId,Status:s.Status,StatusDetails:s.StatusDetails,StandardOutputContent:s.CommandPlugins?.[0]?.Output,StandardErrorContent:s.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags(e){let t=Object.entries(e.tags).map(([c,l])=>({Key:`tag:${c}`,Values:[l]})),r=await this.sendCommand({Targets:t,DocumentName:"AWS-RunShellScript",Parameters:{commands:e.commands},TimeoutSeconds:e.timeoutSeconds||600,Comment:e.comment});if(!r.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let n=e.pollIntervalMs||3000,s=e.maxWaitMs||600000,i=Date.now(),o=new Set(["Success","Failed","Cancelled","TimedOut"]),a=[];while(Date.now()-i<s){await new Promise((c)=>setTimeout(c,n));try{if(a=await this.listCommandInvocations({CommandId:r.CommandId,Details:!0}),a.length===0)continue;if(a.every((l)=>o.has(l.Status||""))){let l=a.map((d)=>({instanceId:d.InstanceId,status:d.Status||"Unknown",output:d.StandardOutputContent,error:d.StandardErrorContent||d.StatusDetails})),u=a.every((d)=>d.Status==="Success");return{success:u,instanceCount:a.length,perInstance:l,error:u?void 0:"One or more instances reported a non-success status"}}}catch(c){if(!c.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:c.message}}}return{success:!1,instanceCount:a.length,perInstance:a.map((c)=>({instanceId:c.InstanceId,status:c.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}function ks(e={}){let t=new Set;for(let r of Object.values(e)){if(!r.domain)continue;if(!(r.redirect||r.deploy==="server"||r.start))continue;t.add(r.domain);for(let n of r.aliases??[]){let s=String(n).trim().toLowerCase();if(s)t.add(s)}}return t}function Dr(e){return e.replace(/\.$/,"").toLowerCase()}function La(e,t,r){let n=Dr(e.name),s=Dr(t),i=Dr(r),o=i===s?"@":i.endsWith(`.${s}`)?i.slice(0,-(s.length+1)):i;return n===i||n===o||o==="@"&&(n===""||n===s)}async function ka(e,t,r,n,s="A"){let i=await e.listRecords(t);if(!i.success)return[`could not list ${s} records: ${i.message||"unknown provider error"}`];let o=i.records.filter((l)=>l.type===s&&La(l,t,r)),a=o.findIndex((l)=>l.content===n);if(o.length<=1||a===-1)return[];let c=[];for(let[l,u]of o.entries()){if(l===a)continue;let d=await e.deleteRecord(t,u);if(!d.success)c.push(`could not remove stale ${u.name} ${s} ${u.content}: ${d.message||"unknown provider error"}`)}return c}function me(e){if(!e)return;let t=e.trim();if(!t)return;if(!t.includes("/"))return t;let[r]=t.split("/");if(!r.endsWith("::"))return r||void 0;return`${r}1`}var Na=new Set(["mail","smtp","imap","mx"]);function po(e){return!Na.has(e.split(".")[0]??"")}async function Ei(e){let{provider:t,zone:r,fqdn:n,ipv4:s,ipv6:i,ttl:o=600}=e,a={published:[],warnings:[]},c=[{type:"A",content:s}];if(i&&po(n))c.push({type:"AAAA",content:i});for(let{type:l,content:u}of c){let d=await t.upsertRecord(r,{name:n,type:l,content:u,ttl:o});if(d?.success===!1){a.warnings.push(`${n} → ${u} failed: ${d.error||d.message||"unknown error"}`);continue}if(a.warnings.push(...(await ka(t,r,n,u,l)).map((m)=>`${n} cleanup: ${m}`)),await mo(t,r,n,u,l))a.published.push({fqdn:n,type:l,content:u});else a.warnings.push(`${n} → ${u} reported success at ${t.name} but no matching ${l} record exists — create it manually: ${l} ${n} → ${u}`)}return a}async function mo(e,t,r,n,s){try{if(typeof e?.listRecords!=="function")return!0;let i=await e.listRecords(t);if(!i?.success||!Array.isArray(i.records))return!0;return i.records.some((o)=>{let a=typeof o?.name==="string"?o.name.replace(/\.$/,""):"";return o?.type===s&&a===r&&o?.content===n})}catch{return!0}}import{readFileSync as Bs}from"node:fs";import{join as Rc}from"node:path";function Lr(e){return(Buffer.isBuffer(e)?e.toString("utf8"):typeof e==="string"?e:"").replace(/(^|\n)(\s*(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*=).*$/gm,"$1$2[redacted]").replace(/encrypted:[A-Za-z0-9+/=]+/g,"encrypted:[redacted]").trim().slice(-8000)}function Pt(e,t){let r=Lr(e?.stderr),n=/line (\d+): syntax error/.exec(r);if(!n)return"";let s=Number(n[1]),i=t.split(`
2
2
  `),o=Math.max(1,s-12),a=Math.min(i.length,s+2),c=i.slice(o-1,a).map((l,u)=>{let d=o+u,m=/^[A-Z_][A-Z0-9_]*=/.test(l)?l.replace(/=.*/,"=<redacted>"):l;return` ${String(d).padStart(4)}${d===s?" >":" "} ${m}`});return["",`The deploy script bash rejected is ${i.length} lines; it stopped at ${s}.`,...c].join(`
3
3
  `)}function Ue(e){let t=e,r=typeof t?.status==="number"?` (exit ${t.status})`:"",n=t?.signal?` (signal ${t.signal})`:"",s=[Lr(t?.stderr),Lr(t?.stdout)].filter(Boolean).join(`
4
4
  `);return`Remote SSH command failed${r}${n}${s?`
@@ -0,0 +1 @@
1
+ import{Ps,pm,mm,Ds}from"./chunk-f0djc6da.js";import"./chunk-qssb91v3.js";import"./chunk-wayhpmn7.js";import"./chunk-33shhgye.js";export{pm as getComputeDeployHistory,Ds as restoreDatabaseBackup,Ps as rollbackComputeSite,mm as runComputeRecipe};
@@ -0,0 +1,11 @@
1
+ import{H,Fr}from"./chunk-wayhpmn7.js";function W(e,t){return`/var/www/${e}-${t}`}var fe=new Set(["laravel","php","statamic","wordpress"]);function ki(e){return e.type!=null&&fe.has(e.type)}function Us(e){let t=e.proxyTo;if(t==null)return[];return(Array.isArray(t)?t:[t]).map((n)=>String(n).trim()).filter((n)=>n.length>0)}function Te(e){return Us(e).length>0}function re(e){if(e.deploy)return e.deploy;if(ki(e))return"server";if(e.start)return"server";return"bucket"}function w(e){if(e.redirect)return"redirect";if(Te(e))return"proxy";if(ki(e))return"server-php";if(re(e)==="bucket")return"bucket";return e.start?"server-app":"server-static"}function Ro(e){return e.infrastructure?.compute!=null||Boolean(e.cloud?.attachTo?.trim())}function Bs(e,t={}){let r=[],n=[],o=e.sites||{},s=Ro(e),c=Fr(e);if(c)r.push(c);let p=new Map;for(let[l,i]of Object.entries(o)){if(!i)continue;let f=re(i),C=w(i);if(C==="redirect"){if(!i.domain)r.push(`Site '${l}' is a redirect site but has no \`domain\` to redirect from.`);if(!(typeof i.redirect==="string"?i.redirect:i.redirect?.to))r.push(`Site '${l}' is a redirect site but has no redirect target (\`redirect\` / \`redirect.to\`).`);if(!s)r.push(`Site '${l}' is a redirect site but no \`infrastructure.compute\` is configured to host the gateway that serves the redirect.`);let a=[];if(i.start)a.push("start");if(i.root)a.push("root");if(i.proxyTo)a.push("proxyTo");if(a.length>0)n.push(`Site '${l}' is a redirect site but also sets ${a.join(", ")}. These are ignored.`);continue}if(C==="proxy"){if(!i.domain)r.push(`Site '${l}' is a proxy site but has no \`domain\` to route from.`);if(!s)r.push(`Site '${l}' is a proxy site but no \`infrastructure.compute\` is configured to host the gateway that forwards it.`);let u=[];if(i.start)u.push("start");if(i.root)u.push("root");if(typeof i.port==="number")u.push("port");if(i.build)u.push("build");if(i.preStart&&i.preStart.length>0)u.push("preStart");if(u.length>0)n.push(`Site '${l}' sets \`proxyTo\`, so ts-cloud ships and supervises nothing for it. ${u.join(", ")} ${u.length===1?"is":"are"} ignored — remove ${u.length===1?"it":"them"}, or drop \`proxyTo\` to let ts-cloud own the service.`);continue}if(f==="server"&&!i.start&&!i.root){r.push(`Site '${l}' sets deploy:'server' but declares neither \`start\` (dynamic app) nor \`root\` (static site to serve). Add one.`);continue}if(C==="server-php"){if(!s)r.push(`Site '${l}' is a PHP site (type:'${i.type}') but no \`infrastructure.compute\` is configured. Add a server (infrastructure.compute) with PHP provisioning.`);if(!i.repository?.url)r.push(`Site '${l}' is a PHP site (type:'${i.type}') but has no \`repository.url\` to clone. PHP sites deploy via git.`)}else if(C==="server-app"){if(!s)r.push(`Site '${l}' deploys to a server (deploy:'server'${i.deploy?"":" inferred from `start`"}) but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`);if(typeof i.port==="number"){let u=t.occupiedPorts?.get(i.port);if(u)r.push(`Site '${l}' wants port ${i.port}, which project '${u}' already serves on this box. Attached projects share one port namespace. Give '${l}' a free port, or let the attach allocate one.`);let a=p.get(i.port);if(a)r.push(`Sites '${a}' and '${l}' both use port ${i.port}. Server apps sharing a box must use distinct ports.`);else p.set(i.port,l)}}else if(C==="server-static"){if(!i.root)r.push(`Site '${l}' is a server static site (deploy:'server', no \`start\`) but has no \`root\` directory to serve.`);if(!s)r.push(`Site '${l}' deploys to a server (deploy:'server') but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`)}else{if(!i.root)r.push(`Site '${l}' deploys to a bucket but has no \`root\` directory to upload.`);let u=[];if(i.start)u.push("start");if(typeof i.port==="number")u.push("port");if(i.preStart&&i.preStart.length>0)u.push("preStart");if(u.length>0)n.push(`Site '${l}' deploys to a bucket but sets server-only field(s): ${u.join(", ")}. These are ignored. Set deploy:'server' to use them.`)}}return{errors:r,warnings:n}}function Fs(e){let t=w(e);return t!=="bucket"&&t!=="redirect"&&t!=="proxy"}function qc(e){return w(e)==="bucket"}function Wc(e,t){if(H(e)==="serverless")return!0;let r=Object.entries(e.sites??{}).filter(([,o])=>o!=null),n=t?r.filter(([o])=>o===t):r;if(n.length===0)return!0;return!n.every(([,o])=>{let s=w(o);return s==="redirect"||s==="proxy"})}var O={php:"php.net",nginx:"nginx.org",composer:"getcomposer.org",mysql:"mysql.com",mariadb:"mariadb.com/server",postgres:"postgresql.org",vitess:"vitess.io",etcd:"etcd.io",redis:"redis.io",memcached:"memcached.org",meilisearch:"meilisearch.com",mail:"github.com/mail-os/mail",git:"git-scm.com",certbot:"certbot.eff.org",bun:"bun.sh",node:"nodejs.org",deno:"deno.land"};var R="/opt/pantry";function M(e){return`'${e.split("'").join("'\\''")}'`}function Tt(e={}){let t=e.installDir??"/usr/local/bin",r=e.version?`export PANTRY_VERSION=${M(e.version)}`:'export PANTRY_VERSION="${PANTRY_VERSION:-latest}"';return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system",`export PANTRY_INSTALL_DIR=${t}`,r,"command -v curl >/dev/null 2>&1 || (apt-get update -y && apt-get install -y curl ca-certificates)","command -v unzip >/dev/null 2>&1 || (apt-get update -y && apt-get install -y unzip)",`OS=$(uname -s | tr '[:upper:]' '[:lower:]'); ARCH=$(uname -m); case "$ARCH" in x86_64|amd64) ARCH=x64 ;; arm64|aarch64) ARCH=arm64 ;; esac; ZIP="pantry-\${OS}-\${ARCH}.zip"; if [ "\${PANTRY_VERSION:-latest}" = latest ]; then REL='latest/download'; else REL="download/v\${PANTRY_VERSION}"; fi; TMP=$(mktemp -d); curl -fsSL -o "\${TMP}/\${ZIP}" "https://github.com/pantry-pm/pantry/releases/\${REL}/\${ZIP}"; mkdir -p ${t}; unzip -o "\${TMP}/\${ZIP}" -d ${t}; chmod +x ${t}/pantry; rm -rf "\${TMP}"`,`export PATH="${t}:$PATH"`,"mkdir -p /opt/pantry"]}function Ve(){return'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true'}function it(e){if(e.length===0)return[];return[`(cd /opt/pantry && pantry install ${[...new Set(e)].map(M).join(" ")})`]}function Io(e){return[...new Set(e)].flatMap((t)=>[`(cd /opt/pantry && pantry start ${M(t)})`,`(cd /opt/pantry && pantry enable ${M(t)})`])}var m="/etc/mail",g="mail-server",F="mail",Y=`${R}/pantry/.bin`;function h(e){return`'${String(e).split("'").join("'\\''")}'`}function P(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function ge(e){return[e.version?`${O.mail}@${e.version}`:O.mail]}function K(e,t){return`${m}/dkim/${t}.${e.dkim.selector}.pem`}function ne(e){return`${e.storagePath}/smtp.db`}function he(e){let t=["# Generated by ts-cloud. Edits are overwritten on the next deploy —","# change `services.mail` in the cloud config instead.","","[server]",`host = ${P(e.bindAddress)}`,`port = ${e.ports.smtp}`,`hostname = ${P(e.hostname)}`];if(e.domains.length>0)t.push(`local_domains = ${P(e.domains.join(", "))}`);if(e.mode==="catcher")t.push("catch_all = true");if(t.push(`max_message_size = ${e.maxMessageSize}`,"","[tls]",`enabled = ${e.tls.enabled}`),e.tls.certPath)t.push(`cert_path = ${P(e.tls.certPath)}`);if(e.tls.keyPath)t.push(`key_path = ${P(e.tls.keyPath)}`);if(t.push("","[auth]",`enabled = ${e.mode==="server"}`,"","[antispam]",`dnsbl = ${e.spam.dnsbl}`,`dnsbl_reject = ${e.spam.dnsblReject}`,`greylist = ${e.spam.greylist}`,`spam_filter = ${e.spam.enabled}`,`junk_score = ${e.spam.junkScore}`,`reject_score = ${e.spam.rejectScore}`,"","[dkim]",`rotation_enabled = ${e.dkim.enabled&&e.dkim.rotate}`,`rotation_interval_days = ${e.dkim.rotateIntervalDays}`,"","[acme]",`enabled = ${e.tls.acme}`),e.tls.acmeEmail)t.push(`email = ${P(e.tls.acmeEmail)}`);if(t.push("","[webhook]",`enabled = ${!!e.webhookUrl}`),e.webhookUrl)t.push(`url = ${P(e.webhookUrl)}`);return t.push(""),t.join(`
2
+ `)}function Ee(e){let t=["# Generated by ts-cloud. See /etc/mail/config.toml for the rest.",`SMTP_DB_PATH=${ne(e)}`,`SMTP_DNSBL_REJECT=${e.spam.dnsblReject}`,`SMTP_DELIVERY_METHOD=${e.delivery==="ses"?"ses":"direct"}`];if(e.delivery==="ses")t.push(`SMTP_SES_REGION=${e.sesRegion}`);if(e.ports.submission)t.push(`SUBMISSION_PORT=${e.ports.submission}`);if(e.ports.submissions)t.push(`SMTPS_PORT=${e.ports.submissions}`);if(e.ports.imap)t.push("IMAP_ENABLED=1",`IMAP_PORT=${e.ports.imap}`);if(e.webmail.enabled)t.push("SMTP_ENABLE_WEBMAIL=true",`SMTP_WEBMAIL_PORT=${e.webmail.port}`,`SMTP_WEBMAIL_TLS=${e.webmail.tls}`,`SMTP_WEBMAIL_SECURE_COOKIES=${e.webmail.secureCookies}`,`SMTP_WEBMAIL_ATTACHMENT_MAX_FILE=${e.webmail.attachmentMaxFileBytes}`,`SMTP_WEBMAIL_ATTACHMENT_MAX_TOTAL=${e.webmail.attachmentMaxTotalBytes}`,`SMTP_WEBMAIL_ATTACHMENT_MAX_COUNT=${e.webmail.attachmentMaxCount}`,`SMTP_WEBMAIL_UNDO_SEND_SECONDS=${e.webmail.undoSendSeconds}`);if(e.tls.requireForAuth)t.push("SMTP_REQUIRE_TLS_FOR_AUTH=true");if(e.dkim.enabled&&e.domains.length>0){let[r,...n]=e.domains;if(t.push(`DKIM_DOMAIN=${r}`,`DKIM_SELECTOR=${e.dkim.selector}`,`DKIM_PRIVATE_KEY_PATH=${K(e,r)}`),n.length>0){let o=n.map((s)=>`${s}:${e.dkim.selector}:${K(e,s)}`);t.push(`DKIM_EXTRA_KEYS=${o.join(",")}`)}}return t.push(""),t.join(`
3
+ `)}function ye(e){let t=[e.ports.smtp,e.ports.submission,e.ports.submissions,e.ports.imap,e.ports.imaps].some((r)=>typeof r==="number"&&r<1024);return["[Unit]","Description=Mail server (SMTP/IMAP + webmail)","After=network-online.target","Wants=network-online.target","","[Service]","Type=simple",`User=${g}`,`Group=${g}`,`WorkingDirectory=${e.storagePath}`,`EnvironmentFile=${m}/mail.env`,`Environment="PATH=${Y}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"`,`ExecStart=${Y}/mail serve --config ${m}/config.toml`,"Restart=always","RestartSec=5","LimitNOFILE=65536",...t?["AmbientCapabilities=CAP_NET_BIND_SERVICE","CapabilityBoundingSet=CAP_NET_BIND_SERVICE"]:[],"NoNewPrivileges=true","PrivateTmp=true","ProtectSystem=strict","ProtectHome=true","ProtectKernelTunables=true","ProtectKernelModules=true","ProtectControlGroups=true",`ReadWritePaths=${e.storagePath} ${m}`,"","[Install]","WantedBy=multi-user.target",""].join(`
4
+ `)}function ve(e){if(!e.dkim.enabled||e.domains.length===0)return[];let t=[`mkdir -p ${m}/dkim`];for(let r of e.domains){let n=K(e,r);t.push(`if [ ! -f ${h(n)} ]; then openssl genrsa -out ${h(n)} 2048; fi`,`chmod 0600 ${h(n)}`,`echo "DKIM ${e.dkim.selector}._domainkey.${r} IN TXT v=DKIM1; k=rsa; p=$(openssl rsa -in ${h(n)} -pubout -outform PEM 2>/dev/null | grep -v '^-----' | tr -d '\\n')"`)}return t.push(`chown -R ${g}:${g} ${m}/dkim`),t}function Ce(e){if(e.accounts.length===0)return[];let t=(r)=>`runuser -u ${g} -- env SMTP_DB_PATH="$TS_CLOUD_MAIL_DB" ${Y}/mail user:local ${r}`;return e.accounts.flatMap((r)=>[t(`create ${h(r.address)} ${h(r.password)} ${h(r.address)}`),...r.passwordPolicy==="managed"?[t(`change-password ${h(r.address)} ${h(r.password)}`)]:[]])}function se(e){if(!e.enabled)return[];return[...it(ge(e)),`id -u ${g} >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin ${g}`,`mkdir -p ${e.storagePath} ${m}`,`chown -R ${g}:${g} ${e.storagePath}`,`TS_CLOUD_MAIL_DB="$(grep -sE '^SMTP_DB_PATH=' ${m}/mail.env | head -1 | cut -d= -f2- || true)"`,`[ -n "$TS_CLOUD_MAIL_DB" ] || TS_CLOUD_MAIL_DB=${h(ne(e))}`,`cat > ${m}/config.toml <<'TS_CLOUD_MAIL_CONF_EOF'`,he(e),"TS_CLOUD_MAIL_CONF_EOF",`cat > ${m}/mail.env <<'TS_CLOUD_MAIL_ENV_EOF'`,Ee(e),"TS_CLOUD_MAIL_ENV_EOF",`sed -i "s|^SMTP_DB_PATH=.*|SMTP_DB_PATH=$TS_CLOUD_MAIL_DB|" ${m}/mail.env`,`chmod 0640 ${m}/mail.env`,`chown root:${g} ${m}/mail.env`,...ve(e),`cat > /etc/systemd/system/${F}.service <<'TS_CLOUD_MAIL_UNIT_EOF'`,ye(e),"TS_CLOUD_MAIL_UNIT_EOF","systemctl daemon-reload",`systemctl enable ${F}`,`systemctl restart ${F}`,...Ce(e)]}var T=`${R}/pantry/.bin`,z=15306,j=15991,N=15999,oe=16101,B=2379,E="/var/lib/vitess",Q=100;function Ni(e){return e===!0||typeof e==="object"&&e!==null}function Pe(e){return typeof e==="object"&&e!==null?e:{}}function _(e){return`'${String(e).split("'").join("'\\''")}'`}function Re(e){let r=[e.version?`vitess.io@${e.version}`:"vitess.io"];if(e.mode!=="combo"&&!e.etcdEndpoint)r.push("etcd.io");return r.push("mysql.com@8.0.43"),r}var S="vitess",De=`${T}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`,le="/usr/local/lib/vitess",J=new Map;function X(e){return`${le}/${e}.sh`}function b(e,t){return J.set(e,be(t)),`/bin/sh ${X(e)}`}function ie(){let e=[`mkdir -p ${le}`];for(let[t,r]of J)e.push(`cat > ${X(t)} <<'TS_CLOUD_VITESS_LAUNCHER_EOF'`,r,"TS_CLOUD_VITESS_LAUNCHER_EOF",`chmod 0755 ${X(t)}`);return e}function be(e){return["#!/bin/sh","set -e",`cd ${R}`,`PANTRY_ENV="$(pantry env 2>/dev/null | grep -E '^(export [A-Za-z_]|[A-Za-z_][A-Za-z0-9_]*=)' || true)"`,'if [ -n "$PANTRY_ENV" ]; then eval "$PANTRY_ENV"; fi',`VT_MYSQL_ROOT="$(dirname "$(dirname "$(readlink -f ${T}/mysqld 2>/dev/null)")")"`,`VTROOT="$(dirname "$(dirname "$(readlink -f ${T}/mysqlctld 2>/dev/null)")")"`,"export VT_MYSQL_ROOT VTROOT",'LD_LIBRARY_PATH="$VT_MYSQL_ROOT/lib:$VTROOT/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"',"export LD_LIBRARY_PATH",`exec ${e.join(" ")}`].join(`
5
+ `)}function A(e){let t=["[Unit]",`Description=${e.description}`,`After=network.target${e.after?.length?` ${e.after.join(" ")}`:""}`];if(e.requires?.length)t.push(`Requires=${e.requires.join(" ")}`);return t.push("","[Service]","Type=simple",`User=${S}`,`Group=${S}`,`Environment="PATH=${De}"`,`Environment="VTDATAROOT=${E}"`,...Object.entries(e.environment??{}).map(([r,n])=>`Environment="${r}=${n}"`),...(e.execStartPre??[]).map((r)=>`ExecStartPre=${r}`),`ExecStart=${e.execStart}`,"Restart=always","RestartSec=5","LimitNOFILE=65535","","[Install]","WantedBy=multi-user.target"),t.join(`
6
+ `)}function ae(e,t){return[`cat > /etc/systemd/system/${e}.service <<'TS_CLOUD_VITESS_UNIT_EOF'`,t,"TS_CLOUD_VITESS_UNIT_EOF"]}function Ae(e){let t=e.cell??"zone1",r=e.vtgatePort??z,o=`${((e.keyspaces?.length)?e.keyspaces:[{name:"app"}]).map((s)=>{let c=(s.sharded?["-80","80-"]:["0"]).map((p)=>`shards:{name:"${p}"}`).join(" ");return`keyspaces:{name:"${s.name}" ${c}}`}).join(" ")} cells:"${t}"`;return A({description:"Vitess (vtcombo, single-process development stack)",execStart:b("vtcombo",[`${T}/vtcombo`,`--cell ${t}`,`--proto-topo ${_(o)}`,`--mysql-server-port ${r}`,"--mysql-server-bind-address 127.0.0.1","--mysql-auth-server-impl none","--start-mysql",`--port ${j}`,`--grpc-port ${N}`])})}function Le(){return A({description:"etcd (Vitess topology store)",execStart:b("etcd",[`${T}/etcd`,`--data-dir ${E}/etcd`,`--listen-client-urls http://127.0.0.1:${B}`,`--advertise-client-urls http://127.0.0.1:${B}`]),execStartPre:[`+/bin/mkdir -p ${E}/etcd`,`+/bin/chown ${S}:${S} ${E}/etcd`]})}function Z(e){return["--topo-implementation etcd2",`--topo-global-server-address ${e.etcdEndpoint??`http://127.0.0.1:${B}`}`,"--topo-global-root /vitess/global"]}function Oe(e){let t=!e.etcdEndpoint;return A({description:"Vitess vtctld (control plane)",after:t?["vitess-etcd.service"]:[],requires:t?["vitess-etcd.service"]:[],execStart:b("vtctld",[`${T}/vtctld`,...Z(e),`--cell ${e.cell??"zone1"}`,"--service-map grpc-vtctl,grpc-vtctld",`--grpc-port ${N}`,`--port ${N+1}`])})}function Ue(e,t,r){let n=e.cell??"zone1";return A({description:`Vitess vttablet (${t}/${r})`,after:["vitess-vtctld.service","vitess-mysqlctld.service"],requires:["vitess-mysqlctld.service"],execStart:b("vttablet",[`${T}/vttablet`,...Z(e),`--tablet-path ${n}-${String(Q).padStart(10,"0")}`,`--init-keyspace ${t}`,`--init-shard ${r}`,"--init-tablet-type replica",`--service-map ${_("grpc-queryservice,grpc-tabletmanager,grpc-updatestream")}`,`--port ${oe}`,`--grpc-port ${oe+1}`,`--db-port ${e.mysqlPort??3306}`,`--mycnf-mysql-port ${e.mysqlPort??3306}`])})}function xe(e){return A({description:"Vitess mysqlctld (managed mysqld)",execStart:b("mysqlctld",[`${T}/mysqlctld`,`--tablet-uid ${Q}`,`--mysql-port ${e.mysqlPort??3306}`,'--init-db-sql-file "$VTROOT/config/init_db.sql"',"--wait-time 2m"]),execStartPre:[`+/bin/mkdir -p ${E}`,`+/bin/chown ${S}:${S} ${E}`]})}var pe="/etc/vitess/auth.json",U="/var/lib/vitess/vtgate-auth.sha256";function ke(e){let t=e.username??"vitess",r=e.password??"";return["mkdir -p /etc/vitess",'VTESS_AUTH_TMP="$(mktemp)"',`cat > "$VTESS_AUTH_TMP" <<'TS_CLOUD_VITESS_AUTH_EOF'`,JSON.stringify({[t]:[{Password:r,UserData:t}]}),"TS_CLOUD_VITESS_AUTH_EOF",`VTESS_VTGATE_AUTH_SHA="$(sha256sum "$VTESS_AUTH_TMP" | awk '{print $1}')"`,"VTESS_VTGATE_AUTH_CHANGED=1",`if [ -f ${U} ] && [ "$(cat ${U})" = "$VTESS_VTGATE_AUTH_SHA" ]; then VTESS_VTGATE_AUTH_CHANGED=0; fi`,`install -o ${S} -g ${S} -m 0600 "$VTESS_AUTH_TMP" ${pe}`,'rm -f "$VTESS_AUTH_TMP"']}function Ie(e){let t=e.cell??"zone1";return A({description:"Vitess vtgate (query router)",after:["vitess-vtctld.service"],execStart:b("vtgate",[`${T}/vtgate`,...Z(e),`--cell ${t}`,`--cells-to-watch ${t}`,"--tablet-types-to-wait PRIMARY,REPLICA",`--service-map ${_("grpc-vtgateservice")}`,`--mysql-server-port ${e.vtgatePort??z}`,`--mysql-server-bind-address ${e.bindAddress??"127.0.0.1"}`,"--mysql-auth-server-impl static",`--mysql-auth-server-static-file ${pe}`,`--port ${j}`,`--grpc-port ${j+1}`])})}function Me(e){let t=e.cell??"zone1",r=e.etcdEndpoint??`http://127.0.0.1:${B}`,n=`${T}/vtctldclient --server 127.0.0.1:${N}`,o=[`for i in $(seq 1 30); do ${n} GetCellInfoNames >/dev/null 2>&1 && break; sleep 2; done`,`if ! ${n} GetCellInfoNames 2>/dev/null | grep -qx ${_(t)}; then`,` ${n} AddCellInfo --root ${_(`/vitess/${t}`)} --server-address ${_(r)} ${_(t)}`,"fi"];for(let s of e.keyspaces??[]){let c=s.sharded?" --sharded":"";o.push(`if ! ${n} GetKeyspace ${_(s.name)} >/dev/null 2>&1; then`,` ${n} CreateKeyspace${c} ${_(s.name)}`,"fi");let p=`${t}-${String(Q).padStart(10,"0")}`;for(let l of s.sharded?["-80","80-"]:["0"]){let i=`${s.name}/${l}`;o.push("for i in $(seq 1 90); do",` if ${n} GetShard ${_(i)} 2>/dev/null | grep -q '"is_primary_serving": *true'; then break; fi`,` ${n} PlannedReparentShard ${_(i)} --new-primary ${_(p)} >/dev/null 2>&1 && break`,` ${n} InitShardPrimary --force ${_(i)} ${_(p)} >/dev/null 2>&1 && break`," sleep 2","done",`if ! ${n} GetShard ${_(i)} 2>/dev/null | grep -q '"is_primary_serving": *true'; then`,` echo "no primary could be elected for ${i}" >&2; exit 1`,"fi")}o.push(`${n} RebuildKeyspaceGraph ${_(s.name)} >/dev/null`)}return o}function ce(e){let t=e.vtgatePort??z;return["for i in $(seq 1 60); do",` if (cd ${R} && eval "$(pantry env 2>/dev/null)"; MYSQL_PWD=${_(e.password??"")} ${T}/mysql -h 127.0.0.1 -P ${t} -u ${_(e.username??"vitess")} --connect-timeout=2 -e 'SHOW KEYSPACES') >/dev/null 2>&1; then`,` echo "vtgate is serving on ${t}"; exit 0`," fi"," sleep 2","done",`echo "vtgate did not become ready on port ${t}" >&2`,"exit 1"]}function Po(e){if(!Ni(e))return[];let t=Pe(e),r=t.mode==="combo";J.clear();let n=['if [ "$(uname -m)" != "x86_64" ]; then',' echo "vitess: Vitess publishes only x86_64 release tarballs; this box is $(uname -m). Drop managedServices.vitess or use an x86_64 host." >&2'," exit 1","fi",...it(Re(t)),`VT_MYSQL_LIB="$(dirname "$(dirname "$(readlink -f ${T}/mysqld)")")/lib"`,'if [ -d "$VT_MYSQL_LIB" ]; then',` printf '%s\\n' "$VT_MYSQL_LIB" > /etc/ld.so.conf.d/vitess-mysql.conf`," ldconfig","else",' echo "mysqld library directory not found under $VT_MYSQL_LIB" >&2; exit 1',"fi",`id -u ${S} >/dev/null 2>&1 || useradd --system --home-dir ${E} --shell /usr/sbin/nologin ${S}`,`mkdir -p ${E}`,`chown -R ${S}:${S} ${E}`];if(r)return n.push(...ae("vitess-vtcombo",Ae(t)),...ie(),"systemctl daemon-reload","systemctl enable --now vitess-vtcombo.service",...ce(t)),n;n.push(...ke(t));let o=[];if(!t.etcdEndpoint)o.push(["vitess-etcd",Le()]);o.push(["vitess-vtctld",Oe(t)],["vitess-mysqlctld",xe(t)],["vitess-vtgate",Ie(t)]);for(let s of t.keyspaces??[])for(let c of s.sharded?["-80","80-"]:["0"])o.push([`vitess-vttablet-${s.name}-${c.replace(/-/g,"x")}`,Ue(t,s.name,c)]);for(let[s,c]of o)n.push(...ae(s,c));n.push(...ie()),n.push("systemctl daemon-reload");for(let[s]of o)n.push(`systemctl enable --now ${s}.service`);return n.push(`if [ "$VTESS_VTGATE_AUTH_CHANGED" = 1 ]; then systemctl restart vitess-vtgate.service; printf '%s\\n' "$VTESS_VTGATE_AUTH_SHA" > ${U}; chown ${S}:${S} ${U}; chmod 0600 ${U}; fi`,...Me(t),...ce(t)),n}var Ne=new Set(["singlestore","vitess"]);function gn(e){if(e?.engine&&Ne.has(e.engine))return!1;return!e?.host||e.host==="127.0.0.1"||e.host==="localhost"}function Et(e,t="psql"){let r=e?.port??5432;if(gn(e))return`${t} -p ${r} -U postgres`;let n=e?.username||"postgres";return`${e?.password?`PGPASSWORD='${e.password.replace(/'/g,"'\\''")}' `:""}${t} -h ${e.host} -p ${r} -U ${n} -w`}function y(e){return e===!0||typeof e==="object"&&e!=null}function we(e){let t=[],r=[];if(y(e.mysql))t.push(typeof e.mysql==="object"&&e.mysql.version?`mysql.com@${e.mysql.version}`:"mysql.com@8.0.43"),r.push("mysql");else if(y(e.mariadb))t.push(O.mariadb),r.push("mariadb");if(y(e.postgres))t.push("postgresql.org"),r.push("postgres");if(y(e.redis))t.push("redis.io"),r.push("redis");if(y(e.memcached))t.push("memcached.org"),r.push("memcached");if(y(e.meilisearch))t.push("meilisearch.com"),r.push("meilisearch");return{packages:t,services:r}}function Do(e={},t={}){let r=we(e),n=Po(e.vitess),o=t.mail?se(t.mail):[];if(r.packages.length===0)return[...n,...o];return[...it(r.packages),...Io(r.services),...n,...o]}function wt(e,t={}){if(e?.requireLocalPasswordAuth&&(e.engine!=="postgres"||!gn(e)||!e.name||!e.username||!e.password||e.users?.some((a)=>!a.password)))throw Error("Password authentication requires a named local PostgreSQL database and nonempty login passwords");if(!e?.name)return[];if(!gn(e))return[];let r=e.name,n=e.username||r,o=e.password||"",s=y(t.postgres)||e.engine==="postgres",c=y(t.mariadb)||e.engine==="mariadb",p=y(t.mysql)||e.engine==="mysql";if(s&&!p&&!c){let a=(d)=>`"${d.replace(/"/g,'""')}"`,D=(d)=>`'${d.replace(/'/g,"''")}'`,L=(d,I)=>[...e.requireLocalPasswordAuth?["SET password_encryption = 'scram-sha-256';"]:[],"DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${D(d)}) THEN`,` CREATE ROLE ${a(d)} LOGIN PASSWORD ${D(I)};`," ELSE",` ALTER ROLE ${a(d)} LOGIN PASSWORD ${D(I)};`," END IF;","END $$;"],x=(d)=>{let I=d.databases&&d.databases.length>0?d.databases:[r],G=[];for(let q of I)if(d.access==="readonly")G.push(`GRANT CONNECT ON DATABASE ${a(q)} TO ${a(d.username)};`,`\\connect ${a(q)}`,`GRANT USAGE ON SCHEMA public TO ${a(d.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${a(d.username)};`,`ALTER DEFAULT PRIVILEGES FOR ROLE ${a(n)} IN SCHEMA public GRANT SELECT ON TABLES TO ${a(d.username)};`,"\\connect postgres");else G.push(`GRANT ALL PRIVILEGES ON DATABASE ${a(q)} TO ${a(d.username)};`);return G},k=e.users||[],me=e.port??5432;return[Ve(),`for i in $(seq 1 30); do pg_isready -p ${me} -q && break; sleep 2; done`,`${Et(e)}${e.requireLocalPasswordAuth?" -v ON_ERROR_STOP=1":""} <<'TS_CLOUD_PG_EOF'`,...L(n,o),`SELECT 'CREATE DATABASE ${a(r)} OWNER ${a(n)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${D(r)})\\gexec`,...k.flatMap((d)=>[...L(d.username,d.password),...x(d)]),"TS_CLOUD_PG_EOF",...e.requireLocalPasswordAuth?[`TS_CLOUD_PG_HBA=$(${Et(e)} -Atc 'SHOW hba_file')`,'case "$TS_CLOUD_PG_HBA" in /*) ;; *) echo "Invalid PostgreSQL authentication path" >&2; exit 1 ;; esac','[ -f "$TS_CLOUD_PG_HBA.before-ts-cloud-password-auth" ] || cp -p "$TS_CLOUD_PG_HBA" "$TS_CLOUD_PG_HBA.before-ts-cloud-password-auth"','TS_CLOUD_PG_AUTH=$(mktemp "$TS_CLOUD_PG_HBA.ts-cloud.XXXXXXXX")',"{"," printf '%s\\n' '# BEGIN ts-cloud password authentication' 'host all all 127.0.0.1/32 scram-sha-256' 'host all all ::1/128 scram-sha-256' 'host replication all 127.0.0.1/32 scram-sha-256' 'host replication all ::1/128 scram-sha-256' '# END ts-cloud password authentication'",` sed '/^# BEGIN ts-cloud password authentication$/,/^# END ts-cloud password authentication$/d' "$TS_CLOUD_PG_HBA"`,'} > "$TS_CLOUD_PG_AUTH"','chown --reference="$TS_CLOUD_PG_HBA" "$TS_CLOUD_PG_AUTH"','chmod --reference="$TS_CLOUD_PG_HBA" "$TS_CLOUD_PG_AUTH"','mv -f "$TS_CLOUD_PG_AUTH" "$TS_CLOUD_PG_HBA"',`${Et(e)} -v ON_ERROR_STOP=1 -c 'SELECT pg_reload_conf()'`]:[],...Be(e)]}let l=c?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",i=(a)=>a.replace(/`/g,"``"),f=(a)=>a.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),C=(a)=>{let D=a.databases&&a.databases.length>0?a.databases:[r],L=a.access==="readonly"?"SELECT":"ALL PRIVILEGES",x=[`CREATE USER IF NOT EXISTS '${f(a.username)}'@'%' IDENTIFIED BY '${f(a.password)}';`,`CREATE USER IF NOT EXISTS '${f(a.username)}'@'localhost' IDENTIFIED BY '${f(a.password)}';`,`ALTER USER '${f(a.username)}'@'%' IDENTIFIED BY '${f(a.password)}';`,`ALTER USER '${f(a.username)}'@'localhost' IDENTIFIED BY '${f(a.password)}';`];for(let k of D)x.push(`GRANT ${L} ON \`${i(k)}\`.* TO '${f(a.username)}'@'%';`,`GRANT ${L} ON \`${i(k)}\`.* TO '${f(a.username)}'@'localhost';`);return x},u=e.users||[];return[Ve(),`for i in $(seq 1 30); do mysqladmin --socket=${l} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${l} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${i(r)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...C({username:n,password:o}),...u.flatMap(C),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}function Be(e){return[`${Et(e)} -tA <<'TS_CLOUD_PG_CAP_EOF' || true`,"\\set QUIET on","SELECT CASE WHEN used::float / NULLIF(cap, 0) >= 0.8"," THEN '[ts-cloud] postgres is at ' || used || '/' || cap || ' connections on this server.'"," || ' Raise max_connections (ALTER SYSTEM SET max_connections = ...; then restart) or'"," || ' set idle_session_timeout so abandoned pools are reclaimed.'"," ELSE NULL END","FROM (SELECT (SELECT count(*) FROM pg_stat_activity) AS used,"," (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS cap) c","WHERE CASE WHEN used::float / NULLIF(cap, 0) >= 0.8 THEN true ELSE false END;","SELECT '[ts-cloud] ' || coalesce(datname, '(background)') || ': ' || count(*) || ' connection(s), oldest idle ' ||"," coalesce(round(extract(epoch from max(now() - state_change)) / 60)::text || 'm', 'n/a')","FROM pg_stat_activity","WHERE (SELECT count(*)::float / NULLIF((SELECT setting::int FROM pg_settings WHERE name = 'max_connections'), 0) FROM pg_stat_activity) >= 0.8","GROUP BY datname ORDER BY count(*) DESC;","TS_CLOUD_PG_CAP_EOF"]}function Kc(e){if(!e?.name)return{};let t=e.engine==="singlestore",r=e.engine==="vitess",n=e.engine==="postgres"?"pgsql":t?"singlestore":r?"vitess":"mysql",o=e.port??(e.engine==="postgres"?5432:r?15306:3306),s={DB_CONNECTION:n,DB_HOST:e.host||"127.0.0.1",DB_PORT:String(o),DB_DATABASE:e.name};if(e.username)s.DB_USERNAME=e.username;if(e.password)s.DB_PASSWORD=e.password;if((t||r)&&e.ssl!==!1)s.DB_SSL="true";return s}var V="/var/backups/ts-cloud",ee="/etc/ts-cloud/backups.config.ts",ue="/etc/cron.d/ts-cloud-backups",fn="/usr/local/bin/ts-cloud-backup.sh";function He(e){if(!e.name)return null;if(!["postgres","mysql","mariadb"].includes(e.engine||""))throw Error("Unsupported scheduled SQL backup engine");return JSON.stringify({type:e.engine==="postgres"?"postgresql":"mysql",name:e.name,connection:{hostname:e.host||"127.0.0.1",port:e.port??(e.engine==="postgres"?5432:3306),database:e.name,username:e.username||e.name,password:e.password||"",ssl:!1},includeSchema:!0,includeData:!0})}function Ge(e,t){let r=e?He(e):null,n=t.bucket?{type:"s3",bucket:t.bucket,prefix:t.prefix||"db-backups",...t.endpoint?{endpoint:t.endpoint}:{},...t.region?{region:t.region}:{},keepDays:t.retentionDays??30,optional:!1,...t.encryptionKey?{encryption:{keyEnv:"TS_CLOUD_BACKUP_ENCRYPTION_KEY"}}:{}}:void 0,o={verbose:!0,outputPath:V,retention:{count:t.retentionCount??5,maxAge:t.retentionDays??30},databases:[],files:t.files||[],destinations:n?[n]:[]};return["import type { BackupConfig } from 'ts-backups'",`const config: BackupConfig = ${JSON.stringify(o,null,2)}`,`config.databases = [
7
+ ${r||""}
8
+ ]`,...t.credentials?["config.destinations![0]!.credentials = { accessKeyId: process.env.TS_CLOUD_BACKUP_ACCESS_KEY!, secretAccessKey: process.env.TS_CLOUD_BACKUP_SECRET_KEY! }"]:[],"export default config",""].join(`
9
+ `)}function ko(e){let{database:t,backups:r}=e;if(!r.enabled)return[];if(r.credentials&&(!r.bucket||!r.credentials.accessKeyId||!r.credentials.secretAccessKey))throw Error("Scheduled backups require complete destination credentials and a bucket");if(r.encryptionKey&&(r.encryptionKey.length<32||!r.bucket))throw Error("Encrypted offsite backups require a bucket and a separate recovery key of at least 32 characters");let n=r.version||"0.1.6";if(!/^\d+\.\d+\.\d+$/.test(n))throw Error("Pin a released ts-backups version");let o=r.schedule||"0 2 * * *";if(!/^[0-9*,/ -]+$/.test(o)||o.trim().split(/\s+/).length!==5)throw Error("Invalid backup schedule");let s=(l)=>`'${l.replace(/'/g,"'\\''")}'`,c=Object.entries({...r.credentials?{TS_CLOUD_BACKUP_ACCESS_KEY:r.credentials.accessKeyId,TS_CLOUD_BACKUP_SECRET_KEY:r.credentials.secretAccessKey}:{},...r.encryptionKey?{TS_CLOUD_BACKUP_ENCRYPTION_KEY:r.encryptionKey}:{}}).map(([l,i])=>`${l}=${s(i)}`).join(`
10
+ `),p="/opt/ts-cloud/backups";return["umask 077",`mkdir -p /etc/ts-cloud ${V} ${p}`,`chmod 700 ${V} ${p}`,'export PATH="/opt/ts-cloud/bun/bin:/opt/pantry/pantry/.bin:/usr/local/bin:/usr/bin:/bin"',`test -f ${p}/package.json || printf '%s' '{"private":true}' > ${p}/package.json`,`bun add --cwd ${p} --no-save ts-backups@${n}`,`printf '%s' ${s(Ge(t,r))} > ${ee}`,`printf '%s\\n' ${s(c)} > /etc/ts-cloud/backups.env`,`chmod 600 ${ee} /etc/ts-cloud/backups.env`,`cat > ${fn} <<'TS_CLOUD_BACKUP_RUN_EOF'`,"#!/bin/bash","set -euo pipefail","umask 077","exec 9>/run/lock/ts-cloud-backups.lock","flock -n 9 || exit 0",'export PATH="/opt/ts-cloud/bun/bin:/opt/pantry/pantry/.bin:/usr/local/bin:/usr/bin:/bin"','eval "$(cd /opt/pantry && pantry env)"',"set -a",". /etc/ts-cloud/backups.env","set +a",'notify() { [ -x /usr/local/bin/ts-cloud-notify ] && /usr/local/bin/ts-cloud-notify "$1" || true; }',"cd /etc/ts-cloud",`if ! ${p}/node_modules/.bin/ts-backups start --config ${ee}; then notify "ts-cloud backup failed"; exit 1; fi`,"date -u +%FT%TZ > /var/backups/ts-cloud/last-success","TS_CLOUD_BACKUP_RUN_EOF",`chmod 700 ${fn}`,`printf '%s\\n' ${s(`${o} root ${fn} >> /var/log/ts-cloud-backup.log 2>&1`)} > ${ue}`,`chmod 644 ${ue}`]}function qe(e){return e==="mariadb"?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock"}function xi(e,t={}){if(!e?.name)return[];let r=e.name,n=e.engine==="postgres",o=t.from?`TS_CLOUD_DUMP="${t.from}"`:`TS_CLOUD_DUMP="$(find ${V} -type f -name '*${r}*.sql' -o -type f -name '*${r}*.sql.gz' 2>/dev/null | xargs -r ls -1t 2>/dev/null | head -1)"`,s=n?`${Et(e)} -d "${r}"`:`mysql --socket=${qe(e.engine)} -u root "${r}"`;return["set -uo pipefail",'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true',o,'[ -n "$TS_CLOUD_DUMP" ] && [ -f "$TS_CLOUD_DUMP" ] || { echo "no backup dump found to restore" >&2; exit 1; }','echo "[ts-cloud] restoring '+r+' from $TS_CLOUD_DUMP"',`case "$TS_CLOUD_DUMP" in *.gz) gunzip -c "$TS_CLOUD_DUMP" ;; *) cat "$TS_CLOUD_DUMP" ;; esac | ${s}`,'echo "restore complete"']}var No=["storage",".env"],_i=4;function v(e){return`${e.replace(/\/+$/,"")}/.ts-cloud`}function js(e){return`${v(e)}/deploy-history.log`}function Fe(e,t){return`${v(e)}/deploys/${t}.log`}function de(e){return`${v(e)}/shared-paths`}function xo(e){return`${e.shared}/stx-images`}function Oi(e){return`${e.shared}/stx-bundles`}function Ht(e,t){let r=e.replace(/\/+$/,"");return{base:r,releases:`${r}/releases`,shared:`${r}/shared`,current:`${r}/current`,release:`${r}/releases/${t}`}}function $e(e){let t=e.split("/").pop()||e;if(t===".env"||t.startsWith(".env."))return!0;return/\.[a-z0-9]+$/i.test(t)}function Vs(e){return typeof e==="string"?e:e.path}function Jc(e){let t=new Map;for(let r of e)t.set(Vs(r),r);return[...t.values()]}function _e(e,t){if(typeof t==="string")return{path:t,target:`${e.shared}/${t}`,seed:!0};return{path:t.path,target:t.target??`${e.shared}/${t.path}`,seed:t.seed!==!1}}function Ye(e){return["ts_cloud_adopt_shared() {",' TS_CLOUD_SP="$1"',' TS_CLOUD_DST="$2"',` TS_CLOUD_SRC="${e.current}/$TS_CLOUD_SP"`,' if [ -e "$TS_CLOUD_DST" ]; then return 0; fi',' if [ -L "$TS_CLOUD_SRC" ] || [ ! -e "$TS_CLOUD_SRC" ]; then return 0; fi',' mkdir -p "$(dirname "$TS_CLOUD_DST")"',' cp -a "$TS_CLOUD_SRC" "$TS_CLOUD_DST"'," for TS_CLOUD_SIDECAR in -wal -shm; do",' if [ -f "$TS_CLOUD_SRC$TS_CLOUD_SIDECAR" ]; then cp -a "$TS_CLOUD_SRC$TS_CLOUD_SIDECAR" "$TS_CLOUD_DST$TS_CLOUD_SIDECAR"; fi'," done",' echo "[ts-cloud] adopted $TS_CLOUD_SP from the live release into shared/ — it now survives deploys"'," return 0","}"]}function $i(e,t=No){let r=[`mkdir -p ${e.releases} ${e.shared} ${xo(e)} ${Oi(e)}`,...Ye(e)],n=t.map((s)=>_e(e,s));for(let{path:s,target:c,seed:p}of n){if(!p)continue;if(r.push(`ts_cloud_adopt_shared '${s}' '${c}'`),$e(s))r.push(`mkdir -p "$(dirname ${c})"`,`touch ${c}`);else if(s==="storage")r.push(`mkdir -p ${c}/app/public`,`mkdir -p ${c}/framework/cache/data`,`mkdir -p ${c}/framework/sessions`,`mkdir -p ${c}/framework/testing`,`mkdir -p ${c}/framework/views`,`mkdir -p ${c}/logs`);else r.push(`mkdir -p ${c}`)}let o=de(e.base);return r.push(`mkdir -p ${v(e.base)}`,`cat > ${o} <<'TS_CLOUD_SHARED_PATHS_EOF'`,...n.map((s)=>`${s.path} ${s.target}`),"TS_CLOUD_SHARED_PATHS_EOF"),r}function zs(e,t=900){let r=`${v(e.base)}/deploy.lock`;return[`mkdir -p "$(dirname ${r})"`,`exec 9>${r}`,`flock -w ${t} 9 || { echo "[ts-cloud] another deploy of this site has held the lock for ${t}s — refusing to race it" >&2; exit 1; }`]}function Hs(e){let t=`${e.release}.incoming`;return[`rm -rf ${t}`,`mkdir -p ${t}`,...Ke(e),'if [ "$TS_CLOUD_IS_LIVE" = "yes" ]; then',` TS_CLOUD_STAGED=${t}`,"else",` rm -rf ${e.release}`,` mkdir -p ${e.release}`,` rmdir ${t}`,` TS_CLOUD_STAGED=${e.release}`,"fi"]}function Gs(e){let t=`TS_CLOUD_TRAP_LIVE="$(readlink -f ${e.current} 2>/dev/null || true)"`,r=`TS_CLOUD_TRAP_TARGET="$(readlink -f ${e.release} 2>/dev/null || echo ${e.release})"`;return`trap '${`if [ $? -ne 0 ]; then ${t}; ${r}; [ "$TS_CLOUD_TRAP_LIVE" = "$TS_CLOUD_TRAP_TARGET" ] || rm -rf ${e.release}; fi`}' EXIT`}function Ke(e){return[`TS_CLOUD_LIVE_PATH="$(readlink -f ${e.current} 2>/dev/null || true)"`,`TS_CLOUD_RELEASE_PATH="$(readlink -f ${e.release} 2>/dev/null || echo ${e.release})"`,'if [ -n "$TS_CLOUD_LIVE_PATH" ] && [ "$TS_CLOUD_LIVE_PATH" = "$TS_CLOUD_RELEASE_PATH" ]; then TS_CLOUD_IS_LIVE=yes; else TS_CLOUD_IS_LIVE=no; fi']}function qs(e){let t=`${e.release}.incoming`;return[`if [ "$TS_CLOUD_STAGED" = "${t}" ]; then`,` rm -rf ${e.release}.previous`,` mv ${e.release} ${e.release}.previous`,` mv ${t} ${e.release}`,` rm -rf ${e.release}.previous`,"fi"]}function je(e,t){return[`if [ -f ${e} ] && [ ! -L ${e} ] && [ -s ${e} ] && [ ! -s ${t} ]; then`,` cp -a ${e} ${t}`,` echo "[ts-cloud] seeded shared/ from the release's own copy of the file"`,"fi"]}function _o(e,t=No){let r=[];for(let n of t){let{path:o,target:s,seed:c}=_e(e,n),p=`${e.release}/${o}`,l=[`rm -rf ${p}`,`mkdir -p "$(dirname ${p})"`,`ln -sfn ${s} ${p}`];if(c){if(o!==".env"&&$e(o))r.push(...je(p,s));r.push(...l);continue}r.push(`if [ -e ${s} ]; then`,...l.map((i)=>` ${i}`),"fi")}return r}function We(e,t){let r=de(e.base);return[`if [ -f ${r} ]; then`,' while IFS="\t" read -r TS_CLOUD_SP TS_CLOUD_TGT; do',' [ -n "$TS_CLOUD_SP" ] || continue',` [ -n "$TS_CLOUD_TGT" ] || TS_CLOUD_TGT="${e.shared}/$TS_CLOUD_SP"`,' [ -e "$TS_CLOUD_TGT" ] || continue',` rm -rf ${t}/"$TS_CLOUD_SP"`,` mkdir -p "$(dirname ${t}/"$TS_CLOUD_SP")"`,` ln -sfn "$TS_CLOUD_TGT" ${t}/"$TS_CLOUD_SP"`,` done < ${r}`,"fi"]}function hn(e){return[`ln -sfn ${e.release} ${e.current}.tmp`,`mv -Tf ${e.current}.tmp ${e.current}`]}function te(e){return`${v(e)}/previous-release`}function Ws(e,t="TS_CLOUD_PREV_CURRENT"){let r=te(e.base);return[`if [ -n "\${${t}:-}" ] && [ -d "$${t}" ] && [ "$(readlink -f "$${t}")" != "$(readlink -f ${e.release})" ]; then mkdir -p ${v(e.base)}; basename "$${t}" > ${r}; fi`]}function Se(e,t){let r=te(e.base);return[`TS_CLOUD_CURRENT=$(readlink -f ${e.current} 2>/dev/null || true)`,...t?[`TS_CLOUD_RB_TARGET=${e.releases}/${t}`]:["TS_CLOUD_RB_TARGET=",`if [ -f ${r} ]; then TS_CLOUD_REC="${e.releases}/$(cat ${r})"; if [ -d "$TS_CLOUD_REC" ] && [ "$(readlink -f "$TS_CLOUD_REC")" != "$TS_CLOUD_CURRENT" ]; then TS_CLOUD_RB_TARGET="$TS_CLOUD_REC"; fi; fi`,`[ -n "$TS_CLOUD_RB_TARGET" ] || TS_CLOUD_RB_TARGET=$(ls -1dt ${e.releases}/*/ 2>/dev/null | sed 's#/$##' | while read -r r; do [ "$(readlink -f "$r")" != "$TS_CLOUD_CURRENT" ] && { echo "$r"; break; }; done)`],'[ -n "$TS_CLOUD_RB_TARGET" ] && [ -d "$TS_CLOUD_RB_TARGET" ] || { echo "no release to roll back to (looked for ${TS_CLOUD_RB_TARGET:-a previous release})" >&2; exit 1; }','[ "$(readlink -f "$TS_CLOUD_RB_TARGET")" != "$TS_CLOUD_CURRENT" ] || { echo "$(basename "$TS_CLOUD_RB_TARGET") is already the live release" >&2; exit 1; }','TS_CLOUD_RB_ID=$(basename "$TS_CLOUD_RB_TARGET")']}function Xc(e,t={}){return[...Se(e,t.to),'echo "would roll back from $(basename "${TS_CLOUD_CURRENT:-none}") to $TS_CLOUD_RB_ID (dry run: nothing changed)"']}function Qc(e,t={}){let r=Math.max(1,t.gateSeconds??5),n=t.systemdDir??"/etc/systemd/system",o=[`ln -sfn "$TS_CLOUD_RB_TARGET" ${e.current}.tmp`,`mv -Tf ${e.current}.tmp ${e.current}`,`rm -f ${te(e.base)}`,'echo "rolled back to $TS_CLOUD_RB_ID"'],s=[...Se(e,t.to),...We(e,'"$TS_CLOUD_RB_TARGET"')];if(!t.unitBase)return[...s,...o];let c=t.unitBase,p=`${c}@\${TS_CLOUD_RB_ID}.service`;return[...s,`if [ -f ${n}/${c}@.service ]; then`,` systemctl start "${p}"`,` for TS_CLOUD_I in $(seq 1 ${r}); do sleep 1; systemctl is-active --quiet "${p}" || { echo "the release rolled back to, $TS_CLOUD_RB_ID, did not stay up; the current release keeps serving" >&2; journalctl -u "${p}" -n 30 --no-pager >&2 || true; systemctl stop "${p}" 2>/dev/null || true; exit 1; }; done`,...o.map((l)=>` ${l}`),` systemctl enable "${p}" 2>/dev/null || true`,` systemctl list-units --plain --no-legend --type=service "${c}@*.service" 2>/dev/null | awk '{print $1}' | { grep -v "^${c}@\${TS_CLOUD_RB_ID}.service$" || true; } | while read -r TS_CLOUD_U; do systemctl stop "$TS_CLOUD_U" 2>/dev/null || true; systemctl disable "$TS_CLOUD_U" 2>/dev/null || true; done`,`elif [ -f ${n}/${c}.service ]; then`,...o.map((l)=>` ${l}`),` systemctl restart ${c}.service`,"else",...o.map((l)=>` ${l}`),"fi"]}function yn(e,t=4){let r=Math.max(1,t);return[`TS_CLOUD_CURRENT=$(readlink -f ${e.current} 2>/dev/null || true)`,`ls -1dt ${e.releases}/*/ 2>/dev/null | sed 's#/$##' | tail -n +${r+1} | while read -r TS_CLOUD_OLD; do`,' [ "$(readlink -f "$TS_CLOUD_OLD")" = "$TS_CLOUD_CURRENT" ] || rm -rf "$TS_CLOUD_OLD"',"done"]}function Xe(e){return`${v(e)}/owner`}function Ks(e,t){let r=Xe(e);return[`if [ -f "${r}" ]; then`,` TS_CLOUD_OWNER=$(cat "${r}")`,` if [ "$TS_CLOUD_OWNER" != "${t}" ]; then`,` echo "[ts-cloud] REFUSING deploy: ${e} belongs to project '$TS_CLOUD_OWNER', not '${t}'. Another project on this box derives the same site key — give one of them a distinct site name/domain, or remove ${r} to transfer ownership." >&2`," exit 1"," fi","else",` mkdir -p "$(dirname "${r}")"`,` printf '%s\\n' "${t}" > "${r}"`,"fi"]}function Oo(e,t){let r=v(e),n=Fe(e,t.releaseId),o=js(e),s=Math.max(1,t.keepLogs??20),c=t.commit||"",p=t.branch||"";return[`mkdir -p ${r}/deploys`,`exec > >(tee -a ${n}) 2>&1`,`echo "[ts-cloud] deploy ${t.releaseId} commit=${c} branch=${p} starting $(date -u +%Y-%m-%dT%H:%M:%SZ)"`,"ts_cloud_record_deploy() {"," TS_CLOUD_RC=$?",' if [ "$TS_CLOUD_RC" -eq 0 ]; then TS_CLOUD_ST=success; else TS_CLOUD_ST=failed; fi',` printf '%s\\t%s\\t%s\\t%s\\trc=%s\\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "${t.releaseId}" "${c}" "$TS_CLOUD_ST" "$TS_CLOUD_RC" >> ${o}`,"}","trap ts_cloud_record_deploy EXIT",`ls -1t ${r}/deploys/*.log 2>/dev/null | tail -n +${s+1} | while read -r TS_CLOUD_OLDLOG; do rm -f "$TS_CLOUD_OLDLOG"; done`]}
11
+ export{W,ki,Us,w,Ro,Bs,Fs,qc,Wc,R,Tt,Ve,it,Io,Ni,Po,gn,Et,Do,wt,Kc,fn,ko,xi,No,_i,js,xo,Oi,Ht,Vs,Jc,$i,zs,Hs,Gs,qs,_o,hn,Ws,Xc,Qc,yn,Ks,Oo};