@stacksjs/ts-cloud 0.5.25 → 0.5.26

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 CHANGED
@@ -7279,7 +7279,7 @@ ${Object.entries($).filter(([Z])=>!Z.startsWith("@_")).map(([Z,W])=>G(Z,W," ","
7279
7279
  `)}
7280
7280
  `}return`${["server {"," listen 80;"," listen [::]:80;",` server_name ${J};`,...Y,"}"].join(`
7281
7281
  `)}
7282
- `}function zU($){let J=`/etc/nginx/sites-available/${$.siteName}`,Y=`/etc/nginx/sites-enabled/${$.siteName}`,Q=vS($),G=[...HU()];if($.auth){let Z=AF($.siteName),W=(H)=>H.split("'").join("'\\''"),U=W($.auth.password),z=W($.auth.username);G.push(`TS_CLOUD_HTPASS=$(openssl passwd -apr1 '${U}')`,`printf '%s:%s\\n' '${z}' "$TS_CLOUD_HTPASS" > ${Z}`,`chmod 640 ${Z}`,`chown root:www-data ${Z} 2>/dev/null || true`)}return G.push(`cat > ${J} <<'TS_CLOUD_NGINX_EOF'`,Q.replace(/\n$/,""),"TS_CLOUD_NGINX_EOF",`ln -sf ${J} ${Y}`,"rm -f /etc/nginx/sites-enabled/default",`${u8} -t`,"systemctl reload ts-cloud-nginx 2>/dev/null || systemctl restart ts-cloud-nginx 2>/dev/null || true"),G}function HU($="/opt/pantry"){return[...C6(),...g8(["nginx.org"]),"if ! /opt/pantry/pantry/.bin/nginx -v >/dev/null 2>&1; then apt-get update -y && apt-get install -y nginx; fi","mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /var/log/nginx /var/lib/nginx/body /var/lib/nginx/proxy /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/scgi","getent passwd www-data >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www-data","chown -R www-data:www-data /var/lib/nginx /var/log/nginx",`cat > ${u8} <<'TS_CLOUD_NGINXBIN_EOF'`,"#!/bin/sh",`eval "$(cd ${$} && pantry env 2>/dev/null)"`,"NGINX_BIN=$(command -v nginx || true)",'if [ -z "$NGINX_BIN" ] || ! "$NGINX_BIN" -v >/dev/null 2>&1; then NGINX_BIN=/usr/sbin/nginx; fi','if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=/opt/pantry/pantry/.bin/nginx; fi','exec "$NGINX_BIN" -c /etc/nginx/nginx.conf "$@"',"TS_CLOUD_NGINXBIN_EOF",`chmod +x ${u8}`,"cat > /etc/nginx/fastcgi_params <<'TS_CLOUD_FCGI_EOF'","fastcgi_param QUERY_STRING $query_string;","fastcgi_param REQUEST_METHOD $request_method;","fastcgi_param CONTENT_TYPE $content_type;","fastcgi_param CONTENT_LENGTH $content_length;","fastcgi_param SCRIPT_NAME $fastcgi_script_name;","fastcgi_param REQUEST_URI $request_uri;","fastcgi_param DOCUMENT_URI $document_uri;","fastcgi_param DOCUMENT_ROOT $document_root;","fastcgi_param SERVER_PROTOCOL $server_protocol;","fastcgi_param REQUEST_SCHEME $scheme;","fastcgi_param HTTPS $https if_not_empty;","fastcgi_param GATEWAY_INTERFACE CGI/1.1;","fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;","fastcgi_param REMOTE_ADDR $remote_addr;","fastcgi_param REMOTE_PORT $remote_port;","fastcgi_param SERVER_ADDR $server_addr;","fastcgi_param SERVER_PORT $server_port;","fastcgi_param SERVER_NAME $server_name;","fastcgi_param REDIRECT_STATUS 200;","TS_CLOUD_FCGI_EOF","cat > /etc/nginx/nginx.conf <<'TS_CLOUD_NGINXCONF_EOF'","user www-data;","worker_processes auto;","pid /run/nginx.pid;","error_log /var/log/nginx/error.log;","events { worker_connections 1024; }","http {"," default_type application/octet-stream;"," types {"," text/html html htm;"," text/css css;"," application/javascript js;"," application/json json;"," image/svg+xml svg;"," image/png png;"," image/jpeg jpg jpeg;"," image/gif gif;"," image/x-icon ico;"," image/webp webp;"," font/woff2 woff2;"," font/woff woff;"," text/plain txt;"," }"," access_log /var/log/nginx/access.log;"," sendfile on;"," tcp_nopush on;"," keepalive_timeout 65;"," server_tokens off;"," client_max_body_size 100m;"," client_body_temp_path /var/lib/nginx/body;"," proxy_temp_path /var/lib/nginx/proxy;"," fastcgi_temp_path /var/lib/nginx/fastcgi;"," uwsgi_temp_path /var/lib/nginx/uwsgi;"," scgi_temp_path /var/lib/nginx/scgi;"," server {"," listen 80 default_server;"," listen [::]:80 default_server;"," server_name _;"," return 444;"," }"," include /etc/nginx/sites-enabled/*;","}","TS_CLOUD_NGINXCONF_EOF","cat > /etc/systemd/system/ts-cloud-nginx.service <<'TS_CLOUD_NGINXUNIT_EOF'","[Unit]","Description=ts-cloud nginx (pantry)","After=network.target","","[Service]","Type=simple",`ExecStartPre=${u8} -t`,`ExecStart=${u8} -g 'daemon off;'`,`ExecReload=${u8} -s reload`,"Restart=always","RestartSec=3","","[Install]","WantedBy=multi-user.target","TS_CLOUD_NGINXUNIT_EOF","systemctl daemon-reload","systemctl disable --now nginx 2>/dev/null || true","systemctl enable ts-cloud-nginx","ls /etc/nginx/sites-enabled/* >/dev/null 2>&1 && systemctl restart ts-cloud-nginx || true"]}var xS,u8="/usr/local/bin/ts-cloud-nginx";var _U=Z0(()=>{e$();y6();xS=new Set(["laravel","php","statamic","wordpress"])});function EF($={}){if($.enabled===!1)return[];let J=[...new Set([...fS,...$.allowedPorts||[]])].filter((Q)=>Q>0).sort((Q,G)=>Q-G),Y=["export DEBIAN_FRONTEND=noninteractive","apt-get install -y ufw","ufw default deny incoming","ufw default allow outgoing","ufw allow OpenSSH"];for(let Q of J)Y.push(`ufw allow ${Q}/tcp`);return Y.push("ufw --force enable"),Y}var fS;var jF=Z0(()=>{fS=[80,443]});function UJ($=!0){if(!$)return[];return["export DEBIAN_FRONTEND=noninteractive","apt-get install -y unattended-upgrades","cat > /etc/apt/apt.conf.d/20auto-upgrades <<'TS_CLOUD_AUTOUPD_EOF'",'APT::Periodic::Update-Package-Lists "1";','APT::Periodic::Unattended-Upgrade "1";','APT::Periodic::Download-Upgradeable-Packages "1";','APT::Periodic::AutocleanInterval "7";',"TS_CLOUD_AUTOUPD_EOF","systemctl enable unattended-upgrades 2>/dev/null || true","systemctl restart unattended-upgrades 2>/dev/null || true"]}function gS($=!0){let J=typeof $==="object"?$:{};return{enabled:typeof $==="boolean"?$:$.enabled!==!1,cpuLoadPerCore:J.alerts?.cpuLoadPerCore??2,memPercent:J.alerts?.memPercent??90,diskPercent:J.alerts?.diskPercent??90}}function zJ($=!0){let{enabled:J,cpuLoadPerCore:Y,memPercent:Q,diskPercent:G}=gS($);if(!J)return[];let Z=qF.map(([U,z])=>`SVC_${U.toUpperCase()}=$(probe ${z})`),W=qF.map(([U])=>`"${U}":"$SVC_${U.toUpperCase()}"`).join(",");return["mkdir -p /var/lib/ts-cloud","cat > /usr/local/bin/ts-cloud-metrics.sh <<'TS_CLOUD_METRICS_EOF'","#!/bin/bash","set -uo pipefail","LOAD=$(cut -d' ' -f1 /proc/loadavg)","CPUS=$(nproc)","MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')","MEM_USED=$(free -m | awk '/^Mem:/{print $3}')","SWAP_TOTAL=$(free -m | awk '/^Swap:/{print $2}')","SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')",`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...Z,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))","cat > /var/lib/ts-cloud/metrics.json.tmp <<JSON",'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+W+"}}","JSON","mv -f /var/lib/ts-cloud/metrics.json.tmp /var/lib/ts-cloud/metrics.json",'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${Y} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${Y}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${Q} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${G} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,"PREV=$(cat /var/lib/ts-cloud/alert-state 2>/dev/null || echo ok)",'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi'," echo alert > /var/lib/ts-cloud/alert-state","else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi'," echo ok > /var/lib/ts-cloud/alert-state","fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnBootSec=60","OnUnitActiveSec=60","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.timer"]}var qF;var XU=Z0(()=>{qF=[["nginx",80],["phpFpm",9074],["mysql",3306],["postgres",5432],["redis",6379],["meilisearch",7700]]});function HJ($=[],J={}){if($.length===0)return[];let Y=J.path??"/root/.ssh/authorized_keys",Q=Y.replace(/\/[^/]*$/,""),G=["# >>> ts-cloud managed keys >>>",...$.map((Z)=>`${Z.publicKey.trim()} ${Z.name}`),"# <<< ts-cloud managed keys <<<"].join(`
7282
+ `}function zU($){let J=`/etc/nginx/sites-available/${$.siteName}`,Y=`/etc/nginx/sites-enabled/${$.siteName}`,Q=vS($),G=[...HU()];if($.auth){let Z=AF($.siteName),W=(H)=>H.split("'").join("'\\''"),U=W($.auth.password),z=W($.auth.username);G.push(`TS_CLOUD_HTPASS=$(openssl passwd -apr1 '${U}')`,`printf '%s:%s\\n' '${z}' "$TS_CLOUD_HTPASS" > ${Z}`,`chmod 640 ${Z}`,`chown root:www-data ${Z} 2>/dev/null || true`)}return G.push(`cat > ${J} <<'TS_CLOUD_NGINX_EOF'`,Q.replace(/\n$/,""),"TS_CLOUD_NGINX_EOF",`ln -sf ${J} ${Y}`,"rm -f /etc/nginx/sites-enabled/default",`${u8} -t`,"systemctl reload ts-cloud-nginx 2>/dev/null || systemctl restart ts-cloud-nginx 2>/dev/null || true"),G}function HU($="/opt/pantry"){return[...C6(),...g8(["nginx.org"]),"mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /var/log/nginx /var/lib/nginx/body /var/lib/nginx/proxy /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/scgi","getent passwd www-data >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www-data","chown -R www-data:www-data /var/lib/nginx /var/log/nginx",`cat > ${u8} <<'TS_CLOUD_NGINXBIN_EOF'`,"#!/bin/sh",`eval "$(cd ${$} && pantry env 2>/dev/null)"`,"NGINX_BIN=/opt/pantry/pantry/.bin/nginx",'if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=$(command -v nginx || true); fi','if [ -z "$NGINX_BIN" ]; then echo "nginx binary not found; run pantry install nginx.org or install nginx explicitly" >&2; exit 1; fi','exec "$NGINX_BIN" -c /etc/nginx/nginx.conf "$@"',"TS_CLOUD_NGINXBIN_EOF",`chmod +x ${u8}`,"cat > /etc/nginx/fastcgi_params <<'TS_CLOUD_FCGI_EOF'","fastcgi_param QUERY_STRING $query_string;","fastcgi_param REQUEST_METHOD $request_method;","fastcgi_param CONTENT_TYPE $content_type;","fastcgi_param CONTENT_LENGTH $content_length;","fastcgi_param SCRIPT_NAME $fastcgi_script_name;","fastcgi_param REQUEST_URI $request_uri;","fastcgi_param DOCUMENT_URI $document_uri;","fastcgi_param DOCUMENT_ROOT $document_root;","fastcgi_param SERVER_PROTOCOL $server_protocol;","fastcgi_param REQUEST_SCHEME $scheme;","fastcgi_param HTTPS $https if_not_empty;","fastcgi_param GATEWAY_INTERFACE CGI/1.1;","fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;","fastcgi_param REMOTE_ADDR $remote_addr;","fastcgi_param REMOTE_PORT $remote_port;","fastcgi_param SERVER_ADDR $server_addr;","fastcgi_param SERVER_PORT $server_port;","fastcgi_param SERVER_NAME $server_name;","fastcgi_param REDIRECT_STATUS 200;","TS_CLOUD_FCGI_EOF","cat > /etc/nginx/nginx.conf <<'TS_CLOUD_NGINXCONF_EOF'","user www-data;","worker_processes auto;","pid /run/nginx.pid;","error_log /var/log/nginx/error.log;","events { worker_connections 1024; }","http {"," default_type application/octet-stream;"," types {"," text/html html htm;"," text/css css;"," application/javascript js;"," application/json json;"," image/svg+xml svg;"," image/png png;"," image/jpeg jpg jpeg;"," image/gif gif;"," image/x-icon ico;"," image/webp webp;"," font/woff2 woff2;"," font/woff woff;"," text/plain txt;"," }"," access_log /var/log/nginx/access.log;"," sendfile on;"," tcp_nopush on;"," keepalive_timeout 65;"," server_tokens off;"," client_max_body_size 100m;"," client_body_temp_path /var/lib/nginx/body;"," proxy_temp_path /var/lib/nginx/proxy;"," fastcgi_temp_path /var/lib/nginx/fastcgi;"," uwsgi_temp_path /var/lib/nginx/uwsgi;"," scgi_temp_path /var/lib/nginx/scgi;"," server {"," listen 80 default_server;"," listen [::]:80 default_server;"," server_name _;"," return 444;"," }"," include /etc/nginx/sites-enabled/*;","}","TS_CLOUD_NGINXCONF_EOF","cat > /etc/systemd/system/ts-cloud-nginx.service <<'TS_CLOUD_NGINXUNIT_EOF'","[Unit]","Description=ts-cloud nginx (pantry)","After=network.target","","[Service]","Type=simple",`ExecStartPre=${u8} -t`,`ExecStart=${u8} -g 'daemon off;'`,`ExecReload=${u8} -s reload`,"Restart=always","RestartSec=3","","[Install]","WantedBy=multi-user.target","TS_CLOUD_NGINXUNIT_EOF","systemctl daemon-reload","systemctl enable ts-cloud-nginx","ls /etc/nginx/sites-enabled/* >/dev/null 2>&1 && systemctl restart ts-cloud-nginx || true"]}var xS,u8="/usr/local/bin/ts-cloud-nginx";var _U=Z0(()=>{e$();y6();xS=new Set(["laravel","php","statamic","wordpress"])});function EF($={}){if($.enabled===!1)return[];let J=[...new Set([...fS,...$.allowedPorts||[]])].filter((Q)=>Q>0).sort((Q,G)=>Q-G),Y=["export DEBIAN_FRONTEND=noninteractive","apt-get install -y ufw","ufw default deny incoming","ufw default allow outgoing","ufw allow OpenSSH"];for(let Q of J)Y.push(`ufw allow ${Q}/tcp`);return Y.push("ufw --force enable"),Y}var fS;var jF=Z0(()=>{fS=[80,443]});function UJ($=!0){if(!$)return[];return["export DEBIAN_FRONTEND=noninteractive","apt-get install -y unattended-upgrades","cat > /etc/apt/apt.conf.d/20auto-upgrades <<'TS_CLOUD_AUTOUPD_EOF'",'APT::Periodic::Update-Package-Lists "1";','APT::Periodic::Unattended-Upgrade "1";','APT::Periodic::Download-Upgradeable-Packages "1";','APT::Periodic::AutocleanInterval "7";',"TS_CLOUD_AUTOUPD_EOF","systemctl enable unattended-upgrades 2>/dev/null || true","systemctl restart unattended-upgrades 2>/dev/null || true"]}function gS($=!0){let J=typeof $==="object"?$:{};return{enabled:typeof $==="boolean"?$:$.enabled!==!1,cpuLoadPerCore:J.alerts?.cpuLoadPerCore??2,memPercent:J.alerts?.memPercent??90,diskPercent:J.alerts?.diskPercent??90}}function zJ($=!0){let{enabled:J,cpuLoadPerCore:Y,memPercent:Q,diskPercent:G}=gS($);if(!J)return[];let Z=qF.map(([U,z])=>`SVC_${U.toUpperCase()}=$(probe ${z})`),W=qF.map(([U])=>`"${U}":"$SVC_${U.toUpperCase()}"`).join(",");return["mkdir -p /var/lib/ts-cloud","cat > /usr/local/bin/ts-cloud-metrics.sh <<'TS_CLOUD_METRICS_EOF'","#!/bin/bash","set -uo pipefail","LOAD=$(cut -d' ' -f1 /proc/loadavg)","CPUS=$(nproc)","MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')","MEM_USED=$(free -m | awk '/^Mem:/{print $3}')","SWAP_TOTAL=$(free -m | awk '/^Swap:/{print $2}')","SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')",`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...Z,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))","cat > /var/lib/ts-cloud/metrics.json.tmp <<JSON",'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+W+"}}","JSON","mv -f /var/lib/ts-cloud/metrics.json.tmp /var/lib/ts-cloud/metrics.json",'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${Y} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${Y}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${Q} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${G} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,"PREV=$(cat /var/lib/ts-cloud/alert-state 2>/dev/null || echo ok)",'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi'," echo alert > /var/lib/ts-cloud/alert-state","else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi'," echo ok > /var/lib/ts-cloud/alert-state","fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnBootSec=60","OnUnitActiveSec=60","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.timer"]}var qF;var XU=Z0(()=>{qF=[["nginx",80],["phpFpm",9074],["mysql",3306],["postgres",5432],["redis",6379],["meilisearch",7700]]});function HJ($=[],J={}){if($.length===0)return[];let Y=J.path??"/root/.ssh/authorized_keys",Q=Y.replace(/\/[^/]*$/,""),G=["# >>> ts-cloud managed keys >>>",...$.map((Z)=>`${Z.publicKey.trim()} ${Z.name}`),"# <<< ts-cloud managed keys <<<"].join(`
7283
7283
  `);return[`mkdir -p ${Q}`,`touch ${Y}`,`sed -i '/^${MF("# >>> ts-cloud managed keys >>>")}$/,/^${MF("# <<< ts-cloud managed keys <<<")}$/d' ${Y}`,`cat >> ${Y} <<'TS_CLOUD_KEYS_EOF'`,G,"TS_CLOUD_KEYS_EOF",`chmod 600 ${Y}`]}function MF($){return $.replace(/[.*[\]\\/^$]/g,"\\$&")}class u1{client;region;constructor($="us-east-1",J){this.region=$,this.client=new Q0(J)}async createEmailIdentity($){return await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/identities",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}async getEmailIdentity($){let J=await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/identities/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}});return{IdentityType:J.IdentityType,IdentityName:$,SendingEnabled:J.VerifiedForSendingStatus,VerificationStatus:J.VerificationStatus,DkimAttributes:J.DkimAttributes,MailFromAttributes:J.MailFromAttributes}}async putEmailIdentityMailFromAttributes($,J){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent($)}/mail-from`,headers:{"Content-Type":"application/json"},body:JSON.stringify(J)})}async listEmailIdentities($){let J="/v2/email/identities",Y=[];if($?.PageSize)Y.push(`PageSize=${$.PageSize}`);if($?.NextToken)Y.push(`NextToken=${encodeURIComponent($.NextToken)}`);if(Y.length>0)J+=`?${Y.join("&")}`;let Q=await this.client.request({service:"email",region:this.region,method:"GET",path:J,headers:{"Content-Type":"application/json"}});return{EmailIdentities:Q.EmailIdentities,NextToken:Q.NextToken}}async deleteEmailIdentity($){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/identities/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async putEmailIdentityDkimAttributes($){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent($.EmailIdentity)}/dkim`,headers:{"Content-Type":"application/json"},body:JSON.stringify({SigningEnabled:$.SigningEnabled})})}async sendEmail($){return{MessageId:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})).MessageId}}async sendBulkEmail($){return{BulkEmailEntryResults:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-bulk-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})).BulkEmailEntryResults}}async createEmailTemplate($){await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/templates",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}async getEmailTemplate($){return await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/templates/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async deleteEmailTemplate($){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/templates/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async listEmailTemplates($){let J="/v2/email/templates",Y=[];if($?.PageSize)Y.push(`PageSize=${$.PageSize}`);if($?.NextToken)Y.push(`NextToken=${encodeURIComponent($.NextToken)}`);if(Y.length>0)J+=`?${Y.join("&")}`;return await this.client.request({service:"email",region:this.region,method:"GET",path:J,headers:{"Content-Type":"application/json"}})}async getSendStatistics(){return{SendDataPoints:(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendStatistics&Version=2010-12-01"})).GetSendStatisticsResponse?.GetSendStatisticsResult?.SendDataPoints?.member}}async getSendQuota(){let J=(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendQuota&Version=2010-12-01"})).GetSendQuotaResponse?.GetSendQuotaResult;return{Max24HourSend:J?.Max24HourSend?Number(J.Max24HourSend):void 0,MaxSendRate:J?.MaxSendRate?Number(J.MaxSendRate):void 0,SentLast24Hours:J?.SentLast24Hours?Number(J.SentLast24Hours):void 0}}async verifyDomain($){let J=await this.createEmailIdentity({EmailIdentity:$});return{dkimTokens:J.DkimAttributes?.Tokens,verificationStatus:J.DkimAttributes?.Status}}async sendSimpleEmail($){let J=Array.isArray($.to)?$.to:[$.to],Y=$.replyTo?Array.isArray($.replyTo)?$.replyTo:[$.replyTo]:void 0,Q={};if($.text)Q.Text={Data:$.text};if($.html)Q.Html={Data:$.html};return this.sendEmail({FromEmailAddress:$.from,Destination:{ToAddresses:J},Content:{Simple:{Subject:{Data:$.subject},Body:Q}},ReplyToAddresses:Y})}async sendTemplatedEmail($){let J=Array.isArray($.to)?$.to:[$.to],Y=$.replyTo?Array.isArray($.replyTo)?$.replyTo:[$.replyTo]:void 0;return this.sendEmail({FromEmailAddress:$.from,Destination:{ToAddresses:J},Content:{Template:{TemplateName:$.templateName,TemplateData:JSON.stringify($.templateData)}},ReplyToAddresses:Y})}async getDkimRecords($){let J=await this.getEmailIdentity($);if(!J.DkimAttributes?.Tokens)return[];return J.DkimAttributes.Tokens.map((Y)=>({name:`${Y}._domainkey.${$}`,type:"CNAME",value:`${Y}.dkim.amazonses.com`}))}async isDomainVerified($){try{let J=await this.getEmailIdentity($);return J.VerificationStatus==="SUCCESS"&&J.SendingEnabled===!0}catch{return!1}}async waitForDomainVerification($,J=60,Y=30000){for(let Q=0;Q<J;Q++){if(await this.isDomainVerified($))return!0;await new Promise((Z)=>setTimeout(Z,Y))}return!1}buildFormBody($){return Object.entries($).filter(([,Y])=>Y!==void 0).map(([Y,Q])=>`${encodeURIComponent(Y)}=${encodeURIComponent(Q)}`).join("&")}async createReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CreateReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async deleteReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async setActiveReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"SetActiveReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async listReceiptRuleSets($){let J={Action:"ListReceiptRuleSets",Version:"2010-12-01"};if($)J.NextToken=$;let Y=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListReceiptRuleSetsResponse?.ListReceiptRuleSetsResult||Y?.ListReceiptRuleSetsResult,G=Q?.RuleSets?.member;return{RuleSets:Array.isArray(G)?G:G?[G]:[],NextToken:Q?.NextToken}}async describeReceiptRuleSet($){let J=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})}),Y=J?.DescribeReceiptRuleSetResponse?.DescribeReceiptRuleSetResult||J?.DescribeReceiptRuleSetResult,Q=Y?.Rules?.member;return{Metadata:Y?.Metadata,Rules:Array.isArray(Q)?Q:Q?[Q]:[]}}async createReceiptRule($){let J={Action:"CreateReceiptRule",Version:"2010-12-01",RuleSetName:$.RuleSetName,"Rule.Name":$.Rule.Name,"Rule.Enabled":$.Rule.Enabled!==!1?"true":"false"};if($.Rule.TlsPolicy)J["Rule.TlsPolicy"]=$.Rule.TlsPolicy;if($.Rule.ScanEnabled!==void 0)J["Rule.ScanEnabled"]=$.Rule.ScanEnabled?"true":"false";if($.After)J.After=$.After;if($.Rule.Recipients)$.Rule.Recipients.forEach((Y,Q)=>{J[`Rule.Recipients.member.${Q+1}`]=Y});$.Rule.Actions.forEach((Y,Q)=>{let G=Q+1;if(Y.S3Action){if(J[`Rule.Actions.member.${G}.S3Action.BucketName`]=Y.S3Action.BucketName,Y.S3Action.ObjectKeyPrefix)J[`Rule.Actions.member.${G}.S3Action.ObjectKeyPrefix`]=Y.S3Action.ObjectKeyPrefix;if(Y.S3Action.KmsKeyArn)J[`Rule.Actions.member.${G}.S3Action.KmsKeyArn`]=Y.S3Action.KmsKeyArn}if(Y.LambdaAction)J[`Rule.Actions.member.${G}.LambdaAction.FunctionArn`]=Y.LambdaAction.FunctionArn,J[`Rule.Actions.member.${G}.LambdaAction.InvocationType`]=Y.LambdaAction.InvocationType||"Event";if(Y.SNSAction){if(J[`Rule.Actions.member.${G}.SNSAction.TopicArn`]=Y.SNSAction.TopicArn,Y.SNSAction.Encoding)J[`Rule.Actions.member.${G}.SNSAction.Encoding`]=Y.SNSAction.Encoding}if(Y.StopAction){if(J[`Rule.Actions.member.${G}.StopAction.Scope`]=Y.StopAction.Scope,Y.StopAction.TopicArn)J[`Rule.Actions.member.${G}.StopAction.TopicArn`]=Y.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async deleteReceiptRule($,J){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRule",Version:"2010-12-01",RuleSetName:$,RuleName:J})})}async receiptRuleSetExists($){try{return await this.describeReceiptRuleSet($),!0}catch(J){if(J.code==="RuleSetDoesNotExist"||J.statusCode===400)return!1;throw J}}async getActiveReceiptRuleSet(){let $=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeActiveReceiptRuleSet",Version:"2010-12-01"})}),J=$?.DescribeActiveReceiptRuleSetResponse?.DescribeActiveReceiptRuleSetResult||$?.DescribeActiveReceiptRuleSetResult;if(!J?.Metadata)return null;let Y=J?.Rules?.member;return{Metadata:J?.Metadata,Rules:Array.isArray(Y)?Y:Y?[Y]:[]}}async updateReceiptRule($){let J={Action:"UpdateReceiptRule",Version:"2010-12-01",RuleSetName:$.RuleSetName,"Rule.Name":$.Rule.Name};if($.Rule.Enabled!==void 0)J["Rule.Enabled"]=$.Rule.Enabled?"true":"false";if($.Rule.TlsPolicy)J["Rule.TlsPolicy"]=$.Rule.TlsPolicy;if($.Rule.ScanEnabled!==void 0)J["Rule.ScanEnabled"]=$.Rule.ScanEnabled?"true":"false";if($.Rule.Recipients)$.Rule.Recipients.forEach((Y,Q)=>{J[`Rule.Recipients.member.${Q+1}`]=Y});$.Rule.Actions.forEach((Y,Q)=>{let G=Q+1;if(Y.S3Action){if(J[`Rule.Actions.member.${G}.S3Action.BucketName`]=Y.S3Action.BucketName,Y.S3Action.ObjectKeyPrefix)J[`Rule.Actions.member.${G}.S3Action.ObjectKeyPrefix`]=Y.S3Action.ObjectKeyPrefix;if(Y.S3Action.KmsKeyArn)J[`Rule.Actions.member.${G}.S3Action.KmsKeyArn`]=Y.S3Action.KmsKeyArn}if(Y.LambdaAction)J[`Rule.Actions.member.${G}.LambdaAction.FunctionArn`]=Y.LambdaAction.FunctionArn,J[`Rule.Actions.member.${G}.LambdaAction.InvocationType`]=Y.LambdaAction.InvocationType||"Event";if(Y.SNSAction){if(J[`Rule.Actions.member.${G}.SNSAction.TopicArn`]=Y.SNSAction.TopicArn,Y.SNSAction.Encoding)J[`Rule.Actions.member.${G}.SNSAction.Encoding`]=Y.SNSAction.Encoding}if(Y.StopAction){if(J[`Rule.Actions.member.${G}.StopAction.Scope`]=Y.StopAction.Scope,Y.StopAction.TopicArn)J[`Rule.Actions.member.${G}.StopAction.TopicArn`]=Y.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async sendRawEmail($){let J=Buffer.from($.rawMessage).toString("base64"),Y={Action:"SendRawEmail",Version:"2010-12-01",Source:$.source,"RawMessage.Data":J};$.destinations.forEach((Z,W)=>{Y[`Destinations.member.${W+1}`]=Z});let Q=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(Y)});return{MessageId:(Q?.SendRawEmailResponse?.SendRawEmailResult||Q?.SendRawEmailResult)?.MessageId}}async getSuppressedDestination($){try{return(await this.client.request({service:"ses",region:this.region,method:"GET",path:`/v2/email/suppression/addresses/${encodeURIComponent($)}`}))?.SuppressedDestination||null}catch(J){if(J.message?.includes("404")||J.message?.includes("NotFoundException"))return null;throw J}}async deleteSuppressedDestination($){await this.client.request({service:"ses",region:this.region,method:"DELETE",path:`/v2/email/suppression/addresses/${encodeURIComponent($)}`})}}var _J=Z0(()=>{z0()});function uS($,J){let Y=[`Action=${$}`,"Version=2010-05-08"];for(let[Q,G]of Object.entries(J)){if(G===void 0||G===null)continue;if(Array.isArray(G))G.forEach((Z,W)=>{if(typeof Z==="object"&&Z!==null)for(let[U,z]of Object.entries(Z))Y.push(`${Q}.member.${W+1}.${U}=${encodeURIComponent(String(z))}`);else Y.push(`${Q}.member.${W+1}=${encodeURIComponent(String(Z))}`)});else if(typeof G==="object"){for(let[Z,W]of Object.entries(G))if(W!==void 0&&W!==null)Y.push(`${Q}.${Z}=${encodeURIComponent(String(W))}`)}else Y.push(`${Q}=${encodeURIComponent(String(G))}`)}return Y.join("&")}function v($,J){let Y=new RegExp(`<${J}>([^<]*)</${J}>`),Q=$.match(Y);return Q?Q[1]:void 0}function w1($,J,Y){let Q=new RegExp(`<${J}>([\\s\\S]*?)</${J}>`),G=$.match(Q);if(!G)return[];let Z=[],W=new RegExp(`<${Y}>([\\s\\S]*?)</${Y}>`,"g"),U;while((U=W.exec(G[1]))!==null)Z.push(U[1]);return Z}class d1{client;region;constructor($="us-east-1"){this.client=new Q0,this.region=$}async request($,J={}){let Y=uS($,J);return await this.client.request({service:"iam",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y})}async createUser($){let J=await this.request("CreateUser",$);return this.parseUser(J)}async getUser($={}){let J=await this.request("GetUser",$);return this.parseUser(J)}async listUsers($={}){let J=await this.request("ListUsers",$),Y=this.parseUsers(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{Users:Y,IsTruncated:Q,Marker:G}}async updateUser($){await this.request("UpdateUser",$)}async deleteUser($){await this.request("DeleteUser",$)}parseUser($){return{UserName:v($,"UserName")||"",UserId:v($,"UserId")||"",Arn:v($,"Arn")||"",Path:v($,"Path"),CreateDate:v($,"CreateDate"),PasswordLastUsed:v($,"PasswordLastUsed")}}parseUsers($){return w1($,"Users","member").map((Y)=>({UserName:v(Y,"UserName")||"",UserId:v(Y,"UserId")||"",Arn:v(Y,"Arn")||"",Path:v(Y,"Path"),CreateDate:v(Y,"CreateDate"),PasswordLastUsed:v(Y,"PasswordLastUsed")}))}async createGroup($){let J=await this.request("CreateGroup",$);return this.parseGroup(J)}async getGroup($){let J=await this.request("GetGroup",$),Y=this.parseGroup(J),Q=this.parseUsers(J),G=v(J,"IsTruncated")==="true",Z=v(J,"Marker");return{Group:Y,Users:Q,IsTruncated:G,Marker:Z}}async listGroups($={}){let J=await this.request("ListGroups",$),Y=this.parseGroups(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{Groups:Y,IsTruncated:Q,Marker:G}}async updateGroup($){await this.request("UpdateGroup",$)}async deleteGroup($){await this.request("DeleteGroup",$)}async addUserToGroup($){await this.request("AddUserToGroup",$)}async removeUserFromGroup($){await this.request("RemoveUserFromGroup",$)}async listGroupsForUser($){let J=await this.request("ListGroupsForUser",$),Y=this.parseGroups(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{Groups:Y,IsTruncated:Q,Marker:G}}parseGroup($){return{GroupName:v($,"GroupName")||"",GroupId:v($,"GroupId")||"",Arn:v($,"Arn")||"",Path:v($,"Path"),CreateDate:v($,"CreateDate")}}parseGroups($){return w1($,"Groups","member").map((Y)=>({GroupName:v(Y,"GroupName")||"",GroupId:v(Y,"GroupId")||"",Arn:v(Y,"Arn")||"",Path:v(Y,"Path"),CreateDate:v(Y,"CreateDate")}))}async createRole($){let J=await this.request("CreateRole",$);return this.parseRole(J)}async getRole($){let J=await this.request("GetRole",$);return this.parseRole(J)}async listRoles($={}){let J=await this.request("ListRoles",$),Y=this.parseRoles(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{Roles:Y,IsTruncated:Q,Marker:G}}async updateRole($){await this.request("UpdateRole",$)}async updateRoleDescription($){let J=await this.request("UpdateRoleDescription",$);return this.parseRole(J)}async updateAssumeRolePolicy($){await this.request("UpdateAssumeRolePolicy",$)}async deleteRole($){await this.request("DeleteRole",$)}async tagRole($){await this.request("TagRole",$)}async untagRole($){await this.request("UntagRole",$)}async listRoleTags($){let J=await this.request("ListRoleTags",$),Y=this.parseTags(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{Tags:Y,IsTruncated:Q,Marker:G}}parseRole($){return{RoleName:v($,"RoleName")||"",RoleId:v($,"RoleId")||"",Arn:v($,"Arn")||"",Path:v($,"Path"),CreateDate:v($,"CreateDate"),AssumeRolePolicyDocument:v($,"AssumeRolePolicyDocument"),Description:v($,"Description"),MaxSessionDuration:v($,"MaxSessionDuration")?Number.parseInt(v($,"MaxSessionDuration"),10):void 0}}parseRoles($){return w1($,"Roles","member").map((Y)=>({RoleName:v(Y,"RoleName")||"",RoleId:v(Y,"RoleId")||"",Arn:v(Y,"Arn")||"",Path:v(Y,"Path"),CreateDate:v(Y,"CreateDate"),AssumeRolePolicyDocument:v(Y,"AssumeRolePolicyDocument"),Description:v(Y,"Description"),MaxSessionDuration:v(Y,"MaxSessionDuration")?Number.parseInt(v(Y,"MaxSessionDuration"),10):void 0}))}parseTags($){return w1($,"Tags","member").map((Y)=>({Key:v(Y,"Key")||"",Value:v(Y,"Value")||""}))}async createPolicy($){let J=await this.request("CreatePolicy",$);return this.parsePolicy(J)}async getPolicy($){let J=await this.request("GetPolicy",$);return this.parsePolicy(J)}async getPolicyVersion($){let J=await this.request("GetPolicyVersion",$);return{VersionId:v(J,"VersionId")||"",IsDefaultVersion:v(J,"IsDefaultVersion")==="true",CreateDate:v(J,"CreateDate"),Document:v(J,"Document")}}async listPolicies($={}){let J=await this.request("ListPolicies",$),Y=this.parsePolicies(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{Policies:Y,IsTruncated:Q,Marker:G}}async listPolicyVersions($){let J=await this.request("ListPolicyVersions",$),Y=this.parsePolicyVersions(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{Versions:Y,IsTruncated:Q,Marker:G}}async createPolicyVersion($){let J=await this.request("CreatePolicyVersion",$);return{VersionId:v(J,"VersionId")||"",IsDefaultVersion:v(J,"IsDefaultVersion")==="true",CreateDate:v(J,"CreateDate")}}async deletePolicyVersion($){await this.request("DeletePolicyVersion",$)}async setDefaultPolicyVersion($){await this.request("SetDefaultPolicyVersion",$)}async deletePolicy($){await this.request("DeletePolicy",$)}async attachUserPolicy($){await this.request("AttachUserPolicy",$)}async detachUserPolicy($){await this.request("DetachUserPolicy",$)}async attachGroupPolicy($){await this.request("AttachGroupPolicy",$)}async detachGroupPolicy($){await this.request("DetachGroupPolicy",$)}async attachRolePolicy($){await this.request("AttachRolePolicy",$)}async detachRolePolicy($){await this.request("DetachRolePolicy",$)}async listAttachedUserPolicies($){let J=await this.request("ListAttachedUserPolicies",$),Y=this.parseAttachedPolicies(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{AttachedPolicies:Y,IsTruncated:Q,Marker:G}}async listAttachedGroupPolicies($){let J=await this.request("ListAttachedGroupPolicies",$),Y=this.parseAttachedPolicies(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{AttachedPolicies:Y,IsTruncated:Q,Marker:G}}async listAttachedRolePolicies($){let J=await this.request("ListAttachedRolePolicies",$),Y=this.parseAttachedPolicies(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{AttachedPolicies:Y,IsTruncated:Q,Marker:G}}parsePolicy($){return{PolicyName:v($,"PolicyName")||"",PolicyId:v($,"PolicyId")||"",Arn:v($,"Arn")||"",Path:v($,"Path"),DefaultVersionId:v($,"DefaultVersionId"),AttachmentCount:v($,"AttachmentCount")?Number.parseInt(v($,"AttachmentCount"),10):void 0,PermissionsBoundaryUsageCount:v($,"PermissionsBoundaryUsageCount")?Number.parseInt(v($,"PermissionsBoundaryUsageCount"),10):void 0,IsAttachable:v($,"IsAttachable")==="true",Description:v($,"Description"),CreateDate:v($,"CreateDate"),UpdateDate:v($,"UpdateDate")}}parsePolicies($){return w1($,"Policies","member").map((Y)=>({PolicyName:v(Y,"PolicyName")||"",PolicyId:v(Y,"PolicyId")||"",Arn:v(Y,"Arn")||"",Path:v(Y,"Path"),DefaultVersionId:v(Y,"DefaultVersionId"),AttachmentCount:v(Y,"AttachmentCount")?Number.parseInt(v(Y,"AttachmentCount"),10):void 0,PermissionsBoundaryUsageCount:v(Y,"PermissionsBoundaryUsageCount")?Number.parseInt(v(Y,"PermissionsBoundaryUsageCount"),10):void 0,IsAttachable:v(Y,"IsAttachable")==="true",Description:v(Y,"Description"),CreateDate:v(Y,"CreateDate"),UpdateDate:v(Y,"UpdateDate")}))}parsePolicyVersions($){return w1($,"Versions","member").map((Y)=>({VersionId:v(Y,"VersionId")||"",IsDefaultVersion:v(Y,"IsDefaultVersion")==="true",CreateDate:v(Y,"CreateDate")}))}parseAttachedPolicies($){return w1($,"AttachedPolicies","member").map((Y)=>({PolicyName:v(Y,"PolicyName")||"",PolicyArn:v(Y,"PolicyArn")||""}))}async putUserPolicy($){await this.request("PutUserPolicy",$)}async getUserPolicy($){let J=await this.request("GetUserPolicy",$);return{UserName:v(J,"UserName")||"",PolicyName:v(J,"PolicyName")||"",PolicyDocument:decodeURIComponent(v(J,"PolicyDocument")||"")}}async deleteUserPolicy($){await this.request("DeleteUserPolicy",$)}async listUserPolicies($){let J=await this.request("ListUserPolicies",$),Y=w1(J,"PolicyNames","member"),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{PolicyNames:Y,IsTruncated:Q,Marker:G}}async putGroupPolicy($){await this.request("PutGroupPolicy",$)}async getGroupPolicy($){let J=await this.request("GetGroupPolicy",$);return{GroupName:v(J,"GroupName")||"",PolicyName:v(J,"PolicyName")||"",PolicyDocument:decodeURIComponent(v(J,"PolicyDocument")||"")}}async deleteGroupPolicy($){await this.request("DeleteGroupPolicy",$)}async listGroupPolicies($){let J=await this.request("ListGroupPolicies",$),Y=w1(J,"PolicyNames","member"),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{PolicyNames:Y,IsTruncated:Q,Marker:G}}async putRolePolicy($){await this.request("PutRolePolicy",$)}async getRolePolicy($){let J=await this.request("GetRolePolicy",$);return{RoleName:v(J,"RoleName")||"",PolicyName:v(J,"PolicyName")||"",PolicyDocument:decodeURIComponent(v(J,"PolicyDocument")||"")}}async deleteRolePolicy($){await this.request("DeleteRolePolicy",$)}async listRolePolicies($){let J=await this.request("ListRolePolicies",$),Y=w1(J,"PolicyNames","member"),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{PolicyNames:Y,IsTruncated:Q,Marker:G}}async createAccessKey($={}){let J=await this.request("CreateAccessKey",$);if(typeof J==="object"){let Y=J?.CreateAccessKeyResult?.AccessKey||J?.AccessKey;if(Y)return{AccessKey:{UserName:Y.UserName||"",AccessKeyId:Y.AccessKeyId||"",Status:Y.Status||"Active",SecretAccessKey:Y.SecretAccessKey||"",CreateDate:Y.CreateDate}}}return{AccessKey:{UserName:v(J,"UserName")||"",AccessKeyId:v(J,"AccessKeyId")||"",Status:v(J,"Status")||"Active",SecretAccessKey:v(J,"SecretAccessKey")||"",CreateDate:v(J,"CreateDate")}}}async listAccessKeys($={}){let J=await this.request("ListAccessKeys",$),Y=this.parseAccessKeys(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{AccessKeyMetadata:Y,IsTruncated:Q,Marker:G}}async updateAccessKey($){await this.request("UpdateAccessKey",$)}async deleteAccessKey($){await this.request("DeleteAccessKey",$)}async getAccessKeyLastUsed($){let J=await this.request("GetAccessKeyLastUsed",$);return{UserName:v(J,"UserName")||"",AccessKeyLastUsed:{LastUsedDate:v(J,"LastUsedDate"),ServiceName:v(J,"ServiceName"),Region:v(J,"Region")}}}parseAccessKeys($){return w1($,"AccessKeyMetadata","member").map((Y)=>({UserName:v(Y,"UserName"),AccessKeyId:v(Y,"AccessKeyId")||"",Status:v(Y,"Status")||"Active",CreateDate:v(Y,"CreateDate")}))}async createInstanceProfile($){let J=await this.request("CreateInstanceProfile",$);return this.parseInstanceProfile(J)}async getInstanceProfile($){let J=await this.request("GetInstanceProfile",$);return this.parseInstanceProfile(J)}async listInstanceProfiles($={}){let J=await this.request("ListInstanceProfiles",$),Y=this.parseInstanceProfiles(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{InstanceProfiles:Y,IsTruncated:Q,Marker:G}}async listInstanceProfilesForRole($){let J=await this.request("ListInstanceProfilesForRole",$),Y=this.parseInstanceProfiles(J),Q=v(J,"IsTruncated")==="true",G=v(J,"Marker");return{InstanceProfiles:Y,IsTruncated:Q,Marker:G}}async addRoleToInstanceProfile($){await this.request("AddRoleToInstanceProfile",$)}async removeRoleFromInstanceProfile($){await this.request("RemoveRoleFromInstanceProfile",$)}async deleteInstanceProfile($){await this.request("DeleteInstanceProfile",$)}parseInstanceProfile($){return{InstanceProfileName:v($,"InstanceProfileName")||"",InstanceProfileId:v($,"InstanceProfileId")||"",Arn:v($,"Arn")||"",Path:v($,"Path"),CreateDate:v($,"CreateDate")}}parseInstanceProfiles($){return w1($,"InstanceProfiles","member").map((Y)=>({InstanceProfileName:v(Y,"InstanceProfileName")||"",InstanceProfileId:v(Y,"InstanceProfileId")||"",Arn:v(Y,"Arn")||"",Path:v(Y,"Path"),CreateDate:v(Y,"CreateDate")}))}async getAccountPasswordPolicy(){let $=await this.request("GetAccountPasswordPolicy");return{MinimumPasswordLength:v($,"MinimumPasswordLength")?Number.parseInt(v($,"MinimumPasswordLength"),10):void 0,RequireSymbols:v($,"RequireSymbols")==="true",RequireNumbers:v($,"RequireNumbers")==="true",RequireUppercaseCharacters:v($,"RequireUppercaseCharacters")==="true",RequireLowercaseCharacters:v($,"RequireLowercaseCharacters")==="true",AllowUsersToChangePassword:v($,"AllowUsersToChangePassword")==="true",ExpirePasswords:v($,"ExpirePasswords")==="true",MaxPasswordAge:v($,"MaxPasswordAge")?Number.parseInt(v($,"MaxPasswordAge"),10):void 0,PasswordReusePrevention:v($,"PasswordReusePrevention")?Number.parseInt(v($,"PasswordReusePrevention"),10):void 0,HardExpiry:v($,"HardExpiry")==="true"}}async updateAccountPasswordPolicy($){await this.request("UpdateAccountPasswordPolicy",$)}async deleteAccountPasswordPolicy(){await this.request("DeleteAccountPasswordPolicy")}async getAccountSummary(){let $=await this.request("GetAccountSummary"),J={},Y=w1($,"SummaryMap","entry");for(let Q of Y){let G=v(Q,"key"),Z=v(Q,"value");if(G&&Z)J[G]=Number.parseInt(Z,10)}return J}async listAccountAliases(){let $=await this.request("ListAccountAliases"),J=w1($,"AccountAliases","member"),Y=v($,"IsTruncated")==="true",Q=v($,"Marker");return{AccountAliases:J,IsTruncated:Y,Marker:Q}}async createAccountAlias($){await this.request("CreateAccountAlias",$)}async deleteAccountAlias($){await this.request("DeleteAccountAlias",$)}async simulatePrincipalPolicy($){let J=await this.request("SimulatePrincipalPolicy",$);return this.parseSimulationResults(J)}parseSimulationResults($){let Y=w1($,"EvaluationResults","member").map((Z)=>{let U=w1(Z,"MatchedStatements","member").map((z)=>({SourcePolicyId:v(z,"SourcePolicyId"),SourcePolicyType:v(z,"SourcePolicyType")}));return{EvalActionName:v(Z,"EvalActionName")||"",EvalResourceName:v(Z,"EvalResourceName"),EvalDecision:v(Z,"EvalDecision")||"",MatchedStatements:U.length>0?U:void 0}}),Q=v($,"IsTruncated")==="true",G=v($,"Marker");return{EvaluationResults:Y,IsTruncated:Q,Marker:G}}}var v6=Z0(()=>{z0()});var wF={};n0(wF,{email:()=>dS,EmailClient:()=>f6});class f6{ses;s3;iam;route53;region;domain;defaultFrom;constructor($={}){this.region=$.region||"us-east-1",this.domain=$.domain,this.defaultFrom=$.defaultFrom,this.ses=new u1(this.region),this.s3=new X0(this.region),this.iam=new d1(this.region),this.route53=new B1(this.region)}async send($){let J=$.from||this.defaultFrom;if(!J)throw Error("From address is required. Set defaultFrom in constructor or provide from in options.");let Y=$.fromName?`${$.fromName} <${J}>`:J,Q=Array.isArray($.to)?$.to:[$.to];if(!$.attachments||$.attachments.length===0)return{messageId:(await this.ses.sendSimpleEmail({from:Y,to:Q,subject:$.subject,text:$.text,html:$.html,replyTo:$.replyTo})).MessageId||""};let G=this.buildRawEmail($,Y,Q);return{messageId:(await this.ses.sendEmail({FromEmailAddress:Y,Destination:{ToAddresses:Q,CcAddresses:$.cc?Array.isArray($.cc)?$.cc:[$.cc]:void 0,BccAddresses:$.bcc?Array.isArray($.bcc)?$.bcc:[$.bcc]:void 0},Content:{Raw:{Data:Buffer.from(G).toString("base64")}}})).MessageId||""}}async sendTemplate($){let J=$.from||this.defaultFrom;if(!J)throw Error("From address is required");let Y=$.fromName?`${$.fromName} <${J}>`:J;return{messageId:(await this.ses.sendTemplatedEmail({from:Y,to:$.to,templateName:$.templateName,templateData:$.templateData,replyTo:$.replyTo})).MessageId||""}}async sendBulk($){let J=$.from||this.defaultFrom;if(!J)throw Error("From address is required");let Y=$.recipients.map((G)=>({Destination:{ToAddresses:Array.isArray(G.to)?G.to:[G.to]},ReplacementEmailContent:G.templateData?{ReplacementTemplate:{ReplacementTemplateData:JSON.stringify(G.templateData)}}:void 0}));return{results:(await this.ses.sendBulkEmail({FromEmailAddress:J,BulkEmailEntries:Y,DefaultContent:{Template:{TemplateName:$.templateName,TemplateData:JSON.stringify($.defaultTemplateData)}}})).BulkEmailEntryResults?.map((G)=>({status:G.Status||"UNKNOWN",messageId:G.MessageId,error:G.Error}))||[]}}async setupDomain($){let J;try{J=await this.ses.getEmailIdentity($)}catch{let Q=await this.ses.createEmailIdentity({EmailIdentity:$});J={VerificationStatus:Q.DkimAttributes?.Status,DkimAttributes:Q.DkimAttributes,SendingEnabled:Q.VerifiedForSendingStatus}}try{await this.ses.putEmailIdentityDkimAttributes({EmailIdentity:$,SigningEnabled:!0})}catch{}try{await this.ses.putEmailIdentityMailFromAttributes($,{MailFromDomain:`mail.${$}`,BehaviorOnMxFailure:"USE_DEFAULT_VALUE"})}catch{}let Y=await this.ses.getDkimRecords($);return{domainVerified:J.SendingEnabled===!0,dkimStatus:J.DkimAttributes?.Status||"UNKNOWN",dkimTokens:J.DkimAttributes?.Tokens,mailFromStatus:J.MailFromAttributes?.MailFromDomainStatus}}async getDnsRecords($){let J=[],Y=await this.ses.getDkimRecords($);for(let Q of Y)J.push({type:Q.type,name:Q.name,value:Q.value,ttl:1800});return J.push({type:"MX",name:$,value:`inbound-smtp.${this.region}.amazonaws.com`,priority:10,ttl:3600}),J.push({type:"MX",name:`mail.${$}`,value:`feedback-smtp.${this.region}.amazonses.com`,priority:10,ttl:3600}),J.push({type:"TXT",name:`mail.${$}`,value:"v=spf1 include:amazonses.com ~all",ttl:3600}),J.push({type:"TXT",name:`_dmarc.${$}`,value:`v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@${$}`,ttl:3600}),J}async isDomainReady($){try{let J=await this.ses.getEmailIdentity($);return J.SendingEnabled===!0&&J.DkimAttributes?.Status==="SUCCESS"}catch{return!1}}async setupReceiving($){let J={Version:"2012-10-17",Statement:[{Sid:"AllowSESPuts",Effect:"Allow",Principal:{Service:"ses.amazonaws.com"},Action:"s3:PutObject",Resource:`arn:aws:s3:::${$.bucketName}/*`,Condition:{StringEquals:{"AWS:SourceAccount":$.accountId}}}]};await this.s3.putBucketPolicy($.bucketName,J);try{await this.ses.createReceiptRuleSet($.ruleSetName)}catch(Q){if(!Q.message?.includes("already exists")&&Q.code!=="AlreadyExists")throw Q}let Y=[{S3Action:{BucketName:$.bucketName,ObjectKeyPrefix:$.prefix||"inbox/"}}];if($.lambdaArn)Y.push({LambdaAction:{FunctionArn:$.lambdaArn,InvocationType:"Event"}});try{await this.ses.createReceiptRule({RuleSetName:$.ruleSetName,Rule:{Name:$.ruleName,Enabled:!0,TlsPolicy:"Optional",Recipients:$.recipients||[$.domain],ScanEnabled:$.scanEnabled!==!1,Actions:Y}})}catch(Q){if(Q.message?.includes("already exists"))await this.ses.deleteReceiptRule($.ruleSetName,$.ruleName),await this.ses.createReceiptRule({RuleSetName:$.ruleSetName,Rule:{Name:$.ruleName,Enabled:!0,TlsPolicy:"Optional",Recipients:$.recipients||[$.domain],ScanEnabled:$.scanEnabled!==!1,Actions:Y}});else throw Q}await this.ses.setActiveReceiptRuleSet($.ruleSetName)}async getIncomingEmails($){return(await this.s3.list({bucket:$.bucket,prefix:$.prefix||"incoming/",maxKeys:$.maxResults||100})).map((Y)=>({key:Y.Key||"",lastModified:Y.LastModified||"",size:Y.Size||0}))}async readEmail($){return await this.s3.getObject($.bucket,$.key)}async createSmtpCredentials($){let J=`ses-smtp-${$.username.replace(/[^a-zA-Z0-9]/g,"-")}`,{AWSClient:Y}=await Promise.resolve().then(() => (z0(),L2)),Q=new Y,G=(_,X)=>{let F={Action:_,Version:"2010-05-08",...X};return Object.entries(F).map(([B,V])=>`${encodeURIComponent(B)}=${encodeURIComponent(V)}`).join("&")};try{await Q.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:G("CreateUser",{UserName:J})})}catch(_){if(!_.message?.includes("EntityAlreadyExists"))throw _}let Z={Version:"2012-10-17",Statement:[{Effect:"Allow",Action:"ses:SendRawEmail",Resource:"*",Condition:{StringLike:{"ses:FromAddress":`*@${$.domain}`}}}]},W=`ses-smtp-policy-${$.domain.replace(/\./g,"-")}`;try{await Q.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:G("PutUserPolicy",{UserName:J,PolicyName:W,PolicyDocument:JSON.stringify(Z)})})}catch{}let z=(await Q.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:G("CreateAccessKey",{UserName:J})}))?.CreateAccessKeyResult?.AccessKey;if(!z?.AccessKeyId||!z?.SecretAccessKey)throw Error("Failed to create access key");let H=this.deriveSmtpPassword(z.SecretAccessKey);return{username:z.AccessKeyId,password:H,server:`email-smtp.${this.region}.amazonaws.com`,port:587}}deriveSmtpPassword($){let J=G0("node:crypto"),Y="SendRawEmail",Q=Buffer.from([4]),G=J.createHmac("sha256",`AWS4${$}`).update("11111111").digest();return G=J.createHmac("sha256",G).update(this.region).digest(),G=J.createHmac("sha256",G).update("ses").digest(),G=J.createHmac("sha256",G).update("aws4_request").digest(),G=J.createHmac("sha256",G).update("SendRawEmail").digest(),Buffer.concat([Q,G]).toString("base64")}async createTemplate($){await this.ses.createEmailTemplate({TemplateName:$.name,TemplateContent:{Subject:$.subject,Text:$.text,Html:$.html}})}async getTemplate($){try{let J=await this.ses.getEmailTemplate($);return{name:J.TemplateName||$,subject:J.TemplateContent?.Subject,text:J.TemplateContent?.Text,html:J.TemplateContent?.Html}}catch{return null}}async deleteTemplate($){await this.ses.deleteEmailTemplate($)}async listTemplates(){return(await this.ses.listEmailTemplates()).TemplatesMetadata?.map((J)=>({name:J.TemplateName||"",createdAt:J.CreatedTimestamp}))||[]}async deploy($){let J=`${$.appName}-${$.environment}-email-rules`,Y=`${$.appName}-inbound-email`,Q=$.storage?.bucketName||`${$.appName}-${$.environment}-email`,G=await this.setupDomain($.domain);if(!(await this.s3.listBuckets()).Buckets?.some((z)=>z.Name===Q))await this.s3.createBucket(Q);await this.setupReceiving({domain:$.domain,ruleSetName:J,ruleName:Y,bucketName:Q,prefix:$.storage?.prefix||"inbox/",accountId:$.accountId,recipients:$.catchAll?[$.domain]:$.mailboxes,scanEnabled:!0});let U=await this.getDnsRecords($.domain);return{success:!0,domainVerified:G.domainVerified,dkimStatus:G.dkimStatus,receiptRuleSet:J,storageBucket:Q,dnsRecords:U}}async undeploy($){let J=`${$.appName}-${$.environment}-email-rules`,Y=`${$.appName}-inbound-email`,Q=`${$.appName}-${$.environment}-email`;try{await this.ses.deleteReceiptRule(J,Y)}catch{}try{await this.ses.deleteReceiptRuleSet(J)}catch{}if($.deleteBucket)try{await this.s3.emptyAndDeleteBucket(Q)}catch{}}async getSendingStats(){let $=await this.ses.getSendQuota();return{sentLast24Hours:$.SentLast24Hours||0,maxSendRate:$.MaxSendRate||0,max24HourSend:$.Max24HourSend||0}}buildRawEmail($,J,Y){let Q=`----=_Part_${Date.now()}_${Math.random().toString(36).substring(2)}`,G="";if(G+=`From: ${J}\r
7284
7284
  `,G+=`To: ${Y.join(", ")}\r
7285
7285
  `,$.cc){let Z=Array.isArray($.cc)?$.cc:[$.cc];G+=`Cc: ${Z.join(", ")}\r
@@ -7413,7 +7413,7 @@ const config = ${JSON.stringify($,null,2)} as const
7413
7413
 
7414
7414
  await startProxies(config as any)
7415
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
- `),"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)}
7416
+ `),"TS_CLOUD_RPX_UNIT_EOF"),"systemctl daemon-reload","systemctl disable --now bun-gateway.service 2>/dev/null || true","systemctl disable --now ts-cloud-nginx.service 2>/dev/null || true",`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 ${$}:
7419
7419
  ${G}`)}catch(G){if(G instanceof Error&&/cloud-init reported an error/.test(G.message))throw G}await this.sleep(J)}throw Error(`Timed out waiting for cloud-init to finish on ${$} after ${Y}ms`)}outputsFromState($,J){return{deployStoragePath:$.deployStoragePath||"/var/ts-cloud/staging",appInstanceId:$.serverId?String($.serverId):void 0,appPublicIp:J?.public_net.ipv4?.ip||$.publicIp,sshUser:$.sshUser||this.sshUser,servicesPrivateIp:$.servicesPrivateIp}}static SSH_HOST_KEY_OPTS=["-o","StrictHostKeyChecking=no","-o","UserKnownHostsFile=/dev/null","-o","LogLevel=ERROR"];sshBaseArgs($,J=[]){return["-i",this.sshPrivateKeyPath,...W8.SSH_HOST_KEY_OPTS,"-o","BatchMode=yes",...J,`${this.sshUser}@${$}`]}scpToHost($,J,Y){wU(["scp","-i",this.sshPrivateKeyPath,...W8.SSH_HOST_KEY_OPTS,"-o","BatchMode=yes",J,`${this.sshUser}@${$}:${Y}`].map((Q)=>`"${Q.replace(/"/g,"\\\"")}"`).join(" "),{stdio:"pipe",maxBuffer:TU})}sshExec($,J){let Y=J.replace(/'/g,"'\\''");return wU(`ssh ${this.sshBaseArgs($).map((Q)=>`"${Q.replace(/"/g,"\\\"")}"`).join(" ")} '${Y}'`,{encoding:"utf8",stdio:["pipe","pipe","pipe"],maxBuffer:TU})}}});function i1($){switch($.provider??o$($.config)){case"aws":return new FJ({region:$.config.project.region});case"hetzner":return new W8({apiToken:$.config.hetzner?.apiToken,sshPrivateKeyPath:$.config.hetzner?.sshPrivateKeyPath,sshUser:$.config.hetzner?.sshUser,location:$.config.hetzner?.location});default:throw Error(`Unknown cloud provider: ${$.provider??o$($.config)}`)}}class DU{drivers=new Map;getDriver($,J){let Y=J??o$($),Q=`${Y}:${$.project.slug}:${$.project.region||"default"}`,G=this.drivers.get(Q);if(G)return G;let Z=i1({config:$,provider:Y});return this.drivers.set(Q,Z),Z}}var YP;var nF=Z0(async()=>{await nJ([L1(),KU(),RU()]);YP=new DU});function p6($){return Object.entries($).map(([J,Y])=>`${J}=${QP(String(Y))}`).join(`
@@ -10212,7 +10212,7 @@ export type ConfigOf = Config
10212
10212
  `;for(let Q of $)Y+=`| \`${Q.key}\` | ${Q.type} | ${Q.description} | \`${Q.example}\` |
10213
10213
  `;return Y}}function Lh($,J,Y={}){return hL($,J,Y,new WeakMap)}function hL($,J,Y,Q){let{arrayMergeMode:G="replace",skipNullish:Z=!1,customMerger:W}=Y;if(J===null||J===void 0)return Z?$:J;if(W){let U=W($,J);if(U!==void 0)return U}if(Array.isArray(J)||Array.isArray($))return yL($,J,G,Q);if(!X$(J)||!X$($))return J;return qh($,J,Y,Q)}function yL($,J,Y,Q){if(Array.isArray(J)&&!Array.isArray($))return J;if(Array.isArray($)&&!Array.isArray(J))return J;if(Array.isArray(J)&&Array.isArray($))switch(Y){case"replace":return J;case"concat":return Ah($,J);case"smart":return Eh($,J,Q);default:return J}return J}function Ah($,J){let Y=[...J];for(let Q of $)if(!Y.some((G)=>hz(G,Q)))Y.push(Q);return Y}function Eh($,J,Y){if(J.length===0)return $;if($.length===0)return J;if(X$(J[0])&&X$($[0]))return jh($,J,Y);if(J.every((Q)=>typeof Q==="string")&&$.every((Q)=>typeof Q==="string")){let Q=[...J];for(let G of $)if(!Q.includes(G))Q.push(G);return Q}return J}function jh($,J,Y){let Q=[...J];for(let G of $){if(!X$(G)){Q.push(G);continue}let Z=["id","name","key","path","type"],W=!1;for(let U of Z)if(U in G){if(Q.find((H)=>X$(H)&&(U in H)&&H[U]===G[U])){W=!0;break}}if(!W)Q.push(G)}return Q}function qh($,J,Y,Q){let G=J;if(X$(G)&&Q.has(G))return Q.get(G);let Z={...$};if(X$(G))Q.set(G,Z);for(let W in G){if(!Object.prototype.hasOwnProperty.call(G,W))continue;let U=G[W],z=Z[W];if(Y.skipNullish&&(U===null||U===void 0))continue;if(U===null||U===void 0){Z[W]=U;continue}if(X$(U)&&X$(z))Z[W]=hL(z,U,Y,Q);else if(Array.isArray(U)||Array.isArray(z))Z[W]=yL(z,U,Y.arrayMergeMode||"smart",Q);else Z[W]=U}return Z}function vL($,J,Y="replace"){return Lh($,J,{arrayMergeMode:Y==="replace"?"replace":"smart",skipNullish:!0})}function hz($,J){if($===J)return!0;if(Array.isArray($)&&Array.isArray(J)){if($.length!==J.length)return!1;for(let Y=0;Y<$.length;Y++)if(!hz($[Y],J[Y]))return!1;return!0}if(X$($)&&X$(J)){let Y=Object.keys($),Q=Object.keys(J);if(Y.length!==Q.length)return!1;for(let G of Y){if(!Object.prototype.hasOwnProperty.call(J,G))return!1;if(!hz($[G],J[G]))return!1}return!0}return!1}function X$($){return Boolean($&&typeof $==="object"&&!Array.isArray($))}class fL{extensions=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];async loadFromPath($,J,Y={}){let{arrayStrategy:Q="replace",useCache:G=!0,cacheTtl:Z,trackPerformance:W=!0,verbose:U=!1}=Y;if(G){let H=yQ.getWithFileCheck("file",$);if(H){if(U)console.log(`Configuration loaded from cache: ${$}`);return H}}let z=async()=>{if(!BQ($))return null;try{let H=`?t=${Date.now()}`,_=await import($+H),X=_.default||_,F="default"in _,B=Object.keys(_).length>0;if(!F&&!B)throw new mQ($,Error("Configuration file is empty and exports nothing"),"unknown");if(typeof X!=="object"||X===null||Array.isArray(X))throw new mQ($,Error("Configuration must export a valid object"),"unknown");let L={config:vL(J,X,Q),source:{type:"file",path:$,priority:100,timestamp:new Date}};if(G)yQ.setWithFileCheck("file",L,$,Z);return L}catch(H){throw H instanceof Error?Z9.configLoad($,H):Z9.configLoad($,Error(String(H)))}};if(W)return Z4.track("loadFromPath",z,{path:$});return z()}async tryLoadFromPaths($,J,Y={}){for(let Q of $)try{let G=await this.loadFromPath(Q,J,Y);if(G)return G}catch(G){if(G instanceof Error&&G.name==="ConfigLoadError")throw G;if(Y.verbose)console.warn(`Failed to load config from ${Q}:`,G)}return null}generateConfigPaths($,J,Y){let Q=this.generateNamePatterns($,Y),G=[];for(let Z of Q)for(let W of this.extensions)G.push(Qz(J,`${Z}${W}`));return G}generateNamePatterns($,J){let Y=[];if(Y.push("config",".config"),$)Y.push($,`.${$}.config`,`${$}.config`,`.${$}`);let Q=J===void 0?[]:Array.isArray(J)?J:[J];for(let Z of Q){if(!Z)continue;if(Y.push(Z,`.${Z}.config`,`${Z}.config`,`.${Z}`),$)Y.push(`${$}.${Z}.config`,`.${$}.${Z}.config`)}let G=new Set;return Y.filter((Z)=>{if(!Z||G.has(Z))return!1;return G.add(Z),!0})}checkFileAccess($){return Vh(async()=>{return BQ($)},{maxRetries:2,retryDelay:100,fallback:!1})}async discoverConfigFiles($,J,Y){let Q=[];if(!BQ($))return Q;if(J||Y){let G=this.generateNamePatterns(J||"",Y);for(let Z of G)for(let W of this.extensions){let U=Qz($,`${Z}${W}`);if(await this.checkFileAccess(U))Q.push(U)}}else try{let{readdirSync:G}=await import("fs"),Z=G($);for(let W of Z)if(this.looksLikeConfigFile(W)){let U=Qz($,W);if(await this.checkFileAccess(U))Q.push(U)}}catch{return[]}return Q}looksLikeConfigFile($){return[/\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,/^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,/config\.(ts|js|mjs|cjs|json|mts|cts)$/].some((Y)=>Y.test($))}async validateConfigFile($){let J=[];try{if(!BQ($))return J.push("Configuration file does not exist"),J;let Y=await import($),Q=Y.default||Y;if(Q===void 0)J.push("Configuration file must export a default value or named exports");else if(typeof Q!=="object"||Q===null)J.push("Configuration must be an object");else if(Array.isArray(Q))J.push("Configuration cannot be an array at the root level");if($.endsWith(".json"))try{let{readFileSync:G}=await import("fs"),Z=G($,"utf8");JSON.parse(Z)}catch(G){J.push(`Invalid JSON syntax: ${G}`)}}catch(Y){J.push(`Failed to load configuration file: ${Y}`)}return J}async getFileModificationTime($){try{let{statSync:J}=await import("fs");return J($).mtime}catch{return null}}async preloadConfigurations($,J={}){let Y=new Map;return await Promise.allSettled($.map(async(Q)=>{try{let G=await this.loadFromPath(Q,{},J);if(G)Y.set(Q,G.config)}catch(G){if(J.verbose)console.warn(`Failed to preload ${Q}:`,G)}})),Y}}class gL{async validateConfiguration($,J,Y={}){let{stopOnFirstError:Q=!1,validateRequired:G=!0,validateTypes:Z=!0,customRules:W=[],trackPerformance:U=!0,verbose:z=!1}=Y,H=async()=>{let _=[],X=[],F={stopOnFirstError:Q,validateRequired:G,validateTypes:Z,customRules:W,trackPerformance:U,verbose:z};try{if(typeof J==="string")return await this.validateWithSchemaFile($,J,F);else if(Array.isArray(J))return this.validateWithRules($,[...J,...W],F);else return this.validateWithJSONSchema($,J,F)}catch(B){return _.push({path:"",message:`Validation failed: ${B}`,rule:"system"}),{isValid:!1,errors:_,warnings:X}}};if(U)return await Z4.track("validateConfiguration",H);return H()}async validateWithSchemaFile($,J,Y){try{if(!Yb(J))throw new pQ(J,[{path:"",message:"Schema file does not exist"}]);let Q=await import(J),G=Q.default||Q;if(Array.isArray(G))return this.validateWithRules($,G,Y);else return this.validateWithJSONSchema($,G,Y)}catch(Q){throw new pQ(J,[{path:"",message:`Failed to load schema: ${Q}`}])}}validateWithJSONSchema($,J,Y){let Q=[],G=[];return this.validateObjectAgainstSchema($,J,"",Q,G,Y),{isValid:Q.length===0,errors:Q,warnings:G}}validateObjectAgainstSchema($,J,Y,Q,G,Z){if(Z.validateTypes&&J.type){let W=Array.isArray($)?"array":typeof $,U=Array.isArray(J.type)?J.type:[J.type];if(!U.includes(W)){if(Q.push({path:Y,message:`Expected type ${U.join(" or ")}, got ${W}`,expected:U.join(" or "),actual:W,rule:"type"}),Z.stopOnFirstError)return}}if(J.enum&&!J.enum.includes($)){if(Q.push({path:Y,message:`Value must be one of: ${J.enum.join(", ")}`,expected:J.enum.join(", "),actual:$,rule:"enum"}),Z.stopOnFirstError)return}if(typeof $==="string"){if(J.minLength!==void 0&&$.length<J.minLength)Q.push({path:Y,message:`String length must be at least ${J.minLength}`,expected:`>= ${J.minLength}`,actual:$.length,rule:"minLength"});if(J.maxLength!==void 0&&$.length>J.maxLength)Q.push({path:Y,message:`String length must not exceed ${J.maxLength}`,expected:`<= ${J.maxLength}`,actual:$.length,rule:"maxLength"});if(J.pattern){if(!new RegExp(J.pattern).test($))Q.push({path:Y,message:`String does not match pattern ${J.pattern}`,expected:J.pattern,actual:$,rule:"pattern"})}}if(typeof $==="number"){if(J.minimum!==void 0&&$<J.minimum)Q.push({path:Y,message:`Value must be at least ${J.minimum}`,expected:`>= ${J.minimum}`,actual:$,rule:"minimum"});if(J.maximum!==void 0&&$>J.maximum)Q.push({path:Y,message:`Value must not exceed ${J.maximum}`,expected:`<= ${J.maximum}`,actual:$,rule:"maximum"})}if(Array.isArray($)&&J.items)for(let W=0;W<$.length;W++){let U=Y?`${Y}[${W}]`:`[${W}]`;if(this.validateObjectAgainstSchema($[W],J.items,U,Q,G,Z),Z.stopOnFirstError&&Q.length>0)return}if($&&typeof $==="object"&&!Array.isArray($)){let W=$;if(Z.validateRequired&&J.required){for(let U of J.required)if(!(U in W)){if(Q.push({path:Y?`${Y}.${U}`:U,message:`Missing required property '${U}'`,expected:"required",rule:"required"}),Z.stopOnFirstError)return}}if(J.properties){for(let[U,z]of Object.entries(J.properties))if(U in W){let H=Y?`${Y}.${U}`:U;if(this.validateObjectAgainstSchema(W[U],z,H,Q,G,Z),Z.stopOnFirstError&&Q.length>0)return}}if(J.additionalProperties===!1){let U=new Set(Object.keys(J.properties||{}));for(let z of Object.keys(W))if(!U.has(z))G.push({path:Y?`${Y}.${z}`:z,message:`Additional property '${z}' is not allowed`,rule:"additionalProperties"})}}}validateWithRules($,J,Y){let Q=[],G=[];for(let Z of J)try{let W=this.getValueByPath($,Z.path),U=this.validateWithRule(W,Z,Z.path);if(Q.push(...U),Y.stopOnFirstError&&Q.length>0)break}catch(W){Q.push({path:Z.path,message:`Rule validation failed: ${W}`,rule:"system"})}return{isValid:Q.length===0,errors:Q,warnings:G}}validateWithRule($,J,Y){let Q=[];if(J.required&&($===void 0||$===null))return Q.push({path:Y,message:J.message||`Property '${Y}' is required`,expected:"required",rule:"required"}),Q;if($===void 0||$===null)return Q;if(J.type){let G=Array.isArray($)?"array":typeof $;if(G!==J.type)Q.push({path:Y,message:J.message||`Expected type ${J.type}, got ${G}`,expected:J.type,actual:G,rule:"type"})}if(J.min!==void 0){let G=Array.isArray($)?$.length:typeof $==="string"?$.length:typeof $==="number"?$:0;if(G<J.min)Q.push({path:Y,message:J.message||`Value must be at least ${J.min}`,expected:`>= ${J.min}`,actual:G,rule:"min"})}if(J.max!==void 0){let G=Array.isArray($)?$.length:typeof $==="string"?$.length:typeof $==="number"?$:0;if(G>J.max)Q.push({path:Y,message:J.message||`Value must not exceed ${J.max}`,expected:`<= ${J.max}`,actual:G,rule:"max"})}if(J.pattern&&typeof $==="string"){if(!J.pattern.test($))Q.push({path:Y,message:J.message||`Value does not match pattern ${J.pattern}`,expected:J.pattern.toString(),actual:$,rule:"pattern"})}if(J.enum&&!J.enum.includes($))Q.push({path:Y,message:J.message||`Value must be one of: ${J.enum.join(", ")}`,expected:J.enum.join(", "),actual:$,rule:"enum"});if(J.validator){let G=J.validator($);if(G)Q.push({path:Y,message:J.message||G,rule:"custom"})}return Q}getValueByPath($,J){if(!J)return $;let Y=J.split("."),Q=$;for(let G of Y)if(Q&&typeof Q==="object"&&G in Q)Q=Q[G];else return;return Q}generateRulesFromInterface($){let J=[],Y=$.matchAll(/(\w+)(\?)?:\s*(\w+)/g);for(let Q of Y){let[,G,Z,W]=Q;J.push({path:G,required:!Z,type:this.mapTypeScriptType(W)})}return J}mapTypeScriptType($){switch($.toLowerCase()){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return"array";case"object":return"object";default:return"object"}}static createCommonRules(){return{server:[{path:"port",required:!0,type:"number",min:1,max:65535},{path:"host",required:!0,type:"string",min:1},{path:"ssl",type:"boolean"}],database:[{path:"url",required:!0,type:"string",min:1},{path:"pool",type:"number",min:1,max:100},{path:"timeout",type:"number",min:0}],api:[{path:"baseUrl",required:!0,type:"string",pattern:Mh},{path:"timeout",type:"number",min:0},{path:"retries",type:"number",min:0,max:10}]}}}function wh($){if(!$)return"";let J=Array.isArray($)?$.filter(Boolean):[$];if(J.length===0)return"";if(J.length===1)return` or alias "${J[0]}"`;return` or aliases ${J.map((Y)=>`"${Y}"`).join(", ")}`}class uL{fileLoader=new fL;envProcessor=new B4;validator=new gL;async loadConfig($){let J=Date.now(),{cache:Y,performance:Q,schema:G,validate:Z,...W}=$;try{if(Y?.enabled){let z=this.checkCache(W.name||"",W);if(z)return z}let U;try{U=await this.loadConfigurationStrategies(W,!0,Y)}catch(z){let H=W.__strictErrorHandling;if(z instanceof Error&&z.name==="ConfigNotFoundError"){if(H)throw z;U={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`No configuration file found for "${W.name||"config"}", using defaults with environment variables`]}}else if(z instanceof Error&&z.name==="ConfigLoadError"){let _=z.message.includes("EACCES")||z.message.includes("EPERM")||z.message.includes("permission denied"),X=!_&&(z.message.includes("syntax")||z.message.includes("Expected")||z.message.includes("Unexpected")||z.message.includes("BuildMessage")||z.message.includes("errors building")),F=z.message.includes("Configuration must export a valid object")||z.message.includes("Configuration file is empty and exports nothing");if(H&&(F||_))throw z;if(X&&(!H||!F))U={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:["Configuration file has syntax errors, using defaults with environment variables"]};else if(!H)U={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading error, using defaults: ${z.message}`]};else throw z}else U={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading failed, using defaults: ${z instanceof Error?z.message:String(z)}`]}}if(G||Z)await this.validateConfiguration(U.config,G,Z,W.name);if(Y?.enabled&&U)this.cacheResult(W.name||"",U,Y,W);if(Q?.enabled){let z={operation:"loadConfig",duration:Date.now()-J,configName:W.name,timestamp:new Date};if(Q.onMetrics)Q.onMetrics(z);if(Q.slowThreshold&&z.duration>Q.slowThreshold)Z2.warn(`Slow configuration loading detected: ${z.duration}ms for ${W.name}`);U.metrics=z}return U}catch(U){if(U instanceof Error&&U.name==="ConfigNotFoundError")throw U;let z=Date.now()-J;throw Z2.error(`Configuration loading failed after ${z}ms:`,[U instanceof Error?U:Error(String(U))]),U}}async loadConfigurationStrategies($,J=!1,Y){let{name:Q="",alias:G,cwd:Z,configDir:W,defaultConfig:U,checkEnv:z=!0,arrayStrategy:H="replace",verbose:_=!1}=$,X=Z||sQ.cwd(),F=[],B=await this.loadLocalConfiguration(Q,G,X,W,U,H,_,z,Y);if(B)return F.push(...this.getLocalSearchPaths(Q,G,X,W)),this.finalizeResult(B,F,z,Q,_);let V=await this.loadHomeConfiguration(Q,G,U,H,_,z);if(V)return F.push(...this.getHomeSearchPaths(Q,G)),this.finalizeResult(V,F,z,Q,_);let K=await this.loadPackageJsonConfiguration(Q,G,X,U,H,_,z);if(K)return F.push(H$(X,"package.json")),this.finalizeResult(K,F,z,Q,_);if(F.push(...this.getAllSearchPaths(Q,G,X,W)),J)throw Z9.configNotFound(Q,F,G);return{...await this.applyEnvironmentVariables(Q,U,z,_),warnings:[`No configuration file found for "${Q}"${wh(G)}, using defaults with environment variables`]}}async loadLocalConfiguration($,J,Y,Q,G,Z,W,U,z){let H=U?VQ($,G,W):G,_=this.getLocalDirectories(Y,Q);for(let X of _){if(W)Z2.info(`Searching for configuration in: ${X}`);let F=this.fileLoader.generateConfigPaths($,X,J),B=await this.fileLoader.tryLoadFromPaths(F,H,{arrayStrategy:Z,verbose:W,cacheTtl:z?.ttl,useCache:!z?.ttl||z.ttl>100});if(B){if(W)Z2.success(`Configuration loaded from: ${B.source.path}`);return B}}return null}async loadHomeConfiguration($,J,Y,Q,G,Z){if(!$)return null;let W=Z?VQ($,Y,G):Y,U=[H$(m8(),".config",$),H$(m8(),".config"),m8()];for(let z of U){if(G)Z2.info(`Checking home directory: ${z}`);let H=this.fileLoader.generateConfigPaths($,z,J),_=await this.fileLoader.tryLoadFromPaths(H,W,{arrayStrategy:Q,verbose:G});if(_){if(G)Z2.success(`Configuration loaded from home directory: ${_.source.path}`);return _}}return null}async loadPackageJsonConfiguration($,J,Y,Q,G,Z,W){let U=W?VQ($,Q,Z):Q;try{let z=H$(Y,"package.json");if(!Vk(z))return null;let H={};try{H=JSON.parse(Lk(z,"utf8"))}catch(F){if(Z)Z2.warn("Failed to parse package.json:",[F instanceof Error?F:Error(String(F))]);return null}let _=H[$],X=$;if(!_&&J){let F=Array.isArray(J)?J:[J];for(let B of F){if(!B)continue;if(H[B]){_=H[B],X=B;break}}}if(_&&typeof _==="object"&&!Array.isArray(_)){if(Z)Z2.success(`Configuration loaded from package.json: ${X}`);return{config:vL(U,_,G),source:{type:"package.json",path:z,priority:30,timestamp:new Date}}}}catch(z){if(Z)Z2.warn("Failed to load package.json:",[z instanceof Error?z:Error(String(z))])}return null}async applyEnvironmentVariables($,J,Y,Q){if(!Y||!$||typeof J!=="object"||J===null||Array.isArray(J))return{config:J,source:{type:"default",priority:10,timestamp:new Date}};return{config:VQ($,J,Q),source:{type:"environment",priority:20,timestamp:new Date}}}async finalizeResult($,J,Y,Q,G){return{config:$.config,source:$.source,path:$.source.path}}async validateConfiguration($,J,Y,Q){let G=[];if(Y){let Z=Y($);if(Z)G.push(...Z)}if(J){let Z=await this.validator.validateConfiguration($,J);if(!Z.isValid)G.push(...Z.errors.map((W)=>W.path?`${W.path}: ${W.message}`:W.message))}if(G.length>0)throw Z9.configValidation(Q||"unknown",G,Q)}checkCache($,J){let Y=this.generateCacheKey($,J);return yQ.get(Y)||null}cacheResult($,J,Y,Q){let G=this.generateCacheKey($,Q);yQ.set(G,J,void 0,Y.ttl)}generateCacheKey($,J){let Y=[$];if(J.alias){let Q=Array.isArray(J.alias)?J.alias.join(","):J.alias;Y.push(`alias:${Q}`)}if(J.cwd)Y.push(`cwd:${J.cwd}`);if(J.configDir)Y.push(`configDir:${J.configDir}`);if("checkEnv"in J)Y.push(`checkEnv:${J.checkEnv}`);return Y.join("|")}getLocalDirectories($,J){return Array.from(new Set([$,H$($,"config"),H$($,".config"),J?H$($,J):void 0].filter(Boolean)))}getAllSearchPaths($,J,Y,Q){let G=[];return G.push(...this.getLocalSearchPaths($,J,Y,Q)),G.push(...this.getHomeSearchPaths($,J)),G.push(H$(Y,"package.json")),G}getLocalSearchPaths($,J,Y,Q){let G=this.getLocalDirectories(Y,Q),Z=[];for(let W of G)Z.push(...this.fileLoader.generateConfigPaths($,W,J));return Z}getHomeSearchPaths($,J){if(!$)return[];let Y=[H$(m8(),".config",$),H$(m8(),".config"),m8()],Q=[];for(let G of Y)Q.push(...this.fileLoader.generateConfigPaths($,G,J));return Q}async loadConfigWithResult($){return this.loadConfig($)}}function VQ($,J,Y=!1){let Q=new B4,G=$.toUpperCase().replace(/[^A-Z0-9]/g,"_");function Z(W,U=[]){let z={...W};for(let[H,_]of Object.entries(W)){let X=[...U,H],F=[`${G}_${X.join("_").toUpperCase()}`,`${G}_${X.map((K)=>K.toUpperCase()).join("")}`,`${G}_${X.map((K)=>K.replace(/([A-Z])/g,"_$1").toUpperCase()).join("")}`],B,V;for(let K of F)if(B=sQ.env[K],B!==void 0){V=K;break}if(B!==void 0&&V)if(typeof _==="boolean")z[H]=["true","1","yes"].includes(B.toLowerCase());else if(typeof _==="number"){let K=Number(B);if(!Number.isNaN(K))z[H]=K}else if(Array.isArray(_))try{z[H]=JSON.parse(B)}catch{z[H]=B.split(",").map((K)=>K.trim())}else z[H]=B;else if(_&&typeof _==="object"&&!Array.isArray(_))z[H]=Z(_,X)}return z}return Z(J)}class DQ{client;region;constructor($="us-east-1"){this.region=$,this.client=new F$}async describeInstances($){let J={Action:"DescribeInstances",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((G,Z)=>{J[`InstanceId.${Z+1}`]=G});if($?.Filters)$.Filters.forEach((G,Z)=>{J[`Filter.${Z+1}.Name`]=G.Name,G.Values.forEach((W,U)=>{J[`Filter.${Z+1}.Value.${U+1}`]=W})});if($?.MaxResults)J.MaxResults=String($.MaxResults);if($?.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeInstancesResponse||Y;return{Reservations:this.parseReservations(Q.reservationSet?.item),NextToken:Q.nextToken}}async getInstance($){return(await this.describeInstances({InstanceIds:[$]})).Reservations?.[0]?.Instances?.[0]}async getConsoleOutput($,J){let Y={Action:"GetConsoleOutput",Version:"2016-11-15",InstanceId:$};if(J)Y.Latest="true";let Q=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()}),G=Q.GetConsoleOutputResponse||Q;return{InstanceId:G.instanceId,Output:G.output,Timestamp:G.timestamp}}async getConsoleOutputDecoded($,J){let Y=await this.getConsoleOutput($,J?.latest);if(!Y.Output)return"No console output available yet";let Q=Buffer.from(Y.Output,"base64").toString("utf-8");if(J?.tailLines)return Q.split(`
10214
10214
  `).slice(-J.tailLines).join(`
10215
- `);return Q}async describeInstanceStatus($){let J={Action:"DescribeInstanceStatus",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Q,G)=>{J[`InstanceId.${G+1}`]=Q});if($?.IncludeAllInstances)J.IncludeAllInstances="true";if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InstanceStatuses:this.parseArray(Y.instanceStatusSet?.item).map((Q)=>({InstanceId:Q.instanceId,InstanceState:Q.instanceState?{Code:Number.parseInt(Q.instanceState.code),Name:Q.instanceState.name}:void 0,InstanceStatus:Q.instanceStatus?{Status:Q.instanceStatus.status,Details:this.parseArray(Q.instanceStatus.details?.item).map((G)=>({Name:G.name,Status:G.status}))}:void 0,SystemStatus:Q.systemStatus?{Status:Q.systemStatus.status,Details:this.parseArray(Q.systemStatus.details?.item).map((G)=>({Name:G.name,Status:G.status}))}:void 0}))}}async startInstances($){let J={Action:"StartInstances",Version:"2016-11-15"};$.forEach((Q,G)=>{J[`InstanceId.${G+1}`]=Q});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{StartingInstances:this.parseArray(Y.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async stopInstances($,J){let Y={Action:"StopInstances",Version:"2016-11-15"};if($.forEach((G,Z)=>{Y[`InstanceId.${Z+1}`]=G}),J)Y.Force="true";let Q=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()});return{StoppingInstances:this.parseArray(Q.instancesSet?.item).map((G)=>({InstanceId:G.instanceId,CurrentState:G.currentState?{Name:G.currentState.name}:void 0,PreviousState:G.previousState?{Name:G.previousState.name}:void 0}))}}async rebootInstances($){let J={Action:"RebootInstances",Version:"2016-11-15"};$.forEach((Y,Q)=>{J[`InstanceId.${Q+1}`]=Y}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async terminateInstances($){let J={Action:"TerminateInstances",Version:"2016-11-15"};$.forEach((Q,G)=>{J[`InstanceId.${G+1}`]=Q});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{TerminatingInstances:this.parseArray(Y.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async createImage($){let J={Action:"CreateImage",Version:"2016-11-15",InstanceId:$.InstanceId,Name:$.Name};if($.Description)J.Description=$.Description;if($.NoReboot!==void 0)J.NoReboot=String($.NoReboot);if($.TagSpecifications)$.TagSpecifications.forEach((G,Z)=>{J[`TagSpecification.${Z+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((W,U)=>{J[`TagSpecification.${Z+1}.Tag.${U+1}.Key`]=W.Key,J[`TagSpecification.${Z+1}.Tag.${U+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{ImageId:(Y.CreateImageResponse||Y).imageId}}async deregisterImage($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeregisterImage",Version:"2016-11-15",ImageId:$}).toString()})}async describeVpcs($){let J={Action:"DescribeVpcs",Version:"2016-11-15"};if($?.VpcIds)$.VpcIds.forEach((Q,G)=>{J[`VpcId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Vpcs:this.parseArray(Y.vpcSet?.item).map((Q)=>({VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,State:Q.state,DhcpOptionsId:Q.dhcpOptionsId,InstanceTenancy:Q.instanceTenancy,IsDefault:Q.isDefault==="true",Tags:this.parseTags(Q.tagSet?.item)}))}}async describeSubnets($){let J={Action:"DescribeSubnets",Version:"2016-11-15"};if($?.SubnetIds)$.SubnetIds.forEach((Q,G)=>{J[`SubnetId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Subnets:this.parseArray(Y.subnetSet?.item).map((Q)=>({SubnetId:Q.subnetId,VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,AvailabilityZone:Q.availabilityZone,AvailableIpAddressCount:Number.parseInt(Q.availableIpAddressCount),State:Q.state,MapPublicIpOnLaunch:Q.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Q.tagSet?.item)}))}}async describeSecurityGroups($){let J={Action:"DescribeSecurityGroups",Version:"2016-11-15"};if($?.GroupIds)$.GroupIds.forEach((Q,G)=>{J[`GroupId.${G+1}`]=Q});if($?.GroupNames)$.GroupNames.forEach((Q,G)=>{J[`GroupName.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{SecurityGroups:this.parseArray(Y.securityGroupInfo?.item).map((Q)=>({GroupId:Q.groupId,GroupName:Q.groupName,Description:Q.groupDescription,VpcId:Q.vpcId,IpPermissions:this.parseIpPermissions(Q.ipPermissions?.item),IpPermissionsEgress:this.parseIpPermissions(Q.ipPermissionsEgress?.item),Tags:this.parseTags(Q.tagSet?.item)}))}}async describeInternetGateways($){let J={Action:"DescribeInternetGateways",Version:"2016-11-15"};if($?.InternetGatewayIds)$.InternetGatewayIds.forEach((Q,G)=>{J[`InternetGatewayId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InternetGateways:this.parseArray(Y.internetGatewaySet?.item).map((Q)=>({InternetGatewayId:Q.internetGatewayId,Attachments:this.parseArray(Q.attachmentSet?.item).map((G)=>({VpcId:G.vpcId,State:G.state})),Tags:this.parseTags(Q.tagSet?.item)}))}}async describeAddresses($){let J={Action:"DescribeAddresses",Version:"2016-11-15"};if($?.AllocationIds)$.AllocationIds.forEach((Q,G)=>{J[`AllocationId.${G+1}`]=Q});if($?.PublicIps)$.PublicIps.forEach((Q,G)=>{J[`PublicIp.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Addresses:this.parseArray(Y.addressesSet?.item).map((Q)=>({PublicIp:Q.publicIp,AllocationId:Q.allocationId,AssociationId:Q.associationId,InstanceId:Q.instanceId,NetworkInterfaceId:Q.networkInterfaceId,PrivateIpAddress:Q.privateIpAddress,Domain:Q.domain,Tags:this.parseTags(Q.tagSet?.item)}))}}async allocateAddress($){let J={Action:"AllocateAddress",Version:"2016-11-15"};if($?.Domain)J.Domain=$.Domain;if($?.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((Z,W)=>{J[`TagSpecification.${G+1}.Tag.${W+1}.Key`]=Z.Key,J[`TagSpecification.${G+1}.Tag.${W+1}.Value`]=Z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{AllocationId:Y.allocationId,PublicIp:Y.publicIp,Domain:Y.domain}}async associateAddress($){let J={Action:"AssociateAddress",Version:"2016-11-15"};if($.AllocationId)J.AllocationId=$.AllocationId;if($.PublicIp)J.PublicIp=$.PublicIp;if($.InstanceId)J.InstanceId=$.InstanceId;if($.NetworkInterfaceId)J.NetworkInterfaceId=$.NetworkInterfaceId;if($.PrivateIpAddress)J.PrivateIpAddress=$.PrivateIpAddress;if($.AllowReassociation)J.AllowReassociation="true";return{AssociationId:(await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})).associationId}}async createTags($){let J={Action:"CreateTags",Version:"2016-11-15"};$.Resources.forEach((Y,Q)=>{J[`ResourceId.${Q+1}`]=Y}),$.Tags.forEach((Y,Q)=>{J[`Tag.${Q+1}.Key`]=Y.Key,J[`Tag.${Q+1}.Value`]=Y.Value}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async waitForInstanceState($,J,Y){let Q=Y?.maxWaitMs||300000,G=Y?.pollIntervalMs||5000,Z=Date.now();while(Date.now()-Z<Q){let W;try{W=await this.getInstance($)}catch{W=void 0}if(W?.State?.Name===J)return W;await new Promise((U)=>setTimeout(U,G))}return}async createVpc($){let J={Action:"CreateVpc",Version:"2016-11-15",CidrBlock:$.CidrBlock};if($.InstanceTenancy)J.InstanceTenancy=$.InstanceTenancy;if($.TagSpecifications)$.TagSpecifications.forEach((Z,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((U,z)=>{J[`TagSpecification.${W+1}.Tag.${z+1}.Key`]=U.Key,J[`TagSpecification.${W+1}.Tag.${z+1}.Value`]=U.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),G=(Y.CreateVpcResponse||Y).vpc;return{Vpc:G?{VpcId:G.vpcId,CidrBlock:G.cidrBlock,State:G.state,DhcpOptionsId:G.dhcpOptionsId,InstanceTenancy:G.instanceTenancy,IsDefault:G.isDefault==="true",Tags:this.parseTags(G.tagSet?.item)}:void 0}}async createSubnet($){let J={Action:"CreateSubnet",Version:"2016-11-15",VpcId:$.VpcId,CidrBlock:$.CidrBlock};if($.AvailabilityZone)J.AvailabilityZone=$.AvailabilityZone;if($.TagSpecifications)$.TagSpecifications.forEach((Z,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((U,z)=>{J[`TagSpecification.${W+1}.Tag.${z+1}.Key`]=U.Key,J[`TagSpecification.${W+1}.Tag.${z+1}.Value`]=U.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),G=(Y.CreateSubnetResponse||Y).subnet;return{Subnet:G?{SubnetId:G.subnetId,VpcId:G.vpcId,CidrBlock:G.cidrBlock,AvailabilityZone:G.availabilityZone,AvailableIpAddressCount:G.availableIpAddressCount?Number.parseInt(G.availableIpAddressCount):void 0,State:G.state,MapPublicIpOnLaunch:G.mapPublicIpOnLaunch==="true",Tags:this.parseTags(G.tagSet?.item)}:void 0}}async modifySubnetAttribute($){let J={Action:"ModifySubnetAttribute",Version:"2016-11-15",SubnetId:$.SubnetId};if($.MapPublicIpOnLaunch!==void 0)J["MapPublicIpOnLaunch.Value"]=String($.MapPublicIpOnLaunch.Value);await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async createSecurityGroup($){let J={Action:"CreateSecurityGroup",Version:"2016-11-15",GroupName:$.GroupName,GroupDescription:$.Description};if($.VpcId)J.VpcId=$.VpcId;if($.TagSpecifications)$.TagSpecifications.forEach((G,Z)=>{J[`TagSpecification.${Z+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((W,U)=>{J[`TagSpecification.${Z+1}.Tag.${U+1}.Key`]=W.Key,J[`TagSpecification.${Z+1}.Tag.${U+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{GroupId:(Y.CreateSecurityGroupResponse||Y).groupId}}async authorizeSecurityGroupIngress($){let J={Action:"AuthorizeSecurityGroupIngress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async authorizeSecurityGroupEgress($){let J={Action:"AuthorizeSecurityGroupEgress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRouteTables($){let J={Action:"DescribeRouteTables",Version:"2016-11-15"};if($?.RouteTableIds)$.RouteTableIds.forEach((G,Z)=>{J[`RouteTableId.${Z+1}`]=G});if($?.Filters)$.Filters.forEach((G,Z)=>{J[`Filter.${Z+1}.Name`]=G.Name,G.Values.forEach((W,U)=>{J[`Filter.${Z+1}.Value.${U+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeRouteTablesResponse||Y;return{RouteTables:this.parseArray(Q.routeTableSet?.item).map((G)=>({RouteTableId:G.routeTableId,VpcId:G.vpcId,Routes:this.parseArray(G.routeSet?.item).map((Z)=>({DestinationCidrBlock:Z.destinationCidrBlock,GatewayId:Z.gatewayId,NatGatewayId:Z.natGatewayId,State:Z.state})),Associations:this.parseArray(G.associationSet?.item).map((Z)=>({RouteTableAssociationId:Z.routeTableAssociationId,SubnetId:Z.subnetId,Main:Z.main==="true"||Z.main===!0})),Tags:this.parseTags(G.tagSet?.item)}))}}async deleteVpc($){let J={Action:"DeleteVpc",Version:"2016-11-15",VpcId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSubnet($){let J={Action:"DeleteSubnet",Version:"2016-11-15",SubnetId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSecurityGroup($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeleteSecurityGroup",Version:"2016-11-15",GroupId:$}).toString()})}async describeNetworkInterfaces($){let J={Action:"DescribeNetworkInterfaces",Version:"2016-11-15"};if($?.NetworkInterfaceIds)$.NetworkInterfaceIds.forEach((G,Z)=>{J[`NetworkInterfaceId.${Z+1}`]=G});if($?.Filters)$.Filters.forEach((G,Z)=>{J[`Filter.${Z+1}.Name`]=G.Name,G.Values.forEach((W,U)=>{J[`Filter.${Z+1}.Value.${U+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeNetworkInterfacesResponse||Y;return{NetworkInterfaces:this.parseArray(Q.networkInterfaceSet?.item).map((G)=>({NetworkInterfaceId:G.networkInterfaceId,SubnetId:G.subnetId,VpcId:G.vpcId,Status:G.status,Attachment:G.attachment?{AttachmentId:G.attachment.attachmentId,InstanceId:G.attachment.instanceId,Status:G.attachment.status}:void 0}))}}async detachNetworkInterface($,J){let Y={Action:"DetachNetworkInterface",Version:"2016-11-15",AttachmentId:$};if(J)Y.Force="true";await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()})}async deleteNetworkInterface($){let J={Action:"DeleteNetworkInterface",Version:"2016-11-15",NetworkInterfaceId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRegions(){let $={Action:"DescribeRegions",Version:"2016-11-15"},J=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams($).toString()}),Y=J.DescribeRegionsResponse||J;return{Regions:this.parseArray(Y.regionInfo?.item).map((Q)=>({RegionName:Q.regionName,Endpoint:Q.regionEndpoint}))}}async runInstances($){let J={Action:"RunInstances",Version:"2016-11-15",ImageId:$.ImageId,InstanceType:$.InstanceType,MinCount:String($.MinCount),MaxCount:String($.MaxCount)};if($.SecurityGroupIds)$.SecurityGroupIds.forEach((G,Z)=>{J[`SecurityGroupId.${Z+1}`]=G});if($.SubnetId)J.SubnetId=$.SubnetId;if($.UserData)J.UserData=$.UserData;if($.IamInstanceProfile){if($.IamInstanceProfile.Name)J["IamInstanceProfile.Name"]=$.IamInstanceProfile.Name;if($.IamInstanceProfile.Arn)J["IamInstanceProfile.Arn"]=$.IamInstanceProfile.Arn}if($.TagSpecifications)$.TagSpecifications.forEach((G,Z)=>{J[`TagSpecification.${Z+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((W,U)=>{J[`TagSpecification.${Z+1}.Tag.${U+1}.Key`]=W.Key,J[`TagSpecification.${Z+1}.Tag.${U+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.RunInstancesResponse||Y;return{Instances:this.parseInstances(Q.instancesSet?.item||Q.instancesSet)}}encodeIpPermissions($,J){J.forEach((Y,Q)=>{let G=`IpPermissions.${Q+1}`;if(Y.IpProtocol!==void 0)$[`${G}.IpProtocol`]=Y.IpProtocol;if(Y.FromPort!==void 0)$[`${G}.FromPort`]=String(Y.FromPort);if(Y.ToPort!==void 0)$[`${G}.ToPort`]=String(Y.ToPort);if(Y.IpRanges)Y.IpRanges.forEach((Z,W)=>{if(Z.CidrIp)$[`${G}.IpRanges.${W+1}.CidrIp`]=Z.CidrIp;if(Z.Description)$[`${G}.IpRanges.${W+1}.Description`]=Z.Description});if(Y.Ipv6Ranges)Y.Ipv6Ranges.forEach((Z,W)=>{if(Z.CidrIpv6)$[`${G}.Ipv6Ranges.${W+1}.CidrIpv6`]=Z.CidrIpv6;if(Z.Description)$[`${G}.Ipv6Ranges.${W+1}.Description`]=Z.Description});if(Y.UserIdGroupPairs)Y.UserIdGroupPairs.forEach((Z,W)=>{if(Z.GroupId)$[`${G}.Groups.${W+1}.GroupId`]=Z.GroupId;if(Z.UserId)$[`${G}.Groups.${W+1}.UserId`]=Z.UserId;if(Z.Description)$[`${G}.Groups.${W+1}.Description`]=Z.Description})})}parseArray($){if(!$)return[];return Array.isArray($)?$:[$]}parseTags($){return this.parseArray($).map((J)=>({Key:J.key,Value:J.value}))}parseReservations($){return this.parseArray($).map((J)=>({ReservationId:J.reservationId,Instances:this.parseInstances(J.instancesSet?.item||J.instancesSet)}))}parseInstances($){return this.parseArray($).map((J)=>({InstanceId:J.instanceId,ImageId:J.imageId,InstanceType:J.instanceType,State:J.instanceState?{Code:Number.parseInt(J.instanceState.code),Name:J.instanceState.name}:void 0,PrivateIpAddress:J.privateIpAddress,PublicIpAddress:J.ipAddress,SubnetId:J.subnetId,VpcId:J.vpcId,SecurityGroups:this.parseArray(J.groupSet?.item).map((Y)=>({GroupId:Y.groupId,GroupName:Y.groupName})),Tags:this.parseTags(J.tagSet?.item),LaunchTime:J.launchTime,Placement:J.placement?{AvailabilityZone:J.placement.availabilityZone,Tenancy:J.placement.tenancy}:void 0,Architecture:J.architecture,RootDeviceType:J.rootDeviceType,RootDeviceName:J.rootDeviceName,BlockDeviceMappings:this.parseArray(J.blockDeviceMapping?.item).map((Y)=>({DeviceName:Y.deviceName,Ebs:Y.ebs?{VolumeId:Y.ebs.volumeId,Status:Y.ebs.status,AttachTime:Y.ebs.attachTime,DeleteOnTermination:Y.ebs.deleteOnTermination==="true"}:void 0})),IamInstanceProfile:J.iamInstanceProfile?{Arn:J.iamInstanceProfile.arn,Id:J.iamInstanceProfile.id}:void 0}))}parseIpPermissions($){return this.parseArray($).map((J)=>({IpProtocol:J.ipProtocol,FromPort:J.fromPort?Number.parseInt(J.fromPort):void 0,ToPort:J.toPort?Number.parseInt(J.toPort):void 0,IpRanges:this.parseArray(J.ipRanges?.item).map((Y)=>({CidrIp:Y.cidrIp,Description:Y.description})),Ipv6Ranges:this.parseArray(J.ipv6Ranges?.item).map((Y)=>({CidrIpv6:Y.cidrIpv6,Description:Y.description})),UserIdGroupPairs:this.parseArray(J.groups?.item).map((Y)=>({GroupId:Y.groupId,UserId:Y.userId,Description:Y.description}))}))}}class yz{client;region;constructor($="us-east-1",J){this.region=$,this.client=new F$}async putParameter($){let J={Name:$.Name,Value:$.Value};if($.Type)J.Type=$.Type;if($.Description)J.Description=$.Description;if($.KeyId)J.KeyId=$.KeyId;if($.Overwrite!==void 0)J.Overwrite=$.Overwrite;if($.AllowedPattern)J.AllowedPattern=$.AllowedPattern;if($.Tags&&$.Tags.length>0)J.Tags=$.Tags;if($.Tier)J.Tier=$.Tier;if($.DataType)J.DataType=$.DataType;let Y=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(J)});return{Version:Y.Version,Tier:Y.Tier}}async getParameter($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=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(J)});return{Parameter:Y.Parameter?this.parseParameter(Y.Parameter):void 0}}async getParameters($){let J={Names:$.Names};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>this.parseParameter(Q)),InvalidParameters:Y.InvalidParameters}}async getParametersByPath($){let J={Path:$.Path};if($.Recursive!==void 0)J.Recursive=$.Recursive;if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;if($.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>this.parseParameter(Q)),NextToken:Y.NextToken}}async deleteParameter($){let J={Name:$.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(J)})}async deleteParameters($){let J={Names:$},Y=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(J)});return{DeletedParameters:Y.DeletedParameters,InvalidParameters:Y.InvalidParameters}}async describeParameters($){let J={};if($?.Filters&&$.Filters.length>0)J.Filters=$.Filters;if($?.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;if($?.MaxResults)J.MaxResults=$.MaxResults;if($?.NextToken)J.NextToken=$.NextToken;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>this.parseParameter(Q)),NextToken:Y.NextToken}}async getParameterHistory($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>({Name:Q.Name,Type:Q.Type,KeyId:Q.KeyId,LastModifiedDate:Q.LastModifiedDate,LastModifiedUser:Q.LastModifiedUser,Description:Q.Description,Value:Q.Value,Version:Q.Version,Labels:Q.Labels,Tier:Q.Tier})),NextToken:Y.NextToken}}async labelParameterVersion($){let J={Name:$.Name,Labels:$.Labels};if($.ParameterVersion!==void 0)J.ParameterVersion=$.ParameterVersion;let Y=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(J)});return{InvalidLabels:Y.InvalidLabels,ParameterVersion:Y.ParameterVersion}}async addTagsToResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,Tags:$.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(J)})}async removeTagsFromResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,TagKeys:$.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(J)})}async listTagsForResource($){let J={ResourceType:$.ResourceType,ResourceId:$.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(J)})).TagList}}async setString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"String",Description:Y?.description,Overwrite:Y?.overwrite??!0,Tags:Y?.tags})}async setSecureString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"SecureString",Description:Y?.description,Overwrite:Y?.overwrite??!0,KeyId:Y?.kmsKeyId,Tags:Y?.tags})}async getValue($){return(await this.getParameter({Name:$,WithDecryption:!0})).Parameter?.Value}async getAllByPath($,J=!0){let Y=[],Q;do{let G=await this.getParametersByPath({Path:$,Recursive:J,WithDecryption:!0,NextToken:Q});if(G.Parameters)Y.push(...G.Parameters);Q=G.NextToken}while(Q);return Y}parseParameter($){return{Name:$.Name,Type:$.Type,Value:$.Value,Version:$.Version,LastModifiedDate:$.LastModifiedDate,ARN:$.ARN,DataType:$.DataType,Description:$.Description,AllowedPattern:$.AllowedPattern,KeyId:$.KeyId,Tier:$.Tier}}async sendCommand($){if(!$.InstanceIds&&!$.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let J={DocumentName:$.DocumentName};if($.InstanceIds)J.InstanceIds=$.InstanceIds;if($.Targets)J.Targets=$.Targets;if($.Parameters)J.Parameters=$.Parameters;if($.TimeoutSeconds)J.TimeoutSeconds=$.TimeoutSeconds;if($.Comment)J.Comment=$.Comment;if($.OutputS3BucketName)J.OutputS3BucketName=$.OutputS3BucketName;if($.OutputS3KeyPrefix)J.OutputS3KeyPrefix=$.OutputS3KeyPrefix;let Y=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(J)});return{CommandId:Y.Command?.CommandId,Status:Y.Command?.Status,StatusDetails:Y.Command?.StatusDetails}}async getCommandInvocation($){let J={CommandId:$.CommandId,InstanceId:$.InstanceId},Y=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(J)});return{Status:Y.Status,StatusDetails:Y.StatusDetails,StandardOutputContent:Y.StandardOutputContent,StandardErrorContent:Y.StandardErrorContent,ResponseCode:Y.ResponseCode}}async runShellCommand($,J,Y){let Q=await this.sendCommand({InstanceIds:[$],DocumentName:"AWS-RunShellScript",Parameters:{commands:J},TimeoutSeconds:Y?.timeoutSeconds||600});if(!Q.CommandId)return{success:!1,error:"Failed to send command"};if(Y?.waitForCompletion===!1)return{success:!0,status:"Pending"};let G=Y?.pollIntervalMs||2000,Z=Y?.maxWaitMs||300000,W=Date.now();while(Date.now()-W<Z){await new Promise((U)=>setTimeout(U,G));try{let U=await this.getCommandInvocation({CommandId:Q.CommandId,InstanceId:$});if(U.Status==="Success")return{success:!0,output:U.StandardOutputContent,error:U.StandardErrorContent,status:U.Status};if(U.Status==="Failed"||U.Status==="Cancelled"||U.Status==="TimedOut")return{success:!1,output:U.StandardOutputContent,error:U.StandardErrorContent||U.StatusDetails,status:U.Status}}catch(U){if(!U.message?.includes("InvocationDoesNotExist"))return{success:!1,error:U.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations($){let J={CommandId:$.CommandId};if($.Details)J.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(J)})).CommandInvocations||[]).map((G)=>({InstanceId:G.InstanceId,Status:G.Status,StatusDetails:G.StatusDetails,StandardOutputContent:G.CommandPlugins?.[0]?.Output,StandardErrorContent:G.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags($){let J=Object.entries($.tags).map(([z,H])=>({Key:`tag:${z}`,Values:[H]})),Y=await this.sendCommand({Targets:J,DocumentName:"AWS-RunShellScript",Parameters:{commands:$.commands},TimeoutSeconds:$.timeoutSeconds||600,Comment:$.comment});if(!Y.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let Q=$.pollIntervalMs||3000,G=$.maxWaitMs||600000,Z=Date.now(),W=new Set(["Success","Failed","Cancelled","TimedOut"]),U=[];while(Date.now()-Z<G){await new Promise((z)=>setTimeout(z,Q));try{if(U=await this.listCommandInvocations({CommandId:Y.CommandId,Details:!0}),U.length===0)continue;if(U.every((H)=>W.has(H.Status||""))){let H=U.map((X)=>({instanceId:X.InstanceId,status:X.Status||"Unknown",output:X.StandardOutputContent,error:X.StandardErrorContent||X.StatusDetails})),_=U.every((X)=>X.Status==="Success");return{success:_,instanceCount:U.length,perInstance:H,error:_?void 0:"One or more instances reported a non-success status"}}}catch(z){if(!z.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:z.message}}}return{success:!1,instanceCount:U.length,perInstance:U.map((z)=>({instanceId:z.InstanceId,status:z.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}function dL($){return $.type!=null&&Dh.has($.type)}function Nh($){if($.deploy)return $.deploy;if(dL($))return"server";if($.start)return"server";return"bucket"}function Sh($){if(dL($))return"server-php";if(Nh($)==="bucket")return"bucket";return $.start?"server-app":"server-static"}function rQ($){return`'${$.split("'").join("'\\''")}'`}function cL($={}){let J=$.version?`export PANTRY_VERSION=${rQ($.version)}`:'export PANTRY_VERSION="${PANTRY_VERSION:-latest}"';return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system",`export PANTRY_INSTALL_DIR=${rB}`,J,"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)","command -v pantry >/dev/null 2>&1 || curl -fsSL https://pantry.dev | bash",`export PATH="${rB}:$PATH"`,`mkdir -p ${X8}`]}function vz(){return`eval "$(cd ${X8} && pantry env 2>/dev/null)" || true`}function K4($){if($.length===0)return[];let J=[...new Set($)];return[`(cd ${X8} && pantry install ${J.map(rQ).join(" ")})`]}function lL($){return[...new Set($)].flatMap((J)=>[`(cd ${X8} && pantry start ${rQ(J)})`,`(cd ${X8} && pantry enable ${rQ(J)})`])}function H2($){return $===!0||typeof $==="object"&&$!=null}function Ih($){let J=[],Y=[];if(H2($.mysql))J.push(typeof $.mysql==="object"&&$.mysql.version?`mysql.com@${$.mysql.version}`:"mysql.com@8.0.43"),Y.push("mysql");else if(H2($.mariadb))J.push(Ch.mariadb),Y.push("mariadb");if(H2($.postgres))J.push("postgresql.org"),Y.push("postgres");if(H2($.redis))J.push("redis.io"),Y.push("redis");if(H2($.memcached))J.push("memcached.org"),Y.push("memcached");if(H2($.meilisearch))J.push("meilisearch.com"),Y.push("meilisearch");return{packages:J,services:Y}}function mL($={},J={}){let Y=Ih($);if(Y.packages.length===0)return[];return[...K4(Y.packages),...lL(Y.services)]}function pL($,J={}){if(!$?.name)return[];if($.host&&$.host!=="127.0.0.1"&&$.host!=="localhost")return[];let Y=$.name,Q=$.username||Y,G=$.password||"",Z=H2(J.postgres)||$.engine==="postgres",W=H2(J.mariadb)||$.engine==="mariadb",U=H2(J.mysql)||$.engine==="mysql";if(Z&&!U&&!W){let B=(A)=>`"${A.replace(/"/g,'""')}"`,V=(A)=>`'${A.replace(/'/g,"''")}'`,K=(A,j)=>["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${V(A)}) THEN`,` CREATE ROLE ${B(A)} LOGIN PASSWORD ${V(j)};`," ELSE",` ALTER ROLE ${B(A)} LOGIN PASSWORD ${V(j)};`," END IF;","END $$;"],L=(A)=>{let j=A.databases&&A.databases.length>0?A.databases:[Y],q=[];for(let M of j)if(A.access==="readonly")q.push(`GRANT CONNECT ON DATABASE ${B(M)} TO ${B(A.username)};`,`\\connect ${B(M)}`,`GRANT USAGE ON SCHEMA public TO ${B(A.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${B(A.username)};`,`ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ${B(A.username)};`,"\\connect postgres");else q.push(`GRANT ALL PRIVILEGES ON DATABASE ${B(M)} TO ${B(A.username)};`);return q},E=$.users||[];return[vz(),"for i in $(seq 1 30); do pg_isready -h 127.0.0.1 -p 5432 -q && break; sleep 2; done","psql -h 127.0.0.1 -p 5432 -U postgres <<'TS_CLOUD_PG_EOF'",...K(Q,G),`SELECT 'CREATE DATABASE ${B(Y)} OWNER ${B(Q)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${V(Y)})\\gexec`,...E.flatMap((A)=>[...K(A.username,A.password),...L(A)]),"TS_CLOUD_PG_EOF"]}let z=W?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",H=(B)=>B.replace(/`/g,"``"),_=(B)=>B.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),X=(B)=>{let V=B.databases&&B.databases.length>0?B.databases:[Y],K=B.access==="readonly"?"SELECT":"ALL PRIVILEGES",L=[`CREATE USER IF NOT EXISTS '${_(B.username)}'@'%' IDENTIFIED BY '${_(B.password)}';`,`CREATE USER IF NOT EXISTS '${_(B.username)}'@'localhost' IDENTIFIED BY '${_(B.password)}';`,`ALTER USER '${_(B.username)}'@'%' IDENTIFIED BY '${_(B.password)}';`,`ALTER USER '${_(B.username)}'@'localhost' IDENTIFIED BY '${_(B.password)}';`];for(let E of V)L.push(`GRANT ${K} ON \`${H(E)}\`.* TO '${_(B.username)}'@'%';`,`GRANT ${K} ON \`${H(E)}\`.* TO '${_(B.username)}'@'localhost';`);return L},F=$.users||[];return[vz(),`for i in $(seq 1 30); do mysqladmin --socket=${z} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${z} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${H(Y)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...X({username:Q,password:G}),...F.flatMap(X),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}function kh($={}){let J=$.versions?.length?$.versions:["8.3"];return $.default&&J.includes($.default)?$.default:J[0]}function bh($={}){return{...$.optimizeForProduction===!1?{}:{...xh},...$.ini||{}}}function hh($={}){let J=bh($),Y=Object.keys(J);if(Y.length===0)return[];let Q=Y.map((Z)=>`${Z}=${J[Z]}`),G="ts-cloud-managed";return[vz(),"TS_CLOUD_SCAN_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Scan this dir for additional .ini files/{print $2}' | head -1)",`TS_CLOUD_LOADED_INI=$(php -r 'echo php_ini_loaded_file() ?: "";' 2>/dev/null)`,'if [ -n "$TS_CLOUD_SCAN_DIR" ] && [ "$TS_CLOUD_SCAN_DIR" != "(none)" ]; then',' mkdir -p "$TS_CLOUD_SCAN_DIR"',' TS_CLOUD_PHP_INI="$TS_CLOUD_SCAN_DIR/zz-ts-cloud.ini"',` cat > "$TS_CLOUD_PHP_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${G} — production PHP tuning`,...Q,"TS_CLOUD_PHPINI_EOF","else",' if [ -z "$TS_CLOUD_LOADED_INI" ]; then'," TS_CLOUD_INI_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Configuration File \\(php.ini\\) Path/{print $2}' | head -1)",' TS_CLOUD_LOADED_INI="$TS_CLOUD_INI_DIR/php.ini"',' mkdir -p "$TS_CLOUD_INI_DIR"',' touch "$TS_CLOUD_LOADED_INI"'," fi",` sed -i '/; ${G} BEGIN/,/; ${G} END/d' "$TS_CLOUD_LOADED_INI"`,` cat >> "$TS_CLOUD_LOADED_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${G} BEGIN`,...Q,`; ${G} END`,"TS_CLOUD_PHPINI_EOF","fi",`(cd ${X8} && pantry restart php-fpm) 2>/dev/null || true`]}function rL($={}){let J=kh($),Y=$.installNginx!==!1,Q=$.installComposer!==!1,G=[`php.net@${J}`];if(Q)G.push("getcomposer.org");if(Y)G.push("nginx.org");return[...K4(G),...lL(["php-fpm"]),...hh($)]}function yh($="/opt/pantry"){return[...cL(),...K4(["nginx.org"]),"if ! /opt/pantry/pantry/.bin/nginx -v >/dev/null 2>&1; then apt-get update -y && apt-get install -y nginx; fi","mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /var/log/nginx /var/lib/nginx/body /var/lib/nginx/proxy /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/scgi","getent passwd www-data >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www-data","chown -R www-data:www-data /var/lib/nginx /var/log/nginx",`cat > ${SJ} <<'TS_CLOUD_NGINXBIN_EOF'`,"#!/bin/sh",`eval "$(cd ${$} && pantry env 2>/dev/null)"`,"NGINX_BIN=$(command -v nginx || true)",'if [ -z "$NGINX_BIN" ] || ! "$NGINX_BIN" -v >/dev/null 2>&1; then NGINX_BIN=/usr/sbin/nginx; fi','if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=/opt/pantry/pantry/.bin/nginx; fi','exec "$NGINX_BIN" -c /etc/nginx/nginx.conf "$@"',"TS_CLOUD_NGINXBIN_EOF",`chmod +x ${SJ}`,"cat > /etc/nginx/fastcgi_params <<'TS_CLOUD_FCGI_EOF'","fastcgi_param QUERY_STRING $query_string;","fastcgi_param REQUEST_METHOD $request_method;","fastcgi_param CONTENT_TYPE $content_type;","fastcgi_param CONTENT_LENGTH $content_length;","fastcgi_param SCRIPT_NAME $fastcgi_script_name;","fastcgi_param REQUEST_URI $request_uri;","fastcgi_param DOCUMENT_URI $document_uri;","fastcgi_param DOCUMENT_ROOT $document_root;","fastcgi_param SERVER_PROTOCOL $server_protocol;","fastcgi_param REQUEST_SCHEME $scheme;","fastcgi_param HTTPS $https if_not_empty;","fastcgi_param GATEWAY_INTERFACE CGI/1.1;","fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;","fastcgi_param REMOTE_ADDR $remote_addr;","fastcgi_param REMOTE_PORT $remote_port;","fastcgi_param SERVER_ADDR $server_addr;","fastcgi_param SERVER_PORT $server_port;","fastcgi_param SERVER_NAME $server_name;","fastcgi_param REDIRECT_STATUS 200;","TS_CLOUD_FCGI_EOF","cat > /etc/nginx/nginx.conf <<'TS_CLOUD_NGINXCONF_EOF'","user www-data;","worker_processes auto;","pid /run/nginx.pid;","error_log /var/log/nginx/error.log;","events { worker_connections 1024; }","http {"," default_type application/octet-stream;"," types {"," text/html html htm;"," text/css css;"," application/javascript js;"," application/json json;"," image/svg+xml svg;"," image/png png;"," image/jpeg jpg jpeg;"," image/gif gif;"," image/x-icon ico;"," image/webp webp;"," font/woff2 woff2;"," font/woff woff;"," text/plain txt;"," }"," access_log /var/log/nginx/access.log;"," sendfile on;"," tcp_nopush on;"," keepalive_timeout 65;"," server_tokens off;"," client_max_body_size 100m;"," client_body_temp_path /var/lib/nginx/body;"," proxy_temp_path /var/lib/nginx/proxy;"," fastcgi_temp_path /var/lib/nginx/fastcgi;"," uwsgi_temp_path /var/lib/nginx/uwsgi;"," scgi_temp_path /var/lib/nginx/scgi;"," server {"," listen 80 default_server;"," listen [::]:80 default_server;"," server_name _;"," return 444;"," }"," include /etc/nginx/sites-enabled/*;","}","TS_CLOUD_NGINXCONF_EOF","cat > /etc/systemd/system/ts-cloud-nginx.service <<'TS_CLOUD_NGINXUNIT_EOF'","[Unit]","Description=ts-cloud nginx (pantry)","After=network.target","","[Service]","Type=simple",`ExecStartPre=${SJ} -t`,`ExecStart=${SJ} -g 'daemon off;'`,`ExecReload=${SJ} -s reload`,"Restart=always","RestartSec=3","","[Install]","WantedBy=multi-user.target","TS_CLOUD_NGINXUNIT_EOF","systemctl daemon-reload","systemctl disable --now nginx 2>/dev/null || true","systemctl enable ts-cloud-nginx","ls /etc/nginx/sites-enabled/* >/dev/null 2>&1 && systemctl restart ts-cloud-nginx || true"]}function fh($={}){if($.enabled===!1)return[];let J=[...new Set([...vh,...$.allowedPorts||[]])].filter((Q)=>Q>0).sort((Q,G)=>Q-G),Y=["export DEBIAN_FRONTEND=noninteractive","apt-get install -y ufw","ufw default deny incoming","ufw default allow outgoing","ufw allow OpenSSH"];for(let Q of J)Y.push(`ufw allow ${Q}/tcp`);return Y.push("ufw --force enable"),Y}function fz($=!0){if(!$)return[];return["export DEBIAN_FRONTEND=noninteractive","apt-get install -y unattended-upgrades","cat > /etc/apt/apt.conf.d/20auto-upgrades <<'TS_CLOUD_AUTOUPD_EOF'",'APT::Periodic::Update-Package-Lists "1";','APT::Periodic::Unattended-Upgrade "1";','APT::Periodic::Download-Upgradeable-Packages "1";','APT::Periodic::AutocleanInterval "7";',"TS_CLOUD_AUTOUPD_EOF","systemctl enable unattended-upgrades 2>/dev/null || true","systemctl restart unattended-upgrades 2>/dev/null || true"]}function ch($=!0){let J=typeof $==="object"?$:{};return{enabled:typeof $==="boolean"?$:$.enabled!==!1,cpuLoadPerCore:J.alerts?.cpuLoadPerCore??gh,memPercent:J.alerts?.memPercent??uh,diskPercent:J.alerts?.diskPercent??dh}}function gz($=!0){let{enabled:J,cpuLoadPerCore:Y,memPercent:Q,diskPercent:G}=ch($);if(!J)return[];let Z=nB.map(([U,z])=>`SVC_${U.toUpperCase()}=$(probe ${z})`),W=nB.map(([U])=>`"${U}":"$SVC_${U.toUpperCase()}"`).join(",");return["mkdir -p /var/lib/ts-cloud","cat > /usr/local/bin/ts-cloud-metrics.sh <<'TS_CLOUD_METRICS_EOF'","#!/bin/bash","set -uo pipefail","LOAD=$(cut -d' ' -f1 /proc/loadavg)","CPUS=$(nproc)","MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')","MEM_USED=$(free -m | awk '/^Mem:/{print $3}')","SWAP_TOTAL=$(free -m | awk '/^Swap:/{print $2}')","SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')",`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...Z,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))",`cat > ${Hz}.tmp <<JSON`,'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+W+"}}","JSON",`mv -f ${Hz}.tmp ${Hz}`,'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${Y} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${Y}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${Q} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${G} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,`PREV=$(cat ${_z} 2>/dev/null || echo ok)`,'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi',` echo alert > ${_z}`,"else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi',` echo ok > ${_z}`,"fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnBootSec=60","OnUnitActiveSec=60","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.timer"]}function uz($=[],J={}){if($.length===0)return[];let Y=J.path??lh,Q=Y.replace(/\/[^/]*$/,""),G=[iB,...$.map((Z)=>`${Z.publicKey.trim()} ${Z.name}`),tB].join(`
10215
+ `);return Q}async describeInstanceStatus($){let J={Action:"DescribeInstanceStatus",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Q,G)=>{J[`InstanceId.${G+1}`]=Q});if($?.IncludeAllInstances)J.IncludeAllInstances="true";if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InstanceStatuses:this.parseArray(Y.instanceStatusSet?.item).map((Q)=>({InstanceId:Q.instanceId,InstanceState:Q.instanceState?{Code:Number.parseInt(Q.instanceState.code),Name:Q.instanceState.name}:void 0,InstanceStatus:Q.instanceStatus?{Status:Q.instanceStatus.status,Details:this.parseArray(Q.instanceStatus.details?.item).map((G)=>({Name:G.name,Status:G.status}))}:void 0,SystemStatus:Q.systemStatus?{Status:Q.systemStatus.status,Details:this.parseArray(Q.systemStatus.details?.item).map((G)=>({Name:G.name,Status:G.status}))}:void 0}))}}async startInstances($){let J={Action:"StartInstances",Version:"2016-11-15"};$.forEach((Q,G)=>{J[`InstanceId.${G+1}`]=Q});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{StartingInstances:this.parseArray(Y.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async stopInstances($,J){let Y={Action:"StopInstances",Version:"2016-11-15"};if($.forEach((G,Z)=>{Y[`InstanceId.${Z+1}`]=G}),J)Y.Force="true";let Q=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()});return{StoppingInstances:this.parseArray(Q.instancesSet?.item).map((G)=>({InstanceId:G.instanceId,CurrentState:G.currentState?{Name:G.currentState.name}:void 0,PreviousState:G.previousState?{Name:G.previousState.name}:void 0}))}}async rebootInstances($){let J={Action:"RebootInstances",Version:"2016-11-15"};$.forEach((Y,Q)=>{J[`InstanceId.${Q+1}`]=Y}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async terminateInstances($){let J={Action:"TerminateInstances",Version:"2016-11-15"};$.forEach((Q,G)=>{J[`InstanceId.${G+1}`]=Q});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{TerminatingInstances:this.parseArray(Y.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async createImage($){let J={Action:"CreateImage",Version:"2016-11-15",InstanceId:$.InstanceId,Name:$.Name};if($.Description)J.Description=$.Description;if($.NoReboot!==void 0)J.NoReboot=String($.NoReboot);if($.TagSpecifications)$.TagSpecifications.forEach((G,Z)=>{J[`TagSpecification.${Z+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((W,U)=>{J[`TagSpecification.${Z+1}.Tag.${U+1}.Key`]=W.Key,J[`TagSpecification.${Z+1}.Tag.${U+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{ImageId:(Y.CreateImageResponse||Y).imageId}}async deregisterImage($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeregisterImage",Version:"2016-11-15",ImageId:$}).toString()})}async describeVpcs($){let J={Action:"DescribeVpcs",Version:"2016-11-15"};if($?.VpcIds)$.VpcIds.forEach((Q,G)=>{J[`VpcId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Vpcs:this.parseArray(Y.vpcSet?.item).map((Q)=>({VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,State:Q.state,DhcpOptionsId:Q.dhcpOptionsId,InstanceTenancy:Q.instanceTenancy,IsDefault:Q.isDefault==="true",Tags:this.parseTags(Q.tagSet?.item)}))}}async describeSubnets($){let J={Action:"DescribeSubnets",Version:"2016-11-15"};if($?.SubnetIds)$.SubnetIds.forEach((Q,G)=>{J[`SubnetId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Subnets:this.parseArray(Y.subnetSet?.item).map((Q)=>({SubnetId:Q.subnetId,VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,AvailabilityZone:Q.availabilityZone,AvailableIpAddressCount:Number.parseInt(Q.availableIpAddressCount),State:Q.state,MapPublicIpOnLaunch:Q.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Q.tagSet?.item)}))}}async describeSecurityGroups($){let J={Action:"DescribeSecurityGroups",Version:"2016-11-15"};if($?.GroupIds)$.GroupIds.forEach((Q,G)=>{J[`GroupId.${G+1}`]=Q});if($?.GroupNames)$.GroupNames.forEach((Q,G)=>{J[`GroupName.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{SecurityGroups:this.parseArray(Y.securityGroupInfo?.item).map((Q)=>({GroupId:Q.groupId,GroupName:Q.groupName,Description:Q.groupDescription,VpcId:Q.vpcId,IpPermissions:this.parseIpPermissions(Q.ipPermissions?.item),IpPermissionsEgress:this.parseIpPermissions(Q.ipPermissionsEgress?.item),Tags:this.parseTags(Q.tagSet?.item)}))}}async describeInternetGateways($){let J={Action:"DescribeInternetGateways",Version:"2016-11-15"};if($?.InternetGatewayIds)$.InternetGatewayIds.forEach((Q,G)=>{J[`InternetGatewayId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InternetGateways:this.parseArray(Y.internetGatewaySet?.item).map((Q)=>({InternetGatewayId:Q.internetGatewayId,Attachments:this.parseArray(Q.attachmentSet?.item).map((G)=>({VpcId:G.vpcId,State:G.state})),Tags:this.parseTags(Q.tagSet?.item)}))}}async describeAddresses($){let J={Action:"DescribeAddresses",Version:"2016-11-15"};if($?.AllocationIds)$.AllocationIds.forEach((Q,G)=>{J[`AllocationId.${G+1}`]=Q});if($?.PublicIps)$.PublicIps.forEach((Q,G)=>{J[`PublicIp.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((Z,W)=>{J[`Filter.${G+1}.Value.${W+1}`]=Z})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Addresses:this.parseArray(Y.addressesSet?.item).map((Q)=>({PublicIp:Q.publicIp,AllocationId:Q.allocationId,AssociationId:Q.associationId,InstanceId:Q.instanceId,NetworkInterfaceId:Q.networkInterfaceId,PrivateIpAddress:Q.privateIpAddress,Domain:Q.domain,Tags:this.parseTags(Q.tagSet?.item)}))}}async allocateAddress($){let J={Action:"AllocateAddress",Version:"2016-11-15"};if($?.Domain)J.Domain=$.Domain;if($?.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((Z,W)=>{J[`TagSpecification.${G+1}.Tag.${W+1}.Key`]=Z.Key,J[`TagSpecification.${G+1}.Tag.${W+1}.Value`]=Z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{AllocationId:Y.allocationId,PublicIp:Y.publicIp,Domain:Y.domain}}async associateAddress($){let J={Action:"AssociateAddress",Version:"2016-11-15"};if($.AllocationId)J.AllocationId=$.AllocationId;if($.PublicIp)J.PublicIp=$.PublicIp;if($.InstanceId)J.InstanceId=$.InstanceId;if($.NetworkInterfaceId)J.NetworkInterfaceId=$.NetworkInterfaceId;if($.PrivateIpAddress)J.PrivateIpAddress=$.PrivateIpAddress;if($.AllowReassociation)J.AllowReassociation="true";return{AssociationId:(await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})).associationId}}async createTags($){let J={Action:"CreateTags",Version:"2016-11-15"};$.Resources.forEach((Y,Q)=>{J[`ResourceId.${Q+1}`]=Y}),$.Tags.forEach((Y,Q)=>{J[`Tag.${Q+1}.Key`]=Y.Key,J[`Tag.${Q+1}.Value`]=Y.Value}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async waitForInstanceState($,J,Y){let Q=Y?.maxWaitMs||300000,G=Y?.pollIntervalMs||5000,Z=Date.now();while(Date.now()-Z<Q){let W;try{W=await this.getInstance($)}catch{W=void 0}if(W?.State?.Name===J)return W;await new Promise((U)=>setTimeout(U,G))}return}async createVpc($){let J={Action:"CreateVpc",Version:"2016-11-15",CidrBlock:$.CidrBlock};if($.InstanceTenancy)J.InstanceTenancy=$.InstanceTenancy;if($.TagSpecifications)$.TagSpecifications.forEach((Z,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((U,z)=>{J[`TagSpecification.${W+1}.Tag.${z+1}.Key`]=U.Key,J[`TagSpecification.${W+1}.Tag.${z+1}.Value`]=U.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),G=(Y.CreateVpcResponse||Y).vpc;return{Vpc:G?{VpcId:G.vpcId,CidrBlock:G.cidrBlock,State:G.state,DhcpOptionsId:G.dhcpOptionsId,InstanceTenancy:G.instanceTenancy,IsDefault:G.isDefault==="true",Tags:this.parseTags(G.tagSet?.item)}:void 0}}async createSubnet($){let J={Action:"CreateSubnet",Version:"2016-11-15",VpcId:$.VpcId,CidrBlock:$.CidrBlock};if($.AvailabilityZone)J.AvailabilityZone=$.AvailabilityZone;if($.TagSpecifications)$.TagSpecifications.forEach((Z,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((U,z)=>{J[`TagSpecification.${W+1}.Tag.${z+1}.Key`]=U.Key,J[`TagSpecification.${W+1}.Tag.${z+1}.Value`]=U.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),G=(Y.CreateSubnetResponse||Y).subnet;return{Subnet:G?{SubnetId:G.subnetId,VpcId:G.vpcId,CidrBlock:G.cidrBlock,AvailabilityZone:G.availabilityZone,AvailableIpAddressCount:G.availableIpAddressCount?Number.parseInt(G.availableIpAddressCount):void 0,State:G.state,MapPublicIpOnLaunch:G.mapPublicIpOnLaunch==="true",Tags:this.parseTags(G.tagSet?.item)}:void 0}}async modifySubnetAttribute($){let J={Action:"ModifySubnetAttribute",Version:"2016-11-15",SubnetId:$.SubnetId};if($.MapPublicIpOnLaunch!==void 0)J["MapPublicIpOnLaunch.Value"]=String($.MapPublicIpOnLaunch.Value);await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async createSecurityGroup($){let J={Action:"CreateSecurityGroup",Version:"2016-11-15",GroupName:$.GroupName,GroupDescription:$.Description};if($.VpcId)J.VpcId=$.VpcId;if($.TagSpecifications)$.TagSpecifications.forEach((G,Z)=>{J[`TagSpecification.${Z+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((W,U)=>{J[`TagSpecification.${Z+1}.Tag.${U+1}.Key`]=W.Key,J[`TagSpecification.${Z+1}.Tag.${U+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{GroupId:(Y.CreateSecurityGroupResponse||Y).groupId}}async authorizeSecurityGroupIngress($){let J={Action:"AuthorizeSecurityGroupIngress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async authorizeSecurityGroupEgress($){let J={Action:"AuthorizeSecurityGroupEgress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRouteTables($){let J={Action:"DescribeRouteTables",Version:"2016-11-15"};if($?.RouteTableIds)$.RouteTableIds.forEach((G,Z)=>{J[`RouteTableId.${Z+1}`]=G});if($?.Filters)$.Filters.forEach((G,Z)=>{J[`Filter.${Z+1}.Name`]=G.Name,G.Values.forEach((W,U)=>{J[`Filter.${Z+1}.Value.${U+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeRouteTablesResponse||Y;return{RouteTables:this.parseArray(Q.routeTableSet?.item).map((G)=>({RouteTableId:G.routeTableId,VpcId:G.vpcId,Routes:this.parseArray(G.routeSet?.item).map((Z)=>({DestinationCidrBlock:Z.destinationCidrBlock,GatewayId:Z.gatewayId,NatGatewayId:Z.natGatewayId,State:Z.state})),Associations:this.parseArray(G.associationSet?.item).map((Z)=>({RouteTableAssociationId:Z.routeTableAssociationId,SubnetId:Z.subnetId,Main:Z.main==="true"||Z.main===!0})),Tags:this.parseTags(G.tagSet?.item)}))}}async deleteVpc($){let J={Action:"DeleteVpc",Version:"2016-11-15",VpcId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSubnet($){let J={Action:"DeleteSubnet",Version:"2016-11-15",SubnetId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSecurityGroup($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeleteSecurityGroup",Version:"2016-11-15",GroupId:$}).toString()})}async describeNetworkInterfaces($){let J={Action:"DescribeNetworkInterfaces",Version:"2016-11-15"};if($?.NetworkInterfaceIds)$.NetworkInterfaceIds.forEach((G,Z)=>{J[`NetworkInterfaceId.${Z+1}`]=G});if($?.Filters)$.Filters.forEach((G,Z)=>{J[`Filter.${Z+1}.Name`]=G.Name,G.Values.forEach((W,U)=>{J[`Filter.${Z+1}.Value.${U+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeNetworkInterfacesResponse||Y;return{NetworkInterfaces:this.parseArray(Q.networkInterfaceSet?.item).map((G)=>({NetworkInterfaceId:G.networkInterfaceId,SubnetId:G.subnetId,VpcId:G.vpcId,Status:G.status,Attachment:G.attachment?{AttachmentId:G.attachment.attachmentId,InstanceId:G.attachment.instanceId,Status:G.attachment.status}:void 0}))}}async detachNetworkInterface($,J){let Y={Action:"DetachNetworkInterface",Version:"2016-11-15",AttachmentId:$};if(J)Y.Force="true";await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()})}async deleteNetworkInterface($){let J={Action:"DeleteNetworkInterface",Version:"2016-11-15",NetworkInterfaceId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRegions(){let $={Action:"DescribeRegions",Version:"2016-11-15"},J=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams($).toString()}),Y=J.DescribeRegionsResponse||J;return{Regions:this.parseArray(Y.regionInfo?.item).map((Q)=>({RegionName:Q.regionName,Endpoint:Q.regionEndpoint}))}}async runInstances($){let J={Action:"RunInstances",Version:"2016-11-15",ImageId:$.ImageId,InstanceType:$.InstanceType,MinCount:String($.MinCount),MaxCount:String($.MaxCount)};if($.SecurityGroupIds)$.SecurityGroupIds.forEach((G,Z)=>{J[`SecurityGroupId.${Z+1}`]=G});if($.SubnetId)J.SubnetId=$.SubnetId;if($.UserData)J.UserData=$.UserData;if($.IamInstanceProfile){if($.IamInstanceProfile.Name)J["IamInstanceProfile.Name"]=$.IamInstanceProfile.Name;if($.IamInstanceProfile.Arn)J["IamInstanceProfile.Arn"]=$.IamInstanceProfile.Arn}if($.TagSpecifications)$.TagSpecifications.forEach((G,Z)=>{J[`TagSpecification.${Z+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((W,U)=>{J[`TagSpecification.${Z+1}.Tag.${U+1}.Key`]=W.Key,J[`TagSpecification.${Z+1}.Tag.${U+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.RunInstancesResponse||Y;return{Instances:this.parseInstances(Q.instancesSet?.item||Q.instancesSet)}}encodeIpPermissions($,J){J.forEach((Y,Q)=>{let G=`IpPermissions.${Q+1}`;if(Y.IpProtocol!==void 0)$[`${G}.IpProtocol`]=Y.IpProtocol;if(Y.FromPort!==void 0)$[`${G}.FromPort`]=String(Y.FromPort);if(Y.ToPort!==void 0)$[`${G}.ToPort`]=String(Y.ToPort);if(Y.IpRanges)Y.IpRanges.forEach((Z,W)=>{if(Z.CidrIp)$[`${G}.IpRanges.${W+1}.CidrIp`]=Z.CidrIp;if(Z.Description)$[`${G}.IpRanges.${W+1}.Description`]=Z.Description});if(Y.Ipv6Ranges)Y.Ipv6Ranges.forEach((Z,W)=>{if(Z.CidrIpv6)$[`${G}.Ipv6Ranges.${W+1}.CidrIpv6`]=Z.CidrIpv6;if(Z.Description)$[`${G}.Ipv6Ranges.${W+1}.Description`]=Z.Description});if(Y.UserIdGroupPairs)Y.UserIdGroupPairs.forEach((Z,W)=>{if(Z.GroupId)$[`${G}.Groups.${W+1}.GroupId`]=Z.GroupId;if(Z.UserId)$[`${G}.Groups.${W+1}.UserId`]=Z.UserId;if(Z.Description)$[`${G}.Groups.${W+1}.Description`]=Z.Description})})}parseArray($){if(!$)return[];return Array.isArray($)?$:[$]}parseTags($){return this.parseArray($).map((J)=>({Key:J.key,Value:J.value}))}parseReservations($){return this.parseArray($).map((J)=>({ReservationId:J.reservationId,Instances:this.parseInstances(J.instancesSet?.item||J.instancesSet)}))}parseInstances($){return this.parseArray($).map((J)=>({InstanceId:J.instanceId,ImageId:J.imageId,InstanceType:J.instanceType,State:J.instanceState?{Code:Number.parseInt(J.instanceState.code),Name:J.instanceState.name}:void 0,PrivateIpAddress:J.privateIpAddress,PublicIpAddress:J.ipAddress,SubnetId:J.subnetId,VpcId:J.vpcId,SecurityGroups:this.parseArray(J.groupSet?.item).map((Y)=>({GroupId:Y.groupId,GroupName:Y.groupName})),Tags:this.parseTags(J.tagSet?.item),LaunchTime:J.launchTime,Placement:J.placement?{AvailabilityZone:J.placement.availabilityZone,Tenancy:J.placement.tenancy}:void 0,Architecture:J.architecture,RootDeviceType:J.rootDeviceType,RootDeviceName:J.rootDeviceName,BlockDeviceMappings:this.parseArray(J.blockDeviceMapping?.item).map((Y)=>({DeviceName:Y.deviceName,Ebs:Y.ebs?{VolumeId:Y.ebs.volumeId,Status:Y.ebs.status,AttachTime:Y.ebs.attachTime,DeleteOnTermination:Y.ebs.deleteOnTermination==="true"}:void 0})),IamInstanceProfile:J.iamInstanceProfile?{Arn:J.iamInstanceProfile.arn,Id:J.iamInstanceProfile.id}:void 0}))}parseIpPermissions($){return this.parseArray($).map((J)=>({IpProtocol:J.ipProtocol,FromPort:J.fromPort?Number.parseInt(J.fromPort):void 0,ToPort:J.toPort?Number.parseInt(J.toPort):void 0,IpRanges:this.parseArray(J.ipRanges?.item).map((Y)=>({CidrIp:Y.cidrIp,Description:Y.description})),Ipv6Ranges:this.parseArray(J.ipv6Ranges?.item).map((Y)=>({CidrIpv6:Y.cidrIpv6,Description:Y.description})),UserIdGroupPairs:this.parseArray(J.groups?.item).map((Y)=>({GroupId:Y.groupId,UserId:Y.userId,Description:Y.description}))}))}}class yz{client;region;constructor($="us-east-1",J){this.region=$,this.client=new F$}async putParameter($){let J={Name:$.Name,Value:$.Value};if($.Type)J.Type=$.Type;if($.Description)J.Description=$.Description;if($.KeyId)J.KeyId=$.KeyId;if($.Overwrite!==void 0)J.Overwrite=$.Overwrite;if($.AllowedPattern)J.AllowedPattern=$.AllowedPattern;if($.Tags&&$.Tags.length>0)J.Tags=$.Tags;if($.Tier)J.Tier=$.Tier;if($.DataType)J.DataType=$.DataType;let Y=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(J)});return{Version:Y.Version,Tier:Y.Tier}}async getParameter($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=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(J)});return{Parameter:Y.Parameter?this.parseParameter(Y.Parameter):void 0}}async getParameters($){let J={Names:$.Names};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>this.parseParameter(Q)),InvalidParameters:Y.InvalidParameters}}async getParametersByPath($){let J={Path:$.Path};if($.Recursive!==void 0)J.Recursive=$.Recursive;if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;if($.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>this.parseParameter(Q)),NextToken:Y.NextToken}}async deleteParameter($){let J={Name:$.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(J)})}async deleteParameters($){let J={Names:$},Y=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(J)});return{DeletedParameters:Y.DeletedParameters,InvalidParameters:Y.InvalidParameters}}async describeParameters($){let J={};if($?.Filters&&$.Filters.length>0)J.Filters=$.Filters;if($?.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;if($?.MaxResults)J.MaxResults=$.MaxResults;if($?.NextToken)J.NextToken=$.NextToken;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>this.parseParameter(Q)),NextToken:Y.NextToken}}async getParameterHistory($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;let Y=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(J)});return{Parameters:Y.Parameters?.map((Q)=>({Name:Q.Name,Type:Q.Type,KeyId:Q.KeyId,LastModifiedDate:Q.LastModifiedDate,LastModifiedUser:Q.LastModifiedUser,Description:Q.Description,Value:Q.Value,Version:Q.Version,Labels:Q.Labels,Tier:Q.Tier})),NextToken:Y.NextToken}}async labelParameterVersion($){let J={Name:$.Name,Labels:$.Labels};if($.ParameterVersion!==void 0)J.ParameterVersion=$.ParameterVersion;let Y=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(J)});return{InvalidLabels:Y.InvalidLabels,ParameterVersion:Y.ParameterVersion}}async addTagsToResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,Tags:$.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(J)})}async removeTagsFromResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,TagKeys:$.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(J)})}async listTagsForResource($){let J={ResourceType:$.ResourceType,ResourceId:$.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(J)})).TagList}}async setString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"String",Description:Y?.description,Overwrite:Y?.overwrite??!0,Tags:Y?.tags})}async setSecureString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"SecureString",Description:Y?.description,Overwrite:Y?.overwrite??!0,KeyId:Y?.kmsKeyId,Tags:Y?.tags})}async getValue($){return(await this.getParameter({Name:$,WithDecryption:!0})).Parameter?.Value}async getAllByPath($,J=!0){let Y=[],Q;do{let G=await this.getParametersByPath({Path:$,Recursive:J,WithDecryption:!0,NextToken:Q});if(G.Parameters)Y.push(...G.Parameters);Q=G.NextToken}while(Q);return Y}parseParameter($){return{Name:$.Name,Type:$.Type,Value:$.Value,Version:$.Version,LastModifiedDate:$.LastModifiedDate,ARN:$.ARN,DataType:$.DataType,Description:$.Description,AllowedPattern:$.AllowedPattern,KeyId:$.KeyId,Tier:$.Tier}}async sendCommand($){if(!$.InstanceIds&&!$.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let J={DocumentName:$.DocumentName};if($.InstanceIds)J.InstanceIds=$.InstanceIds;if($.Targets)J.Targets=$.Targets;if($.Parameters)J.Parameters=$.Parameters;if($.TimeoutSeconds)J.TimeoutSeconds=$.TimeoutSeconds;if($.Comment)J.Comment=$.Comment;if($.OutputS3BucketName)J.OutputS3BucketName=$.OutputS3BucketName;if($.OutputS3KeyPrefix)J.OutputS3KeyPrefix=$.OutputS3KeyPrefix;let Y=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(J)});return{CommandId:Y.Command?.CommandId,Status:Y.Command?.Status,StatusDetails:Y.Command?.StatusDetails}}async getCommandInvocation($){let J={CommandId:$.CommandId,InstanceId:$.InstanceId},Y=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(J)});return{Status:Y.Status,StatusDetails:Y.StatusDetails,StandardOutputContent:Y.StandardOutputContent,StandardErrorContent:Y.StandardErrorContent,ResponseCode:Y.ResponseCode}}async runShellCommand($,J,Y){let Q=await this.sendCommand({InstanceIds:[$],DocumentName:"AWS-RunShellScript",Parameters:{commands:J},TimeoutSeconds:Y?.timeoutSeconds||600});if(!Q.CommandId)return{success:!1,error:"Failed to send command"};if(Y?.waitForCompletion===!1)return{success:!0,status:"Pending"};let G=Y?.pollIntervalMs||2000,Z=Y?.maxWaitMs||300000,W=Date.now();while(Date.now()-W<Z){await new Promise((U)=>setTimeout(U,G));try{let U=await this.getCommandInvocation({CommandId:Q.CommandId,InstanceId:$});if(U.Status==="Success")return{success:!0,output:U.StandardOutputContent,error:U.StandardErrorContent,status:U.Status};if(U.Status==="Failed"||U.Status==="Cancelled"||U.Status==="TimedOut")return{success:!1,output:U.StandardOutputContent,error:U.StandardErrorContent||U.StatusDetails,status:U.Status}}catch(U){if(!U.message?.includes("InvocationDoesNotExist"))return{success:!1,error:U.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations($){let J={CommandId:$.CommandId};if($.Details)J.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(J)})).CommandInvocations||[]).map((G)=>({InstanceId:G.InstanceId,Status:G.Status,StatusDetails:G.StatusDetails,StandardOutputContent:G.CommandPlugins?.[0]?.Output,StandardErrorContent:G.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags($){let J=Object.entries($.tags).map(([z,H])=>({Key:`tag:${z}`,Values:[H]})),Y=await this.sendCommand({Targets:J,DocumentName:"AWS-RunShellScript",Parameters:{commands:$.commands},TimeoutSeconds:$.timeoutSeconds||600,Comment:$.comment});if(!Y.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let Q=$.pollIntervalMs||3000,G=$.maxWaitMs||600000,Z=Date.now(),W=new Set(["Success","Failed","Cancelled","TimedOut"]),U=[];while(Date.now()-Z<G){await new Promise((z)=>setTimeout(z,Q));try{if(U=await this.listCommandInvocations({CommandId:Y.CommandId,Details:!0}),U.length===0)continue;if(U.every((H)=>W.has(H.Status||""))){let H=U.map((X)=>({instanceId:X.InstanceId,status:X.Status||"Unknown",output:X.StandardOutputContent,error:X.StandardErrorContent||X.StatusDetails})),_=U.every((X)=>X.Status==="Success");return{success:_,instanceCount:U.length,perInstance:H,error:_?void 0:"One or more instances reported a non-success status"}}}catch(z){if(!z.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:z.message}}}return{success:!1,instanceCount:U.length,perInstance:U.map((z)=>({instanceId:z.InstanceId,status:z.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}function dL($){return $.type!=null&&Dh.has($.type)}function Nh($){if($.deploy)return $.deploy;if(dL($))return"server";if($.start)return"server";return"bucket"}function Sh($){if(dL($))return"server-php";if(Nh($)==="bucket")return"bucket";return $.start?"server-app":"server-static"}function rQ($){return`'${$.split("'").join("'\\''")}'`}function cL($={}){let J=$.version?`export PANTRY_VERSION=${rQ($.version)}`:'export PANTRY_VERSION="${PANTRY_VERSION:-latest}"';return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system",`export PANTRY_INSTALL_DIR=${rB}`,J,"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)","command -v pantry >/dev/null 2>&1 || curl -fsSL https://pantry.dev | bash",`export PATH="${rB}:$PATH"`,`mkdir -p ${X8}`]}function vz(){return`eval "$(cd ${X8} && pantry env 2>/dev/null)" || true`}function K4($){if($.length===0)return[];let J=[...new Set($)];return[`(cd ${X8} && pantry install ${J.map(rQ).join(" ")})`]}function lL($){return[...new Set($)].flatMap((J)=>[`(cd ${X8} && pantry start ${rQ(J)})`,`(cd ${X8} && pantry enable ${rQ(J)})`])}function H2($){return $===!0||typeof $==="object"&&$!=null}function Ih($){let J=[],Y=[];if(H2($.mysql))J.push(typeof $.mysql==="object"&&$.mysql.version?`mysql.com@${$.mysql.version}`:"mysql.com@8.0.43"),Y.push("mysql");else if(H2($.mariadb))J.push(Ch.mariadb),Y.push("mariadb");if(H2($.postgres))J.push("postgresql.org"),Y.push("postgres");if(H2($.redis))J.push("redis.io"),Y.push("redis");if(H2($.memcached))J.push("memcached.org"),Y.push("memcached");if(H2($.meilisearch))J.push("meilisearch.com"),Y.push("meilisearch");return{packages:J,services:Y}}function mL($={},J={}){let Y=Ih($);if(Y.packages.length===0)return[];return[...K4(Y.packages),...lL(Y.services)]}function pL($,J={}){if(!$?.name)return[];if($.host&&$.host!=="127.0.0.1"&&$.host!=="localhost")return[];let Y=$.name,Q=$.username||Y,G=$.password||"",Z=H2(J.postgres)||$.engine==="postgres",W=H2(J.mariadb)||$.engine==="mariadb",U=H2(J.mysql)||$.engine==="mysql";if(Z&&!U&&!W){let B=(A)=>`"${A.replace(/"/g,'""')}"`,V=(A)=>`'${A.replace(/'/g,"''")}'`,K=(A,j)=>["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${V(A)}) THEN`,` CREATE ROLE ${B(A)} LOGIN PASSWORD ${V(j)};`," ELSE",` ALTER ROLE ${B(A)} LOGIN PASSWORD ${V(j)};`," END IF;","END $$;"],L=(A)=>{let j=A.databases&&A.databases.length>0?A.databases:[Y],q=[];for(let M of j)if(A.access==="readonly")q.push(`GRANT CONNECT ON DATABASE ${B(M)} TO ${B(A.username)};`,`\\connect ${B(M)}`,`GRANT USAGE ON SCHEMA public TO ${B(A.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${B(A.username)};`,`ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ${B(A.username)};`,"\\connect postgres");else q.push(`GRANT ALL PRIVILEGES ON DATABASE ${B(M)} TO ${B(A.username)};`);return q},E=$.users||[];return[vz(),"for i in $(seq 1 30); do pg_isready -h 127.0.0.1 -p 5432 -q && break; sleep 2; done","psql -h 127.0.0.1 -p 5432 -U postgres <<'TS_CLOUD_PG_EOF'",...K(Q,G),`SELECT 'CREATE DATABASE ${B(Y)} OWNER ${B(Q)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${V(Y)})\\gexec`,...E.flatMap((A)=>[...K(A.username,A.password),...L(A)]),"TS_CLOUD_PG_EOF"]}let z=W?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",H=(B)=>B.replace(/`/g,"``"),_=(B)=>B.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),X=(B)=>{let V=B.databases&&B.databases.length>0?B.databases:[Y],K=B.access==="readonly"?"SELECT":"ALL PRIVILEGES",L=[`CREATE USER IF NOT EXISTS '${_(B.username)}'@'%' IDENTIFIED BY '${_(B.password)}';`,`CREATE USER IF NOT EXISTS '${_(B.username)}'@'localhost' IDENTIFIED BY '${_(B.password)}';`,`ALTER USER '${_(B.username)}'@'%' IDENTIFIED BY '${_(B.password)}';`,`ALTER USER '${_(B.username)}'@'localhost' IDENTIFIED BY '${_(B.password)}';`];for(let E of V)L.push(`GRANT ${K} ON \`${H(E)}\`.* TO '${_(B.username)}'@'%';`,`GRANT ${K} ON \`${H(E)}\`.* TO '${_(B.username)}'@'localhost';`);return L},F=$.users||[];return[vz(),`for i in $(seq 1 30); do mysqladmin --socket=${z} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${z} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${H(Y)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...X({username:Q,password:G}),...F.flatMap(X),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}function kh($={}){let J=$.versions?.length?$.versions:["8.3"];return $.default&&J.includes($.default)?$.default:J[0]}function bh($={}){return{...$.optimizeForProduction===!1?{}:{...xh},...$.ini||{}}}function hh($={}){let J=bh($),Y=Object.keys(J);if(Y.length===0)return[];let Q=Y.map((Z)=>`${Z}=${J[Z]}`),G="ts-cloud-managed";return[vz(),"TS_CLOUD_SCAN_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Scan this dir for additional .ini files/{print $2}' | head -1)",`TS_CLOUD_LOADED_INI=$(php -r 'echo php_ini_loaded_file() ?: "";' 2>/dev/null)`,'if [ -n "$TS_CLOUD_SCAN_DIR" ] && [ "$TS_CLOUD_SCAN_DIR" != "(none)" ]; then',' mkdir -p "$TS_CLOUD_SCAN_DIR"',' TS_CLOUD_PHP_INI="$TS_CLOUD_SCAN_DIR/zz-ts-cloud.ini"',` cat > "$TS_CLOUD_PHP_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${G} — production PHP tuning`,...Q,"TS_CLOUD_PHPINI_EOF","else",' if [ -z "$TS_CLOUD_LOADED_INI" ]; then'," TS_CLOUD_INI_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Configuration File \\(php.ini\\) Path/{print $2}' | head -1)",' TS_CLOUD_LOADED_INI="$TS_CLOUD_INI_DIR/php.ini"',' mkdir -p "$TS_CLOUD_INI_DIR"',' touch "$TS_CLOUD_LOADED_INI"'," fi",` sed -i '/; ${G} BEGIN/,/; ${G} END/d' "$TS_CLOUD_LOADED_INI"`,` cat >> "$TS_CLOUD_LOADED_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${G} BEGIN`,...Q,`; ${G} END`,"TS_CLOUD_PHPINI_EOF","fi",`(cd ${X8} && pantry restart php-fpm) 2>/dev/null || true`]}function rL($={}){let J=kh($),Y=$.installNginx!==!1,Q=$.installComposer!==!1,G=[`php.net@${J}`];if(Q)G.push("getcomposer.org");if(Y)G.push("nginx.org");return[...K4(G),...lL(["php-fpm"]),...hh($)]}function yh($="/opt/pantry"){return[...cL(),...K4(["nginx.org"]),"mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /var/log/nginx /var/lib/nginx/body /var/lib/nginx/proxy /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/scgi","getent passwd www-data >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www-data","chown -R www-data:www-data /var/lib/nginx /var/log/nginx",`cat > ${SJ} <<'TS_CLOUD_NGINXBIN_EOF'`,"#!/bin/sh",`eval "$(cd ${$} && pantry env 2>/dev/null)"`,"NGINX_BIN=/opt/pantry/pantry/.bin/nginx",'if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=$(command -v nginx || true); fi','if [ -z "$NGINX_BIN" ]; then echo "nginx binary not found; run pantry install nginx.org or install nginx explicitly" >&2; exit 1; fi','exec "$NGINX_BIN" -c /etc/nginx/nginx.conf "$@"',"TS_CLOUD_NGINXBIN_EOF",`chmod +x ${SJ}`,"cat > /etc/nginx/fastcgi_params <<'TS_CLOUD_FCGI_EOF'","fastcgi_param QUERY_STRING $query_string;","fastcgi_param REQUEST_METHOD $request_method;","fastcgi_param CONTENT_TYPE $content_type;","fastcgi_param CONTENT_LENGTH $content_length;","fastcgi_param SCRIPT_NAME $fastcgi_script_name;","fastcgi_param REQUEST_URI $request_uri;","fastcgi_param DOCUMENT_URI $document_uri;","fastcgi_param DOCUMENT_ROOT $document_root;","fastcgi_param SERVER_PROTOCOL $server_protocol;","fastcgi_param REQUEST_SCHEME $scheme;","fastcgi_param HTTPS $https if_not_empty;","fastcgi_param GATEWAY_INTERFACE CGI/1.1;","fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;","fastcgi_param REMOTE_ADDR $remote_addr;","fastcgi_param REMOTE_PORT $remote_port;","fastcgi_param SERVER_ADDR $server_addr;","fastcgi_param SERVER_PORT $server_port;","fastcgi_param SERVER_NAME $server_name;","fastcgi_param REDIRECT_STATUS 200;","TS_CLOUD_FCGI_EOF","cat > /etc/nginx/nginx.conf <<'TS_CLOUD_NGINXCONF_EOF'","user www-data;","worker_processes auto;","pid /run/nginx.pid;","error_log /var/log/nginx/error.log;","events { worker_connections 1024; }","http {"," default_type application/octet-stream;"," types {"," text/html html htm;"," text/css css;"," application/javascript js;"," application/json json;"," image/svg+xml svg;"," image/png png;"," image/jpeg jpg jpeg;"," image/gif gif;"," image/x-icon ico;"," image/webp webp;"," font/woff2 woff2;"," font/woff woff;"," text/plain txt;"," }"," access_log /var/log/nginx/access.log;"," sendfile on;"," tcp_nopush on;"," keepalive_timeout 65;"," server_tokens off;"," client_max_body_size 100m;"," client_body_temp_path /var/lib/nginx/body;"," proxy_temp_path /var/lib/nginx/proxy;"," fastcgi_temp_path /var/lib/nginx/fastcgi;"," uwsgi_temp_path /var/lib/nginx/uwsgi;"," scgi_temp_path /var/lib/nginx/scgi;"," server {"," listen 80 default_server;"," listen [::]:80 default_server;"," server_name _;"," return 444;"," }"," include /etc/nginx/sites-enabled/*;","}","TS_CLOUD_NGINXCONF_EOF","cat > /etc/systemd/system/ts-cloud-nginx.service <<'TS_CLOUD_NGINXUNIT_EOF'","[Unit]","Description=ts-cloud nginx (pantry)","After=network.target","","[Service]","Type=simple",`ExecStartPre=${SJ} -t`,`ExecStart=${SJ} -g 'daemon off;'`,`ExecReload=${SJ} -s reload`,"Restart=always","RestartSec=3","","[Install]","WantedBy=multi-user.target","TS_CLOUD_NGINXUNIT_EOF","systemctl daemon-reload","systemctl enable ts-cloud-nginx","ls /etc/nginx/sites-enabled/* >/dev/null 2>&1 && systemctl restart ts-cloud-nginx || true"]}function fh($={}){if($.enabled===!1)return[];let J=[...new Set([...vh,...$.allowedPorts||[]])].filter((Q)=>Q>0).sort((Q,G)=>Q-G),Y=["export DEBIAN_FRONTEND=noninteractive","apt-get install -y ufw","ufw default deny incoming","ufw default allow outgoing","ufw allow OpenSSH"];for(let Q of J)Y.push(`ufw allow ${Q}/tcp`);return Y.push("ufw --force enable"),Y}function fz($=!0){if(!$)return[];return["export DEBIAN_FRONTEND=noninteractive","apt-get install -y unattended-upgrades","cat > /etc/apt/apt.conf.d/20auto-upgrades <<'TS_CLOUD_AUTOUPD_EOF'",'APT::Periodic::Update-Package-Lists "1";','APT::Periodic::Unattended-Upgrade "1";','APT::Periodic::Download-Upgradeable-Packages "1";','APT::Periodic::AutocleanInterval "7";',"TS_CLOUD_AUTOUPD_EOF","systemctl enable unattended-upgrades 2>/dev/null || true","systemctl restart unattended-upgrades 2>/dev/null || true"]}function ch($=!0){let J=typeof $==="object"?$:{};return{enabled:typeof $==="boolean"?$:$.enabled!==!1,cpuLoadPerCore:J.alerts?.cpuLoadPerCore??gh,memPercent:J.alerts?.memPercent??uh,diskPercent:J.alerts?.diskPercent??dh}}function gz($=!0){let{enabled:J,cpuLoadPerCore:Y,memPercent:Q,diskPercent:G}=ch($);if(!J)return[];let Z=nB.map(([U,z])=>`SVC_${U.toUpperCase()}=$(probe ${z})`),W=nB.map(([U])=>`"${U}":"$SVC_${U.toUpperCase()}"`).join(",");return["mkdir -p /var/lib/ts-cloud","cat > /usr/local/bin/ts-cloud-metrics.sh <<'TS_CLOUD_METRICS_EOF'","#!/bin/bash","set -uo pipefail","LOAD=$(cut -d' ' -f1 /proc/loadavg)","CPUS=$(nproc)","MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')","MEM_USED=$(free -m | awk '/^Mem:/{print $3}')","SWAP_TOTAL=$(free -m | awk '/^Swap:/{print $2}')","SWAP_USED=$(free -m | awk '/^Swap:/{print $3}')",`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...Z,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))",`cat > ${Hz}.tmp <<JSON`,'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+W+"}}","JSON",`mv -f ${Hz}.tmp ${Hz}`,'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${Y} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${Y}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${Q} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${G} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,`PREV=$(cat ${_z} 2>/dev/null || echo ok)`,'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi',` echo alert > ${_z}`,"else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi',` echo ok > ${_z}`,"fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnBootSec=60","OnUnitActiveSec=60","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.timer"]}function uz($=[],J={}){if($.length===0)return[];let Y=J.path??lh,Q=Y.replace(/\/[^/]*$/,""),G=[iB,...$.map((Z)=>`${Z.publicKey.trim()} ${Z.name}`),tB].join(`
10216
10216
  `);return[`mkdir -p ${Q}`,`touch ${Y}`,`sed -i '/^${aB(iB)}$/,/^${aB(tB)}$/d' ${Y}`,`cat >> ${Y} <<'TS_CLOUD_KEYS_EOF'`,G,"TS_CLOUD_KEYS_EOF",`chmod 600 ${Y}`]}function aB($){return $.replace(/[.*[\]\\/^$]/g,"\\$&")}function nL($){if(!$)return[];let J=[];if($.slack?.webhookUrl)J.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"text\\":\\"$MSG\\"}" ${$.slack.webhookUrl} || true`);if($.discord?.webhookUrl)J.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"content\\":\\"$MSG\\"}" ${$.discord.webhookUrl} || true`);if($.telegram?.botToken&&$.telegram.chatId)J.push(`curl -fsS -X POST "https://api.telegram.org/bot${$.telegram.botToken}/sendMessage" --data-urlencode "chat_id=${$.telegram.chatId}" --data-urlencode "text=$MSG" || true`);if($.webhook?.url)J.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"message\\":\\"$MSG\\"}" ${$.webhook.url} || true`);if(J.length===0)return[];return["cat > /usr/local/bin/ts-cloud-notify <<'TS_CLOUD_NOTIFY_EOF'","#!/bin/bash",'MSG="$1"',...J,"TS_CLOUD_NOTIFY_EOF","chmod +x /usr/local/bin/ts-cloud-notify"]}function ph($){if(!$.name)return null;let J=$.host||"127.0.0.1",Y=$.engine==="postgres",Q=Y?"postgresql":"mysql",G=$.port??(Y?5432:3306),Z=(W)=>W.replace(/\\/g,"\\\\").replace(/'/g,"\\'");return[" {",` type: '${Q}',`,` name: '${Z($.name)}',`," connection: {",` hostname: '${Z(J)}',`,` port: ${G},`,` database: '${Z($.name)}',`,` username: '${Z($.username||$.name)}',`,` password: '${Z($.password||"")}',`," ssl: false,"," },"," includeSchema: true,"," includeData: true,"," },"].join(`
10217
10217
  `)}function rh($,J){let Y=$?ph($):null,Q=J.bucket?[" destinations: ["," {"," type: 's3',",` bucket: '${J.bucket}',`," prefix: 'db-backups',",...J.endpoint?[` endpoint: '${J.endpoint}',`]:[]," optional: false,"," },"," ],"]:[];return["import type { BackupConfig } from 'ts-backups'","","const config: BackupConfig = {"," verbose: true,",` outputPath: '${iL}',`," retention: {",` count: ${J.retentionCount??5},`,` maxAge: ${J.retentionDays??30},`," },"," databases: [",...Y?[Y]:[]," ],",...Q,"}","","export default config",""].join(`
10218
10218
  `)}function nh($){let{database:J,backups:Y}=$;if(!Y.enabled)return[];let Q=Y.schedule||"0 2 * * *",G=rh(J,Y);return["export DEBIAN_FRONTEND=noninteractive",`mkdir -p /etc/ts-cloud ${iL}`,"command -v bun >/dev/null 2>&1 || (curl -fsSL https://bun.sh/install | bash && ln -sf /root/.bun/bin/bun /usr/local/bin/bun)","bun add -g ts-backups || true",`cat > ${mh} <<'TS_CLOUD_BACKUP_CFG_EOF'`,G.replace(/\n$/,""),"TS_CLOUD_BACKUP_CFG_EOF",`cat > ${Xz} <<'TS_CLOUD_BACKUP_RUN_EOF'`,"#!/bin/bash","set -uo pipefail",'export PATH="/root/.bun/bin:/usr/local/bin:$PATH"','notify() { [ -x /usr/local/bin/ts-cloud-notify ] && /usr/local/bin/ts-cloud-notify "$1" || true; }',"cd /etc/ts-cloud",'if ! ts-backups backup --config /etc/ts-cloud/backups.config.ts; then notify "❌ ts-cloud backup failed"; exit 1; fi',"TS_CLOUD_BACKUP_RUN_EOF",`chmod +x ${Xz}`,`cat > ${oB} <<'TS_CLOUD_BACKUP_CRON_EOF'`,`${Q} root ${Xz} >> /var/log/ts-cloud-backup.log 2>&1`,"TS_CLOUD_BACKUP_CRON_EOF",`chmod 644 ${oB}`]}function tL($){let J=$.infrastructure?.compute??{},Y=J.runtime==="php"||!!J.php,Q=Y||!!J.managedServices,G=Q?cL():[],Z=J.webServer!=="rpx",W=Y?[...G,...rL({versions:J.php?.versions,default:J.php?.default,extensions:J.php?.extensions,installNginx:Z,optimizeForProduction:J.php?.optimizeForProduction,ini:J.php?.ini}),...Z?yh():[]]:void 0,U=[];if(!Y&&Q)U.push(...G);if(U.push(...nL($.notifications)),J.managedServices)U.push(...mL(J.managedServices),...pL($.infrastructure?.appDatabase,J.managedServices));if(U.push(...fh(J.firewall??(Y?{enabled:!0}:{enabled:!1}))),U.push(...fz(J.autoUpdates??Y)),U.push(...gz(J.monitoring??Y)),U.push(...uz(J.sshKeys)),J.backups?.enabled)U.push(...nh({database:$.infrastructure?.appDatabase,backups:J.backups}));return{runtime:J.runtime||"bun",runtimeVersion:J.runtimeVersion||"latest",phpBox:Y,phpProvision:W,servicesProvision:U.length>0?U:void 0}}function NQ($={}){let{runtime:J="bun",runtimeVersion:Y="latest",systemPackages:Q=[],database:G,phpProvision:Z,servicesProvision:W,caddyfile:U,rpxProvision:z,baked:H=!1}=$,_=new Set(Q);if(G==="sqlite")_.add("sqlite3");else if(G==="mysql")_.add("mysql-client");else if(G==="postgres")_.add("postgresql-client");let X=`#!/bin/bash
@@ -10314,7 +10314,7 @@ const config = ${JSON.stringify($,null,2)} as const
10314
10314
 
10315
10315
  await startProxies(config as any)
10316
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
- `),"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)}
10317
+ `),"TS_CLOUD_RPX_UNIT_EOF"),"systemctl daemon-reload","systemctl disable --now bun-gateway.service 2>/dev/null || true","systemctl disable --now ts-cloud-nginx.service 2>/dev/null || true",`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');
10320
10320
  const { DynamoDBClient, PutItemCommand } = require('@aws-sdk/client-dynamodb');
@@ -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.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'
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.26";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
@@ -84236,16 +84236,15 @@ function buildNginxServiceScript(projectDir = "/opt/pantry") {
84236
84236
  return [
84237
84237
  ...buildPantryBootstrapScript(),
84238
84238
  ...buildPantryInstallScript(["nginx.org"]),
84239
- "if ! /opt/pantry/pantry/.bin/nginx -v >/dev/null 2>&1; then apt-get update -y && apt-get install -y nginx; fi",
84240
84239
  "mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /var/log/nginx /var/lib/nginx/body /var/lib/nginx/proxy /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/scgi",
84241
84240
  "getent passwd www-data >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www-data",
84242
84241
  "chown -R www-data:www-data /var/lib/nginx /var/log/nginx",
84243
84242
  `cat > ${NGINX_WRAPPER} <<'TS_CLOUD_NGINXBIN_EOF'`,
84244
84243
  "#!/bin/sh",
84245
84244
  `eval "$(cd ${projectDir} && pantry env 2>/dev/null)"`,
84246
- "NGINX_BIN=$(command -v nginx || true)",
84247
- 'if [ -z "$NGINX_BIN" ] || ! "$NGINX_BIN" -v >/dev/null 2>&1; then NGINX_BIN=/usr/sbin/nginx; fi',
84248
- 'if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=/opt/pantry/pantry/.bin/nginx; fi',
84245
+ "NGINX_BIN=/opt/pantry/pantry/.bin/nginx",
84246
+ 'if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=$(command -v nginx || true); fi',
84247
+ 'if [ -z "$NGINX_BIN" ]; then echo "nginx binary not found; run pantry install nginx.org or install nginx explicitly" >&2; exit 1; fi',
84249
84248
  'exec "$NGINX_BIN" -c /etc/nginx/nginx.conf "$@"',
84250
84249
  "TS_CLOUD_NGINXBIN_EOF",
84251
84250
  `chmod +x ${NGINX_WRAPPER}`,
@@ -84330,7 +84329,6 @@ function buildNginxServiceScript(projectDir = "/opt/pantry") {
84330
84329
  "WantedBy=multi-user.target",
84331
84330
  "TS_CLOUD_NGINXUNIT_EOF",
84332
84331
  "systemctl daemon-reload",
84333
- "systemctl disable --now nginx 2>/dev/null || true",
84334
84332
  "systemctl enable ts-cloud-nginx",
84335
84333
  "ls /etc/nginx/sites-enabled/* >/dev/null 2>&1 && systemctl restart ts-cloud-nginx || true"
84336
84334
  ];
@@ -85510,6 +85508,8 @@ function buildRpxProvisionScript(options) {
85510
85508
  ].join(`
85511
85509
  `), "TS_CLOUD_RPX_UNIT_EOF"),
85512
85510
  "systemctl daemon-reload",
85511
+ "systemctl disable --now bun-gateway.service 2>/dev/null || true",
85512
+ "systemctl disable --now ts-cloud-nginx.service 2>/dev/null || true",
85513
85513
  `systemctl enable ${RPX_SERVICE_NAME}`,
85514
85514
  `systemctl restart ${RPX_SERVICE_NAME}`
85515
85515
  ];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/ts-cloud",
3
3
  "type": "module",
4
- "version": "0.5.25",
4
+ "version": "0.5.26",
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.25",
93
- "@ts-cloud/core": "0.5.25",
92
+ "@ts-cloud/aws-types": "0.5.26",
93
+ "@ts-cloud/core": "0.5.26",
94
94
  "@stacksjs/ts-xml": "^0.1.0"
95
95
  },
96
96
  "devDependencies": {