@stacksjs/ts-cloud 0.9.3 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aws/index.js +1 -269
- package/dist/bin/chunk-00kg80qg.js +1 -0
- package/dist/bin/{chunk-hzqw8xm5.js → chunk-1k5kszjp.js} +1 -1
- package/dist/bin/{chunk-9v39615t.js → chunk-21e0mavm.js} +1 -1
- package/dist/bin/{chunk-waayf9ay.js → chunk-2empps47.js} +1 -1
- package/dist/bin/{chunk-14cwr6eh.js → chunk-3vqfexc4.js} +1 -1
- package/dist/bin/chunk-5ectjq0b.js +1 -0
- package/dist/bin/{chunk-b5gd39s8.js → chunk-5erkxpt7.js} +4 -4
- package/dist/bin/{chunk-41x17hw1.js → chunk-5mrtzemj.js} +1 -1
- package/dist/bin/{chunk-p8q9bq9g.js → chunk-5n9fmabb.js} +1 -1
- package/dist/bin/{chunk-gqf6jsmy.js → chunk-9knpg30y.js} +1 -1
- package/dist/bin/{chunk-r3kv0vm9.js → chunk-ddk4rt4j.js} +1 -1
- package/dist/bin/{chunk-avm7tnwe.js → chunk-e0rkrq70.js} +1 -1
- package/dist/bin/{chunk-ry030a6b.js → chunk-etrb03mt.js} +1 -1
- package/dist/bin/{chunk-8v7ddyvf.js → chunk-k9t9wvms.js} +1 -1
- package/dist/bin/{chunk-92mea34a.js → chunk-m7dgskt1.js} +1 -1
- package/dist/bin/{chunk-3r4fb59r.js → chunk-mz0wbbsj.js} +1 -1
- package/dist/bin/{chunk-b9qbp8j1.js → chunk-qk9qgepa.js} +1 -1
- package/dist/bin/chunk-rxcvf10f.js +7364 -0
- package/dist/bin/{chunk-r9hjwcj9.js → chunk-tga3hhwk.js} +1 -1
- package/dist/bin/{chunk-ynjvbphf.js → chunk-tx0tqq2k.js} +1 -1
- package/dist/bin/{chunk-57y1zxbf.js → chunk-vm3q5gf2.js} +1 -1
- package/dist/bin/{chunk-bz828v8q.js → chunk-y7s5r8y6.js} +1 -1
- package/dist/bin/{chunk-sgyffpgm.js → chunk-zmegvjp8.js} +1 -1
- package/dist/bin/cli.js +14 -14
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/chunk-0ccta6z6.js +6 -0
- package/dist/chunk-0k1cs6pp.js +1 -0
- package/dist/chunk-1egjn203.js +704 -0
- package/dist/chunk-2wx29qga.js +5 -0
- package/dist/chunk-5m5rqmv7.js +1 -0
- package/dist/chunk-8ea5022g.js +114 -0
- package/dist/chunk-8xqn3c0w.js +2 -0
- package/dist/chunk-b4esxhmw.js +2 -0
- package/dist/chunk-b8e5wzwn.js +44 -0
- package/dist/chunk-bggt4n6e.js +2 -0
- package/dist/chunk-cwkg37rs.js +37 -0
- package/dist/chunk-dskvqt67.js +7355 -0
- package/dist/chunk-gahsdmxf.js +1617 -0
- package/dist/chunk-gnv3r2jg.js +1 -0
- package/dist/chunk-hg3c48cp.js +34 -0
- package/dist/chunk-m5azeva3.js +2 -0
- package/dist/chunk-r3qf56b3.js +92 -0
- package/dist/chunk-sdqa9ghv.js +141 -0
- package/dist/chunk-svrvvcm7.js +1 -0
- package/dist/chunk-v0p3hpc3.js +60 -0
- package/dist/chunk-wdzjbecg.js +50 -0
- package/dist/chunk-ww8k3g7j.js +1 -0
- package/dist/chunk-xmqfc62w.js +1 -0
- package/dist/chunk-xrebj679.js +435 -0
- package/dist/chunk-xt3s24vr.js +2 -0
- package/dist/chunk-y21zk0pn.js +4 -0
- package/dist/deploy/index.js +1 -168
- package/dist/dns/index.js +1 -41
- package/dist/drivers/index.js +1 -154
- package/dist/index.js +100 -6129
- package/dist/protection/index.js +1 -89
- package/dist/push/index.js +1 -509
- package/dist/spend/index.js +1 -173
- package/dist/ui/404.html +1 -1
- package/dist/ui/accept-invitation.html +1 -1
- package/dist/ui/access-denied.html +1 -1
- package/dist/ui/account/automation.html +6 -6
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +6 -6
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +5 -5
- package/dist/ui/data/services.html +5 -5
- package/dist/ui/data/volumes.html +6 -6
- package/dist/ui/index.html +6 -6
- package/dist/ui/infrastructure/topology.html +5 -5
- package/dist/ui/integrations.html +1 -1
- package/dist/ui/operations/alerts.html +5 -5
- package/dist/ui/operations/configuration.html +5 -5
- package/dist/ui/operations/jobs.html +5 -5
- package/dist/ui/operations/maintenance.html +5 -5
- package/dist/ui/operations/observability.html +6 -6
- package/dist/ui/operations/previews.html +6 -6
- package/dist/ui/operations/queue.html +6 -6
- package/dist/ui/operations/regions.html +6 -6
- package/dist/ui/operations/releases.html +6 -6
- package/dist/ui/operations/spend.html +6 -6
- package/dist/ui/operations/workloads.html +6 -6
- package/dist/ui/security.html +1 -1
- package/dist/ui/server/actions.html +5 -5
- package/dist/ui/server/activity.html +1 -1
- package/dist/ui/server/capacity.html +6 -6
- package/dist/ui/server/database.html +6 -6
- package/dist/ui/server/deployments.html +6 -6
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +6 -6
- package/dist/ui/server/fleet.html +6 -6
- package/dist/ui/server/logs.html +6 -6
- package/dist/ui/server/metrics.html +6 -6
- package/dist/ui/server/security.html +2 -2
- package/dist/ui/server/services.html +1 -1
- package/dist/ui/server/sites.html +6 -6
- package/dist/ui/server/ssh-keys.html +6 -6
- package/dist/ui/server/team.html +6 -6
- package/dist/ui/server/terminal.html +1 -1
- package/dist/ui/serverless/alarms.html +5 -5
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/cost.html +1 -1
- package/dist/ui/serverless/data.html +6 -6
- package/dist/ui/serverless/deployments.html +2 -2
- package/dist/ui/serverless/firewall.html +1 -1
- package/dist/ui/serverless/functions.html +6 -6
- package/dist/ui/serverless/logs.html +6 -6
- package/dist/ui/serverless/metrics.html +2 -2
- package/dist/ui/serverless/queues.html +6 -6
- package/dist/ui/serverless/secrets.html +6 -6
- package/dist/ui/serverless/traces.html +6 -6
- package/dist/ui/serverless.html +5 -5
- package/package.json +3 -3
- package/dist/bin/chunk-jpjamjey.js +0 -6935
- package/dist/bin/chunk-m2zwtapr.js +0 -1
- package/dist/bin/chunk-rtczra13.js +0 -1
- package/dist/chunk-01d86gt1.js +0 -1324
- package/dist/chunk-050r7ycy.js +0 -46516
- package/dist/chunk-1c8dbv57.js +0 -7278
- package/dist/chunk-29rse4p1.js +0 -12203
- package/dist/chunk-32e7ya18.js +0 -642
- package/dist/chunk-4cjrg98a.js +0 -597
- package/dist/chunk-50jpda9q.js +0 -371
- package/dist/chunk-6a1t7fnq.js +0 -12121
- package/dist/chunk-728jvrr0.js +0 -1701
- package/dist/chunk-7m60qnc8.js +0 -1762
- package/dist/chunk-aa2dkn7b.js +0 -205
- package/dist/chunk-d48vtdj4.js +0 -433
- package/dist/chunk-f55nkpvb.js +0 -8
- package/dist/chunk-fgk8cqew.js +0 -152
- package/dist/chunk-he9a874b.js +0 -769
- package/dist/chunk-k2yyatfw.js +0 -10
- package/dist/chunk-k4px0bnv.js +0 -23
- package/dist/chunk-nsgqsmrh.js +0 -1779
- package/dist/chunk-q0st3se8.js +0 -42033
- package/dist/chunk-qr803fye.js +0 -2122
- package/dist/chunk-rds0sy87.js +0 -1771
- package/dist/chunk-ttz2ra5j.js +0 -12
- package/dist/chunk-v0bahtg2.js +0 -4
- package/dist/chunk-va2yd85b.js +0 -200
- package/dist/chunk-x9s0cqfx.js +0 -13
- package/dist/chunk-zqtpg06c.js +0 -1752
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{nh as o,oh as n}from"./chunk-
|
|
1
|
+
import{nh as o,oh as n}from"./chunk-rxcvf10f.js";function dj(j,Z){return`/var/www/${j}-${Z}`}var Hj=new Set(["laravel","php","statamic","wordpress"]);function i(j){return j.type!=null&&Hj.has(j.type)}function Yj(j){let Z=j.proxyTo;if(Z==null)return[];return(Array.isArray(Z)?Z:[Z]).map((z)=>String(z).trim()).filter((z)=>z.length>0)}function Fj(j){return Yj(j).length>0}function t(j){if(j.deploy)return j.deploy;if(i(j))return"server";if(j.start)return"server";return"bucket"}function f(j){if(j.redirect)return"redirect";if(Fj(j))return"proxy";if(i(j))return"server-php";if(t(j)==="bucket")return"bucket";return j.start?"server-app":"server-static"}function wj(j){return j.infrastructure?.compute!=null||Boolean(j.cloud?.attachTo?.trim())}function pj(j,Z={}){let $=[],z=[],Q=j.sites||{},W=wj(j),q=n(j);if(q)$.push(q);let H=new Map;for(let[K,X]of Object.entries(Q)){if(!X)continue;let F=t(X),L=f(X);if(L==="redirect"){if(!X.domain)$.push(`Site '${K}' is a redirect site but has no \`domain\` to redirect from.`);if(!(typeof X.redirect==="string"?X.redirect:X.redirect?.to))$.push(`Site '${K}' is a redirect site but has no redirect target (\`redirect\` / \`redirect.to\`).`);if(!W)$.push(`Site '${K}' is a redirect site but no \`infrastructure.compute\` is configured to host the gateway that serves the redirect.`);let J=[];if(X.start)J.push("start");if(X.root)J.push("root");if(X.proxyTo)J.push("proxyTo");if(J.length>0)z.push(`Site '${K}' is a redirect site but also sets ${J.join(", ")}. These are ignored.`);continue}if(L==="proxy"){if(!X.domain)$.push(`Site '${K}' is a proxy site but has no \`domain\` to route from.`);if(!W)$.push(`Site '${K}' is a proxy site but no \`infrastructure.compute\` is configured to host the gateway that forwards it.`);let M=[];if(X.start)M.push("start");if(X.root)M.push("root");if(typeof X.port==="number")M.push("port");if(X.build)M.push("build");if(X.preStart&&X.preStart.length>0)M.push("preStart");if(M.length>0)z.push(`Site '${K}' sets \`proxyTo\`, so ts-cloud ships and supervises nothing for it. ${M.join(", ")} ${M.length===1?"is":"are"} ignored — remove ${M.length===1?"it":"them"}, or drop \`proxyTo\` to let ts-cloud own the service.`);continue}if(F==="server"&&!X.start&&!X.root){$.push(`Site '${K}' sets deploy:'server' but declares neither \`start\` (dynamic app) nor \`root\` (static site to serve). Add one.`);continue}if(L==="server-php"){if(!W)$.push(`Site '${K}' is a PHP site (type:'${X.type}') but no \`infrastructure.compute\` is configured. Add a server (infrastructure.compute) with PHP provisioning.`);if(!X.repository?.url)$.push(`Site '${K}' is a PHP site (type:'${X.type}') but has no \`repository.url\` to clone. PHP sites deploy via git.`)}else if(L==="server-app"){if(!W)$.push(`Site '${K}' deploys to a server (deploy:'server'${X.deploy?"":" inferred from `start`"}) but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`);if(typeof X.port==="number"){let M=Z.occupiedPorts?.get(X.port);if(M)$.push(`Site '${K}' wants port ${X.port}, which project '${M}' already serves on this box. Attached projects share one port namespace. Give '${K}' a free port, or let the attach allocate one.`);let J=H.get(X.port);if(J)$.push(`Sites '${J}' and '${K}' both use port ${X.port}. Server apps sharing a box must use distinct ports.`);else H.set(X.port,K)}}else if(L==="server-static"){if(!X.root)$.push(`Site '${K}' is a server static site (deploy:'server', no \`start\`) but has no \`root\` directory to serve.`);if(!W)$.push(`Site '${K}' deploys to a server (deploy:'server') but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`)}else{if(!X.root)$.push(`Site '${K}' deploys to a bucket but has no \`root\` directory to upload.`);let M=[];if(X.start)M.push("start");if(typeof X.port==="number")M.push("port");if(X.preStart&&X.preStart.length>0)M.push("preStart");if(M.length>0)z.push(`Site '${K}' deploys to a bucket but sets server-only field(s): ${M.join(", ")}. These are ignored. Set deploy:'server' to use them.`)}}return{errors:$,warnings:z}}function rj(j){let Z=f(j);return Z!=="bucket"&&Z!=="redirect"&&Z!=="proxy"}function oj(j){return f(j)==="bucket"}function nj(j,Z){if(o(j)==="serverless")return!0;let $=Object.entries(j.sites??{}).filter(([,Q])=>Q!=null),z=Z?$.filter(([Q])=>Q===Z):$;if(z.length===0)return!0;return!z.every(([,Q])=>{let W=f(Q);return W==="redirect"||W==="proxy"})}var s={php:"php.net",nginx:"nginx.org",composer:"getcomposer.org",mysql:"mysql.com",mariadb:"mariadb.com/server",postgres:"postgresql.org",vitess:"vitess.io",etcd:"etcd.io",redis:"redis.io",memcached:"memcached.org",meilisearch:"meilisearch.com",git:"git-scm.com",certbot:"certbot.eff.org",bun:"bun.sh",node:"nodejs.org",deno:"deno.land"};var y="/opt/pantry";function v(j){return`'${j.split("'").join("'\\''")}'`}function tj(j={}){return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system","export PANTRY_INSTALL_DIR=/usr/local/bin",j.version?`export PANTRY_VERSION=${v(j.version)}`:'export PANTRY_VERSION="${PANTRY_VERSION:-latest}"',"command -v curl >/dev/null 2>&1 || (apt-get update -y && apt-get install -y curl ca-certificates)","command -v unzip >/dev/null 2>&1 || (apt-get update -y && apt-get install -y unzip)",'OS=$(uname -s | tr \'[:upper:]\' \'[:lower:]\'); ARCH=$(uname -m); case "$ARCH" in x86_64|amd64) ARCH=x64 ;; arm64|aarch64) ARCH=arm64 ;; esac; ZIP="pantry-${OS}-${ARCH}.zip"; if [ "${PANTRY_VERSION:-latest}" = latest ]; then REL=\'latest/download\'; else REL="download/v${PANTRY_VERSION}"; fi; TMP=$(mktemp -d); curl -fsSL -o "${TMP}/${ZIP}" "https://github.com/pantry-pm/pantry/releases/${REL}/${ZIP}"; unzip -o "${TMP}/${ZIP}" -d /usr/local/bin; chmod +x /usr/local/bin/pantry; rm -rf "${TMP}"','export PATH="/usr/local/bin:$PATH"',"mkdir -p /opt/pantry"]}function T(){return'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true'}function m(j){if(j.length===0)return[];return[`(cd /opt/pantry && pantry install ${[...new Set(j)].map(v).join(" ")})`]}function a(j){return[...new Set(j)].flatMap((Z)=>[`(cd /opt/pantry && pantry start ${v(Z)})`,`(cd /opt/pantry && pantry enable ${v(Z)})`])}var w=`${y}/pantry/.bin`,h=15306,b=15991,E=15999,e=16101,P=2379,B="/var/lib/vitess",g=100;function Bj(j){return j===!0||typeof j==="object"&&j!==null}function Dj(j){return typeof j==="object"&&j!==null?j:{}}function G(j){return`'${String(j).split("'").join("'\\''")}'`}function Lj(j){let $=[j.version?`vitess.io@${j.version}`:"vitess.io"];if(j.mode!=="combo"&&!j.etcdEndpoint)$.push("etcd.io");return $.push("mysql.com@8.0.43"),$}var Y="vitess",Nj=`${w}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`,zj="/usr/local/lib/vitess",l=new Map;function u(j){return`${zj}/${j}.sh`}function O(j,Z){return l.set(j,Cj(Z)),`/bin/sh ${u(j)}`}function jj(){let j=[`mkdir -p ${zj}`];for(let[Z,$]of l)j.push(`cat > ${u(Z)} <<'TS_CLOUD_VITESS_LAUNCHER_EOF'`,$,"TS_CLOUD_VITESS_LAUNCHER_EOF",`chmod 0755 ${u(Z)}`);return j}function Cj(j){return["#!/bin/sh","set -e",`cd ${y}`,`PANTRY_ENV="$(pantry env 2>/dev/null | grep -E '^(export [A-Za-z_]|[A-Za-z_][A-Za-z0-9_]*=)' || true)"`,'if [ -n "$PANTRY_ENV" ]; then eval "$PANTRY_ENV"; fi',`VT_MYSQL_ROOT="$(dirname "$(dirname "$(readlink -f ${w}/mysqld 2>/dev/null)")")"`,`VTROOT="$(dirname "$(dirname "$(readlink -f ${w}/mysqlctld 2>/dev/null)")")"`,"export VT_MYSQL_ROOT VTROOT",'LD_LIBRARY_PATH="$VT_MYSQL_ROOT/lib:$VTROOT/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"',"export LD_LIBRARY_PATH",`exec ${j.join(" ")}`].join(`
|
|
2
2
|
`)}function V(j){let Z=["[Unit]",`Description=${j.description}`,`After=network.target${j.after?.length?` ${j.after.join(" ")}`:""}`];if(j.requires?.length)Z.push(`Requires=${j.requires.join(" ")}`);return Z.push("","[Service]","Type=simple",`User=${Y}`,`Group=${Y}`,`Environment="PATH=${Nj}"`,`Environment="VTDATAROOT=${B}"`,...Object.entries(j.environment??{}).map(([$,z])=>`Environment="${$}=${z}"`),...(j.execStartPre??[]).map(($)=>`ExecStartPre=${$}`),`ExecStart=${j.execStart}`,"Restart=always","RestartSec=5","LimitNOFILE=65535","","[Install]","WantedBy=multi-user.target"),Z.join(`
|
|
3
3
|
`)}function Zj(j,Z){return[`cat > /etc/systemd/system/${j}.service <<'TS_CLOUD_VITESS_UNIT_EOF'`,Z,"TS_CLOUD_VITESS_UNIT_EOF"]}function Oj(j){let Z=j.cell??"zone1",$=j.vtgatePort??h,Q=`${((j.keyspaces?.length)?j.keyspaces:[{name:"app"}]).map((W)=>{let q=(W.sharded?["-80","80-"]:["0"]).map((H)=>`shards:{name:"${H}"}`).join(" ");return`keyspaces:{name:"${W.name}" ${q}}`}).join(" ")} cells:"${Z}"`;return V({description:"Vitess (vtcombo, single-process development stack)",execStart:O("vtcombo",[`${w}/vtcombo`,`--cell ${Z}`,`--proto-topo ${G(Q)}`,`--mysql-server-port ${$}`,"--mysql-server-bind-address 127.0.0.1","--mysql-auth-server-impl none","--start-mysql",`--port ${b}`,`--grpc-port ${E}`])})}function Vj(){return V({description:"etcd (Vitess topology store)",execStart:O("etcd",[`${w}/etcd`,`--data-dir ${B}/etcd`,`--listen-client-urls http://127.0.0.1:${P}`,`--advertise-client-urls http://127.0.0.1:${P}`]),execStartPre:[`+/bin/mkdir -p ${B}/etcd`,`+/bin/chown ${Y}:${Y} ${B}/etcd`]})}function c(j){return["--topo-implementation etcd2",`--topo-global-server-address ${j.etcdEndpoint??`http://127.0.0.1:${P}`}`,"--topo-global-root /vitess/global"]}function Uj(j){let Z=!j.etcdEndpoint;return V({description:"Vitess vtctld (control plane)",after:Z?["vitess-etcd.service"]:[],requires:Z?["vitess-etcd.service"]:[],execStart:O("vtctld",[`${w}/vtctld`,...c(j),`--cell ${j.cell??"zone1"}`,"--service-map grpc-vtctl,grpc-vtctld",`--grpc-port ${E}`,`--port ${E+1}`])})}function Aj(j,Z,$){let z=j.cell??"zone1";return V({description:`Vitess vttablet (${Z}/${$})`,after:["vitess-vtctld.service","vitess-mysqlctld.service"],requires:["vitess-mysqlctld.service"],execStart:O("vttablet",[`${w}/vttablet`,...c(j),`--tablet-path ${z}-${String(g).padStart(10,"0")}`,`--init-keyspace ${Z}`,`--init-shard ${$}`,"--init-tablet-type replica",`--service-map ${G("grpc-queryservice,grpc-tabletmanager,grpc-updatestream")}`,`--port ${e}`,`--grpc-port ${e+1}`,`--db-port ${j.mysqlPort??3306}`,`--mycnf-mysql-port ${j.mysqlPort??3306}`])})}function kj(j){return V({description:"Vitess mysqlctld (managed mysqld)",execStart:O("mysqlctld",[`${w}/mysqlctld`,`--tablet-uid ${g}`,`--mysql-port ${j.mysqlPort??3306}`,'--init-db-sql-file "$VTROOT/config/init_db.sql"',"--wait-time 2m"]),execStartPre:[`+/bin/mkdir -p ${B}`,`+/bin/chown ${Y}:${Y} ${B}`]})}var Wj="/etc/vitess/auth.json",A="/var/lib/vitess/vtgate-auth.sha256";function Rj(j){let Z=j.username??"vitess",$=j.password??"";return["mkdir -p /etc/vitess",'VTESS_AUTH_TMP="$(mktemp)"',`cat > "$VTESS_AUTH_TMP" <<'TS_CLOUD_VITESS_AUTH_EOF'`,JSON.stringify({[Z]:[{Password:$,UserData:Z}]}),"TS_CLOUD_VITESS_AUTH_EOF",`VTESS_VTGATE_AUTH_SHA="$(sha256sum "$VTESS_AUTH_TMP" | awk '{print $1}')"`,"VTESS_VTGATE_AUTH_CHANGED=1",`if [ -f ${A} ] && [ "$(cat ${A})" = "$VTESS_VTGATE_AUTH_SHA" ]; then VTESS_VTGATE_AUTH_CHANGED=0; fi`,`install -o ${Y} -g ${Y} -m 0600 "$VTESS_AUTH_TMP" ${Wj}`,'rm -f "$VTESS_AUTH_TMP"']}function Ij(j){let Z=j.cell??"zone1";return V({description:"Vitess vtgate (query router)",after:["vitess-vtctld.service"],execStart:O("vtgate",[`${w}/vtgate`,...c(j),`--cell ${Z}`,`--cells-to-watch ${Z}`,"--tablet-types-to-wait PRIMARY,REPLICA",`--service-map ${G("grpc-vtgateservice")}`,`--mysql-server-port ${j.vtgatePort??h}`,`--mysql-server-bind-address ${j.bindAddress??"127.0.0.1"}`,"--mysql-auth-server-impl static",`--mysql-auth-server-static-file ${Wj}`,`--port ${b}`,`--grpc-port ${b+1}`])})}function fj(j){let Z=j.cell??"zone1",$=j.etcdEndpoint??`http://127.0.0.1:${P}`,z=`${w}/vtctldclient --server 127.0.0.1:${E}`,Q=[`for i in $(seq 1 30); do ${z} GetCellInfoNames >/dev/null 2>&1 && break; sleep 2; done`,`if ! ${z} GetCellInfoNames 2>/dev/null | grep -qx ${G(Z)}; then`,` ${z} AddCellInfo --root ${G(`/vitess/${Z}`)} --server-address ${G($)} ${G(Z)}`,"fi"];for(let W of j.keyspaces??[]){let q=W.sharded?" --sharded":"";Q.push(`if ! ${z} GetKeyspace ${G(W.name)} >/dev/null 2>&1; then`,` ${z} CreateKeyspace${q} ${G(W.name)}`,"fi");let H=`${Z}-${String(g).padStart(10,"0")}`;for(let K of W.sharded?["-80","80-"]:["0"]){let X=`${W.name}/${K}`;Q.push("for i in $(seq 1 90); do",` if ${z} GetShard ${G(X)} 2>/dev/null | grep -q '"is_primary_serving": *true'; then break; fi`,` ${z} PlannedReparentShard ${G(X)} --new-primary ${G(H)} >/dev/null 2>&1 && break`,` ${z} InitShardPrimary --force ${G(X)} ${G(H)} >/dev/null 2>&1 && break`," sleep 2","done",`if ! ${z} GetShard ${G(X)} 2>/dev/null | grep -q '"is_primary_serving": *true'; then`,` echo "no primary could be elected for ${X}" >&2; exit 1`,"fi")}Q.push(`${z} RebuildKeyspaceGraph ${G(W.name)} >/dev/null`)}return Q}function $j(j){let Z=j.vtgatePort??h;return["for i in $(seq 1 60); do",` if (cd ${y} && eval "$(pantry env 2>/dev/null)"; MYSQL_PWD=${G(j.password??"")} ${w}/mysql -h 127.0.0.1 -P ${Z} -u ${G(j.username??"vitess")} --connect-timeout=2 -e 'SHOW KEYSPACES') >/dev/null 2>&1; then`,` echo "vtgate is serving on ${Z}"; exit 0`," fi"," sleep 2","done",`echo "vtgate did not become ready on port ${Z}" >&2`,"exit 1"]}function Xj(j){if(!Bj(j))return[];let Z=Dj(j),$=Z.mode==="combo";l.clear();let z=[...m(Lj(Z)),`VT_MYSQL_LIB="$(dirname "$(dirname "$(readlink -f ${w}/mysqld)")")/lib"`,'if [ -d "$VT_MYSQL_LIB" ]; then',` printf '%s\\n' "$VT_MYSQL_LIB" > /etc/ld.so.conf.d/vitess-mysql.conf`," ldconfig","else",' echo "mysqld library directory not found under $VT_MYSQL_LIB" >&2; exit 1',"fi",`id -u ${Y} >/dev/null 2>&1 || useradd --system --home-dir ${B} --shell /usr/sbin/nologin ${Y}`,`mkdir -p ${B}`,`chown -R ${Y}:${Y} ${B}`];if($)return z.push(...Zj("vitess-vtcombo",Oj(Z)),...jj(),"systemctl daemon-reload","systemctl enable --now vitess-vtcombo.service",...$j(Z)),z;z.push(...Rj(Z));let Q=[];if(!Z.etcdEndpoint)Q.push(["vitess-etcd",Vj()]);Q.push(["vitess-vtctld",Uj(Z)],["vitess-mysqlctld",kj(Z)],["vitess-vtgate",Ij(Z)]);for(let W of Z.keyspaces??[])for(let q of W.sharded?["-80","80-"]:["0"])Q.push([`vitess-vttablet-${W.name}-${q.replace(/-/g,"x")}`,Aj(Z,W.name,q)]);for(let[W,q]of Q)z.push(...Zj(W,q));z.push(...jj()),z.push("systemctl daemon-reload");for(let[W]of Q)z.push(`systemctl enable --now ${W}.service`);return z.push(`if [ "$VTESS_VTGATE_AUTH_CHANGED" = 1 ]; then systemctl restart vitess-vtgate.service; printf '%s\\n' "$VTESS_VTGATE_AUTH_SHA" > ${A}; chown ${Y}:${Y} ${A}; chmod 0600 ${A}; fi`,...fj(Z),...$j(Z)),z}var vj=new Set(["singlestore","vitess"]);function Jj(j){if(j?.engine&&vj.has(j.engine))return!1;return!j?.host||j.host==="127.0.0.1"||j.host==="localhost"}function d(j,Z="psql"){let $=j?.port??5432;if(Jj(j))return`${Z} -p ${$} -U postgres`;let z=j?.username||"postgres";return`${j?.password?`PGPASSWORD='${j.password.replace(/'/g,"'\\''")}' `:""}${Z} -h ${j.host} -p ${$} -U ${z} -w`}function D(j){return j===!0||typeof j==="object"&&j!=null}function yj(j){let Z=[],$=[];if(D(j.mysql))Z.push(typeof j.mysql==="object"&&j.mysql.version?`mysql.com@${j.mysql.version}`:"mysql.com@8.0.43"),$.push("mysql");else if(D(j.mariadb))Z.push(s.mariadb),$.push("mariadb");if(D(j.postgres))Z.push("postgresql.org"),$.push("postgres");if(D(j.redis))Z.push("redis.io"),$.push("redis");if(D(j.memcached))Z.push("memcached.org"),$.push("memcached");if(D(j.meilisearch))Z.push("meilisearch.com"),$.push("meilisearch");return{packages:Z,services:$}}function $Z(j={},Z={}){let $=yj(j),z=Xj(j.vitess);if($.packages.length===0)return z;return[...m($.packages),...a($.services),...z]}function zZ(j,Z={}){if(!j?.name)return[];if(!Jj(j))return[];let $=j.name,z=j.username||$,Q=j.password||"",W=D(Z.postgres)||j.engine==="postgres",q=D(Z.mariadb)||j.engine==="mariadb",H=D(Z.mysql)||j.engine==="mysql";if(W&&!H&&!q){let J=(x)=>`"${x.replace(/"/g,'""')}"`,C=(x)=>`'${x.replace(/'/g,"''")}'`,U=(x,I)=>["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${C(x)}) THEN`,` CREATE ROLE ${J(x)} LOGIN PASSWORD ${C(I)};`," ELSE",` ALTER ROLE ${J(x)} LOGIN PASSWORD ${C(I)};`," END IF;","END $$;"],k=(x)=>{let I=x.databases&&x.databases.length>0?x.databases:[$],_=[];for(let S of I)if(x.access==="readonly")_.push(`GRANT CONNECT ON DATABASE ${J(S)} TO ${J(x.username)};`,`\\connect ${J(S)}`,`GRANT USAGE ON SCHEMA public TO ${J(x.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${J(x.username)};`,`ALTER DEFAULT PRIVILEGES FOR ROLE ${J(z)} IN SCHEMA public GRANT SELECT ON TABLES TO ${J(x.username)};`,"\\connect postgres");else _.push(`GRANT ALL PRIVILEGES ON DATABASE ${J(S)} TO ${J(x.username)};`);return _},R=j.users||[],Gj=j.port??5432;return[T(),`for i in $(seq 1 30); do pg_isready -p ${Gj} -q && break; sleep 2; done`,`${d(j)} <<'TS_CLOUD_PG_EOF'`,...U(z,Q),`SELECT 'CREATE DATABASE ${J($)} OWNER ${J(z)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${C($)})\\gexec`,...R.flatMap((x)=>[...U(x.username,x.password),...k(x)]),"TS_CLOUD_PG_EOF"]}let K=q?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",X=(J)=>J.replace(/`/g,"``"),F=(J)=>J.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),L=(J)=>{let C=J.databases&&J.databases.length>0?J.databases:[$],U=J.access==="readonly"?"SELECT":"ALL PRIVILEGES",k=[`CREATE USER IF NOT EXISTS '${F(J.username)}'@'%' IDENTIFIED BY '${F(J.password)}';`,`CREATE USER IF NOT EXISTS '${F(J.username)}'@'localhost' IDENTIFIED BY '${F(J.password)}';`,`ALTER USER '${F(J.username)}'@'%' IDENTIFIED BY '${F(J.password)}';`,`ALTER USER '${F(J.username)}'@'localhost' IDENTIFIED BY '${F(J.password)}';`];for(let R of C)k.push(`GRANT ${U} ON \`${X(R)}\`.* TO '${F(J.username)}'@'%';`,`GRANT ${U} ON \`${X(R)}\`.* TO '${F(J.username)}'@'localhost';`);return k},M=j.users||[];return[T(),`for i in $(seq 1 30); do mysqladmin --socket=${K} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${K} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${X($)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...L({username:z,password:Q}),...M.flatMap(L),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}function WZ(j){if(!j?.name)return{};let Z=j.engine==="singlestore",$=j.engine==="vitess",z=j.engine==="postgres"?"pgsql":Z?"singlestore":$?"vitess":"mysql",Q=j.port??(j.engine==="postgres"?5432:$?15306:3306),W={DB_CONNECTION:z,DB_HOST:j.host||"127.0.0.1",DB_PORT:String(Q),DB_DATABASE:j.name};if(j.username)W.DB_USERNAME=j.username;if(j.password)W.DB_PASSWORD=j.password;if((Z||$)&&j.ssl!==!1)W.DB_SSL="true";return W}var r="/var/backups/ts-cloud",mj="/etc/ts-cloud/backups.config.ts",Qj="/etc/cron.d/ts-cloud-backups",p="/usr/local/bin/ts-cloud-backup.sh";function Ej(j){if(!j.name)return null;let Z=j.host||"127.0.0.1",$=j.engine==="postgres",z=$?"postgresql":"mysql",Q=j.port??($?5432:3306),W=(q)=>q.replace(/\\/g,"\\\\").replace(/'/g,"\\'");return[" {",` type: '${z}',`,` name: '${W(j.name)}',`," connection: {",` hostname: '${W(Z)}',`,` port: ${Q},`,` database: '${W(j.name)}',`,` username: '${W(j.username||j.name)}',`,` password: '${W(j.password||"")}',`," ssl: false,"," },"," includeSchema: true,"," includeData: true,"," },"].join(`
|
|
4
4
|
`)}function Pj(j,Z){let $=j?Ej(j):null,z=Z.bucket?[" destinations: ["," {"," type: 's3',",` bucket: '${Z.bucket}',`," prefix: 'db-backups',",...Z.endpoint?[` endpoint: '${Z.endpoint}',`]:[]," optional: false,"," },"," ],"]:[];return["import type { BackupConfig } from 'ts-backups'","","const config: BackupConfig = {"," verbose: true,",` outputPath: '${r}',`," retention: {",` count: ${Z.retentionCount??5},`,` maxAge: ${Z.retentionDays??30},`," },"," databases: [",...$?[$]:[]," ],",...z,"}","","export default config",""].join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ng as I}from"./chunk-
|
|
1
|
+
import{ng as I}from"./chunk-etrb03mt.js";var _=(e)=>e==null?void 0:String(e),b=(e)=>Number(e)===1,y=(e,r)=>{try{return e==null?r:JSON.parse(String(e))}catch{return r}};function C(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),scope:{type:String(e.scope_type),id:String(e.scope_id),environmentId:_(e.environment_id),resourceId:_(e.resource_id),previewId:_(e.preview_id)},key:String(e.key),kind:String(e.kind),value:_(e.value),valueFingerprint:String(e.value_fingerprint),secretRef:_(e.secret_ref),backend:String(e.backend),backendVersion:_(e.backend_version),origin:String(e.origin),required:b(e.required),metadata:y(e.metadata,{}),lastUsedAt:_(e.last_used_at),rotatedAt:_(e.rotated_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function R(e){return{entryId:String(e.entry_id),resourceId:String(e.resource_id),injectionTarget:String(e.injection_target),required:b(e.required),requiresRedeploy:b(e.requires_redeploy),lastDeployedVersion:e.last_deployed_version==null?void 0:Number(e.last_deployed_version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}class q{controlPlane;now;constructor(e,r=()=>new Date){this.controlPlane=e;this.now=r}get(e){let r=this.controlPlane.database.query("SELECT * FROM configuration_entries WHERE id=?").get(e);return r?C(r):void 0}find(e,r,o){let t=this.controlPlane.database.query("SELECT * FROM configuration_entries WHERE project_id=? AND scope_type=? AND scope_id=? AND key=?").get(e,r.type,r.id,o);return t?C(t):void 0}list(e){let r=["project_id=?"],o=[e.projectId];if(e.scope)r.push("scope_type=?","scope_id=?"),o.push(e.scope.type,e.scope.id);if(e.kind)r.push("kind=?"),o.push(e.kind);return this.controlPlane.database.query(`SELECT * FROM configuration_entries WHERE ${r.join(" AND ")} ORDER BY key,scope_type,scope_id`).all(...o).map(C)}create(e){this.validateScope(e),this.validateEntry(e);let r=crypto.randomUUID(),o=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO configuration_entries (id,organization_id,project_id,scope_type,scope_id,environment_id,resource_id,preview_id,key,kind,value,value_fingerprint,secret_ref,backend,backend_version,origin,required,metadata,last_used_at,rotated_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.organizationId,e.projectId,e.scope.type,e.scope.id,e.scope.environmentId??null,e.scope.resourceId??null,e.scope.previewId??null,e.key,e.kind,e.value??null,e.valueFingerprint,e.secretRef??null,e.backend,e.backendVersion??null,e.origin,e.required?1:0,JSON.stringify(e.metadata),e.lastUsedAt??null,e.rotatedAt??null,1,o,o]),this.get(r)}update(e,r,o){let t=this.get(e);if(!t)throw Error("Configuration entry was not found.");if(this.validateEntry({...t,...o}),this.controlPlane.database.run("UPDATE configuration_entries SET value=?,value_fingerprint=?,secret_ref=?,backend=?,backend_version=?,required=?,metadata=?,rotated_at=?,version=version+1,updated_at=? WHERE id=? AND version=?",[o.value??null,o.valueFingerprint,o.secretRef??null,o.backend,o.backendVersion??null,o.required?1:0,JSON.stringify(o.metadata),o.rotatedAt??null,this.now().toISOString(),e,r]).changes!==1)throw Error("Configuration entry changed; refresh and retry.");return this.get(e)}remove(e,r){let o=this.get(e);if(!o)throw Error("Configuration entry was not found.");if(o.version!==r)throw Error("Configuration entry changed; refresh and retry.");if(this.controlPlane.database.run("DELETE FROM configuration_entries WHERE id=? AND version=?",[e,r]).changes<1)throw Error("Configuration entry changed; refresh and retry.");return o}setDependency(e){let r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO configuration_dependencies (entry_id,resource_id,injection_target,required,requires_redeploy,last_deployed_version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?) ON CONFLICT(entry_id,resource_id) DO UPDATE SET injection_target=excluded.injection_target,required=excluded.required,requires_redeploy=excluded.requires_redeploy,last_deployed_version=excluded.last_deployed_version,updated_at=excluded.updated_at",[e.entryId,e.resourceId,e.injectionTarget,e.required?1:0,e.requiresRedeploy?1:0,e.lastDeployedVersion??null,r,r]),this.dependencies(e.entryId).find((o)=>o.resourceId===e.resourceId)}dependencies(e){return this.controlPlane.database.query("SELECT * FROM configuration_dependencies WHERE entry_id=? ORDER BY resource_id").all(e).map(R)}dependenciesForResource(e){return this.controlPlane.database.query("SELECT * FROM configuration_dependencies WHERE resource_id=? ORDER BY entry_id").all(e).map(R)}mutation(e){let r=this.controlPlane.database.query("SELECT request_hash,result FROM configuration_mutations WHERE idempotency_key=?").get(e);return r?{requestHash:r.request_hash,result:y(r.result,{})}:void 0}recordMutation(e){this.controlPlane.database.run("INSERT INTO configuration_mutations (id,project_id,idempotency_key,request_hash,result,actor_id,created_at) VALUES (?,?,?,?,?,?,?)",[crypto.randomUUID(),e.projectId,e.idempotencyKey,e.requestHash,JSON.stringify(e.result),e.actorId??null,this.now().toISOString()])}validateEntry(e){if(!/^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(e.key))throw Error(`Invalid configuration key: ${e.key}`);if(e.kind==="variable"&&(e.value==null||e.secretRef||e.backend!=="plaintext"))throw Error("Variables require a plaintext value and cannot use a secret backend.");if(e.kind==="secret"&&(e.value!=null||!e.secretRef||e.backend==="plaintext"))throw Error("Secrets require a non-plaintext backend reference and cannot store a plaintext value.")}validateScope(e){let r=this.controlPlane.getProject(e.projectId);if(!r||r.organizationId!==e.organizationId)throw Error("Configuration project does not belong to the organization.");let o=e.scope;if(o.type==="project"){if(o.id!==e.projectId||o.environmentId||o.resourceId||o.previewId)throw Error("Project configuration scope must reference only its project.");return}if(o.type==="environment"){let n=this.controlPlane.database.query("SELECT project_id FROM environments WHERE id=?").get(o.id);if(!n||n.project_id!==e.projectId||o.environmentId&&o.environmentId!==o.id||o.resourceId||o.previewId)throw Error("Environment configuration scope does not belong to the project.");return}if(o.type==="service"||o.type==="function"){let n=this.controlPlane.getResource(o.id);if(!n||n.projectId!==e.projectId||o.type==="function"&&n.kind!=="function"||o.resourceId&&o.resourceId!==o.id||o.environmentId&&n.environmentId!==o.environmentId||o.previewId)throw Error(`${o.type==="function"?"Function":"Service"} configuration scope does not belong to the project.`);return}let t=this.controlPlane.database.query("SELECT project_id,base_environment_id,resource_id FROM preview_instances WHERE id=?").get(o.id);if(!t||t.project_id!==e.projectId||o.previewId&&o.previewId!==o.id||o.environmentId&&o.environmentId!==t.base_environment_id||o.resourceId&&o.resourceId!==t.resource_id)throw Error("Preview configuration scope does not belong to the project.")}}var P=/^[A-Za-z_][A-Za-z0-9_]{0,255}$/;function O(e){let r={n:`
|
|
2
2
|
`,r:"\r",t:"\t","\\":"\\",'"':'"',$:"$"};return e.replace(/\\(n|r|t|\\|"|\$)/g,(o,t)=>r[t])}function x(e){let r={},o=[],t=e.replace(/\r\n?/g,`
|
|
3
3
|
`).split(`
|
|
4
4
|
`);for(let n=0;n<t.length;n++){let s=n+1,c=t[n];if(!c.trim()||c.trimStart().startsWith("#"))continue;if(/^\s*export\s+/.test(c))c=c.replace(/^\s*export\s+/,"");let l=c.match(/^\s*([^=\s]+)\s*=\s*(.*)$/);if(!l){o.push({line:s,severity:"error",code:"invalid_line",message:"Expected KEY=VALUE."});continue}let i=l[1],a=l[2];if(!P.test(i)){o.push({line:s,key:i,severity:"error",code:"invalid_key",message:`Invalid environment variable name: ${i}`});continue}let d=a;if(a.startsWith('"')||a.startsWith("'")){let g=a[0],f=[a.slice(1)],S=!1;while(!0){let m=f[f.length-1],h=!1,E=-1;for(let u=0;u<m.length;u++){if(g==='"'&&m[u]==="\\"&&!h){h=!0;continue}if(m[u]===g&&!h){E=u;break}h=!1}if(E>=0){f[f.length-1]=m.slice(0,E),S=!0;break}if(++n>=t.length)break;f.push(t[n])}if(!S){o.push({line:s,key:i,severity:"error",code:"unterminated_quote",message:`Unterminated quoted value for ${i}.`});continue}if(d=f.join(`
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{yd as Wg}from"./chunk-4vrqm9h0.js";import{Jd as Zg,Od as $g}from"./chunk-3r4fb59r.js";import{Rd as xg}from"./chunk-p66ptpmr.js";import{Tf as Yg}from"./chunk-axhnkn5g.js";import{Uf as Og}from"./chunk-h5pa5men.js";import{$f as s,_f as c}from"./chunk-fy8j3y8p.js";import{Og as Q,Pg as gg}from"./chunk-fpm59y25.js";import{Gh as Xg,Un as Bg}from"./chunk-jpjamjey.js";class r{client;region;constructor(g="us-east-1",T){this.region=g,this.client=new Q(c(T))}async query(g){let T=new URLSearchParams(gg({Version:"2010-08-01",...g})).toString();return this.client.request({service:"monitoring",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:T})}async getMetricStatistics(g){let T={Action:"GetMetricStatistics",Namespace:g.Namespace,MetricName:g.MetricName,StartTime:g.StartTime.toISOString(),EndTime:g.EndTime.toISOString(),Period:g.Period};(g.Statistics??[]).forEach((P,Y)=>{T[`Statistics.member.${Y+1}`]=P}),(g.ExtendedStatistics??[]).forEach((P,Y)=>{T[`ExtendedStatistics.member.${Y+1}`]=P}),(g.Dimensions??[]).forEach((P,Y)=>{T[`Dimensions.member.${Y+1}.Name`]=P.Name,T[`Dimensions.member.${Y+1}.Value`]=P.Value});let N=await this.query(T),L=(N.GetMetricStatisticsResult||N)?.Datapoints?.member??[];if(!Array.isArray(L))L=L?[L]:[];return L.map((P)=>{let Y={},X=P.ExtendedStatistics?.entry;if(X){if(!Array.isArray(X))X=[X];for(let Z of X)if(Z?.key!=null)Y[Z.key]=Number(Z.value)}return{Timestamp:P.Timestamp,Sum:P.Sum!=null?Number(P.Sum):void 0,Average:P.Average!=null?Number(P.Average):void 0,Maximum:P.Maximum!=null?Number(P.Maximum):void 0,Minimum:P.Minimum!=null?Number(P.Minimum):void 0,Percentiles:Object.keys(Y).length?Y:void 0,Unit:P.Unit}})}async getMetricSeries(g){let T=/^p\d/.test(g.Stat);return(await this.getMetricStatistics({Namespace:g.Namespace,MetricName:g.MetricName,Dimensions:g.Dimensions,StartTime:g.StartTime,EndTime:g.EndTime,Period:g.Period,Statistics:T?[]:[g.Stat],ExtendedStatistics:T?[g.Stat]:[]})).slice().sort((z,L)=>new Date(z.Timestamp??0).getTime()-new Date(L.Timestamp??0).getTime()).map((z)=>T?z.Percentiles?.[g.Stat]??0:z[g.Stat]??0)}async describeAlarms(g){let T={Action:"DescribeAlarms"};if(g?.AlarmNamePrefix)T.AlarmNamePrefix=g.AlarmNamePrefix;if(g?.MaxRecords)T.MaxRecords=g.MaxRecords;let N=await this.query(T),L=(N.DescribeAlarmsResult||N)?.MetricAlarms?.member??[];if(!Array.isArray(L))L=L?[L]:[];return L.map((P)=>({AlarmName:P.AlarmName,StateValue:P.StateValue,MetricName:P.MetricName,ComparisonOperator:P.ComparisonOperator,Threshold:P.Threshold!=null?Number(P.Threshold):void 0,Namespace:P.Namespace}))}async putMetricAlarm(g){let T={Action:"PutMetricAlarm",AlarmName:g.AlarmName,Namespace:g.Namespace,MetricName:g.MetricName,ComparisonOperator:g.ComparisonOperator,Threshold:g.Threshold,EvaluationPeriods:g.EvaluationPeriods,Period:g.Period,Statistic:g.Statistic};if(g.AlarmDescription)T.AlarmDescription=g.AlarmDescription;(g.Dimensions??[]).forEach((N,z)=>{T[`Dimensions.member.${z+1}.Name`]=N.Name,T[`Dimensions.member.${z+1}.Value`]=N.Value}),(g.AlarmActions??[]).forEach((N,z)=>{T[`AlarmActions.member.${z+1}`]=N}),await this.query(T)}async deleteAlarms(g){if(!g.length)return;let T={Action:"DeleteAlarms"};g.forEach((N,z)=>{T[`AlarmNames.member.${z+1}`]=N}),await this.query(T)}}class a{client;region;constructor(g="us-east-1",T){this.region=g,this.client=new Q(void 0,{profile:T})}async createLogGroup(g,T){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.CreateLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:g,...T?{tags:T}:{}})})}async putRetentionPolicy(g,T){if(![1,3,5,7,14,30,60,90,120,150,180,365,400,545,731,1096,1827,2192,2557,2922,3288,3653].includes(T))throw Error("Unsupported CloudWatch Logs retention period");await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.PutRetentionPolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:g,retentionInDays:T})})}async describeLogStreams(g){let T={logGroupName:g.logGroupName};if(g.logStreamNamePrefix)T.logStreamNamePrefix=g.logStreamNamePrefix;if(g.orderBy)T.orderBy=g.orderBy;if(g.descending!==void 0)T.descending=g.descending;if(g.limit)T.limit=g.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogStreams","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}async getLogEvents(g){let T={logGroupName:g.logGroupName,logStreamName:g.logStreamName};if(g.startTime)T.startTime=g.startTime;if(g.endTime)T.endTime=g.endTime;if(g.limit)T.limit=g.limit;if(g.startFromHead!==void 0)T.startFromHead=g.startFromHead;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.GetLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}async describeLogGroups(g){let T={};if(g?.logGroupNamePrefix)T.logGroupNamePrefix=g.logGroupNamePrefix;if(g?.limit)T.limit=g.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogGroups","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}async deleteLogGroup(g){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DeleteLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:g})})}async filterLogEvents(g){let T={logGroupName:g.logGroupName};if(g.logStreamNames)T.logStreamNames=g.logStreamNames;if(g.startTime)T.startTime=g.startTime;if(g.endTime)T.endTime=g.endTime;if(g.filterPattern)T.filterPattern=g.filterPattern;if(g.limit)T.limit=g.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.FilterLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}}import{createHash as jg}from"node:crypto";import{existsSync as Tg,mkdirSync as Vg,readdirSync as Hg,readFileSync as Ug,rmSync as Kg,writeFileSync as Eg}from"node:fs";import{homedir as Qg}from"node:os";import{join as m}from"node:path";var Ng=1,Lg=3600000,Rg=24*Lg,Fg=Lg,qg=30*Rg;function i(){let g=process.env.XDG_CACHE_HOME;return m(g&&g.trim()?g:m(Qg(),".cache"),"ts-cloud","cost-explorer")}function f(g){return m(i(),g??"__default__")}function Gg(g){let T={s:g.start,e:g.end,g:g.granularity,m:[...g.metrics].sort(),gb:[...g.groupBy].map((N)=>`${N.Type}:${N.Key}`).sort(),f:g.filter??null};return jg("sha256").update(JSON.stringify(T)).digest("hex").slice(0,24)}function Ag(g,T){let N=Date.parse(`${T}T00:00:00Z`);if(Number.isNaN(N))return!1;let z=new Date,L=Date.UTC(z.getUTCFullYear(),z.getUTCMonth(),1);return N<=L}function Sg(g){return Ag(g.start,g.end)?qg:Fg}function zg(g,T){let N=m(f(g),`${Gg(T)}.json`);if(!Tg(N))return null;let z;try{z=JSON.parse(Ug(N,"utf-8"))}catch{return null}if(z.schema!==Ng)return null;let L=Date.now()-z.savedAt;if(L<0||L>Sg(T))return null;return{response:z.response,ageSeconds:Math.floor(L/1000)}}function Jg(g,T,N){let z=f(g);Vg(z,{recursive:!0});let L={schema:Ng,savedAt:Date.now(),key:T,response:N};Eg(m(z,`${Gg(T)}.json`),JSON.stringify(L))}function wg(g){let T=g===void 0?i():f(g);if(!Tg(T))return{deletedFiles:0,scope:g??"all profiles"};let N=0;function z(L){for(let P of Hg(L,{withFileTypes:!0})){let Y=m(L,P.name);if(P.isDirectory())z(Y);else if(P.isFile()&&P.name.endsWith(".json"))N++}}return z(T),Kg(T,{recursive:!0,force:!0}),{deletedFiles:N,scope:g??"all profiles"}}function vg(g){return g===void 0?i():f(g)}class e{client;profile;useCache;lastCacheAgeSeconds=null;constructor(g,T){this.profile=g,this.useCache=T?.useCache??!0,this.client=new Q(c(g))}async getCostByService(g){return(await this.getCostByDimension({...g,dimension:"SERVICE"})).map((N)=>({service:N.key,amount:N.amount,unit:N.unit}))}async getCostByDimension(g){let{start:T,end:N,dimension:z,granularity:L="MONTHLY",filter:P}=g,Y=["UnblendedCost"],X=[{Type:"DIMENSION",Key:z}],Z={start:T,end:N,granularity:L,metrics:Y,groupBy:X,filter:P};if(this.useCache){let U=zg(this.profile,Z);if(U)return this.lastCacheAgeSeconds=U.ageSeconds,U.response}this.lastCacheAgeSeconds=null;let W=new Map,G;do{let U={TimePeriod:{Start:T,End:N},Granularity:L,Metrics:Y,GroupBy:X};if(P)U.Filter=P;if(G)U.NextPageToken=G;let S=await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify(U)});for(let v of S?.ResultsByTime??[])for(let K of v?.Groups??[]){let C=K.Keys?.[0]??"Unknown",u=Number.parseFloat(K.Metrics?.UnblendedCost?.Amount??"0"),l=K.Metrics?.UnblendedCost?.Unit??"USD",_=W.get(C);W.set(C,{key:C,amount:(_?.amount??0)+u,unit:l})}G=S?.NextPageToken||void 0}while(G);let b=[...W.values()].filter((U)=>U.amount>0).sort((U,S)=>S.amount-U.amount);if(this.useCache)Jg(this.profile,Z,b);return b}async getDailyTotals(g){return((await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify({TimePeriod:{Start:g.start,End:g.end},Granularity:"DAILY",Metrics:["UnblendedCost"]})}))?.ResultsByTime??[]).map((z)=>Number.parseFloat(z.Total?.UnblendedCost?.Amount??"0"))}}class p{client;region;constructor(g="us-east-1"){this.region=g,this.client=new Q}async describeFileSystems(g){let T=[];if(g?.FileSystemId)T.push(`FileSystemId=${encodeURIComponent(g.FileSystemId)}`);if(g?.CreationToken)T.push(`CreationToken=${encodeURIComponent(g.CreationToken)}`);let N=`/2015-02-01/file-systems${T.length>0?`?${T.join("&")}`:""}`;return{FileSystems:((await this.client.request({service:"elasticfilesystem",region:this.region,method:"GET",path:N,headers:{"Content-Type":"application/json"}})).FileSystems||[]).map((L)=>({FileSystemId:L.FileSystemId,Name:L.Name,CreationTime:L.CreationTime,LifeCycleState:L.LifeCycleState,NumberOfMountTargets:L.NumberOfMountTargets,SizeInBytes:L.SizeInBytes?{Value:L.SizeInBytes.Value,Timestamp:L.SizeInBytes.Timestamp}:void 0,PerformanceMode:L.PerformanceMode,Encrypted:L.Encrypted,ThroughputMode:L.ThroughputMode,Tags:L.Tags}))}}}class t{client;region;constructor(g="us-east-1"){this.region=g,this.client=new Q}async call(g,T){return this.client.request({service:"wafv2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSWAF_20190729.${g}`},body:JSON.stringify(T)})}async listWebACLs(g="REGIONAL"){return(await this.call("ListWebACLs",{Scope:g,Limit:100}))?.WebACLs??[]}async getWebACLRules(g,T,N="REGIONAL"){return((await this.call("GetWebACL",{Name:g,Id:T,Scope:N}))?.WebACL?.Rules??[]).map((P)=>({Name:P.Name,Priority:P.Priority,Action:P.Action?Object.keys(P.Action)[0]:P.OverrideAction?Object.keys(P.OverrideAction)[0]:"count"}))}}function Pg(g){return String(g).padStart(2,"0")}function y(g){return`${g.getUTCFullYear()}-${Pg(g.getUTCMonth()+1)}-${Pg(g.getUTCDate())}`}function _g(g){let T=Math.max(0,Math.round((Date.now()-g)/1000));if(T<60)return`${T}s ago`;let N=Math.round(T/60);if(N<60)return`${N}m ago`;let z=Math.round(N/60);if(z<48)return`${z}h ago`;return`${Math.round(z/24)}d ago`}async function k(g,T,N,z,L,P){let Y=await g.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:N,Dimensions:[{Name:"FunctionName",Value:T}],StartTime:L,EndTime:P,Period:86400,Statistics:[z]}).catch(()=>[]);if(!Y.length)return 0;if(z==="Sum")return Y.reduce((X,Z)=>X+(Z.Sum??0),0);if(z==="Maximum")return Math.max(...Y.map((X)=>X.Maximum??0));return Y.reduce((X,Z)=>X+(Z.Average??0),0)/Y.length}async function w(g,T,N,z,L,P,Y){let X=await g.getMetricStatistics({Namespace:T,MetricName:N,Dimensions:z,StartTime:P,EndTime:Y,Period:86400,Statistics:[L]}).catch(()=>[]);if(!X.length)return 0;if(L==="Sum")return X.reduce((Z,W)=>Z+(W.Sum??0),0);if(L==="Maximum")return Math.max(...X.map((Z)=>Z.Maximum??0));return X.reduce((Z,W)=>Z+(W.Average??0),0)/X.length}async function n(g,T,N,z,L){let P=await g.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:[{Name:"FunctionName",Value:T}],StartTime:z,EndTime:L,Period:86400,ExtendedStatistics:[N]}).catch(()=>[]);return Math.round(P.reduce((Y,X)=>Y+(X.Percentiles?.[N]??0),0))}async function PT(g,T){let N=await $g(g,T),z=N.region,L=new r(z),P=new xg(z),Y=new a(z),X=new Date,Z=new Date(X.getTime()-86400000),W=g.environments?.[T]?.app,G={};G.app={name:N.slug,env:T,region:z,runtime:W?.kind==="php"?`php-${W?.phpVersion??"8.3"} (fpm)`:W?.kind??"node",url:N.endpoint??"",build:N.lastRelease?.sha?.slice(0,7)??"—",deployedAt:N.lastRelease?.timestamp??"—"},G.maintenance={enabled:!1},G.scheduler={enabled:N.scheduler!=="off",expression:N.scheduler==="sub-minute"?"rate(1 minute) · sub-minute":"rate(1 minute)",lastRun:"—"};let b=0,U=0,S=0,v=[],K=[],C=[];for(let J of N.functions){let[O,x,B,V,$,H,E,R,I]=await Promise.all([k(L,J.name,"Invocations","Sum",Z,X),k(L,J.name,"Errors","Sum",Z,X),k(L,J.name,"Throttles","Sum",Z,X),k(L,J.name,"Duration","Average",Z,X),P.getFunction(J.name).catch(()=>null),n(L,J.name,"p50",Z,X),n(L,J.name,"p95",Z,X),n(L,J.name,"p99",Z,X),L.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:J.name}],StartTime:new Date(X.getTime()-43200000),EndTime:X,Period:3600,Stat:"Sum"}).catch(()=>[])]);b+=O,U+=x,S=Math.max(S,V);let D=$?.Configuration?.MemorySize??0,F=Object.keys($?.Configuration?.Environment?.Variables??{}),M=[],j=0;try{let{events:d=[]}=await Y.filterLogEvents({logGroupName:`/aws/lambda/${J.name}`,startTime:Z.getTime(),limit:120});for(let A of d){let h=(A.message??"").trim(),o=/Max Memory Used:\s*(\d+)\s*MB/.exec(h);if(o)j=Math.max(j,Number(o[1]));if(h&&!/^(?:START|END|REPORT|INIT_START)/.test(h))C.push({source:J.mode||J.name,timestamp:new Date(A.timestamp??0).toISOString(),when:_g(A.timestamp??0),message:h.slice(0,400),level:/error|exception|fatal|panic|traceback/i.test(h)?"error":/warn|warning|timeout|retr(?:y|ies)|throttl/i.test(h)?"warn":"info"})}M=d.filter((A)=>!/^(?:START|END|REPORT|INIT_START)/.test((A.message??"").trim())).slice(-6).map((A)=>({ts:new Date(A.timestamp??0).toISOString().slice(11,19),msg:(A.message??"").trim().slice(0,120),err:/error|exception|fatal/i.test(A.message??"")}))}catch{}let q=Math.max(1,...I);v.push({key:J.mode,name:J.name,version:J.version,memory:D,timeout:$?.Configuration?.Timeout??0,runtime:$?.Configuration?.Runtime??"provided.al2023",invocations:Math.round(O),errors:Math.round(x),p95:E||Math.round(V),status:"active",provisioned:J.provisioned?`${J.provisioned.allocated}/${J.provisioned.requested}`:void 0}),K.push({key:J.mode,name:J.name,runtime:$?.Configuration?.Runtime??"provided.al2023",arch:$?.Configuration?.Architectures?.[0]??"x86_64",memory:D,timeout:$?.Configuration?.Timeout??0,ephemeral:$?.Configuration?.EphemeralStorage?.Size??512,version:J.version,concurrency:W?.concurrency??"—",invocations:Math.round(O),errors:Math.round(x),throttles:Math.round(B),p50:H||Math.round(V),p95:E||Math.round(V),p99:R||Math.round(V),maxMem:j,spark:I.length?I.map((d)=>Math.round(d/q*100)):[0],env:F.length?F:["(none)"],recent:M.length?M:[{ts:"—",msg:"no recent events",err:!1}]})}G.functions=v,G.functionsDetail=K,G.serverlessLogs=C.sort((J,O)=>String(O.timestamp).localeCompare(String(J.timestamp))).slice(0,600),G.serverlessLogsEmptyReason=C.length?void 0:"No recent function logs were found in CloudWatch for this environment.";let u=b?Number((U/b*100).toFixed(2)):0,l=Math.round(await k(L,N.functions[0]?.name??"","ConcurrentExecutions","Maximum",Z,X));G.metrics={invocations:Math.round(b),errorRatePct:u,p95Ms:Math.round(S),coldStartPct:void 0,concurrency:l,estCostUsd:void 0};try{let J=new Wg(z),O=[],x=[],B=0;try{let{QueueUrl:$}=await J.getQueueUrl(`${N.slug}-${T}-dlq`),{Attributes:H}=await J.getQueueAttributes($);B=Number(H.ApproximateNumberOfMessages??0)}catch{}let V=W?Bg(W,N.slug,T):[];for(let $ of V){let H=$.name.replace(`${N.slug}-${T}-`,""),E=0,R=0;try{let{QueueUrl:D}=await J.getQueueUrl($.name),{Attributes:F}=await J.getQueueAttributes(D);E=Number(F.ApproximateNumberOfMessages??0),R=Number(F.ApproximateNumberOfMessagesNotVisible??0)}catch{}let I=Math.round(await w(L,"AWS/SQS","NumberOfMessagesDeleted",[{Name:"QueueName",Value:$.name}],"Sum",Z,X));O.push({name:H,visible:E,inFlight:R,processed:I,dlq:B}),x.push({name:$.name,short:H,visible:E,inFlight:R,delayed:0,processed:I,oldestSec:0,concurrency:$.concurrency??W?.queueConcurrency??"—",tries:W?.queueTries??3,visTimeout:(W?.queueTimeout??120)*6,dlq:B})}if(O.length)G.queues=O;if(x.length)G.queuesDetail=x;G.dlqItems=[]}catch{}try{let J=new Og(z),{Stacks:O}=await J.describeStacks({stackName:Xg(g,T)}),x={};for(let B of O?.[0]?.Outputs??[])if(B.OutputKey)x[B.OutputKey]=B.OutputValue??"";if(W?.database?.connection==="aurora-serverless"){let B=`${N.slug}-${T}-db`,V=[{Name:"DBClusterIdentifier",Value:B}],[$,H]=await Promise.all([w(L,"AWS/RDS","ServerlessDatabaseCapacity",V,"Average",Z,X),w(L,"AWS/RDS","DatabaseConnections",V,"Maximum",Z,X)]);if(G.aurora={id:B,engine:"aurora-mysql",minAcu:W?.database?.minCapacity??0.5,maxAcu:W?.database?.maxCapacity??4,currentAcu:$?Number($.toFixed(1)):W?.database?.minCapacity??0.5,database:"app",connections:Math.round(H),status:x.DbEndpoint?"available":"creating"},W?.rdsProxy)G.proxy={name:`${N.slug}-${T}-proxy`,endpoint:x.DbProxyEndpoint??"—",pooledConns:Math.round(H),status:"available"}}if(W?.cache?.driver==="elasticache"){let B=`${N.slug}-${T}-cache`,V=[{Name:"CacheClusterId",Value:`${B}-001`}],[$,H]=await Promise.all([w(L,"AWS/ElastiCache","CacheHits",V,"Sum",Z,X),w(L,"AWS/ElastiCache","CacheMisses",V,"Sum",Z,X)]),E=$+H>0?Number(($/($+H)*100).toFixed(1)):0;G.redis={id:B,node:"cache.t4g.micro",engine:"redis",hitRate:E,status:x.CacheEndpoint?"available":"creating"}}if(W?.efs){let B=0;try{if(x.EfsFileSystemId){let V=new p(z),{FileSystems:$}=await V.describeFileSystems({FileSystemId:x.EfsFileSystemId});B=Number((($?.[0]?.SizeInBytes?.Value??0)/1048576).toFixed(1))}}catch{}G.efs={id:x.EfsFileSystemId??"efs",mount:"/mnt/local",sizeMb:B,status:"available"}}G.assetsInfo=x.AssetsCdnDomain?{bucket:x.AssetsBucketName??`${N.slug}-${T}-assets`,cdn:x.AssetsCdnDomain,customDomain:W?.assetDomain??"—",assetUrl:N.assetUrl??"—",files:0,sizeMb:0,cacheHitPct:0,build:G.app.build}:void 0}catch{}if(G.assetsInfo)try{let O=await new s(z).list({bucket:G.assetsInfo.bucket,maxKeys:1000});G.assetsInfo.files=O.length,G.assetsInfo.sizeMb=Number((O.reduce((x,B)=>x+(B.Size??0),0)/1048576).toFixed(1)),G.assetsRecent=O.slice(0,8).map((x)=>({path:`/${x.Key}`,size:`${Math.max(1,Math.round((x.Size??0)/1024))} KB`,type:x.Key.split(".").pop()??""}))}catch{}try{if(W?.secrets){let J=Array.isArray(W.secrets)?W.secrets.map((O)=>({key:O.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),source:O})):Object.entries(W.secrets).map(([O,x])=>({key:O,source:String(x)}));G.secretsList=J.map((O)=>({...O,updated:"—"}))}}catch{}try{let J=new s(z),O=`${N.slug}-${T}-deployments`,x=await J.getObjectJson(O,`deployments/${N.slug}/${T}/history.json`).catch(()=>null);if(x?.records?.length)G.deploymentsDetail=x.records.slice(-12).reverse().map((B)=>({sha:(B.sha??"").slice(0,7),status:B.status??"success",when:B.timestamp??"—",took:B.took??"—",by:B.by??"—",version:B.version??"—",hooks:B.hooks??[]}))}catch{}G.metricsTotals={invocations:G.metrics.invocations,errors:Math.round(U),errorRatePct:u,p95Ms:G.metrics.p95Ms,throttles:K.reduce((J,O)=>J+O.throttles,0),coldStartPct:void 0,estCostUsd:void 0,concurrency:l},G.metricsPerFn=K.map((J)=>({key:J.key,invocations:J.invocations,errors:J.errors,throttles:J.throttles,avgMs:J.p50,maxMs:J.p99,costUsd:void 0}));try{G.invSpark=await L.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:N.functions.find((J)=>J.mode==="http")?.name??""}],StartTime:new Date(X.getTime()-86400000),EndTime:X,Period:3600,Stat:"Sum"})}catch{}try{let J=new e,O=X,x=new Date(Date.UTC(O.getUTCFullYear(),O.getUTCMonth(),1)),B=new Date(Date.UTC(O.getUTCFullYear(),O.getUTCMonth()-1,1)),[V,$]=await Promise.all([J.getCostByService({start:y(x),end:y(O),granularity:"MONTHLY"}).catch(()=>[]),J.getCostByService({start:y(B),end:y(x),granularity:"MONTHLY"}).catch(()=>[])]);if(V.length){let H=V.reduce((j,q)=>j+q.amount,0),E=$.reduce((j,q)=>j+q.amount,0),R=O.getUTCDate(),I=new Date(Date.UTC(O.getUTCFullYear(),O.getUTCMonth()+1,0)).getUTCDate();G.costSummary={monthToDateUsd:Number(H.toFixed(2)),projectedUsd:Number((H/R*I).toFixed(2)),lastMonthUsd:Number(E.toFixed(2)),dailyAvgUsd:Number((H/R).toFixed(2))},G.costServices=V.filter((j)=>j.amount>0).sort((j,q)=>q.amount-j.amount).slice(0,12).map((j)=>({name:j.service,usd:Number(j.amount.toFixed(2)),note:""})),G.metrics.estCostUsd=Number((H/R).toFixed(2)),G.metricsTotals.estCostUsd=G.metrics.estCostUsd,G.costTrend=await J.getDailyTotals({start:y(x),end:y(O)}).catch(()=>[]);let D=V.find((j)=>/lambda/i.test(j.service))?.amount??0,F=(j)=>j.invocations*(j.p50/1000)*(j.memory/1024),M=K.reduce((j,q)=>j+F(q),0)||1;G.costPerFn=K.map((j)=>({key:j.key,requests:j.invocations,gbSec:Math.round(F(j)),usd:Number((D*(F(j)/M)).toFixed(2))}))}}catch{}if(W?.firewall)try{let J=await L.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"BlockedRequests",StartTime:Z,EndTime:X,Period:86400,Statistics:["Sum"]}).catch(()=>[]),O=await L.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"AllowedRequests",StartTime:Z,EndTime:X,Period:86400,Statistics:["Sum"]}).catch(()=>[]);G.waf={enabled:!0,scope:"REGIONAL",acl:`${N.slug}-${T}-waf`,allowed24h:Math.round(O.reduce((x,B)=>x+(B.Sum??0),0)),blocked24h:Math.round(J.reduce((x,B)=>x+(B.Sum??0),0))};try{let x=new t(z),B=await x.listWebACLs("REGIONAL"),V=B.find(($)=>$.Name?.includes(`${N.slug}-${T}`))??B[0];if(V?.Name&&V.Id){G.waf.acl=V.Name;let $=await x.getWebACLRules(V.Name,V.Id,"REGIONAL");if($.length)G.wafRules=$.map((H)=>({name:H.Name??"—",detail:`priority ${H.Priority??0}`,action:H.Action??"count",blocked24h:0}))}}catch{}}catch{}let _=[];if(G.aurora)_.push({name:"Aurora Serverless v2",detail:`${G.aurora.id} · ${G.aurora.minAcu}-${G.aurora.maxAcu} ACU`,status:G.aurora.status});if(G.proxy)_.push({name:"RDS Proxy",detail:G.proxy.name,status:G.proxy.status});if(G.redis)_.push({name:`ElastiCache (${G.redis.engine})`,detail:`${G.redis.node} · ${G.redis.hitRate}% hit rate`,status:G.redis.status});if(G.efs)_.push({name:"EFS",detail:`${G.efs.mount} · ${G.efs.sizeMb} MB`,status:G.efs.status});if(_.length)G.dataServices=_;if(N.scheduler!=="off"&&W?.kind==="php")try{let J=await Zg(g,T,"schedule:list"),O=[];for(let x of(J||"").split(`
|
|
1
|
+
import{yd as Wg}from"./chunk-4vrqm9h0.js";import{Jd as Zg,Od as $g}from"./chunk-mz0wbbsj.js";import{Rd as xg}from"./chunk-p66ptpmr.js";import{Tf as Yg}from"./chunk-axhnkn5g.js";import{Uf as Og}from"./chunk-h5pa5men.js";import{$f as s,_f as c}from"./chunk-fy8j3y8p.js";import{Og as Q,Pg as gg}from"./chunk-fpm59y25.js";import{Gh as Xg,Un as Bg}from"./chunk-rxcvf10f.js";class r{client;region;constructor(g="us-east-1",T){this.region=g,this.client=new Q(c(T))}async query(g){let T=new URLSearchParams(gg({Version:"2010-08-01",...g})).toString();return this.client.request({service:"monitoring",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:T})}async getMetricStatistics(g){let T={Action:"GetMetricStatistics",Namespace:g.Namespace,MetricName:g.MetricName,StartTime:g.StartTime.toISOString(),EndTime:g.EndTime.toISOString(),Period:g.Period};(g.Statistics??[]).forEach((P,Y)=>{T[`Statistics.member.${Y+1}`]=P}),(g.ExtendedStatistics??[]).forEach((P,Y)=>{T[`ExtendedStatistics.member.${Y+1}`]=P}),(g.Dimensions??[]).forEach((P,Y)=>{T[`Dimensions.member.${Y+1}.Name`]=P.Name,T[`Dimensions.member.${Y+1}.Value`]=P.Value});let N=await this.query(T),L=(N.GetMetricStatisticsResult||N)?.Datapoints?.member??[];if(!Array.isArray(L))L=L?[L]:[];return L.map((P)=>{let Y={},X=P.ExtendedStatistics?.entry;if(X){if(!Array.isArray(X))X=[X];for(let Z of X)if(Z?.key!=null)Y[Z.key]=Number(Z.value)}return{Timestamp:P.Timestamp,Sum:P.Sum!=null?Number(P.Sum):void 0,Average:P.Average!=null?Number(P.Average):void 0,Maximum:P.Maximum!=null?Number(P.Maximum):void 0,Minimum:P.Minimum!=null?Number(P.Minimum):void 0,Percentiles:Object.keys(Y).length?Y:void 0,Unit:P.Unit}})}async getMetricSeries(g){let T=/^p\d/.test(g.Stat);return(await this.getMetricStatistics({Namespace:g.Namespace,MetricName:g.MetricName,Dimensions:g.Dimensions,StartTime:g.StartTime,EndTime:g.EndTime,Period:g.Period,Statistics:T?[]:[g.Stat],ExtendedStatistics:T?[g.Stat]:[]})).slice().sort((z,L)=>new Date(z.Timestamp??0).getTime()-new Date(L.Timestamp??0).getTime()).map((z)=>T?z.Percentiles?.[g.Stat]??0:z[g.Stat]??0)}async describeAlarms(g){let T={Action:"DescribeAlarms"};if(g?.AlarmNamePrefix)T.AlarmNamePrefix=g.AlarmNamePrefix;if(g?.MaxRecords)T.MaxRecords=g.MaxRecords;let N=await this.query(T),L=(N.DescribeAlarmsResult||N)?.MetricAlarms?.member??[];if(!Array.isArray(L))L=L?[L]:[];return L.map((P)=>({AlarmName:P.AlarmName,StateValue:P.StateValue,MetricName:P.MetricName,ComparisonOperator:P.ComparisonOperator,Threshold:P.Threshold!=null?Number(P.Threshold):void 0,Namespace:P.Namespace}))}async putMetricAlarm(g){let T={Action:"PutMetricAlarm",AlarmName:g.AlarmName,Namespace:g.Namespace,MetricName:g.MetricName,ComparisonOperator:g.ComparisonOperator,Threshold:g.Threshold,EvaluationPeriods:g.EvaluationPeriods,Period:g.Period,Statistic:g.Statistic};if(g.AlarmDescription)T.AlarmDescription=g.AlarmDescription;(g.Dimensions??[]).forEach((N,z)=>{T[`Dimensions.member.${z+1}.Name`]=N.Name,T[`Dimensions.member.${z+1}.Value`]=N.Value}),(g.AlarmActions??[]).forEach((N,z)=>{T[`AlarmActions.member.${z+1}`]=N}),await this.query(T)}async deleteAlarms(g){if(!g.length)return;let T={Action:"DeleteAlarms"};g.forEach((N,z)=>{T[`AlarmNames.member.${z+1}`]=N}),await this.query(T)}}class a{client;region;constructor(g="us-east-1",T){this.region=g,this.client=new Q(void 0,{profile:T})}async createLogGroup(g,T){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.CreateLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:g,...T?{tags:T}:{}})})}async putRetentionPolicy(g,T){if(![1,3,5,7,14,30,60,90,120,150,180,365,400,545,731,1096,1827,2192,2557,2922,3288,3653].includes(T))throw Error("Unsupported CloudWatch Logs retention period");await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.PutRetentionPolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:g,retentionInDays:T})})}async describeLogStreams(g){let T={logGroupName:g.logGroupName};if(g.logStreamNamePrefix)T.logStreamNamePrefix=g.logStreamNamePrefix;if(g.orderBy)T.orderBy=g.orderBy;if(g.descending!==void 0)T.descending=g.descending;if(g.limit)T.limit=g.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogStreams","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}async getLogEvents(g){let T={logGroupName:g.logGroupName,logStreamName:g.logStreamName};if(g.startTime)T.startTime=g.startTime;if(g.endTime)T.endTime=g.endTime;if(g.limit)T.limit=g.limit;if(g.startFromHead!==void 0)T.startFromHead=g.startFromHead;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.GetLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}async describeLogGroups(g){let T={};if(g?.logGroupNamePrefix)T.logGroupNamePrefix=g.logGroupNamePrefix;if(g?.limit)T.limit=g.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogGroups","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}async deleteLogGroup(g){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DeleteLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:g})})}async filterLogEvents(g){let T={logGroupName:g.logGroupName};if(g.logStreamNames)T.logStreamNames=g.logStreamNames;if(g.startTime)T.startTime=g.startTime;if(g.endTime)T.endTime=g.endTime;if(g.filterPattern)T.filterPattern=g.filterPattern;if(g.limit)T.limit=g.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.FilterLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(T)})}}import{createHash as jg}from"node:crypto";import{existsSync as Tg,mkdirSync as Vg,readdirSync as Hg,readFileSync as Ug,rmSync as Kg,writeFileSync as Eg}from"node:fs";import{homedir as Qg}from"node:os";import{join as m}from"node:path";var Ng=1,Lg=3600000,Rg=24*Lg,Fg=Lg,qg=30*Rg;function i(){let g=process.env.XDG_CACHE_HOME;return m(g&&g.trim()?g:m(Qg(),".cache"),"ts-cloud","cost-explorer")}function f(g){return m(i(),g??"__default__")}function Gg(g){let T={s:g.start,e:g.end,g:g.granularity,m:[...g.metrics].sort(),gb:[...g.groupBy].map((N)=>`${N.Type}:${N.Key}`).sort(),f:g.filter??null};return jg("sha256").update(JSON.stringify(T)).digest("hex").slice(0,24)}function Ag(g,T){let N=Date.parse(`${T}T00:00:00Z`);if(Number.isNaN(N))return!1;let z=new Date,L=Date.UTC(z.getUTCFullYear(),z.getUTCMonth(),1);return N<=L}function Sg(g){return Ag(g.start,g.end)?qg:Fg}function zg(g,T){let N=m(f(g),`${Gg(T)}.json`);if(!Tg(N))return null;let z;try{z=JSON.parse(Ug(N,"utf-8"))}catch{return null}if(z.schema!==Ng)return null;let L=Date.now()-z.savedAt;if(L<0||L>Sg(T))return null;return{response:z.response,ageSeconds:Math.floor(L/1000)}}function Jg(g,T,N){let z=f(g);Vg(z,{recursive:!0});let L={schema:Ng,savedAt:Date.now(),key:T,response:N};Eg(m(z,`${Gg(T)}.json`),JSON.stringify(L))}function wg(g){let T=g===void 0?i():f(g);if(!Tg(T))return{deletedFiles:0,scope:g??"all profiles"};let N=0;function z(L){for(let P of Hg(L,{withFileTypes:!0})){let Y=m(L,P.name);if(P.isDirectory())z(Y);else if(P.isFile()&&P.name.endsWith(".json"))N++}}return z(T),Kg(T,{recursive:!0,force:!0}),{deletedFiles:N,scope:g??"all profiles"}}function vg(g){return g===void 0?i():f(g)}class e{client;profile;useCache;lastCacheAgeSeconds=null;constructor(g,T){this.profile=g,this.useCache=T?.useCache??!0,this.client=new Q(c(g))}async getCostByService(g){return(await this.getCostByDimension({...g,dimension:"SERVICE"})).map((N)=>({service:N.key,amount:N.amount,unit:N.unit}))}async getCostByDimension(g){let{start:T,end:N,dimension:z,granularity:L="MONTHLY",filter:P}=g,Y=["UnblendedCost"],X=[{Type:"DIMENSION",Key:z}],Z={start:T,end:N,granularity:L,metrics:Y,groupBy:X,filter:P};if(this.useCache){let U=zg(this.profile,Z);if(U)return this.lastCacheAgeSeconds=U.ageSeconds,U.response}this.lastCacheAgeSeconds=null;let W=new Map,G;do{let U={TimePeriod:{Start:T,End:N},Granularity:L,Metrics:Y,GroupBy:X};if(P)U.Filter=P;if(G)U.NextPageToken=G;let S=await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify(U)});for(let v of S?.ResultsByTime??[])for(let K of v?.Groups??[]){let C=K.Keys?.[0]??"Unknown",u=Number.parseFloat(K.Metrics?.UnblendedCost?.Amount??"0"),l=K.Metrics?.UnblendedCost?.Unit??"USD",_=W.get(C);W.set(C,{key:C,amount:(_?.amount??0)+u,unit:l})}G=S?.NextPageToken||void 0}while(G);let b=[...W.values()].filter((U)=>U.amount>0).sort((U,S)=>S.amount-U.amount);if(this.useCache)Jg(this.profile,Z,b);return b}async getDailyTotals(g){return((await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify({TimePeriod:{Start:g.start,End:g.end},Granularity:"DAILY",Metrics:["UnblendedCost"]})}))?.ResultsByTime??[]).map((z)=>Number.parseFloat(z.Total?.UnblendedCost?.Amount??"0"))}}class p{client;region;constructor(g="us-east-1"){this.region=g,this.client=new Q}async describeFileSystems(g){let T=[];if(g?.FileSystemId)T.push(`FileSystemId=${encodeURIComponent(g.FileSystemId)}`);if(g?.CreationToken)T.push(`CreationToken=${encodeURIComponent(g.CreationToken)}`);let N=`/2015-02-01/file-systems${T.length>0?`?${T.join("&")}`:""}`;return{FileSystems:((await this.client.request({service:"elasticfilesystem",region:this.region,method:"GET",path:N,headers:{"Content-Type":"application/json"}})).FileSystems||[]).map((L)=>({FileSystemId:L.FileSystemId,Name:L.Name,CreationTime:L.CreationTime,LifeCycleState:L.LifeCycleState,NumberOfMountTargets:L.NumberOfMountTargets,SizeInBytes:L.SizeInBytes?{Value:L.SizeInBytes.Value,Timestamp:L.SizeInBytes.Timestamp}:void 0,PerformanceMode:L.PerformanceMode,Encrypted:L.Encrypted,ThroughputMode:L.ThroughputMode,Tags:L.Tags}))}}}class t{client;region;constructor(g="us-east-1"){this.region=g,this.client=new Q}async call(g,T){return this.client.request({service:"wafv2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSWAF_20190729.${g}`},body:JSON.stringify(T)})}async listWebACLs(g="REGIONAL"){return(await this.call("ListWebACLs",{Scope:g,Limit:100}))?.WebACLs??[]}async getWebACLRules(g,T,N="REGIONAL"){return((await this.call("GetWebACL",{Name:g,Id:T,Scope:N}))?.WebACL?.Rules??[]).map((P)=>({Name:P.Name,Priority:P.Priority,Action:P.Action?Object.keys(P.Action)[0]:P.OverrideAction?Object.keys(P.OverrideAction)[0]:"count"}))}}function Pg(g){return String(g).padStart(2,"0")}function y(g){return`${g.getUTCFullYear()}-${Pg(g.getUTCMonth()+1)}-${Pg(g.getUTCDate())}`}function _g(g){let T=Math.max(0,Math.round((Date.now()-g)/1000));if(T<60)return`${T}s ago`;let N=Math.round(T/60);if(N<60)return`${N}m ago`;let z=Math.round(N/60);if(z<48)return`${z}h ago`;return`${Math.round(z/24)}d ago`}async function k(g,T,N,z,L,P){let Y=await g.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:N,Dimensions:[{Name:"FunctionName",Value:T}],StartTime:L,EndTime:P,Period:86400,Statistics:[z]}).catch(()=>[]);if(!Y.length)return 0;if(z==="Sum")return Y.reduce((X,Z)=>X+(Z.Sum??0),0);if(z==="Maximum")return Math.max(...Y.map((X)=>X.Maximum??0));return Y.reduce((X,Z)=>X+(Z.Average??0),0)/Y.length}async function w(g,T,N,z,L,P,Y){let X=await g.getMetricStatistics({Namespace:T,MetricName:N,Dimensions:z,StartTime:P,EndTime:Y,Period:86400,Statistics:[L]}).catch(()=>[]);if(!X.length)return 0;if(L==="Sum")return X.reduce((Z,W)=>Z+(W.Sum??0),0);if(L==="Maximum")return Math.max(...X.map((Z)=>Z.Maximum??0));return X.reduce((Z,W)=>Z+(W.Average??0),0)/X.length}async function n(g,T,N,z,L){let P=await g.getMetricStatistics({Namespace:"AWS/Lambda",MetricName:"Duration",Dimensions:[{Name:"FunctionName",Value:T}],StartTime:z,EndTime:L,Period:86400,ExtendedStatistics:[N]}).catch(()=>[]);return Math.round(P.reduce((Y,X)=>Y+(X.Percentiles?.[N]??0),0))}async function PT(g,T){let N=await $g(g,T),z=N.region,L=new r(z),P=new xg(z),Y=new a(z),X=new Date,Z=new Date(X.getTime()-86400000),W=g.environments?.[T]?.app,G={};G.app={name:N.slug,env:T,region:z,runtime:W?.kind==="php"?`php-${W?.phpVersion??"8.3"} (fpm)`:W?.kind??"node",url:N.endpoint??"",build:N.lastRelease?.sha?.slice(0,7)??"—",deployedAt:N.lastRelease?.timestamp??"—"},G.maintenance={enabled:!1},G.scheduler={enabled:N.scheduler!=="off",expression:N.scheduler==="sub-minute"?"rate(1 minute) · sub-minute":"rate(1 minute)",lastRun:"—"};let b=0,U=0,S=0,v=[],K=[],C=[];for(let J of N.functions){let[O,x,B,V,$,H,E,R,I]=await Promise.all([k(L,J.name,"Invocations","Sum",Z,X),k(L,J.name,"Errors","Sum",Z,X),k(L,J.name,"Throttles","Sum",Z,X),k(L,J.name,"Duration","Average",Z,X),P.getFunction(J.name).catch(()=>null),n(L,J.name,"p50",Z,X),n(L,J.name,"p95",Z,X),n(L,J.name,"p99",Z,X),L.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:J.name}],StartTime:new Date(X.getTime()-43200000),EndTime:X,Period:3600,Stat:"Sum"}).catch(()=>[])]);b+=O,U+=x,S=Math.max(S,V);let D=$?.Configuration?.MemorySize??0,F=Object.keys($?.Configuration?.Environment?.Variables??{}),M=[],j=0;try{let{events:d=[]}=await Y.filterLogEvents({logGroupName:`/aws/lambda/${J.name}`,startTime:Z.getTime(),limit:120});for(let A of d){let h=(A.message??"").trim(),o=/Max Memory Used:\s*(\d+)\s*MB/.exec(h);if(o)j=Math.max(j,Number(o[1]));if(h&&!/^(?:START|END|REPORT|INIT_START)/.test(h))C.push({source:J.mode||J.name,timestamp:new Date(A.timestamp??0).toISOString(),when:_g(A.timestamp??0),message:h.slice(0,400),level:/error|exception|fatal|panic|traceback/i.test(h)?"error":/warn|warning|timeout|retr(?:y|ies)|throttl/i.test(h)?"warn":"info"})}M=d.filter((A)=>!/^(?:START|END|REPORT|INIT_START)/.test((A.message??"").trim())).slice(-6).map((A)=>({ts:new Date(A.timestamp??0).toISOString().slice(11,19),msg:(A.message??"").trim().slice(0,120),err:/error|exception|fatal/i.test(A.message??"")}))}catch{}let q=Math.max(1,...I);v.push({key:J.mode,name:J.name,version:J.version,memory:D,timeout:$?.Configuration?.Timeout??0,runtime:$?.Configuration?.Runtime??"provided.al2023",invocations:Math.round(O),errors:Math.round(x),p95:E||Math.round(V),status:"active",provisioned:J.provisioned?`${J.provisioned.allocated}/${J.provisioned.requested}`:void 0}),K.push({key:J.mode,name:J.name,runtime:$?.Configuration?.Runtime??"provided.al2023",arch:$?.Configuration?.Architectures?.[0]??"x86_64",memory:D,timeout:$?.Configuration?.Timeout??0,ephemeral:$?.Configuration?.EphemeralStorage?.Size??512,version:J.version,concurrency:W?.concurrency??"—",invocations:Math.round(O),errors:Math.round(x),throttles:Math.round(B),p50:H||Math.round(V),p95:E||Math.round(V),p99:R||Math.round(V),maxMem:j,spark:I.length?I.map((d)=>Math.round(d/q*100)):[0],env:F.length?F:["(none)"],recent:M.length?M:[{ts:"—",msg:"no recent events",err:!1}]})}G.functions=v,G.functionsDetail=K,G.serverlessLogs=C.sort((J,O)=>String(O.timestamp).localeCompare(String(J.timestamp))).slice(0,600),G.serverlessLogsEmptyReason=C.length?void 0:"No recent function logs were found in CloudWatch for this environment.";let u=b?Number((U/b*100).toFixed(2)):0,l=Math.round(await k(L,N.functions[0]?.name??"","ConcurrentExecutions","Maximum",Z,X));G.metrics={invocations:Math.round(b),errorRatePct:u,p95Ms:Math.round(S),coldStartPct:void 0,concurrency:l,estCostUsd:void 0};try{let J=new Wg(z),O=[],x=[],B=0;try{let{QueueUrl:$}=await J.getQueueUrl(`${N.slug}-${T}-dlq`),{Attributes:H}=await J.getQueueAttributes($);B=Number(H.ApproximateNumberOfMessages??0)}catch{}let V=W?Bg(W,N.slug,T):[];for(let $ of V){let H=$.name.replace(`${N.slug}-${T}-`,""),E=0,R=0;try{let{QueueUrl:D}=await J.getQueueUrl($.name),{Attributes:F}=await J.getQueueAttributes(D);E=Number(F.ApproximateNumberOfMessages??0),R=Number(F.ApproximateNumberOfMessagesNotVisible??0)}catch{}let I=Math.round(await w(L,"AWS/SQS","NumberOfMessagesDeleted",[{Name:"QueueName",Value:$.name}],"Sum",Z,X));O.push({name:H,visible:E,inFlight:R,processed:I,dlq:B}),x.push({name:$.name,short:H,visible:E,inFlight:R,delayed:0,processed:I,oldestSec:0,concurrency:$.concurrency??W?.queueConcurrency??"—",tries:W?.queueTries??3,visTimeout:(W?.queueTimeout??120)*6,dlq:B})}if(O.length)G.queues=O;if(x.length)G.queuesDetail=x;G.dlqItems=[]}catch{}try{let J=new Og(z),{Stacks:O}=await J.describeStacks({stackName:Xg(g,T)}),x={};for(let B of O?.[0]?.Outputs??[])if(B.OutputKey)x[B.OutputKey]=B.OutputValue??"";if(W?.database?.connection==="aurora-serverless"){let B=`${N.slug}-${T}-db`,V=[{Name:"DBClusterIdentifier",Value:B}],[$,H]=await Promise.all([w(L,"AWS/RDS","ServerlessDatabaseCapacity",V,"Average",Z,X),w(L,"AWS/RDS","DatabaseConnections",V,"Maximum",Z,X)]);if(G.aurora={id:B,engine:"aurora-mysql",minAcu:W?.database?.minCapacity??0.5,maxAcu:W?.database?.maxCapacity??4,currentAcu:$?Number($.toFixed(1)):W?.database?.minCapacity??0.5,database:"app",connections:Math.round(H),status:x.DbEndpoint?"available":"creating"},W?.rdsProxy)G.proxy={name:`${N.slug}-${T}-proxy`,endpoint:x.DbProxyEndpoint??"—",pooledConns:Math.round(H),status:"available"}}if(W?.cache?.driver==="elasticache"){let B=`${N.slug}-${T}-cache`,V=[{Name:"CacheClusterId",Value:`${B}-001`}],[$,H]=await Promise.all([w(L,"AWS/ElastiCache","CacheHits",V,"Sum",Z,X),w(L,"AWS/ElastiCache","CacheMisses",V,"Sum",Z,X)]),E=$+H>0?Number(($/($+H)*100).toFixed(1)):0;G.redis={id:B,node:"cache.t4g.micro",engine:"redis",hitRate:E,status:x.CacheEndpoint?"available":"creating"}}if(W?.efs){let B=0;try{if(x.EfsFileSystemId){let V=new p(z),{FileSystems:$}=await V.describeFileSystems({FileSystemId:x.EfsFileSystemId});B=Number((($?.[0]?.SizeInBytes?.Value??0)/1048576).toFixed(1))}}catch{}G.efs={id:x.EfsFileSystemId??"efs",mount:"/mnt/local",sizeMb:B,status:"available"}}G.assetsInfo=x.AssetsCdnDomain?{bucket:x.AssetsBucketName??`${N.slug}-${T}-assets`,cdn:x.AssetsCdnDomain,customDomain:W?.assetDomain??"—",assetUrl:N.assetUrl??"—",files:0,sizeMb:0,cacheHitPct:0,build:G.app.build}:void 0}catch{}if(G.assetsInfo)try{let O=await new s(z).list({bucket:G.assetsInfo.bucket,maxKeys:1000});G.assetsInfo.files=O.length,G.assetsInfo.sizeMb=Number((O.reduce((x,B)=>x+(B.Size??0),0)/1048576).toFixed(1)),G.assetsRecent=O.slice(0,8).map((x)=>({path:`/${x.Key}`,size:`${Math.max(1,Math.round((x.Size??0)/1024))} KB`,type:x.Key.split(".").pop()??""}))}catch{}try{if(W?.secrets){let J=Array.isArray(W.secrets)?W.secrets.map((O)=>({key:O.split("/").pop().toUpperCase().replace(/[^A-Z0-9_]/g,"_"),source:O})):Object.entries(W.secrets).map(([O,x])=>({key:O,source:String(x)}));G.secretsList=J.map((O)=>({...O,updated:"—"}))}}catch{}try{let J=new s(z),O=`${N.slug}-${T}-deployments`,x=await J.getObjectJson(O,`deployments/${N.slug}/${T}/history.json`).catch(()=>null);if(x?.records?.length)G.deploymentsDetail=x.records.slice(-12).reverse().map((B)=>({sha:(B.sha??"").slice(0,7),status:B.status??"success",when:B.timestamp??"—",took:B.took??"—",by:B.by??"—",version:B.version??"—",hooks:B.hooks??[]}))}catch{}G.metricsTotals={invocations:G.metrics.invocations,errors:Math.round(U),errorRatePct:u,p95Ms:G.metrics.p95Ms,throttles:K.reduce((J,O)=>J+O.throttles,0),coldStartPct:void 0,estCostUsd:void 0,concurrency:l},G.metricsPerFn=K.map((J)=>({key:J.key,invocations:J.invocations,errors:J.errors,throttles:J.throttles,avgMs:J.p50,maxMs:J.p99,costUsd:void 0}));try{G.invSpark=await L.getMetricSeries({Namespace:"AWS/Lambda",MetricName:"Invocations",Dimensions:[{Name:"FunctionName",Value:N.functions.find((J)=>J.mode==="http")?.name??""}],StartTime:new Date(X.getTime()-86400000),EndTime:X,Period:3600,Stat:"Sum"})}catch{}try{let J=new e,O=X,x=new Date(Date.UTC(O.getUTCFullYear(),O.getUTCMonth(),1)),B=new Date(Date.UTC(O.getUTCFullYear(),O.getUTCMonth()-1,1)),[V,$]=await Promise.all([J.getCostByService({start:y(x),end:y(O),granularity:"MONTHLY"}).catch(()=>[]),J.getCostByService({start:y(B),end:y(x),granularity:"MONTHLY"}).catch(()=>[])]);if(V.length){let H=V.reduce((j,q)=>j+q.amount,0),E=$.reduce((j,q)=>j+q.amount,0),R=O.getUTCDate(),I=new Date(Date.UTC(O.getUTCFullYear(),O.getUTCMonth()+1,0)).getUTCDate();G.costSummary={monthToDateUsd:Number(H.toFixed(2)),projectedUsd:Number((H/R*I).toFixed(2)),lastMonthUsd:Number(E.toFixed(2)),dailyAvgUsd:Number((H/R).toFixed(2))},G.costServices=V.filter((j)=>j.amount>0).sort((j,q)=>q.amount-j.amount).slice(0,12).map((j)=>({name:j.service,usd:Number(j.amount.toFixed(2)),note:""})),G.metrics.estCostUsd=Number((H/R).toFixed(2)),G.metricsTotals.estCostUsd=G.metrics.estCostUsd,G.costTrend=await J.getDailyTotals({start:y(x),end:y(O)}).catch(()=>[]);let D=V.find((j)=>/lambda/i.test(j.service))?.amount??0,F=(j)=>j.invocations*(j.p50/1000)*(j.memory/1024),M=K.reduce((j,q)=>j+F(q),0)||1;G.costPerFn=K.map((j)=>({key:j.key,requests:j.invocations,gbSec:Math.round(F(j)),usd:Number((D*(F(j)/M)).toFixed(2))}))}}catch{}if(W?.firewall)try{let J=await L.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"BlockedRequests",StartTime:Z,EndTime:X,Period:86400,Statistics:["Sum"]}).catch(()=>[]),O=await L.getMetricStatistics({Namespace:"AWS/WAFV2",MetricName:"AllowedRequests",StartTime:Z,EndTime:X,Period:86400,Statistics:["Sum"]}).catch(()=>[]);G.waf={enabled:!0,scope:"REGIONAL",acl:`${N.slug}-${T}-waf`,allowed24h:Math.round(O.reduce((x,B)=>x+(B.Sum??0),0)),blocked24h:Math.round(J.reduce((x,B)=>x+(B.Sum??0),0))};try{let x=new t(z),B=await x.listWebACLs("REGIONAL"),V=B.find(($)=>$.Name?.includes(`${N.slug}-${T}`))??B[0];if(V?.Name&&V.Id){G.waf.acl=V.Name;let $=await x.getWebACLRules(V.Name,V.Id,"REGIONAL");if($.length)G.wafRules=$.map((H)=>({name:H.Name??"—",detail:`priority ${H.Priority??0}`,action:H.Action??"count",blocked24h:0}))}}catch{}}catch{}let _=[];if(G.aurora)_.push({name:"Aurora Serverless v2",detail:`${G.aurora.id} · ${G.aurora.minAcu}-${G.aurora.maxAcu} ACU`,status:G.aurora.status});if(G.proxy)_.push({name:"RDS Proxy",detail:G.proxy.name,status:G.proxy.status});if(G.redis)_.push({name:`ElastiCache (${G.redis.engine})`,detail:`${G.redis.node} · ${G.redis.hitRate}% hit rate`,status:G.redis.status});if(G.efs)_.push({name:"EFS",detail:`${G.efs.mount} · ${G.efs.sizeMb} MB`,status:G.efs.status});if(_.length)G.dataServices=_;if(N.scheduler!=="off"&&W?.kind==="php")try{let J=await Zg(g,T,"schedule:list"),O=[];for(let x of(J||"").split(`
|
|
2
2
|
`)){let B=/^\s*([\d*/,\-\s]+?)\s{2,}(.+?)(?:\s{2,}Next Due.*)?$/.exec(x);if(B&&/[*\d]/.test(B[1])&&B[1].trim().split(/\s+/).length===5)O.push({command:B[2].trim().replace(/^php artisan /,""),cron:B[1].trim(),desc:"",lastRun:"—",lastStatus:"ok"})}if(O.length)G.schedulerTasks=O}catch{}return G.topology=Yg(G,{project:g.project.name,environment:T}),G}
|
|
3
3
|
export{a as sd,r as td,wg as ud,vg as vd,e as wd,PT as xd};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Bf as F,Ef as H,Ff as w,Of as A,gf as $,pf as Z}from"./chunk-
|
|
1
|
+
import{Bf as F,Ef as H,Ff as w,Of as A,gf as $,pf as Z}from"./chunk-tga3hhwk.js";function C(z){return`'${z.split("'").join("'\\''")}'`}function q(z){let G=z.user||"root",K=z.script.join(`
|
|
2
2
|
`),M=G==="root"?'bash -l "$TS_CLOUD_RECIPE"':`runuser -l ${C(G)} -c "bash $TS_CLOUD_RECIPE"`;return["set -uo pipefail",`echo "__TS_CLOUD_RECIPE_BEGIN__ ${z.name} (user=${G})"`,"TS_CLOUD_RECIPE=$(mktemp)",`cat > "$TS_CLOUD_RECIPE" <<'TS_CLOUD_RECIPE_EOF'`,K,"TS_CLOUD_RECIPE_EOF",'chmod +r "$TS_CLOUD_RECIPE"',M,"TS_CLOUD_RC=$?",'rm -f "$TS_CLOUD_RECIPE"',`echo "__TS_CLOUD_RECIPE_END__ ${z.name} exit=$TS_CLOUD_RC"`,"exit $TS_CLOUD_RC"]}var j={info:()=>{},warn:()=>{},error:()=>{},step:()=>{},success:()=>{}};async function X(z){return await z.driver.findComputeTargets({slug:z.slug,environment:z.environment,role:z.role||"app"})}async function B(z,G){let K=z.logger||j,M=await X(z);if(M.length===0)return{success:!1,error:`No '${z.role||"app"}' servers found for ${z.slug}/${z.environment}.`};let Q=$(z.slug,G.siteName),W=w(Q,G.to||"unused"),U=["set -uo pipefail",...A(W,{...G.to?{to:G.to}:{},unitBase:`${z.slug}-${G.siteName}`}),`(cd ${Z} && pantry restart php-fpm) 2>/dev/null || true`,`(cd ${W.current} && eval "$(cd ${Z} && pantry env 2>/dev/null)" && php artisan queue:restart) 2>/dev/null || true`];K.step(`Rolling back ${G.siteName}${G.to?` to ${G.to}`:" to the previous release"} on ${M.length} server(s)...`);let V=await z.driver.runRemoteDeploy({targets:M,commands:U,comment:`ts-cloud rollback ${z.slug}/${G.siteName}`,tags:{Project:z.slug,Environment:z.environment,Role:z.role||"app"}});if(!V.success)K.error(`Rollback failed: ${V.error||"unknown error"}`);else K.success(`Rolled back ${G.siteName}.`);return{success:V.success,error:V.error,perInstance:V.perInstance}}async function I(z,G){let K=await X(z);if(K.length===0)return{success:!1,error:`No '${z.role||"app"}' servers found for ${z.slug}/${z.environment}.`};let M=H($(z.slug,G.siteName)),Q=Math.max(1,G.limit??20),W=[`[ -f ${M} ] && tail -n ${Q} ${M} || echo "no deploy history for ${G.siteName}"`],U=await z.driver.runRemoteDeploy({targets:K,commands:W,comment:`ts-cloud deploy:history ${z.slug}/${G.siteName}`,tags:{Project:z.slug,Environment:z.environment,Role:z.role||"app"}});return{success:U.success,error:U.error,perInstance:U.perInstance}}async function L(z,G){let K=z.logger||j,M=await X(z);if(M.length===0)return{success:!1,error:`No '${z.role||"app"}' servers found for ${z.slug}/${z.environment}.`};K.step(`Running recipe '${G.name}' as ${G.user||"root"} on ${M.length} server(s)...`);let Q=await z.driver.runRemoteDeploy({targets:M,commands:q({name:G.name,script:G.script,user:G.user}),comment:`ts-cloud recipe ${G.name}`,tags:{Project:z.slug,Environment:z.environment,Role:z.role||"app"}});if(!Q.success)K.error(`Recipe '${G.name}' failed: ${Q.error||"unknown error"}`);else K.success(`Recipe '${G.name}' completed.`);return{success:Q.success,error:Q.error,perInstance:Q.perInstance}}async function S(z,G){let K=z.logger||j;if(!G.database?.name)return{success:!1,error:"No appDatabase configured to restore."};let M=await X(z);if(M.length===0)return{success:!1,error:`No '${z.role||"app"}' servers found for ${z.slug}/${z.environment}.`};K.step(`Restoring database '${G.database.name}'${G.from?` from ${G.from}`:" from the latest backup"} on ${M.length} server(s)...`);let Q=await z.driver.runRemoteDeploy({targets:M,commands:F(G.database,{from:G.from}),comment:`ts-cloud db:restore ${z.slug}/${G.database.name}`,tags:{Project:z.slug,Environment:z.environment,Role:z.role||"app"}});if(!Q.success)K.error(`Restore failed: ${Q.error||"unknown error"}`);else K.success(`Restored ${G.database.name}.`);return{success:Q.success,error:Q.error,perInstance:Q.perInstance}}
|
|
3
3
|
export{B as od,I as pd,L as qd,S as rd};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Ne as S1}from"./chunk-3gykfyq4.js";import{Ue as y1}from"./chunk-ax9mr6wm.js";import{Xe as t1}from"./chunk-ggn7ax8p.js";import{df as V1,ef as q1,ff as u2}from"./chunk-r3kv0vm9.js";import{Af as e0,Cf as y2,Df as d0,Ff as c0,Gf as L2,Hf as l0,If as l$,Jf as p$,Kf as a$,Lf as r$,Mf as H$,Nf as P0,Pf as I0,Qf as Q1,Rf as K$,gf as U0,hf as H1,if as x1,jf as u,pf as Y0,qf as t0,rf as r0,sf as n0,tf as D1,wf as o0,xf as E0,yf as g2}from"./chunk-r9hjwcj9.js";import{Sf as F1}from"./chunk-axhnkn5g.js";import{Uf as i1}from"./chunk-h5pa5men.js";import{$f as n1}from"./chunk-fy8j3y8p.js";import{Og as A1}from"./chunk-fpm59y25.js";import{Ah as I,Ui as O1,ph as V0,qh as _0}from"./chunk-jpjamjey.js";import{Vo as Rz}from"./chunk-mh0kdzqp.js";import{existsSync as L6,readFileSync as A6}from"node:fs";import{join as R6}from"node:path";import{readFileSync as s1}from"node:fs";import{join as gz}from"node:path";function r6($={}){let z=new Set;for(let J of Object.values($)){if(!J.domain)continue;if(J.redirect||J.deploy==="server"||J.start)z.add(J.domain)}return z}function L$($){return $.replace(/\.$/,"").toLowerCase()}function Zz($,z,J){let Z=L$($.name),Y=L$(z),G=L$(J),j=G===Y?"@":G.endsWith(`.${Y}`)?G.slice(0,-(Y.length+1)):G;return Z===G||Z===j||j==="@"&&(Z===""||Z===Y)}async function Yz($,z,J,Z,Y="A"){let G=await $.listRecords(z);if(!G.success)return[`could not list ${Y} records: ${G.message||"unknown provider error"}`];let j=G.records.filter((q)=>q.type===Y&&Zz(q,z,J)),O=j.findIndex((q)=>q.content===Z);if(j.length<=1||O===-1)return[];let Q=[];for(let[q,V]of j.entries()){if(q===O)continue;let W=await $.deleteRecord(z,V);if(!W.success)Q.push(`could not remove stale ${V.name} ${Y} ${V.content}: ${W.message||"unknown provider error"}`)}return Q}function z0($){if(!$)return;let z=$.trim();if(!z)return;if(!z.includes("/"))return z;let[J]=z.split("/");if(!J.endsWith("::"))return J||void 0;return`${J}1`}var Gz=new Set(["mail","smtp","imap","mx"]);function jz($){return!Gz.has($.split(".")[0]??"")}async function n6($){let{provider:z,zone:J,fqdn:Z,ipv4:Y,ipv6:G,ttl:j=600}=$,O={published:[],warnings:[]},Q=[{type:"A",content:Y}];if(G&&jz(Z))Q.push({type:"AAAA",content:G});for(let{type:q,content:V}of Q){let W=await z.upsertRecord(J,{name:Z,type:q,content:V,ttl:j});if(W?.success===!1){O.warnings.push(`${Z} → ${V} failed: ${W.error||W.message||"unknown error"}`);continue}if(O.warnings.push(...(await Yz(z,J,Z,V,q)).map((H)=>`${Z} cleanup: ${H}`)),await Oz(z,J,Z,V,q))O.published.push({fqdn:Z,type:q,content:V});else O.warnings.push(`${Z} → ${V} reported success at ${z.name} but no matching ${q} record exists — create it manually: ${q} ${Z} → ${V}`)}return O}async function Oz($,z,J,Z,Y){try{if(typeof $?.listRecords!=="function")return!0;let G=await $.listRecords(z);if(!G?.success||!Array.isArray(G.records))return!0;return G.records.some((j)=>{let O=typeof j?.name==="string"?j.name.replace(/\.$/,""):"";return j?.type===Y&&O===J&&j?.content===Z})}catch{return!0}}class a0{client;region;constructor($="us-east-1",z){this.region=$,this.client=new A1}async putParameter($){let z={Name:$.Name,Value:$.Value};if($.Type)z.Type=$.Type;if($.Description)z.Description=$.Description;if($.KeyId)z.KeyId=$.KeyId;if($.Overwrite!==void 0)z.Overwrite=$.Overwrite;if($.AllowedPattern)z.AllowedPattern=$.AllowedPattern;if($.Tags&&$.Tags.length>0)z.Tags=$.Tags;if($.Tier)z.Tier=$.Tier;if($.DataType)z.DataType=$.DataType;let J=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(z)});return{Version:J.Version,Tier:J.Tier}}async getParameter($){let z={Name:$.Name};if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;let J=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(z)});return{Parameter:J.Parameter?this.parseParameter(J.Parameter):void 0}}async getParameters($){let z={Names:$.Names};if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>this.parseParameter(Z)),InvalidParameters:J.InvalidParameters}}async getParametersByPath($){let z={Path:$.Path};if($.Recursive!==void 0)z.Recursive=$.Recursive;if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;if($.MaxResults)z.MaxResults=$.MaxResults;if($.NextToken)z.NextToken=$.NextToken;if($.ParameterFilters&&$.ParameterFilters.length>0)z.ParameterFilters=$.ParameterFilters;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:J.NextToken}}async deleteParameter($){let z={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(z)})}async deleteParameters($){let z={Names:$},J=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(z)});return{DeletedParameters:J.DeletedParameters,InvalidParameters:J.InvalidParameters}}async describeParameters($){let z={};if($?.Filters&&$.Filters.length>0)z.Filters=$.Filters;if($?.ParameterFilters&&$.ParameterFilters.length>0)z.ParameterFilters=$.ParameterFilters;if($?.MaxResults)z.MaxResults=$.MaxResults;if($?.NextToken)z.NextToken=$.NextToken;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:J.NextToken}}async getParameterHistory($){let z={Name:$.Name};if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;if($.MaxResults)z.MaxResults=$.MaxResults;if($.NextToken)z.NextToken=$.NextToken;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>({Name:Z.Name,Type:Z.Type,KeyId:Z.KeyId,LastModifiedDate:Z.LastModifiedDate,LastModifiedUser:Z.LastModifiedUser,Description:Z.Description,Value:Z.Value,Version:Z.Version,Labels:Z.Labels,Tier:Z.Tier})),NextToken:J.NextToken}}async labelParameterVersion($){let z={Name:$.Name,Labels:$.Labels};if($.ParameterVersion!==void 0)z.ParameterVersion=$.ParameterVersion;let J=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(z)});return{InvalidLabels:J.InvalidLabels,ParameterVersion:J.ParameterVersion}}async addTagsToResource($){let z={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(z)})}async removeTagsFromResource($){let z={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(z)})}async listTagsForResource($){let z={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(z)})).TagList}}async setString($,z,J){return this.putParameter({Name:$,Value:z,Type:"String",Description:J?.description,Overwrite:J?.overwrite??!0,Tags:J?.tags})}async setSecureString($,z,J){return this.putParameter({Name:$,Value:z,Type:"SecureString",Description:J?.description,Overwrite:J?.overwrite??!0,KeyId:J?.kmsKeyId,Tags:J?.tags})}async getValue($){return(await this.getParameter({Name:$,WithDecryption:!0})).Parameter?.Value}async getAllByPath($,z=!0){let J=[],Z;do{let Y=await this.getParametersByPath({Path:$,Recursive:z,WithDecryption:!0,NextToken:Z});if(Y.Parameters)J.push(...Y.Parameters);Z=Y.NextToken}while(Z);return J}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 z={DocumentName:$.DocumentName};if($.InstanceIds)z.InstanceIds=$.InstanceIds;if($.Targets)z.Targets=$.Targets;if($.Parameters)z.Parameters=$.Parameters;if($.TimeoutSeconds)z.TimeoutSeconds=$.TimeoutSeconds;if($.Comment)z.Comment=$.Comment;if($.OutputS3BucketName)z.OutputS3BucketName=$.OutputS3BucketName;if($.OutputS3KeyPrefix)z.OutputS3KeyPrefix=$.OutputS3KeyPrefix;let J=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(z)});return{CommandId:J.Command?.CommandId,Status:J.Command?.Status,StatusDetails:J.Command?.StatusDetails}}async getCommandInvocation($){let z={CommandId:$.CommandId,InstanceId:$.InstanceId},J=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(z)});return{Status:J.Status,StatusDetails:J.StatusDetails,StandardOutputContent:J.StandardOutputContent,StandardErrorContent:J.StandardErrorContent,ResponseCode:J.ResponseCode}}async runShellCommand($,z,J){let Z=await this.sendCommand({InstanceIds:[$],DocumentName:"AWS-RunShellScript",Parameters:{commands:z},TimeoutSeconds:J?.timeoutSeconds||600});if(!Z.CommandId)return{success:!1,error:"Failed to send command"};if(J?.waitForCompletion===!1)return{success:!0,status:"Pending"};let Y=J?.pollIntervalMs||2000,G=J?.maxWaitMs||300000,j=Date.now();while(Date.now()-j<G){await new Promise((O)=>setTimeout(O,Y));try{let O=await this.getCommandInvocation({CommandId:Z.CommandId,InstanceId:$});if(O.Status==="Success")return{success:!0,output:O.StandardOutputContent,error:O.StandardErrorContent,status:O.Status};if(O.Status==="Failed"||O.Status==="Cancelled"||O.Status==="TimedOut")return{success:!1,output:O.StandardOutputContent,error:O.StandardErrorContent||O.StatusDetails,status:O.Status}}catch(O){if(!O.message?.includes("InvocationDoesNotExist"))return{success:!1,error:O.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations($){let z={CommandId:$.CommandId};if($.Details)z.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(z)})).CommandInvocations||[]).map((Y)=>({InstanceId:Y.InstanceId,Status:Y.Status,StatusDetails:Y.StatusDetails,StandardOutputContent:Y.CommandPlugins?.[0]?.Output,StandardErrorContent:Y.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags($){let z=Object.entries($.tags).map(([Q,q])=>({Key:`tag:${Q}`,Values:[q]})),J=await this.sendCommand({Targets:z,DocumentName:"AWS-RunShellScript",Parameters:{commands:$.commands},TimeoutSeconds:$.timeoutSeconds||600,Comment:$.comment});if(!J.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let Z=$.pollIntervalMs||3000,Y=$.maxWaitMs||600000,G=Date.now(),j=new Set(["Success","Failed","Cancelled","TimedOut"]),O=[];while(Date.now()-G<Y){await new Promise((Q)=>setTimeout(Q,Z));try{if(O=await this.listCommandInvocations({CommandId:J.CommandId,Details:!0}),O.length===0)continue;if(O.every((q)=>j.has(q.Status||""))){let q=O.map((W)=>({instanceId:W.InstanceId,status:W.Status||"Unknown",output:W.StandardOutputContent,error:W.StandardErrorContent||W.StatusDetails})),V=O.every((W)=>W.Status==="Success");return{success:V,instanceCount:O.length,perInstance:q,error:V?void 0:"One or more instances reported a non-success status"}}}catch(Q){if(!Q.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:Q.message}}}return{success:!1,instanceCount:O.length,perInstance:O.map((Q)=>({instanceId:Q.InstanceId,status:Q.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}function J0($=!0){if(!$)return[];return["export DEBIAN_FRONTEND=noninteractive","dpkg-query -W -f='${Status}' unattended-upgrades 2>/dev/null | grep -q 'ok installed' || 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 --now unattended-upgrades 2>/dev/null || true"]}var R1=[["nginx",80],["https",443],["phpFpm",9074],["mysql",3306],["postgres",5432],["redis",6379],["meilisearch",7700],["typesense",8108],["smtp",25]];function Qz($=!0){let z=typeof $==="object"?$:{},J=typeof $==="boolean"?$:$.enabled!==!1,Z=Number(z.alerts?.bandwidthTb??0);return{enabled:J,cpuLoadPerCore:z.alerts?.cpuLoadPerCore??2,memPercent:z.alerts?.memPercent??90,diskPercent:z.alerts?.diskPercent??90,bandwidthTb:Number.isFinite(Z)&&Z>0?Z:0,bandwidthPercent:z.alerts?.bandwidthPercent??80}}function Z0($=!0){let{enabled:z,cpuLoadPerCore:J,memPercent:Z,diskPercent:Y,bandwidthTb:G,bandwidthPercent:j}=Qz($);if(!z)return[];let O=Math.round(G*1000000000000),Q=R1.map(([V,W])=>`SVC_${V.toUpperCase()}=$(probe ${W})`),q=R1.map(([V])=>`"${V}":"$SVC_${V.toUpperCase()}"`).join(",");return["if ! command -v sadf >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive; apt-get update -qq; apt-get install -y -qq sysstat; fi","systemctl enable --now sysstat.service 2>/dev/null || true","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)",`read MEM_TOTAL MEM_USED SWAP_TOTAL SWAP_USED <<EOF
|
|
1
|
+
import{Ne as S1}from"./chunk-3gykfyq4.js";import{Ue as y1}from"./chunk-ax9mr6wm.js";import{Xe as t1}from"./chunk-ggn7ax8p.js";import{df as V1,ef as q1,ff as u2}from"./chunk-ddk4rt4j.js";import{Af as e0,Cf as y2,Df as d0,Ff as c0,Gf as L2,Hf as l0,If as l$,Jf as p$,Kf as a$,Lf as r$,Mf as H$,Nf as P0,Pf as I0,Qf as Q1,Rf as K$,gf as U0,hf as H1,if as x1,jf as u,pf as Y0,qf as t0,rf as r0,sf as n0,tf as D1,wf as o0,xf as E0,yf as g2}from"./chunk-tga3hhwk.js";import{Sf as F1}from"./chunk-axhnkn5g.js";import{Uf as i1}from"./chunk-h5pa5men.js";import{$f as n1}from"./chunk-fy8j3y8p.js";import{Og as A1}from"./chunk-fpm59y25.js";import{Ah as I,Ui as O1,ph as V0,qh as _0}from"./chunk-rxcvf10f.js";import{Vo as Rz}from"./chunk-mh0kdzqp.js";import{existsSync as L6,readFileSync as A6}from"node:fs";import{join as R6}from"node:path";import{readFileSync as s1}from"node:fs";import{join as gz}from"node:path";function r6($={}){let z=new Set;for(let J of Object.values($)){if(!J.domain)continue;if(J.redirect||J.deploy==="server"||J.start)z.add(J.domain)}return z}function L$($){return $.replace(/\.$/,"").toLowerCase()}function Zz($,z,J){let Z=L$($.name),Y=L$(z),G=L$(J),j=G===Y?"@":G.endsWith(`.${Y}`)?G.slice(0,-(Y.length+1)):G;return Z===G||Z===j||j==="@"&&(Z===""||Z===Y)}async function Yz($,z,J,Z,Y="A"){let G=await $.listRecords(z);if(!G.success)return[`could not list ${Y} records: ${G.message||"unknown provider error"}`];let j=G.records.filter((q)=>q.type===Y&&Zz(q,z,J)),O=j.findIndex((q)=>q.content===Z);if(j.length<=1||O===-1)return[];let Q=[];for(let[q,V]of j.entries()){if(q===O)continue;let W=await $.deleteRecord(z,V);if(!W.success)Q.push(`could not remove stale ${V.name} ${Y} ${V.content}: ${W.message||"unknown provider error"}`)}return Q}function z0($){if(!$)return;let z=$.trim();if(!z)return;if(!z.includes("/"))return z;let[J]=z.split("/");if(!J.endsWith("::"))return J||void 0;return`${J}1`}var Gz=new Set(["mail","smtp","imap","mx"]);function jz($){return!Gz.has($.split(".")[0]??"")}async function n6($){let{provider:z,zone:J,fqdn:Z,ipv4:Y,ipv6:G,ttl:j=600}=$,O={published:[],warnings:[]},Q=[{type:"A",content:Y}];if(G&&jz(Z))Q.push({type:"AAAA",content:G});for(let{type:q,content:V}of Q){let W=await z.upsertRecord(J,{name:Z,type:q,content:V,ttl:j});if(W?.success===!1){O.warnings.push(`${Z} → ${V} failed: ${W.error||W.message||"unknown error"}`);continue}if(O.warnings.push(...(await Yz(z,J,Z,V,q)).map((H)=>`${Z} cleanup: ${H}`)),await Oz(z,J,Z,V,q))O.published.push({fqdn:Z,type:q,content:V});else O.warnings.push(`${Z} → ${V} reported success at ${z.name} but no matching ${q} record exists — create it manually: ${q} ${Z} → ${V}`)}return O}async function Oz($,z,J,Z,Y){try{if(typeof $?.listRecords!=="function")return!0;let G=await $.listRecords(z);if(!G?.success||!Array.isArray(G.records))return!0;return G.records.some((j)=>{let O=typeof j?.name==="string"?j.name.replace(/\.$/,""):"";return j?.type===Y&&O===J&&j?.content===Z})}catch{return!0}}class a0{client;region;constructor($="us-east-1",z){this.region=$,this.client=new A1}async putParameter($){let z={Name:$.Name,Value:$.Value};if($.Type)z.Type=$.Type;if($.Description)z.Description=$.Description;if($.KeyId)z.KeyId=$.KeyId;if($.Overwrite!==void 0)z.Overwrite=$.Overwrite;if($.AllowedPattern)z.AllowedPattern=$.AllowedPattern;if($.Tags&&$.Tags.length>0)z.Tags=$.Tags;if($.Tier)z.Tier=$.Tier;if($.DataType)z.DataType=$.DataType;let J=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(z)});return{Version:J.Version,Tier:J.Tier}}async getParameter($){let z={Name:$.Name};if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;let J=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(z)});return{Parameter:J.Parameter?this.parseParameter(J.Parameter):void 0}}async getParameters($){let z={Names:$.Names};if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>this.parseParameter(Z)),InvalidParameters:J.InvalidParameters}}async getParametersByPath($){let z={Path:$.Path};if($.Recursive!==void 0)z.Recursive=$.Recursive;if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;if($.MaxResults)z.MaxResults=$.MaxResults;if($.NextToken)z.NextToken=$.NextToken;if($.ParameterFilters&&$.ParameterFilters.length>0)z.ParameterFilters=$.ParameterFilters;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:J.NextToken}}async deleteParameter($){let z={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(z)})}async deleteParameters($){let z={Names:$},J=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(z)});return{DeletedParameters:J.DeletedParameters,InvalidParameters:J.InvalidParameters}}async describeParameters($){let z={};if($?.Filters&&$.Filters.length>0)z.Filters=$.Filters;if($?.ParameterFilters&&$.ParameterFilters.length>0)z.ParameterFilters=$.ParameterFilters;if($?.MaxResults)z.MaxResults=$.MaxResults;if($?.NextToken)z.NextToken=$.NextToken;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:J.NextToken}}async getParameterHistory($){let z={Name:$.Name};if($.WithDecryption!==void 0)z.WithDecryption=$.WithDecryption;if($.MaxResults)z.MaxResults=$.MaxResults;if($.NextToken)z.NextToken=$.NextToken;let J=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(z)});return{Parameters:J.Parameters?.map((Z)=>({Name:Z.Name,Type:Z.Type,KeyId:Z.KeyId,LastModifiedDate:Z.LastModifiedDate,LastModifiedUser:Z.LastModifiedUser,Description:Z.Description,Value:Z.Value,Version:Z.Version,Labels:Z.Labels,Tier:Z.Tier})),NextToken:J.NextToken}}async labelParameterVersion($){let z={Name:$.Name,Labels:$.Labels};if($.ParameterVersion!==void 0)z.ParameterVersion=$.ParameterVersion;let J=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(z)});return{InvalidLabels:J.InvalidLabels,ParameterVersion:J.ParameterVersion}}async addTagsToResource($){let z={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(z)})}async removeTagsFromResource($){let z={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(z)})}async listTagsForResource($){let z={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(z)})).TagList}}async setString($,z,J){return this.putParameter({Name:$,Value:z,Type:"String",Description:J?.description,Overwrite:J?.overwrite??!0,Tags:J?.tags})}async setSecureString($,z,J){return this.putParameter({Name:$,Value:z,Type:"SecureString",Description:J?.description,Overwrite:J?.overwrite??!0,KeyId:J?.kmsKeyId,Tags:J?.tags})}async getValue($){return(await this.getParameter({Name:$,WithDecryption:!0})).Parameter?.Value}async getAllByPath($,z=!0){let J=[],Z;do{let Y=await this.getParametersByPath({Path:$,Recursive:z,WithDecryption:!0,NextToken:Z});if(Y.Parameters)J.push(...Y.Parameters);Z=Y.NextToken}while(Z);return J}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 z={DocumentName:$.DocumentName};if($.InstanceIds)z.InstanceIds=$.InstanceIds;if($.Targets)z.Targets=$.Targets;if($.Parameters)z.Parameters=$.Parameters;if($.TimeoutSeconds)z.TimeoutSeconds=$.TimeoutSeconds;if($.Comment)z.Comment=$.Comment;if($.OutputS3BucketName)z.OutputS3BucketName=$.OutputS3BucketName;if($.OutputS3KeyPrefix)z.OutputS3KeyPrefix=$.OutputS3KeyPrefix;let J=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(z)});return{CommandId:J.Command?.CommandId,Status:J.Command?.Status,StatusDetails:J.Command?.StatusDetails}}async getCommandInvocation($){let z={CommandId:$.CommandId,InstanceId:$.InstanceId},J=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(z)});return{Status:J.Status,StatusDetails:J.StatusDetails,StandardOutputContent:J.StandardOutputContent,StandardErrorContent:J.StandardErrorContent,ResponseCode:J.ResponseCode}}async runShellCommand($,z,J){let Z=await this.sendCommand({InstanceIds:[$],DocumentName:"AWS-RunShellScript",Parameters:{commands:z},TimeoutSeconds:J?.timeoutSeconds||600});if(!Z.CommandId)return{success:!1,error:"Failed to send command"};if(J?.waitForCompletion===!1)return{success:!0,status:"Pending"};let Y=J?.pollIntervalMs||2000,G=J?.maxWaitMs||300000,j=Date.now();while(Date.now()-j<G){await new Promise((O)=>setTimeout(O,Y));try{let O=await this.getCommandInvocation({CommandId:Z.CommandId,InstanceId:$});if(O.Status==="Success")return{success:!0,output:O.StandardOutputContent,error:O.StandardErrorContent,status:O.Status};if(O.Status==="Failed"||O.Status==="Cancelled"||O.Status==="TimedOut")return{success:!1,output:O.StandardOutputContent,error:O.StandardErrorContent||O.StatusDetails,status:O.Status}}catch(O){if(!O.message?.includes("InvocationDoesNotExist"))return{success:!1,error:O.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations($){let z={CommandId:$.CommandId};if($.Details)z.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(z)})).CommandInvocations||[]).map((Y)=>({InstanceId:Y.InstanceId,Status:Y.Status,StatusDetails:Y.StatusDetails,StandardOutputContent:Y.CommandPlugins?.[0]?.Output,StandardErrorContent:Y.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags($){let z=Object.entries($.tags).map(([Q,q])=>({Key:`tag:${Q}`,Values:[q]})),J=await this.sendCommand({Targets:z,DocumentName:"AWS-RunShellScript",Parameters:{commands:$.commands},TimeoutSeconds:$.timeoutSeconds||600,Comment:$.comment});if(!J.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let Z=$.pollIntervalMs||3000,Y=$.maxWaitMs||600000,G=Date.now(),j=new Set(["Success","Failed","Cancelled","TimedOut"]),O=[];while(Date.now()-G<Y){await new Promise((Q)=>setTimeout(Q,Z));try{if(O=await this.listCommandInvocations({CommandId:J.CommandId,Details:!0}),O.length===0)continue;if(O.every((q)=>j.has(q.Status||""))){let q=O.map((W)=>({instanceId:W.InstanceId,status:W.Status||"Unknown",output:W.StandardOutputContent,error:W.StandardErrorContent||W.StatusDetails})),V=O.every((W)=>W.Status==="Success");return{success:V,instanceCount:O.length,perInstance:q,error:V?void 0:"One or more instances reported a non-success status"}}}catch(Q){if(!Q.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:Q.message}}}return{success:!1,instanceCount:O.length,perInstance:O.map((Q)=>({instanceId:Q.InstanceId,status:Q.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}function J0($=!0){if(!$)return[];return["export DEBIAN_FRONTEND=noninteractive","dpkg-query -W -f='${Status}' unattended-upgrades 2>/dev/null | grep -q 'ok installed' || 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 --now unattended-upgrades 2>/dev/null || true"]}var R1=[["nginx",80],["https",443],["phpFpm",9074],["mysql",3306],["postgres",5432],["redis",6379],["meilisearch",7700],["typesense",8108],["smtp",25]];function Qz($=!0){let z=typeof $==="object"?$:{},J=typeof $==="boolean"?$:$.enabled!==!1,Z=Number(z.alerts?.bandwidthTb??0);return{enabled:J,cpuLoadPerCore:z.alerts?.cpuLoadPerCore??2,memPercent:z.alerts?.memPercent??90,diskPercent:z.alerts?.diskPercent??90,bandwidthTb:Number.isFinite(Z)&&Z>0?Z:0,bandwidthPercent:z.alerts?.bandwidthPercent??80}}function Z0($=!0){let{enabled:z,cpuLoadPerCore:J,memPercent:Z,diskPercent:Y,bandwidthTb:G,bandwidthPercent:j}=Qz($);if(!z)return[];let O=Math.round(G*1000000000000),Q=R1.map(([V,W])=>`SVC_${V.toUpperCase()}=$(probe ${W})`),q=R1.map(([V])=>`"${V}":"$SVC_${V.toUpperCase()}"`).join(",");return["if ! command -v sadf >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive; apt-get update -qq; apt-get install -y -qq sysstat; fi","systemctl enable --now sysstat.service 2>/dev/null || true","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)",`read MEM_TOTAL MEM_USED SWAP_TOTAL SWAP_USED <<EOF
|
|
2
2
|
$(free -m | awk '/^Mem:/{total=$2; used=$3} /^Swap:/{print total, used, $2, $3}')
|
|
3
3
|
EOF`,`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)`,"NOW_EPOCH=$(date -u +%s); TODAY=$(date -u +%Y-%m-%d); MONTH=$(date -u +%Y-%m)","if [ -r /var/lib/ts-cloud/bandwidth-state ]; then . /var/lib/ts-cloud/bandwidth-state; fi","PREV_EPOCH=${PREV_EPOCH:-0}; PREV_RX=${PREV_RX:-0}; PREV_TX=${PREV_TX:-0}","DAY_KEY=${DAY_KEY:-$TODAY}; MONTH_KEY=${MONTH_KEY:-$MONTH}","DAY_RX=${DAY_RX:-0}; DAY_TX=${DAY_TX:-0}; MONTH_RX=${MONTH_RX:-0}; MONTH_TX=${MONTH_TX:-0}","ELAPSED=$(( NOW_EPOCH - PREV_EPOCH ))",'if [ "$PREV_EPOCH" -le 0 ] || [ "$ELAPSED" -le 0 ] || [ "$RX_BYTES" -lt "$PREV_RX" ] || [ "$TX_BYTES" -lt "$PREV_TX" ]; then'," DELTA_RX=0; DELTA_TX=0; ELAPSED=0","else"," DELTA_RX=$(( RX_BYTES - PREV_RX )); DELTA_TX=$(( TX_BYTES - PREV_TX ))","fi",'if [ "$DAY_KEY" != "$TODAY" ]; then DAY_KEY=$TODAY; DAY_RX=0; DAY_TX=0; fi','if [ "$MONTH_KEY" != "$MONTH" ]; then MONTH_KEY=$MONTH; MONTH_RX=0; MONTH_TX=0; fi',"DAY_RX=$(( DAY_RX + DELTA_RX )); DAY_TX=$(( DAY_TX + DELTA_TX ))","MONTH_RX=$(( MONTH_RX + DELTA_RX )); MONTH_TX=$(( MONTH_TX + DELTA_TX ))",'if [ "$ELAPSED" -gt 0 ]; then RX_RATE=$(( DELTA_RX / ELAPSED )); TX_RATE=$(( DELTA_TX / ELAPSED )); else RX_RATE=0; TX_RATE=0; fi',"cat > /var/lib/ts-cloud/bandwidth-state.tmp <<BWSTATE","PREV_EPOCH=$NOW_EPOCH","PREV_RX=$RX_BYTES","PREV_TX=$TX_BYTES","RX_RATE=$RX_RATE","TX_RATE=$TX_RATE","DAY_KEY=$DAY_KEY","DAY_RX=$DAY_RX","DAY_TX=$DAY_TX","MONTH_KEY=$MONTH_KEY","MONTH_RX=$MONTH_RX","MONTH_TX=$MONTH_TX","BWSTATE","mv -f /var/lib/ts-cloud/bandwidth-state.tmp /var/lib/ts-cloud/bandwidth-state","probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...Q,"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,"rxBytesPerSec":$RX_RATE,"txBytesPerSec":$TX_RATE,"dayKey":"$DAY_KEY","rxBytesToday":$DAY_RX,"txBytesToday":$DAY_TX,"monthKey":"$MONTH_KEY","rxBytesMonth":$MONTH_RX,"txBytesMonth":$MONTH_TX,"budgetBytes":${O}},"services":{`+q+"}}","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=${J} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${J}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${Z} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${Y} ]; 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",...O>0?["BW_TOTAL=$(( MONTH_RX + MONTH_TX ))",`BW_PCT=$(( BW_TOTAL * 100 / ${O} ))`,"BW_PREV=$(cat /var/lib/ts-cloud/bandwidth-alert-state 2>/dev/null || echo ok)",`if [ "$BW_PCT" -ge ${j} ]; then`,` if [ "$BW_PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): bandwidth at \${BW_PCT}% of the ${G} TB monthly allowance ($MONTH_KEY)" || true; fi`," echo alert > /var/lib/ts-cloud/bandwidth-alert-state","else",' if [ "$BW_PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): bandwidth back under the monthly allowance (${BW_PCT}%)" || true; fi'," echo ok > /var/lib/ts-cloud/bandwidth-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]","OnCalendar=*-*-* *:*:00","AccuracySec=1s","RandomizedDelaySec=5s","Persistent=true","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable --now ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.service"]}var Vz={"opcache.enable":"1","opcache.enable_cli":"1","opcache.memory_consumption":"256","opcache.interned_strings_buffer":"16","opcache.max_accelerated_files":"20000","opcache.validate_timestamps":"0","opcache.revalidate_freq":"0","opcache.save_comments":"1","opcache.fast_shutdown":"1",realpath_cache_size:"4096K",realpath_cache_ttl:"600"},qz="127.0.0.1:9074";function _1($){return qz}function Wz($={}){let z=$.versions?.length?$.versions:["8.3"];return $.default&&z.includes($.default)?$.default:z[0]}function Hz($={}){return{...$.optimizeForProduction===!1?{}:{...Vz},...$.ini||{}}}function Mz($={}){let z=Hz($),J=Object.keys(z);if(J.length===0)return[];let Z=J.map((G)=>`${G}=${z[G]}`),Y="ts-cloud-managed";return[r0(),"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'`,`; ${Y} — production PHP tuning`,...Z,"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 '/; ${Y} BEGIN/,/; ${Y} END/d' "$TS_CLOUD_LOADED_INI"`,` cat >> "$TS_CLOUD_LOADED_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${Y} BEGIN`,...Z,`; ${Y} END`,"TS_CLOUD_PHPINI_EOF","fi",`(cd ${Y0} && pantry restart php-fpm) 2>/dev/null || true`]}function i0($={}){let z=Wz($),J=$.installNginx!==!1,Z=$.installComposer!==!1,Y=[`php.net@${z}`];if(Z)Y.push("getcomposer.org");if(J)Y.push("nginx.org");return[...n0(Y),...D1(["php-fpm"]),...Mz($)]}function A$($,z){if(!$)return[];let J=[];if($.template&&z?.[$.template])J.push(...z[$.template]);if($.serverSnippet)J.push(...$.serverSnippet);return J}function Xz($){if(!$)return"";let z=typeof $==="object"?$:{},Z=[`max-age=${z.maxAge??31536000}`];if(z.includeSubDomains??!0)Z.push("includeSubDomains");if(z.preload)Z.push("preload");return` add_header Strict-Transport-Security "${Z.join("; ")}" always;`}function Kz($){if(!$||!$.allow?.length&&!$.deny?.length)return[];let z=[];for(let J of $.deny||[])z.push(` deny ${J};`);if($.allow?.length){for(let J of $.allow)z.push(` allow ${J};`);z.push(" deny all;")}return z}function E1($){return`/etc/nginx/.htpasswd-${$}`}var Fz=new Set(["laravel","php","statamic","wordpress"]);function Bz($){return Fz.has($)}function Uz($){return $==="laravel"||$==="statamic"?"public":""}function Cz($,z){let J=$.replace(/\/+$/,""),Z=z.replace(/^\/+|\/+$/g,"");return Z?`${J}/${Z}`:J}function Lz($){let z=$.type??"laravel",J=$.webDirectory??Uz(z),Z=Cz($.appDir,J),Y=Bz(z),G=$.phpVersion??"8.3",j=[` root ${Z};`,"",' add_header X-Frame-Options "SAMEORIGIN";',' add_header X-Content-Type-Options "nosniff";'],O=Xz($.hsts);if(O)j.push(O);for(let Q of Kz($.security))j.push(Q);if(j.push("",` index ${Y?"index.php index.html":"index.html index.htm"};`,""," charset utf-8;",""),$.clientMaxBodySize)j.push(` client_max_body_size ${$.clientMaxBodySize};`,"");if($.auth)j.push(` auth_basic "${$.auth.realm||"Restricted"}";`,` auth_basic_user_file ${E1($.siteName)};`,"");for(let[Q,q]of Object.entries($.redirects||{}))j.push(` location = ${Q} { return 301 ${q}; }`);if(Object.keys($.redirects||{}).length>0)j.push("");if(Y){if(j.push(" location / {"," try_files $uri $uri/ /index.php?$query_string;"," }",""," location = /favicon.ico { access_log off; log_not_found off; }"," location = /robots.txt { access_log off; log_not_found off; }",""," error_page 404 /index.php;",""," location ~ \\.php$ {",` fastcgi_pass ${$.fastcgiPass??_1(G)};`," fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;"," include fastcgi_params;"," }",""," location ~ /\\.(?!well-known).* {"," deny all;"," }"),z==="wordpress")j.push(""," location = /xmlrpc.php { deny all; }"," location ~* /(?:wp-config\\.php|readme\\.html|license\\.txt)$ { deny all; }"," location ~* /wp-content/uploads/.*\\.php$ { deny all; }")}else if(z==="spa")j.push(" location / {"," try_files $uri $uri/ /index.html;"," }");else j.push(" location / {"," try_files $uri $uri/ =404;"," }");if($.serverSnippet&&$.serverSnippet.length>0){j.push("");for(let Q of $.serverSnippet)j.push(Q?` ${Q}`:"")}return j}function Az($){let z=[$.domain,...$.aliases||[]].filter(Boolean);for(let G of z)if(!/^(?=.{1,253}$)(?:\*\.)?[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i.test(G.trim()))throw Error(`Refusing to build a vhost: '${G}' is not a valid hostname.`);if(!z.length)throw Error("Refusing to build a vhost: no server_name (domain) was given.");let J=z.join(" "),Z=Lz($);if($.ssl){let G=["server {"," listen 80;"," listen [::]:80;",` server_name ${J};`," return 301 https://$host$request_uri;","}"],j=["server {"," listen 443 ssl;"," listen [::]:443 ssl;",` server_name ${J};`,` ssl_certificate ${$.ssl.certPath};`,` ssl_certificate_key ${$.ssl.keyPath};`,...$.tlsProtocols?.length?[` ssl_protocols ${$.tlsProtocols.join(" ")};`]:[],"",...Z,"}"];return`${[...G,"",...j].join(`
|
|
4
4
|
`)}
|