@stacksjs/ts-cloud 0.5.24 → 0.5.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +3 -3
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/dist/bin/cli.js
CHANGED
|
@@ -7412,7 +7412,7 @@ import { startProxies } from '@stacksjs/rpx'
|
|
|
7412
7412
|
const config = ${JSON.stringify($,null,2)} as const
|
|
7413
7413
|
|
|
7414
7414
|
await startProxies(config as any)
|
|
7415
|
-
`}function kF($,J,Y){return[`cat > ${$} <<'${Y}'`,J,Y]}function LJ($){let{config:J,proxy:Y}=$,Q=$.bunBin??"/usr/local/bin/bun",G=Y.version??"latest",Z=J.productionCerts.certsDir,W=vF(J),z=[`Environment=RPX_UPSTREAM_TIMEOUT=${Y.upstreamTimeout??60}`];if(typeof Y.maxUpstreamConns==="number")z.push(`Environment=RPX_MAX_UPSTREAM_CONNS=${Y.maxUpstreamConns}`);return["set -euo pipefail",`mkdir -p ${fF} ${Z}
|
|
7415
|
+
`}function kF($,J,Y){return[`cat > ${$} <<'${Y}'`,J,Y]}function LJ($){let{config:J,proxy:Y}=$,Q=$.bunBin??"/usr/local/bin/bun",G=Y.version??"latest",Z=J.productionCerts.certsDir,W=vF(J),z=[`Environment=RPX_UPSTREAM_TIMEOUT=${Y.upstreamTimeout??60}`];if(typeof Y.maxUpstreamConns==="number")z.push(`Environment=RPX_MAX_UPSTREAM_CONNS=${Y.maxUpstreamConns}`);return["set -euo pipefail",`mkdir -p ${fF} ${Z}`,`mkdir -p /tmp/ts-cloud-rpx-install && (cd /tmp/ts-cloud-rpx-install && ${Q} add -g @stacksjs/rpx@${G})`,...kF(jU,W,"TS_CLOUD_RPX_EOF"),...kF(`/etc/systemd/system/${c6}`,["[Unit]","Description=rpx reverse-proxy gateway (managed by ts-cloud)","After=network.target network-online.target","Wants=network-online.target","","[Service]","Type=simple",`ExecStart=${Q} ${jU}`,"Environment=BUN_INSTALL=/root/.bun",...z,"Restart=always","RestartSec=5","LimitNOFILE=1048576","AmbientCapabilities=CAP_NET_BIND_SERVICE","","[Install]","WantedBy=multi-user.target"].join(`
|
|
7416
7416
|
`),"TS_CLOUD_RPX_UNIT_EOF"),"systemctl daemon-reload",`systemctl enable ${c6}`,`systemctl restart ${c6}`]}var bF="/etc/rpx/certs",fF="/etc/rpx",jU="/etc/rpx/gateway.ts",c6="rpx-gateway.service";var l6=Z0(()=>{KJ()});function gF($={}){let J=Math.max(1,$.appServers??$.instances??1),Y=!!$.servicesServer||J>1,Q=J>1||!!$.server?.loadBalancer;return{appServers:J,loadBalancer:Q,dedicatedServices:Y,servicesOnApp:!Y}}function uF($,J){let Y={REDIS_HOST:$,MEILISEARCH_HOST:`http://${$}:7700`};if(J?.name){if(Y.DB_CONNECTION=J.engine==="postgres"?"pgsql":"mysql",Y.DB_HOST=$,Y.DB_PORT=String(J.port??(J.engine==="postgres"?5432:3306)),Y.DB_DATABASE=J.name,J.username)Y.DB_USERNAME=J.username;if(J.password)Y.DB_PASSWORD=J.password}return Y}function qU($){let J=new Set([80,443,...$.sitePorts]);if($.allowSsh)J.add(22);return[...J].map((Y)=>{return{direction:"in",protocol:"tcp",port:String(Y),source_ips:["0.0.0.0/0","::/0"],description:`ts-cloud port ${Y}`}})}function m6($){if(!$)return MU.micro;if($ in MU)return MU[$];return $}function Y2($,J,Y="app"){return{[`${G8}/project`]:$,[`${G8}/environment`]:J,[`${G8}/role`]:Y,[`${G8}/managed-by`]:"ts-cloud"}}function Z8($,J,Y,Q="app"){if(!$)return!1;return $[`${G8}/project`]===J&&$[`${G8}/environment`]===Y&&$[`${G8}/role`]===Q}var MU,G8="ts-cloud";var dF=Z0(()=>{MU={micro:"cpx11",small:"cx23",medium:"cx33",large:"cx43",xlarge:"cx53","2xlarge":"ccx33"}});import{mkdir as tS,readFile as aS,writeFile as oS}from"node:fs/promises";import{join as cF}from"node:path";function mF($){return cF(process.cwd(),lF,`${$}.json`)}async function AJ($){try{let J=await aS(mF($),"utf8");return JSON.parse(J)}catch{return null}}async function EJ($,J){let Y=mF($);await tS(cF(process.cwd(),lF),{recursive:!0}),await oS(Y,`${JSON.stringify(J,null,2)}
|
|
7417
7417
|
`,"utf8")}var lF=".ts-cloud/state";var pF=()=>{};import{existsSync as sS,readFileSync as eS}from"node:fs";import{homedir as $P}from"node:os";import{join as JP}from"node:path";import{execSync as wU}from"node:child_process";function rF($){return $.startsWith("~/")?JP($P(),$.slice(2)):$}var TU=268435456,W8;var RU=Z0(async()=>{LU();l6();BU();y6();b6();XU();dF();pF();await L1();W8=class W8{name="hetzner";usesCloudFormation=!1;client;sshPrivateKeyPath;sshPublicKeyPath;sshUser;location;waitForBoot;bootWait;constructor($={}){this.client=$.client??new OJ({apiToken:d6($.apiToken)}),this.sshPrivateKeyPath=rF($.sshPrivateKeyPath||process.env.HCLOUD_SSH_KEY||"~/.ssh/id_ed25519"),this.sshPublicKeyPath=rF($.sshPublicKeyPath||process.env.HCLOUD_SSH_PUBLIC_KEY||`${this.sshPrivateKeyPath}.pub`),this.sshUser=$.sshUser||process.env.HCLOUD_SSH_USER||"root",this.location=$.location||process.env.HCLOUD_LOCATION||"fsn1",this.waitForBoot=$.waitForBoot??!0,this.bootWait={sshIntervalMs:$.bootWait?.sshIntervalMs??5000,sshTimeoutMs:$.bootWait?.sshTimeoutMs??300000,cloudInitIntervalMs:$.bootWait?.cloudInitIntervalMs??5000,cloudInitTimeoutMs:$.bootWait?.cloudInitTimeoutMs??600000}}async provisionComputeInfrastructure($){let{config:J,environment:Y}=$,Q=J.project.slug,G=J.infrastructure?.compute;if(!G)throw Error("infrastructure.compute is required to provision Hetzner compute");let Z=f1(J,Y),W=`${Q}-${Y}-app`,U=gF(G);if(U.dedicatedServices||U.appServers>1)return this.provisionFleet($,U);let z=await AJ(Z);if(z?.serverId){let k=await this.tryGetServer(z.serverId);if(k&&k.status!=="off")return this.outputsFromState(z,k)}let H=Y2(Q,Y,"app"),_=await this.findExistingServer(Q,Y,W);if(_&&_.status!=="off"){let k={provider:"hetzner",stackName:Z,serverId:_.id,serverName:_.name,publicIp:_.public_net.ipv4?.ip,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser};return await EJ(Z,k),this.outputsFromState(k,_)}let X=J.sites||{},F=this.collectUpstreamPorts(X),B=G.proxy?.engine==="rpx"?LJ({proxy:G.proxy,config:VJ(X,{proxy:G.proxy}),bunBin:G.runtime==="node"||G.runtime==="deno"?void 0:"/usr/local/bin/bun"}):void 0,V=u6(J),K=G.bakedImage===!0,L=J2({runtime:V.runtime,runtimeVersion:V.runtimeVersion,systemPackages:G.systemPackages,database:J.infrastructure?.database,phpProvision:V.phpProvision,servicesProvision:V.servicesProvision,rpxProvision:B,baked:K}),E=d8(L),A=m6(G.size),j=G.image||J.hetzner?.image||"ubuntu-24.04",q=`${Q}-${Y}-app-fw`,{firewall:M}=await this.ensureFirewall(q,H,qU({allowSsh:G.allowSsh!==!1,sitePorts:F})),T=await this.ensureSshKey(Q,Y,H),{server:R,action:S}=await this.client.createServer({name:W,serverType:A,image:j,location:J.hetzner?.location||this.location,userData:E,labels:H,sshKeys:T?[T]:void 0,firewalls:[{firewall:M.id}]});await this.client.waitForAction(S.id);let N=await this.client.waitForServerRunning(R.id),C={provider:"hetzner",stackName:Z,serverId:N.id,serverName:N.name,firewallId:M.id,publicIp:N.public_net.ipv4?.ip,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser};await EJ(Z,C);let x=N.public_net.ipv4?.ip;if(x&&this.waitForBoot)await this.waitForSshReady(x),await this.waitForCloudInit(x);return this.outputsFromState(C,N)}async provisionFleet($,J){let{config:Y,environment:Q}=$,G=Y.project.slug,Z=Y.infrastructure.compute,W=f1(Y,Q),U=m6(Z.size),z=Z.image||Y.hetzner?.image||"ubuntu-24.04",H=Y.hetzner?.location||this.location,_=Z.bakedImage===!0,X=await AJ(W);if(X?.loadBalancerId){let s=(await this.client.listLoadBalancers().catch(()=>[])).find((Y0)=>Y0.id===X.loadBalancerId);if(s)return{appPublicIp:s.public_net?.ipv4?.ip,loadBalancerIp:s.public_net?.ipv4?.ip,servicesPrivateIp:X.servicesPrivateIp,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser}}let F=await this.ensureSshKey(G,Q,Y2(G,Q,"app")),B=`${G}-${Q}-net`,K=(await this.client.listNetworks().catch(()=>[])).find((a)=>a.name===B)??await this.client.createNetwork({name:B,labels:Y2(G,Q,"app")}),{firewall:L}=await this.ensureFirewall(`${G}-${Q}-app-fw`,Y2(G,Q,"app"),qU({allowSsh:!0,sitePorts:[]})),{firewall:E}=await this.ensureFirewall(`${G}-${Q}-services-fw`,Y2(G,Q,"services"),[{direction:"in",protocol:"tcp",port:"22",source_ips:["0.0.0.0/0","::/0"]},{direction:"in",protocol:"tcp",port:"3306",source_ips:[K.ip_range]},{direction:"in",protocol:"tcp",port:"5432",source_ips:[K.ip_range]},{direction:"in",protocol:"tcp",port:"6379",source_ips:[K.ip_range]},{direction:"in",protocol:"tcp",port:"7700",source_ips:[K.ip_range]}]),A=[...x6(Z.managedServices??{mysql:!0,redis:!0},{bindPrivate:!0}),...k6(Y.infrastructure?.appDatabase,Z.managedServices??{mysql:!0}),...UJ(!0),...zJ(!0),...HJ(Z.sshKeys)],j=d8(J2({runtime:"php",servicesProvision:A,baked:_})),q=await this.client.listServers().catch(()=>[]),M=[],T=q.find((a)=>Z8(a.labels,G,Q,"services"));if(!T){let{server:a,action:s}=await this.client.createServer({name:`${G}-${Q}-services`,serverType:m6(typeof Z.servicesServer==="object"?Z.servicesServer.size:Z.size),image:z,location:H,userData:j,labels:Y2(G,Q,"services"),sshKeys:F?[F]:void 0,firewalls:[{firewall:E.id}],networks:[K.id]});await this.client.waitForAction(s.id),T=await this.client.waitForServerRunning(a.id),M.push(a.id)}let R=T.id,S=T.private_net?.[0]?.ip??(await this.client.getServer(R)).private_net?.[0]?.ip,N=[...UJ(!0),...zJ(!0),...HJ(Z.sshKeys),...g6(Y.notifications)],C=h6({versions:Z.php?.versions,default:Z.php?.default,extensions:Z.php?.extensions,installNginx:Z.webServer!=="rpx",optimizeForProduction:Z.php?.optimizeForProduction,ini:Z.php?.ini}),x=d8(J2({runtime:"php",phpProvision:C,servicesProvision:N,baked:_})),k=q.filter((a)=>Z8(a.labels,G,Q,"app")),b=k.map((a)=>a.id);if(k.length>J.appServers)for(let a of k.slice(J.appServers))await this.client.deleteServer(a.id).catch(()=>{}),b.splice(b.indexOf(a.id),1);for(let a=k.length;a<J.appServers;a++){let{server:s,action:Y0}=await this.client.createServer({name:`${G}-${Q}-app-${a+1}`,serverType:U,image:z,location:H,userData:x,labels:Y2(G,Q,"app"),sshKeys:F?[F]:void 0,firewalls:[{firewall:L.id}],networks:[K.id]});await this.client.waitForAction(Y0.id),b.push(s.id),M.push(s.id)}if(this.waitForBoot&&M.length>0)await Promise.all(M.map(async(a)=>{let Y0=(await this.client.waitForServerRunning(a)).public_net.ipv4?.ip;if(Y0)await this.waitForSshReady(Y0),await this.waitForCloudInit(Y0)}));let m=`${G}-${Q}-lb`,h,u;if(J.loadBalancer){let s=(await this.client.listLoadBalancers().catch(()=>[])).find((Y0)=>Y0.name===m)??await this.client.createLoadBalancer({name:m,location:H,network:K.id,labels:Y2(G,Q,"lb"),labelSelector:`ts-cloud/project=${G},ts-cloud/environment=${Q},ts-cloud/role=app`,services:[{listenPort:80,destinationPort:80},{listenPort:443,destinationPort:443}]});u=s.id,h=s.public_net?.ipv4?.ip}let $0=h??(await this.client.getServer(b[0]).catch(()=>{return}))?.public_net.ipv4?.ip,J0={provider:"hetzner",stackName:W,networkId:K.id,loadBalancerId:u,servicesServerId:R,servicesPrivateIp:S,publicIp:$0,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser};return await EJ(W,J0),{appPublicIp:$0,loadBalancerIp:h,servicesPrivateIp:S,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser}}async destroyCompute($){let{config:J,environment:Y}=$,Q=J.project.slug,G=f1(J,Y),Z=await AJ(G),W=[],U=`${Q}-${Y}-lb`,H=(await this.client.listLoadBalancers().catch(()=>[])).find((L)=>L.name===U);if(H)try{await this.client.deleteLoadBalancer(H.id),W.push(`load balancer ${U}`)}catch{}let _=await this.client.listServers().catch(()=>[]),X=new Set;for(let L of _)if(Z8(L.labels,Q,Y,"app")||Z8(L.labels,Q,Y,"services"))X.add(L.id);if(Z?.serverId)X.add(Z.serverId);if(Z?.servicesServerId)X.add(Z.servicesServerId);for(let L of X)try{await this.client.deleteServer(L),W.push(`server ${L}`)}catch{}let F=await this.client.listFirewalls().catch(()=>[]);for(let L of[`${Q}-${Y}-app-fw`,`${Q}-${Y}-services-fw`]){let E=F.find((A)=>A.name===L);if(!E)continue;for(let A=0;A<12;A++)try{await this.client.deleteFirewall(E.id),W.push(`firewall ${L}`);break}catch{await this.sleep(3000)}}let B=`${Q}-${Y}-net`,K=(await this.client.listNetworks().catch(()=>[])).find((L)=>L.name===B);if(K)for(let L=0;L<12;L++)try{await this.client.deleteNetwork(K.id),W.push(`network ${B}`);break}catch{await this.sleep(3000)}return await EJ(G,{provider:"hetzner",stackName:G}).catch(()=>{}),{destroyed:W}}async getComputeOutputs($){let J=f1($.config,$.environment),Y=await AJ(J);if(Y?.serverId){let Z=await this.client.getServer(Y.serverId);return this.outputsFromState(Y,Z)}if(Y?.loadBalancerId||Y?.servicesPrivateIp)return this.outputsFromState(Y);let G=(await this.findComputeTargets({slug:$.config.project.slug,environment:$.environment,role:"app"}))[0];return{deployStoragePath:"/var/ts-cloud/staging",appInstanceId:G?.id,appPublicIp:G?.publicIp,sshUser:this.sshUser}}async uploadRelease($){let J=$.targets?.length?$.targets:await this.findComputeTargets({slug:$.config.project.slug,environment:$.environment,role:"app"});if(J.length===0)throw Error("No Hetzner compute targets found for release upload");let Y=`/var/ts-cloud/staging/${$.remoteKey.split("/").pop()}`;for(let Q of J){if(!Q.publicIp)throw Error(`Target ${Q.id} has no public IP for SCP upload`);this.scpToHost(Q.publicIp,$.localPath,Y)}return{artifactRef:Y}}async findComputeTargets($){return(await this.client.listServers()).filter((Y)=>Z8(Y.labels,$.slug,$.environment,$.role||"app")).map((Y)=>({id:String(Y.id),name:Y.name,publicIp:Y.public_net.ipv4?.ip,privateIp:Y.private_net?.[0]?.ip,status:Y.status}))}async runRemoteDeploy($){if($.targets.length===0)return{success:!1,instanceCount:0,perInstance:[],error:"No targets provided"};let J=$.commands.join(`
|
|
7418
7418
|
`),Y=[];for(let G of $.targets){if(!G.publicIp){Y.push({instanceId:G.id,status:"Failed",error:"Missing public IP"});continue}try{let Z=this.sshExec(G.publicIp,J);Y.push({instanceId:G.id,status:"Success",output:Z})}catch(Z){Y.push({instanceId:G.id,status:"Failed",error:Z.message})}}let Q=Y.every((G)=>G.status==="Success");return{success:Q,instanceCount:$.targets.length,perInstance:Y,error:Q?void 0:"One or more SSH deploy commands failed"}}async ensureSshKey($,J,Y){if(!sS(this.sshPublicKeyPath))throw Error(`SSH public key not found at ${this.sshPublicKeyPath}. ts-cloud deploys to Hetzner over SSH and needs a public key to authorize on the server. Generate one (\`ssh-keygen -t ed25519\`) or set hetzner.sshPrivateKeyPath / HCLOUD_SSH_PUBLIC_KEY.`);let Q=eS(this.sshPublicKeyPath,"utf8").trim(),G=VU(Q),W=(await this.client.listSshKeys()).find((z)=>VU(z.public_key)===G);if(W)return W.id;return(await this.client.createSshKey({name:`${$}-${J}-deploy`,publicKey:Q,labels:Y})).id}async tryGetServer($){try{return await this.client.getServer($)}catch{return null}}async findExistingServer($,J,Y){return(await this.client.listServers()).find((G)=>Z8(G.labels,$,J,"app")||G.name===Y)}async ensureFirewall($,J,Y){let G=(await this.client.listFirewalls()).find((W)=>W.name===$);if(G)return await this.client.setFirewallRules(G.id,Y),{firewall:G};let{firewall:Z}=await this.client.createFirewall({name:$,labels:J,rules:Y});return{firewall:Z}}collectUpstreamPorts($){let J=new Set;for(let Y of Object.values($))if(typeof Y.port==="number")J.add(Y.port);return[...J].filter((Y)=>![80,443].includes(Y))}async sleep($){await new Promise((J)=>setTimeout(J,$))}async waitForSshReady($){let{sshIntervalMs:J,sshTimeoutMs:Y}=this.bootWait,Q=Date.now(),G;while(Date.now()-Q<Y)try{wU(`ssh ${this.sshBaseArgs($,["-o","ConnectTimeout=5"]).map((Z)=>`"${Z.replace(/"/g,"\\\"")}"`).join(" ")} true`,{stdio:"pipe",maxBuffer:TU});return}catch(Z){G=Z,await this.sleep(J)}throw Error(`Timed out waiting for SSH on ${$} after ${Y}ms: ${G?.message??"unknown error"}`)}async waitForCloudInit($){let{cloudInitIntervalMs:J,cloudInitTimeoutMs:Y}=this.bootWait,Q=Date.now();while(Date.now()-Q<Y){try{let G=this.sshExec($,"cloud-init status --long 2>/dev/null || cloud-init status 2>/dev/null || echo status:\\ done");if(/status:\s*done/.test(G))return;if(/status:\s*error/.test(G))throw Error(`cloud-init reported an error on ${$}:
|
|
@@ -10313,7 +10313,7 @@ import { startProxies } from '@stacksjs/rpx'
|
|
|
10313
10313
|
const config = ${JSON.stringify($,null,2)} as const
|
|
10314
10314
|
|
|
10315
10315
|
await startProxies(config as any)
|
|
10316
|
-
`}function $K($,J,Y){return[`cat > ${$} <<'${Y}'`,J,Y]}function Xy($){let{config:J,proxy:Y}=$,Q=$.bunBin??"/usr/local/bin/bun",G=Y.version??"latest",Z=J.productionCerts.certsDir,W=Hy(J),z=[`Environment=RPX_UPSTREAM_TIMEOUT=${Y.upstreamTimeout??60}`];if(typeof Y.maxUpstreamConns==="number")z.push(`Environment=RPX_MAX_UPSTREAM_CONNS=${Y.maxUpstreamConns}`);return["set -euo pipefail",`mkdir -p ${_y} ${Z}
|
|
10316
|
+
`}function $K($,J,Y){return[`cat > ${$} <<'${Y}'`,J,Y]}function Xy($){let{config:J,proxy:Y}=$,Q=$.bunBin??"/usr/local/bin/bun",G=Y.version??"latest",Z=J.productionCerts.certsDir,W=Hy(J),z=[`Environment=RPX_UPSTREAM_TIMEOUT=${Y.upstreamTimeout??60}`];if(typeof Y.maxUpstreamConns==="number")z.push(`Environment=RPX_MAX_UPSTREAM_CONNS=${Y.maxUpstreamConns}`);return["set -euo pipefail",`mkdir -p ${_y} ${Z}`,`mkdir -p /tmp/ts-cloud-rpx-install && (cd /tmp/ts-cloud-rpx-install && ${Q} add -g @stacksjs/rpx@${G})`,...$K(eB,W,"TS_CLOUD_RPX_EOF"),...$K(`/etc/systemd/system/${Bz}`,["[Unit]","Description=rpx reverse-proxy gateway (managed by ts-cloud)","After=network.target network-online.target","Wants=network-online.target","","[Service]","Type=simple",`ExecStart=${Q} ${eB}`,"Environment=BUN_INSTALL=/root/.bun",...z,"Restart=always","RestartSec=5","LimitNOFILE=1048576","AmbientCapabilities=CAP_NET_BIND_SERVICE","","[Install]","WantedBy=multi-user.target"].join(`
|
|
10317
10317
|
`),"TS_CLOUD_RPX_UNIT_EOF"),"systemctl daemon-reload",`systemctl enable ${Bz}`,`systemctl restart ${Bz}`]}function Fy($={}){let J=Math.max(1,$.appServers??$.instances??1),Y=!!$.servicesServer||J>1,Q=J>1||!!$.server?.loadBalancer;return{appServers:J,loadBalancer:Q,dedicatedServices:Y,servicesOnApp:!Y}}function JK($){let J=new Set([80,443,...$.sitePorts]);if($.allowSsh)J.add(22);return[...J].map((Y)=>{return{direction:"in",protocol:"tcp",port:String(Y),source_ips:["0.0.0.0/0","::/0"],description:`ts-cloud port ${Y}`}})}function Vz($){if(!$)return Kz.micro;if($ in Kz)return Kz[$];return $}function k2($,J,Y="app"){return{[`${z8}/project`]:$,[`${z8}/environment`]:J,[`${z8}/role`]:Y,[`${z8}/managed-by`]:"ts-cloud"}}function J9($,J,Y,Q="app"){if(!$)return!1;return $[`${z8}/project`]===J&&$[`${z8}/environment`]===Y&&$[`${z8}/role`]===Q}function $A($){return sL(process.cwd(),eL,`${$}.json`)}async function LQ($){try{let J=await By($A($),"utf8");return JSON.parse(J)}catch{return null}}async function AQ($,J){let Y=$A($);await Oy(sL(process.cwd(),eL),{recursive:!0}),await Ky(Y,`${JSON.stringify(J,null,2)}
|
|
10318
10318
|
`,"utf8")}function YK($){return $.startsWith("~/")?Yy(Jy(),$.slice(2)):$}function Vy($){switch($.provider??Ez($.config)){case"aws":return new aL({region:$.config.project.region});case"hetzner":return new nQ({apiToken:$.config.hetzner?.apiToken,sshPrivateKeyPath:$.config.hetzner?.sshPrivateKeyPath,sshUser:$.config.hetzner?.sshUser,location:$.config.hetzner?.location});default:throw Error(`Unknown cloud provider: ${$.provider??Ez($.config)}`)}}class JA{drivers=new Map;getDriver($,J){let Y=J??Ez($),Q=`${Y}:${$.project.slug}:${$.project.region||"default"}`,G=this.drivers.get(Q);if(G)return G;let Z=Vy({config:$,provider:Y});return this.drivers.set(Q,Z),Z}}var DP,NP=($)=>$,iQ=($,J)=>{for(var Y in J)DP($,Y,{get:J[Y],enumerable:!0,configurable:!0,set:SP.bind(J,Y)})},a0=($,J)=>()=>($&&(J=$($=0)),J),EQ,jV,vC=($)=>$,U8=($,J)=>{for(var Y in J)jV($,Y,{get:J[Y],enumerable:!0,configurable:!0,set:QC.bind(J,Y)})},fC=($,J)=>()=>($&&(J=$($=0)),J),IO,xO,Q9,F8,qV=100,MV,NJ,gC,uC,e,dC,cC,lC,mC,pC,rC,nC,iC,kO,dU=`
|
|
10319
10319
|
const { SNSClient, PublishCommand } = require('@aws-sdk/client-sns');
|
|
@@ -13716,7 +13716,7 @@ Run \`${this.name??"cli"} --help\` for usage.`;B2.stderr.write(`${Z}${G}${W}
|
|
|
13716
13716
|
`).length-1;this.output.write(d$.move(-999,$*-1))}render(){let $=Y7(this._render(this)??"",J7.stdout.columns,{hard:!0,trim:!1});if($===this._prevFrame)return;if(this.state==="initial")this.output.write(d$.hide);else{let J=AE(this._prevFrame,$);if(this.restoreCursor(),J&&J?.length===1){let Y=J[0];this.output.write(d$.move(0,Y)),this.output.write(X5.lines(1));let Q=$.split(`
|
|
13717
13717
|
`);this.output.write(Q[Y]),this._prevFrame=$,this.output.write(d$.move(0,Q.length-Y-1));return}if(J&&J?.length>1){let Y=J[0];this.output.write(d$.move(0,Y)),this.output.write(X5.down());let G=$.split(`
|
|
13718
13718
|
`).slice(Y);this.output.write(G.join(`
|
|
13719
|
-
`)),this._prevFrame=$;return}this.output.write(X5.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function TE($,J){if($===void 0)return 0;if(J.length===0)return 0;let Q=J.findIndex((G)=>G.value===$);return Q!==-1?Q:0}function RE($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function DE($,J){if(!J)return;if($)return J;return J[0]}class NE extends L5{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Q;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return oJ.inverse(oJ.hidden("_"));if(this._cursor>=this.userInput.length)return`${this.userInput}█`;let $=this.userInput.slice(0,this._cursor),[J,...Y]=this.userInput.slice(this._cursor);return`${$}${oJ.inverse(J)}${Y.join("")}`}get options(){if(typeof this.#J==="function")return this.#J();return this.#J}constructor($){super($);this.#J=$.options;let J=this.options;this.filteredOptions=[...J],this.multiple=$.multiple===!0,this.#Q=$.filter??RE;let Y;if($.initialValue&&Array.isArray($.initialValue))if(this.multiple)Y=$.initialValue;else Y=$.initialValue.slice(0,1);else if(!this.multiple&&this.options.length>0)Y=[this.options[0].value];if(Y)for(let Q of Y){let G=J.findIndex((Z)=>Z.value===Q);if(G!==-1)this.toggleSelected(Q),this.#$=G}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Q,G)=>this.#G(Q,G)),this.on("userInput",(Q)=>this.#Z(Q))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#G($,J){let Y=J.name==="up",Q=J.name==="down",G=J.name==="return";if(Y||Q){if(this.#$=Math.max(0,Math.min(this.#$+(Y?-1:1),this.filteredOptions.length-1)),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)this.selectedValues=[this.focusedValue];this.isNavigating=!0}else if(G)this.value=DE(this.multiple,this.selectedValues);else if(this.multiple)if(this.focusedValue!==void 0&&(J.name==="tab"||this.isNavigating&&J.name==="space"))this.toggleSelected(this.focusedValue);else this.isNavigating=!1;else{if(this.focusedValue)this.selectedValues=[this.focusedValue];this.isNavigating=!1}}deselectAll(){this.selectedValues=[]}toggleSelected($){if(this.filteredOptions.length===0)return;if(this.multiple)if(this.selectedValues.includes($))this.selectedValues=this.selectedValues.filter((J)=>J!==$);else this.selectedValues=[...this.selectedValues,$];else this.selectedValues=[$]}#Z($){if($!==this.#Y){this.#Y=$;let J=this.options;if($)this.filteredOptions=J.filter((Y)=>this.#Q($,Y));else this.filteredOptions=[...J];if(this.#$=TE(this.focusedValue,this.filteredOptions),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)if(this.focusedValue!==void 0)this.toggleSelected(this.focusedValue);else this.deselectAll()}}}class SE extends L5{options;cursor=0;#$;getGroupItems($){return this.options.filter((J)=>J.group===$)}isGroupSelected($){let J=this.getGroupItems($),Y=this.value;if(Y===void 0)return!1;return J.every((Q)=>Y.includes(Q.value))}toggleValue(){let $=this.options[this.cursor];if(this.value===void 0)this.value=[];if($.group===!0){let J=$.value,Y=this.getGroupItems(J);if(this.isGroupSelected(J))this.value=this.value.filter((Q)=>Y.findIndex((G)=>G.value===Q)===-1);else this.value=[...this.value,...Y.map((Q)=>Q.value)];this.value=Array.from(new Set(this.value))}else{let J=this.value.includes($.value);this.value=J?this.value.filter((Y)=>Y!==$.value):[...this.value,$.value]}}constructor($){super($,!1);let{options:J}=$;this.#$=$.selectableGroups!==!1,this.options=Object.entries(J).flatMap(([Y,Q])=>[{value:Y,group:!0,label:Y},...Q.map((G)=>({...G,group:Y}))]),this.value=[...$.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:Y})=>Y===$.cursorAt),this.#$?0:1),this.on("cursor",(Y)=>{switch(Y){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var PE=vA();var f0=($,J)=>PE?$:J,Iv=f0("◆","*"),xv=f0("■","x"),kv=f0("▲","x"),bv=f0("◇","o"),hv=f0("┌","T"),CE=f0("│","|"),yv=f0("└","—"),vv=f0("●",">"),fv=f0("○"," "),gv=f0("◻","[•]"),uv=f0("◼","[+]"),dv=f0("◻","[ ]"),cv=f0("▪","•"),lv=f0("─","-"),mv=f0("╮","+"),pv=f0("├","+"),rv=f0("╯","+"),nv=f0("●","•"),iv=f0("◆","*"),tv=f0("▲","!"),av=f0("■","x");var ov={light:f0("─","-"),heavy:f0("━","="),block:f0("█","#")};function IE(){return`${oJ.gray(CE)} `}var sv=IE();var A5="0.5.
|
|
13719
|
+
`)),this._prevFrame=$;return}this.output.write(X5.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function TE($,J){if($===void 0)return 0;if(J.length===0)return 0;let Q=J.findIndex((G)=>G.value===$);return Q!==-1?Q:0}function RE($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function DE($,J){if(!J)return;if($)return J;return J[0]}class NE extends L5{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Q;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return oJ.inverse(oJ.hidden("_"));if(this._cursor>=this.userInput.length)return`${this.userInput}█`;let $=this.userInput.slice(0,this._cursor),[J,...Y]=this.userInput.slice(this._cursor);return`${$}${oJ.inverse(J)}${Y.join("")}`}get options(){if(typeof this.#J==="function")return this.#J();return this.#J}constructor($){super($);this.#J=$.options;let J=this.options;this.filteredOptions=[...J],this.multiple=$.multiple===!0,this.#Q=$.filter??RE;let Y;if($.initialValue&&Array.isArray($.initialValue))if(this.multiple)Y=$.initialValue;else Y=$.initialValue.slice(0,1);else if(!this.multiple&&this.options.length>0)Y=[this.options[0].value];if(Y)for(let Q of Y){let G=J.findIndex((Z)=>Z.value===Q);if(G!==-1)this.toggleSelected(Q),this.#$=G}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Q,G)=>this.#G(Q,G)),this.on("userInput",(Q)=>this.#Z(Q))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#G($,J){let Y=J.name==="up",Q=J.name==="down",G=J.name==="return";if(Y||Q){if(this.#$=Math.max(0,Math.min(this.#$+(Y?-1:1),this.filteredOptions.length-1)),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)this.selectedValues=[this.focusedValue];this.isNavigating=!0}else if(G)this.value=DE(this.multiple,this.selectedValues);else if(this.multiple)if(this.focusedValue!==void 0&&(J.name==="tab"||this.isNavigating&&J.name==="space"))this.toggleSelected(this.focusedValue);else this.isNavigating=!1;else{if(this.focusedValue)this.selectedValues=[this.focusedValue];this.isNavigating=!1}}deselectAll(){this.selectedValues=[]}toggleSelected($){if(this.filteredOptions.length===0)return;if(this.multiple)if(this.selectedValues.includes($))this.selectedValues=this.selectedValues.filter((J)=>J!==$);else this.selectedValues=[...this.selectedValues,$];else this.selectedValues=[$]}#Z($){if($!==this.#Y){this.#Y=$;let J=this.options;if($)this.filteredOptions=J.filter((Y)=>this.#Q($,Y));else this.filteredOptions=[...J];if(this.#$=TE(this.focusedValue,this.filteredOptions),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)if(this.focusedValue!==void 0)this.toggleSelected(this.focusedValue);else this.deselectAll()}}}class SE extends L5{options;cursor=0;#$;getGroupItems($){return this.options.filter((J)=>J.group===$)}isGroupSelected($){let J=this.getGroupItems($),Y=this.value;if(Y===void 0)return!1;return J.every((Q)=>Y.includes(Q.value))}toggleValue(){let $=this.options[this.cursor];if(this.value===void 0)this.value=[];if($.group===!0){let J=$.value,Y=this.getGroupItems(J);if(this.isGroupSelected(J))this.value=this.value.filter((Q)=>Y.findIndex((G)=>G.value===Q)===-1);else this.value=[...this.value,...Y.map((Q)=>Q.value)];this.value=Array.from(new Set(this.value))}else{let J=this.value.includes($.value);this.value=J?this.value.filter((Y)=>Y!==$.value):[...this.value,$.value]}}constructor($){super($,!1);let{options:J}=$;this.#$=$.selectableGroups!==!1,this.options=Object.entries(J).flatMap(([Y,Q])=>[{value:Y,group:!0,label:Y},...Q.map((G)=>({...G,group:Y}))]),this.value=[...$.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:Y})=>Y===$.cursorAt),this.#$?0:1),this.on("cursor",(Y)=>{switch(Y){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var PE=vA();var f0=($,J)=>PE?$:J,Iv=f0("◆","*"),xv=f0("■","x"),kv=f0("▲","x"),bv=f0("◇","o"),hv=f0("┌","T"),CE=f0("│","|"),yv=f0("└","—"),vv=f0("●",">"),fv=f0("○"," "),gv=f0("◻","[•]"),uv=f0("◼","[+]"),dv=f0("◻","[ ]"),cv=f0("▪","•"),lv=f0("─","-"),mv=f0("╮","+"),pv=f0("├","+"),rv=f0("╯","+"),nv=f0("●","•"),iv=f0("◆","*"),tv=f0("▲","!"),av=f0("■","x");var ov={light:f0("─","-"),heavy:f0("━","="),block:f0("█","#")};function IE(){return`${oJ.gray(CE)} `}var sv=IE();var A5="0.5.25";O0();import{existsSync as S5}from"node:fs";import{mkdir as cE,writeFile as j7}from"node:fs/promises";function P5($){$.command("init","Initialize a new ts-cloud project").option("--mode <mode>","Deployment mode: server, serverless, or hybrid").option("--name <name>","Project name").option("--region <region>","AWS Region").action(async(J)=>{if(P("Initializing ts-cloud Project"),S5("cloud.config.ts")){if(!await p("cloud.config.ts already exists. Overwrite?",!1)){O("Initialization cancelled");return}}let Y=J?.name||await k0("Project name","my-app"),Q=J?.mode||await $Y("Select deployment mode",["serverless","server","hybrid"]),G=J?.region||await $Y("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),Z=new I("Creating configuration file...");Z.start();let W=`import { defineConfig } from '@ts-cloud/core'
|
|
13720
13720
|
|
|
13721
13721
|
export default defineConfig({
|
|
13722
13722
|
project: {
|
package/dist/index.js
CHANGED
|
@@ -85487,7 +85487,7 @@ function buildRpxProvisionScript(options) {
|
|
|
85487
85487
|
return [
|
|
85488
85488
|
"set -euo pipefail",
|
|
85489
85489
|
`mkdir -p ${RPX_DIR} ${certsDir}`,
|
|
85490
|
-
|
|
85490
|
+
`mkdir -p /tmp/ts-cloud-rpx-install && (cd /tmp/ts-cloud-rpx-install && ${bunBin} add -g @stacksjs/rpx@${version2})`,
|
|
85491
85491
|
...writeFileHeredoc(RPX_LAUNCHER_PATH, launcher, "TS_CLOUD_RPX_EOF"),
|
|
85492
85492
|
...writeFileHeredoc(`/etc/systemd/system/${RPX_SERVICE_NAME}`, [
|
|
85493
85493
|
"[Unit]",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/ts-cloud",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.25",
|
|
5
5
|
"description": "A lightweight, performant infrastructure-as-code library and CLI for deploying both server-based (EC2) and serverless applications.",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
"test": "bun test"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@ts-cloud/aws-types": "0.5.
|
|
93
|
-
"@ts-cloud/core": "0.5.
|
|
92
|
+
"@ts-cloud/aws-types": "0.5.25",
|
|
93
|
+
"@ts-cloud/core": "0.5.25",
|
|
94
94
|
"@stacksjs/ts-xml": "^0.1.0"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|