@stacksjs/ts-cloud 0.12.9 → 0.12.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aws/index.js +1 -1
- package/dist/aws/sms-voice.d.ts +35 -0
- package/dist/bin/{chunk-tfbs8k8v.js → chunk-0x8szp53.js} +1 -1
- package/dist/bin/chunk-1hggd7yz.js +1 -0
- package/dist/bin/{chunk-rtecnmts.js → chunk-2pevjm25.js} +2 -2
- package/dist/bin/{chunk-0zwknfwp.js → chunk-2tsg6e8j.js} +1 -1
- package/dist/{chunk-c8cadhgc.js → bin/chunk-3f27aa5r.js} +2 -2
- package/dist/bin/{chunk-dz1ec589.js → chunk-3g80gjw6.js} +2 -2
- package/dist/bin/chunk-40j9hgzc.js +1 -0
- package/dist/bin/{chunk-82mj52xr.js → chunk-48eb4z0c.js} +1 -1
- package/dist/bin/chunk-4gqfdr7t.js +1 -0
- package/dist/{chunk-pb47hr0h.js → bin/chunk-5gx38418.js} +1 -1
- package/dist/bin/chunk-5jv4cpky.js +1 -0
- package/dist/bin/chunk-5kxm5mx7.js +1 -0
- package/dist/bin/{chunk-my3ewh3a.js → chunk-5rhvcgzt.js} +2 -2
- package/dist/bin/{chunk-mcr0r4at.js → chunk-8223r1xn.js} +2 -2
- package/dist/bin/{chunk-4q6tad44.js → chunk-84703zpq.js} +91 -91
- package/dist/bin/{chunk-3aph4c1w.js → chunk-9edyzdm0.js} +1 -1
- package/dist/bin/{chunk-xhwqpgwq.js → chunk-9xbsmz1f.js} +1 -1
- package/dist/bin/{chunk-mfrf9q4b.js → chunk-a8t3c4qe.js} +1 -1
- package/dist/bin/chunk-aghy01we.js +1 -0
- package/dist/{chunk-w2ddj42w.js → bin/chunk-akwfvn5k.js} +1 -1
- package/dist/bin/chunk-asvz121j.js +1 -0
- package/dist/bin/{chunk-6tfwm33r.js → chunk-b0xtsv8k.js} +3 -3
- package/dist/bin/chunk-bcpdj01b.js +1 -0
- package/dist/bin/{chunk-btsyjhk7.js → chunk-bj4ft4qc.js} +2 -2
- package/dist/bin/chunk-da49my09.js +1 -0
- package/dist/bin/{chunk-hq9x489e.js → chunk-dep2n31v.js} +1 -1
- package/dist/bin/{chunk-b4wt9jcg.js → chunk-ewxf62t8.js} +2 -2
- package/dist/bin/{chunk-e2bybahr.js → chunk-f42gqn6c.js} +1 -1
- package/dist/bin/{chunk-s4yzes15.js → chunk-fc6r1ack.js} +1 -1
- package/dist/bin/{chunk-vj2dp0nh.js → chunk-ftcjjf76.js} +6 -6
- package/dist/bin/chunk-g76sry03.js +1 -0
- package/dist/bin/{chunk-e5ab5twy.js → chunk-hv3w2qy1.js} +2 -2
- package/dist/bin/{chunk-9a88fp00.js → chunk-hwdfky19.js} +2 -2
- package/dist/bin/chunk-j02d6qmn.js +1 -0
- package/dist/bin/{chunk-8ewncfce.js → chunk-j2cb8we4.js} +1 -1
- package/dist/bin/chunk-kmz8vb77.js +1 -0
- package/dist/bin/{chunk-0thy7q96.js → chunk-kyr5rasx.js} +74 -75
- package/dist/bin/{chunk-ja1vjdn1.js → chunk-mhrtx0p1.js} +1 -1
- package/dist/bin/{chunk-w32xv8n4.js → chunk-nc9pp87y.js} +2 -2
- package/dist/bin/{chunk-xk08030d.js → chunk-ncrnbcsa.js} +2 -2
- package/dist/bin/chunk-py1hyeb2.js +1 -0
- package/dist/bin/{chunk-q5cmfpzt.js → chunk-qa06sft7.js} +1 -1
- package/dist/bin/{chunk-azymqbcy.js → chunk-qr0xck72.js} +1 -1
- package/dist/bin/chunk-r85ahkwq.js +1 -0
- package/dist/bin/{chunk-ehc63fvs.js → chunk-re15e6p4.js} +1 -1
- package/dist/bin/chunk-t6y3pkm8.js +1 -0
- package/dist/bin/{chunk-c0bdafbx.js → chunk-tfmx17he.js} +1 -1
- package/dist/bin/chunk-vfcchrby.js +1 -0
- package/dist/bin/chunk-vmdh41kp.js +1 -0
- package/dist/bin/{chunk-cd0ps58j.js → chunk-vrc7eemq.js} +1 -1
- package/dist/bin/{chunk-d7ke90zt.js → chunk-vsd7670h.js} +1 -1
- package/dist/bin/{chunk-kg61p5hw.js → chunk-vwqn3yx6.js} +2 -2
- package/dist/bin/{chunk-71t1gmsq.js → chunk-vxbnjz78.js} +1 -1
- package/dist/bin/chunk-w8s8vgdj.js +1 -0
- package/dist/bin/chunk-yq9vetf8.js +698 -0
- package/dist/bin/{chunk-zpe64t4r.js → chunk-zrgd65r8.js} +1 -1
- package/dist/bin/cli.js +143 -143
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/{chunk-fgfm7cfm.js → chunk-0a4tqwm9.js} +89 -90
- package/dist/{chunk-982rye5b.js → chunk-2ybcnrte.js} +1 -1
- package/dist/chunk-4884der5.js +1 -0
- package/dist/{bin/chunk-9kf0np8j.js → chunk-4wdxsnn2.js} +1 -1
- package/dist/{bin/chunk-xkfrqqcs.js → chunk-5hhyyhjt.js} +1 -1
- package/dist/chunk-5zkacdw1.js +1 -0
- package/dist/{chunk-557qj7q9.js → chunk-6cxb8d6y.js} +2 -2
- package/dist/chunk-6f68caq0.js +1 -0
- package/dist/{chunk-2qm3rw8b.js → chunk-7z50g5xz.js} +2 -2
- package/dist/chunk-8fh4m5ge.js +1 -0
- package/dist/chunk-97pb7wb1.js +1 -0
- package/dist/{chunk-a368cs92.js → chunk-ac87ds1k.js} +1 -1
- package/dist/{chunk-qrte4gy2.js → chunk-dndxwssj.js} +1 -1
- package/dist/{bin/chunk-a7w13qfm.js → chunk-ess6vxfj.js} +2 -2
- package/dist/chunk-fvpkxznh.js +558 -0
- package/dist/{chunk-rg7d67xk.js → chunk-j06r5rwv.js} +1 -1
- package/dist/{chunk-70v77sqv.js → chunk-j1g67djb.js} +2 -2
- package/dist/{chunk-fbwpm0zm.js → chunk-k8x8mrkr.js} +1 -1
- package/dist/{chunk-82gezmen.js → chunk-mnmz8t7q.js} +1 -1
- package/dist/{chunk-7j100g7w.js → chunk-n1fyryha.js} +1 -1
- package/dist/{chunk-c1hr34a5.js → chunk-n1hg0jxs.js} +2 -2
- package/dist/{chunk-bcffjsnj.js → chunk-n5xmh0ma.js} +1 -1
- package/dist/chunk-q22qfwsc.js +22 -0
- package/dist/{chunk-5hkq5081.js → chunk-q9a1z53k.js} +2 -2
- package/dist/{chunk-fsssdd5k.js → chunk-r8t25tbm.js} +91 -91
- package/dist/{chunk-2k0mt6j5.js → chunk-whyttetx.js} +1 -1
- package/dist/{chunk-a5213256.js → chunk-yf8stygs.js} +6 -6
- package/dist/{chunk-jphewtbx.js → chunk-ze5x2bpm.js} +1 -1
- package/dist/{chunk-jxrs1219.js → chunk-zh0apedk.js} +2 -2
- package/dist/{chunk-0hw5wjjg.js → chunk-zjyz926j.js} +1 -1
- package/dist/deploy/index.js +1 -1
- package/dist/dns/index.js +1 -1
- package/dist/drivers/hetzner/cloud-init.d.ts +14 -1
- package/dist/drivers/hetzner/driver.d.ts +2 -15
- package/dist/drivers/hetzner/state.d.ts +17 -2
- package/dist/drivers/index.d.ts +17 -1
- package/dist/drivers/index.js +1 -1
- package/dist/drivers/local-box/driver.d.ts +1 -1
- package/dist/drivers/shared/compute-provision.d.ts +7 -0
- package/dist/drivers/shared/driver-state.d.ts +68 -0
- package/dist/drivers/shared/remote-exec.d.ts +10 -1
- package/dist/drivers/shared/remote-failure.d.ts +41 -0
- package/dist/drivers/shared/ssh-transport.d.ts +121 -0
- package/dist/drivers/ssh/bootstrap.d.ts +61 -0
- package/dist/drivers/ssh/config.d.ts +86 -0
- package/dist/drivers/ssh/config.test.d.ts +1 -0
- package/dist/drivers/ssh/driver.d.ts +107 -0
- package/dist/drivers/ssh/factory-wiring.test.d.ts +1 -0
- package/dist/drivers/ssh/first-boot.d.ts +38 -0
- package/dist/drivers/ssh/preflight.d.ts +76 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +7 -7
- package/dist/operations/index.js +1 -1
- package/dist/operations/inventory.d.ts +46 -1
- package/dist/protection/index.js +1 -1
- package/dist/push/index.js +1 -1
- package/dist/spend/index.js +1 -1
- package/dist/ui/404.html +1 -1
- package/dist/ui/accept-invitation.html +1 -1
- package/dist/ui/access-denied.html +2 -2
- package/dist/ui/account/automation.html +6 -6
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +6 -6
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +6 -6
- package/dist/ui/data/services.html +6 -6
- package/dist/ui/data/volumes.html +6 -6
- package/dist/ui/index.html +6 -6
- package/dist/ui/infrastructure/topology.html +6 -6
- package/dist/ui/integrations.html +2 -2
- package/dist/ui/operations/alerts.html +6 -6
- package/dist/ui/operations/configuration.html +6 -6
- package/dist/ui/operations/jobs.html +6 -6
- 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 +5 -5
- package/dist/ui/operations/releases.html +5 -5
- package/dist/ui/operations/spend.html +6 -6
- package/dist/ui/operations/workloads.html +6 -6
- package/dist/ui/security.html +1 -1
- package/dist/ui/server/actions.html +6 -6
- package/dist/ui/server/activity.html +1 -1
- package/dist/ui/server/capacity.html +6 -6
- package/dist/ui/server/database.html +6 -6
- package/dist/ui/server/deployments.html +5 -5
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +5 -5
- package/dist/ui/server/fleet.html +6 -6
- package/dist/ui/server/logs.html +6 -6
- package/dist/ui/server/metrics.html +5 -5
- package/dist/ui/server/security.html +2 -2
- package/dist/ui/server/services.html +2 -2
- package/dist/ui/server/sites.html +6 -6
- package/dist/ui/server/ssh-keys.html +6 -6
- package/dist/ui/server/team.html +6 -6
- package/dist/ui/server/terminal.html +2 -2
- package/dist/ui/serverless/alarms.html +6 -6
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/cost.html +2 -2
- package/dist/ui/serverless/data.html +6 -6
- package/dist/ui/serverless/deployments.html +2 -2
- package/dist/ui/serverless/firewall.html +2 -2
- 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 +6 -6
- package/dist/ui-src/src/charts.ts +1 -1
- package/dist/ui-src/src/topology.ts +1 -1
- package/package.json +3 -3
- package/dist/bin/chunk-04dkwaqp.js +0 -1
- package/dist/bin/chunk-5nkqza92.js +0 -1
- package/dist/bin/chunk-64vczwwt.js +0 -1
- package/dist/bin/chunk-7g2ahkse.js +0 -1
- package/dist/bin/chunk-aw8bhggq.js +0 -594
- package/dist/bin/chunk-cxt74wsj.js +0 -1
- package/dist/bin/chunk-djg4zyqk.js +0 -1
- package/dist/bin/chunk-dkaz333b.js +0 -1
- package/dist/bin/chunk-edvvx3hg.js +0 -1
- package/dist/bin/chunk-f06c5np9.js +0 -1
- package/dist/bin/chunk-gq8794k6.js +0 -1
- package/dist/bin/chunk-k3120rx6.js +0 -1
- package/dist/bin/chunk-nw3d4k52.js +0 -1
- package/dist/bin/chunk-p70bc9yr.js +0 -1
- package/dist/bin/chunk-sg1g92cf.js +0 -1
- package/dist/bin/chunk-tvz9c388.js +0 -1
- package/dist/bin/chunk-y1h63vpm.js +0 -1
- package/dist/bin/chunk-zdt2rjk6.js +0 -1
- package/dist/bin/chunk-zh2d4704.js +0 -1
- package/dist/chunk-1bj94sc2.js +0 -1
- package/dist/chunk-3swnmwfc.js +0 -454
- package/dist/chunk-5pbtmy2k.js +0 -1
- package/dist/chunk-7sc8t7v1.js +0 -1
- package/dist/chunk-gny5s4kp.js +0 -1
- package/dist/chunk-qpjcd415.js +0 -22
- package/dist/chunk-xkw7h4pw.js +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
export{P as
|
|
1
|
+
import{ho as h,io as y}from"./chunk-r8t25tbm.js";function P(t,s){return`/var/www/${t}-${s}`}var v=new Set(["laravel","php","statamic","wordpress"]);function g(t){return t.type!=null&&v.has(t.type)}function b(t){let s=t.proxyTo;if(s==null)return[];return(Array.isArray(s)?s:[s]).map((n)=>String(n).trim()).filter((n)=>n.length>0)}function x(t){return b(t).length>0}function S(t){if(t.deploy)return t.deploy;if(g(t))return"server";if(t.start)return"server";return"bucket"}function l(t){if(t.redirect)return"redirect";if(x(t))return"proxy";if(g(t))return"server-php";if(S(t)==="bucket")return"bucket";return t.start?"server-app":"server-static"}function C(t){return t.infrastructure?.compute!=null||Boolean(t.cloud?.attachTo?.trim())}function T(t,s={}){let r=[],n=[],a=t.sites||{},p=C(t),f=y(t);if(f)r.push(f);let d=new Map;for(let[o,e]of Object.entries(a)){if(!e)continue;let m=S(e),c=l(e);if(c==="redirect"){if(!e.domain)r.push(`Site '${o}' is a redirect site but has no \`domain\` to redirect from.`);if(!(typeof e.redirect==="string"?e.redirect:e.redirect?.to))r.push(`Site '${o}' is a redirect site but has no redirect target (\`redirect\` / \`redirect.to\`).`);if(!p)r.push(`Site '${o}' is a redirect site but no \`infrastructure.compute\` is configured to host the gateway that serves the redirect.`);let u=[];if(e.start)u.push("start");if(e.root)u.push("root");if(e.proxyTo)u.push("proxyTo");if(u.length>0)n.push(`Site '${o}' is a redirect site but also sets ${u.join(", ")}. These are ignored.`);continue}if(c==="proxy"){if(!e.domain)r.push(`Site '${o}' is a proxy site but has no \`domain\` to route from.`);if(!p)r.push(`Site '${o}' is a proxy site but no \`infrastructure.compute\` is configured to host the gateway that forwards it.`);let i=[];if(e.start)i.push("start");if(e.root)i.push("root");if(typeof e.port==="number")i.push("port");if(e.build)i.push("build");if(e.preStart&&e.preStart.length>0)i.push("preStart");if(i.length>0)n.push(`Site '${o}' sets \`proxyTo\`, so ts-cloud ships and supervises nothing for it. ${i.join(", ")} ${i.length===1?"is":"are"} ignored — remove ${i.length===1?"it":"them"}, or drop \`proxyTo\` to let ts-cloud own the service.`);continue}if(m==="server"&&!e.start&&!e.root){r.push(`Site '${o}' sets deploy:'server' but declares neither \`start\` (dynamic app) nor \`root\` (static site to serve). Add one.`);continue}if(c==="server-php"){if(!p)r.push(`Site '${o}' is a PHP site (type:'${e.type}') but no \`infrastructure.compute\` is configured. Add a server (infrastructure.compute) with PHP provisioning.`);if(!e.repository?.url)r.push(`Site '${o}' is a PHP site (type:'${e.type}') but has no \`repository.url\` to clone. PHP sites deploy via git.`)}else if(c==="server-app"){if(!p)r.push(`Site '${o}' deploys to a server (deploy:'server'${e.deploy?"":" inferred from `start`"}) but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`);if(typeof e.port==="number"){let i=s.occupiedPorts?.get(e.port);if(i)r.push(`Site '${o}' wants port ${e.port}, which project '${i}' already serves on this box. Attached projects share one port namespace. Give '${o}' a free port, or let the attach allocate one.`);let u=d.get(e.port);if(u)r.push(`Sites '${u}' and '${o}' both use port ${e.port}. Server apps sharing a box must use distinct ports.`);else d.set(e.port,o)}}else if(c==="server-static"){if(!e.root)r.push(`Site '${o}' is a server static site (deploy:'server', no \`start\`) but has no \`root\` directory to serve.`);if(!p)r.push(`Site '${o}' deploys to a server (deploy:'server') but no \`infrastructure.compute\` is configured. Set deploy:'bucket' or add a server (infrastructure.compute).`)}else{if(!e.root)r.push(`Site '${o}' deploys to a bucket but has no \`root\` directory to upload.`);let i=[];if(e.start)i.push("start");if(typeof e.port==="number")i.push("port");if(e.preStart&&e.preStart.length>0)i.push("preStart");if(i.length>0)n.push(`Site '${o}' deploys to a bucket but sets server-only field(s): ${i.join(", ")}. These are ignored. Set deploy:'server' to use them.`)}}return{errors:r,warnings:n}}function k(t){let s=l(t);return s!=="bucket"&&s!=="redirect"&&s!=="proxy"}function D(t){return l(t)==="bucket"}function j(t,s){if(h(t)==="serverless")return!0;let r=Object.entries(t.sites??{}).filter(([,a])=>a!=null),n=s?r.filter(([a])=>a===s):r;if(n.length===0)return!0;return!n.every(([,a])=>{let p=l(a);return p==="redirect"||p==="proxy"})}
|
|
2
|
+
export{P as vk,g as wk,b as xk,x as yk,S as zk,l as Ak,C as Bk,T as Ck,k as Dk,D as Ek,j as Fk};
|
|
@@ -34,4 +34,4 @@ fi
|
|
|
34
34
|
mv "${s}.new" "${s}"
|
|
35
35
|
echo "ts-cloud: WAF config installed (mode: ${n.mode})"
|
|
36
36
|
`}function _(e,r){return e.map((t)=>({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,kind:"event",source:"zig-waf",name:t.action==="blocked"?"waf.blocked":"waf.matched",timestamp:t.timestamp,value:1,host:t.host,pathTemplate:t.path,method:t.method,attributes:{ruleId:t.ruleId??null,anomalyScore:t.anomalyScore,action:t.action,messages:t.messages.slice(0,5)}}))}
|
|
37
|
-
export{l as
|
|
37
|
+
export{l as hj,g as ij,R as jj,v as kj,I as lj,_ as mj};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import{ok as g,rk as w,sk as y,tk as v}from"./chunk-7z50g5xz.js";function D(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function tt(t,e="/var/www"){let n=`${e}/${t}-`;return["set -u",`for TS_CLOUD_DIR in ${n}*; do`,' [ -d "$TS_CLOUD_DIR" ] || continue',' [ -d "$TS_CLOUD_DIR/releases" ] || continue',` TS_CLOUD_SITE="\${TS_CLOUD_DIR#${n}}"`," TS_CLOUD_ACTIVE=no",` for TS_CLOUD_UNIT in $(ls /etc/systemd/system/ 2>/dev/null | grep -E "^${D(t)}-$TS_CLOUD_SITE[-@.]" || true); do`,' systemctl is-active "$TS_CLOUD_UNIT" >/dev/null 2>&1 && TS_CLOUD_ACTIVE=yes'," done",' TS_CLOUD_SIZE="$(du -sh "$TS_CLOUD_DIR" 2>/dev/null | cut -f1)"',' echo "site:$TS_CLOUD_SITE:$TS_CLOUD_ACTIVE:${TS_CLOUD_SIZE:-?}"',"done","exit 0"]}function et(t){if(!t)return[];let e=[];for(let n of t.split(`
|
|
2
|
+
`)){let r=n.trim();if(!r.startsWith("site:"))continue;let[,s,o,i]=r.split(":");if(!s||o!=="no")continue;e.push({name:s,size:i||"?"})}return e}function nt(t,e,n){let r=t.map((o)=>` ${e}-${o.name} (${o.size})`).join(`
|
|
3
|
+
`),s=t.length===1?"it":"them";return`This server still holds ${t.length} site tree${t.length===1?"":"s"} with nothing running for ${s}:
|
|
4
|
+
${r}
|
|
5
|
+
`+"A site moved off this box keeps its files here on purpose — they are the rollback, and they are what makes "+`the move reversible until this server is destroyed. Destroying it now discards that.
|
|
6
|
+
Verify the site is serving from its new home first, then re-run with ${n} to destroy it anyway.`}var R="ts-cloud/project",T="ts-cloud/environment",E="ts-cloud/role";function d(t){return typeof t==="string"&&t.trim()?t.trim():void 0}function m(t){if(typeof t==="string")return d(t);if(t&&typeof t==="object")return d(t.name);return}function ot(t){let e={};for(let[n,r]of Object.entries(t?.labels??{}))if(typeof r==="string")e[n]=r;return{id:String(t?.id??""),name:d(t?.name)??"(unnamed)",status:d(t?.status)??"unknown",ipv4:d(t?.public_net?.ipv4?.ip)??d(t?.ipv4),ipv6:d(t?.public_net?.ipv6?.ip)??d(t?.ipv6),type:d(t?.server_type?.name)??d(t?.type),location:m(t?.location)??m(t?.datacenter?.location)??m(t?.datacenter),labels:e,project:d(e[R]),environment:d(e[T]),role:d(e[E])}}function _(t){return t.slug?.trim()||"app"}function j(t){let e=[];for(let n of t){let r=_(n);for(let s of n.proxies??[]){let o=d(s?.to);if(!o)continue;e.push({slug:r,host:o,path:d(s?.path)??"/",...I(s)})}}return e.sort((n,r)=>n.slug.localeCompare(r.slug)||n.host.localeCompare(r.host)||n.path.localeCompare(r.path))}function I(t){let e=t?.from;if(typeof e==="string"&&e.trim())return{target:e.trim(),kind:"app"};if(Array.isArray(e)&&e.length>0)return{target:e.filter((s)=>typeof s==="string").join(", "),kind:"app"};let n=t?.static;if(typeof n==="string"&&n.trim())return{target:n.trim(),kind:"static"};if(n&&typeof n==="object"&&d(n.dir))return{target:d(n.dir),kind:"static"};let r=typeof t?.redirect==="string"?d(t.redirect):d(t?.redirect?.to);if(r)return{target:r,kind:"redirect"};return{target:"(no upstream)",kind:"unknown"}}function H(t){let e=new Map;for(let n of t){let r=e.get(n.slug);if(r)r.push(n);else e.set(n.slug,[n])}return[...e.entries()].map(([n,r])=>({slug:n,routes:r})).sort((n,r)=>r.routes.length-n.routes.length||n.slug.localeCompare(r.slug))}async function st(t,e,n=g){if(!t.ipv4)return{server:t.name,routes:[],unavailable:"no public IPv4 address to reach it on"};if(t.status!=="running")return{server:t.name,ip:t.ipv4,routes:[],unavailable:`server is ${t.status}`};try{let r=await e(t.ipv4,y(n));if(r.code!==0){let s=r.stderr.trim().split(`
|
|
7
|
+
`)[0]||`remote command exited ${r.code}`;return{server:t.name,ip:t.ipv4,routes:[],unavailable:s}}return{server:t.name,ip:t.ipv4,routes:j(v(r.stdout))}}catch(r){let s=r instanceof Error?r.message.split(`
|
|
8
|
+
`)[0]:String(r);return{server:t.name,ip:t.ipv4,routes:[],unavailable:s}}}function u(t,e){let n=e==="/"?"/":e.replace(/\/+$/,"");return`${t.toLowerCase()}${n||"/"}`}function at(t,e,n){let r=new Set(e.filter((a)=>a.slug===n).map((a)=>u(a.host,a.path))),s=[],o=[],i=[];for(let a of t)if(a.loopbackOnly)i.push(a);else if(a.domain&&r.has(u(a.domain,a.path)))s.push(a);else o.push(a);return{present:s,absent:o,loopback:i,foreign:e.filter((a)=>a.slug!==n)}}function A(t,e,n){let r=new Set;for(let s of e)for(let o of s.routes)if(o.slug===n)r.add(u(o.host,o.path));return t.filter((s)=>!s.loopbackOnly&&s.domain!==void 0&&!r.has(u(s.domain,s.path)))}function ct(t){let{slug:e,servers:n,probes:r,declared:s}=t,o=[];if(o.push(n.length===0?"No servers found.":`${n.length} server${n.length===1?"":"s"}:`),n.length>0)o.push("");let i=new Map(r.map((a)=>[a.server,a]));for(let a of n){let p=[a.ipv4,a.type,a.location,a.status].filter(Boolean);o.push(` ${a.name} ${p.join(" ")}`),o.push(` ${L(a)}`);let c=i.get(a.name);if(!c)o.push(" not probed, so co-tenants on this box are not listed");else if(c.unavailable)o.push(` could not read ${g}: ${c.unavailable}`);else o.push(...U(c,e));o.push("")}return o.push(...M(t)),o}function L(t){if(!t.project)return"no ts-cloud labels: provisioned outside ts-cloud, or by a version that did not label boxes";let e=[t.environment,t.role&&`role ${t.role}`].filter(Boolean).join(", ");return`owned by '${t.project}'${e?` (${e})`:""}`}function U(t,e){let n=H(t.routes);if(n.length===0)return[` serves nothing: ${g} is empty or absent`];let r=[` serves ${t.routes.length} route${t.routes.length===1?"":"s"} for ${n.length} project${n.length===1?"":"s"}:`];for(let s of n){r.push(` ${s.slug}${s.slug===e?" (this project)":""}`);for(let o of s.routes)r.push(` ${o.host}${o.path==="/"?"/":o.path} -> ${N(o)}`)}return r}function N(t){if(t.kind==="redirect")return`redirect to ${t.target}`;if(t.kind==="static")return`static ${t.target}`;return t.target}function M(t){let{slug:e,declared:n,probes:r,servers:s}=t;if(n.length===0)return[`This project ('${e}') declares no sites.`];let o=[`This project ('${e}') declares ${n.length} site${n.length===1?"":"s"}: `+n.map((c)=>c.name).join(", ")],i=n.filter((c)=>c.loopbackOnly);if(i.length>0)o.push(` ${i.length} with no domain, so the gateway never routes ${i.length===1?"it":"them"} (reached through another site's proxy): ${i.map((c)=>c.name).join(", ")}`);let a=r.filter((c)=>!c.unavailable);if(a.length===0)return o.push(" Nothing to reconcile them against: no box reported what it serves."),o;let p=A(n,a,e);if(o.push(` ${n.length-i.length-p.length} routed by a box above`),p.length>0){o.push(` ${p.length} not routed by any box above: ${p.map((C)=>C.name).join(", ")}`);let c=r.length-a.length,f=s.length-r.length;if(c>0)o.push(` Either they were never deployed, or they are on one of the ${c} server${c===1?"":"s"} that could not be read.`);else if(f>0)o.push(` Either they were never deployed, or they are on one of the ${f} server${f===1?"":"s"} this run did not probe.`);else o.push(" Either they were never deployed, or they are on a server this listing did not cover.")}return o}async function dt(t){let e=[];for(let n of t.steps)try{e.push({step:n,state:await n.satisfied()?"satisfied":"pending"})}catch(r){e.push({step:n,state:"unknown",reason:r instanceof Error?r.message:String(r)})}return e}function b(t){return t.filter((e)=>e.state!=="satisfied")}function z(t){return b(t).some((e)=>e.step.destructive===!0)}function pt(t,e){let n=b(e),r=[`${t.operation} ${t.target}`];if(n.length===0)return r.push(" Nothing to do — every step is already satisfied."),r;for(let{step:o,state:i,reason:a}of e){let p=i==="satisfied"?"ok ":i==="unknown"?"? ":"→ ",c=[o.destructive?"DESTRUCTIVE":"",i==="satisfied"?"already done":""].filter(Boolean);if(r.push(` ${p}${o.title}${c.length>0?` [${c.join(", ")}]`:""}`),o.change)r.push(` ${o.change.from} → ${o.change.to}`);if(a)r.push(` could not check: ${a}`)}let s=n.filter((o)=>o.step.destructive).length;return r.push(` ${n.length} step(s) would run`+(s>0?`, ${s} irreversible — re-run with --confirm ${t.target}`:"")),r}async function ut(t,e,n={}){let r={operation:t.operation,target:t.target,steps:[],success:!0};if(z(e)&&n.confirm!==t.target)throw Error(`${t.operation} includes an irreversible step. Re-run with --confirm ${t.target} to authorize it.`);for(let{step:s,state:o}of e){if(o==="satisfied"){r.steps.push({id:s.id,title:s.title,state:"skipped"}),n.log?.(`skip ${s.title} (already done)`);continue}n.audit?.({operation:t.operation,target:t.target,step:s.id,state:"started"});try{await s.apply(),r.steps.push({id:s.id,title:s.title,state:"applied"}),n.log?.(`done ${s.title}`),n.audit?.({operation:t.operation,target:t.target,step:s.id,state:"applied"})}catch(i){let a=i instanceof Error?i.message:String(i);return r.steps.push({id:s.id,title:s.title,state:"failed",error:a}),r.success=!1,n.log?.(`FAIL ${s.title}: ${a}`),n.audit?.({operation:t.operation,target:t.target,step:s.id,state:"failed",error:a}),r}}return r}function B(t){if(t.length===0)throw Error("A server name cannot be empty.");if(t.length>253)throw Error(`'${t}' is longer than the 253 characters a hostname allows.`);for(let e of t.split(".")){if(e.length===0)throw Error(`'${t}' has an empty label — a hostname cannot contain '..'.`);if(e.length>63)throw Error(`'${e}' is longer than the 63 characters a hostname label allows.`);if(!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(e))throw Error(`'${e}' is not a valid hostname label. Use letters, digits and hyphens, not starting or ending with a hyphen.`)}}async function ht(t,e,n){if(B(e),t===e)throw Error(`'${t}' is already named that.`);if((await n.takenNames()).some((o)=>o===e&&o!==t))throw Error(`'${e}' is already taken. Server names have to be unique within a provider project.`);let s=[];if(n.providerName&&n.renameProvider){let{providerName:o,renameProvider:i}=n;s.push({id:"provider",title:"Rename the server at the provider",change:{from:t,to:e},satisfied:async()=>await o()===e,apply:()=>i(e)})}if(n.stateName&&n.writeStateName){let{stateName:o,writeStateName:i}=n;s.push({id:"state-pin",title:"Update the recorded name in the local driver state",change:{from:t,to:e},satisfied:async()=>{let a=await o();return a===void 0||a===e},apply:()=>i(e)})}if(n.remoteHostname&&n.setRemoteHostname){let{remoteHostname:o,setRemoteHostname:i}=n;s.push({id:"hostname",title:"Set the hostname on the box",change:{from:t,to:e},satisfied:async()=>await o()===e,apply:()=>i(e)})}return s.push({id:"inventory",title:"Rename the fleet inventory record",change:{from:t,to:e},satisfied:async()=>n.inventoryName()===e,apply:async()=>{await n.renameInventory(e)}}),{operation:"server:rename",target:t,steps:s}}function ft(t){let e=`'${t.replace(/'/g,`'"'"'`)}'`;return["set -eu",'TS_CLOUD_OLD="$(hostname)"',`hostnamectl set-hostname ${e} 2>/dev/null || { echo ${e} > /etc/hostname && hostname ${e}; }`,'if grep -q "^127.0.1.1" /etc/hosts; then',` TS_CLOUD_HOSTS="$(sed -E "s/^127\\.0\\.1\\.1.*/127.0.1.1\\t${t}/" /etc/hosts)"`,` printf '%s\\n' "$TS_CLOUD_HOSTS" > /etc/hosts`,"else",` printf '127.0.1.1\\t%s\\n' ${e} >> /etc/hosts`,"fi",'printf "%s -> %s\\n" "$TS_CLOUD_OLD" "$(hostname)"'].join(`
|
|
9
|
+
`)}function yt(t,e,n){let r=e.trim();if(!r)return{problem:"No server named."};let[s,...o]=t.filter((c)=>c.name===r);if(s&&o.length===0)return{server:s};let i=t.filter((c)=>c.project===r);if(i.length>1&&n)i=i.filter((c)=>!c.environment||c.environment===n);let[a,...p]=i;if(a&&p.length===0)return{server:a};if(i.length>1)return{problem:`'${r}' owns ${i.length} servers (${i.map((c)=>c.name).join(", ")}). Name one of them, or narrow it by environment.`};return{problem:`No server matched '${r}'. Nothing is named that, and no box carries the label ts-cloud/project=${r}.`}}function vt(t,e){let n=[];if(!e.project)n.push(`'${e.name}' carries no ts-cloud/project label, so it is not a box ts-cloud provisioned. Attaching to it would deploy into a host nothing manages.`);else if(e.project===t)n.push(`This project's slug is '${t}', which is also the slug that owns '${e.name}'. A tenant deploy owns the gateway fragment named after its slug, so attaching would overwrite '${e.project}'s own fragment and take its sites down. Change this project's slug first.`);if(e.status!=="running")n.push(`'${e.name}' is ${e.status}, so what it serves could not be read.`);if(!e.ipv4)n.push(`'${e.name}' has no public IPv4 address, so it cannot be reached to check what it serves.`);return n}function S(t,e){let n=e==="/"?"/":e.replace(/\/+$/,"");return`${t.toLowerCase()}${n||"/"}`}function bt(t,e,n){let r=[],s=w(n.filter((i)=>i.kind==="app").map((i)=>({slug:i.slug,proxies:[{from:i.target.split(",").map((a)=>a.trim())}]})),{ignoreSlug:t}),o=new Map;for(let i of n)if(i.slug!==t)o.set(S(i.host,i.path),i.slug);for(let i of e){if(i.port!==void 0){let a=s.get(i.port);if(a)r.push({kind:"port",site:i.name,detail:`port ${i.port}`,heldBy:a})}if(i.domain){let a=o.get(S(i.domain,i.path));if(a)r.push({kind:"route",site:i.name,detail:`${i.domain}${i.path==="/"?"/":i.path}`,heldBy:a})}}return r}function St(t){return t.registryRead&&t.conflicts.length===0}function wt(t){let{slug:e,owner:n,server:r,declared:s,conflicts:o}=t,i=[];i.push(`Attach '${e}' to '${r.name}' (${r.ipv4??"no IPv4"}), owned by '${n}'.`,""),i.push(` ${s.length} site${s.length===1?"":"s"} would deploy onto this box:`);for(let a of s){let p=a.loopbackOnly?`loopback only${a.port?` on :${a.port}`:""}`:`${a.domain}${a.path==="/"?"/":a.path}${a.port?` on :${a.port}`:""}`;i.push(` ${a.name} ${p} -> ${a.installBase??"(install path unresolved)"}`)}if(i.push(""),!t.registryRead)i.push(` Could not read what '${r.name}' already serves: ${t.registryProblem??"unknown reason"}`),i.push(" So this attach is UNCHECKED: a port or hostname already taken by another"),i.push(" project would not error, it would serve that project's site from your domain.");else if(o.length>0){i.push(` ${o.length} conflict${o.length===1?"":"s"} with what the box already serves:`);for(let a of o)i.push(` site '${a.site}' wants ${a.detail}, held by '${a.heldBy}'`);i.push(""),i.push(" Two services on one port do not error: the kernel load-balances, and each"),i.push(" domain serves the other's site about half the time. Pick free ports and"),i.push(" hostnames, then re-run.")}else i.push(` No conflicts with what '${r.name}' already serves.`);return i}function h(t,e){return`/tmp/ts-cloud-move-${t}-${e}.tar.gz`}function x(t,e){return`${t}-${e}*.service`}function l(t){return`'${t.split("'").join("'\\''")}'`}function W(t,e){return["set -eu",`for unit in $(ls /etc/systemd/system/ 2>/dev/null | grep -E ${l(k(t,e))} || true); do`,' systemctl stop "$unit" 2>/dev/null || true',"done"].join(`
|
|
10
|
+
`)}function k(t,e){return`^${t}-${e}-((queue|daemon)-.*|scheduler)\\.service$`}function F(t,e){return P(k(t,e))}function P(t){return[`ls /etc/systemd/system/ 2>/dev/null | grep -E ${l(t)} | while read -r unit; do`,' systemctl is-active "$unit" >/dev/null 2>&1 && echo "active:$unit" || true',"done"].join(`
|
|
11
|
+
`)}function V(t){return!t.split(`
|
|
12
|
+
`).some((e)=>e.trim().startsWith("active:"))}function q(t,e,n){let r=h(t,e);return["set -eu",`test -d ${l(n)} || { echo "no site tree at ${n}" >&2; exit 1; }`,`rm -f ${l(r)}`,`tar czf ${l(r)} -C "$(dirname ${l(n)})" "$(basename ${l(n)})" -C /etc/systemd/system $(cd /etc/systemd/system && ls ${x(t,e)} 2>/dev/null | tr '\\n' ' ')`,`sha256sum ${l(r)} | cut -d' ' -f1`].join(`
|
|
13
|
+
`)}function G(t,e,n){let r=h(t,e);return["set -eu",`test -f ${l(r)} || { echo "archive not staged at ${r}" >&2; exit 1; }`,`mkdir -p "$(dirname ${l(n)})"`,`tar xzf ${l(r)} -C "$(dirname ${l(n)})" "$(basename ${l(n)})"`,`tar xzf ${l(r)} -C /etc/systemd/system --wildcards ${l(x(t,e))} 2>/dev/null || true`,"systemctl daemon-reload",`systemctl enable ${t}-${e}.service 2>/dev/null || true`,`systemctl restart ${t}-${e}.service`,`rm -f ${l(r)}`].join(`
|
|
14
|
+
`)}function K(t,e,n){return[`test -d ${l(n)} && echo tree:present || echo tree:absent`,`systemctl is-active ${t}-${e}.service >/dev/null 2>&1 && echo unit:active || echo unit:inactive`].join(`
|
|
15
|
+
`)}function Z(t){return t.includes("tree:present")&&t.includes("unit:active")}function J(t,e="/",n=10){let r=`http://127.0.0.1:${t}${e.startsWith("/")?e:`/${e}`}`;return["set -eu",`for i in $(seq 1 ${n}); do`,` if curl -fsS -o /dev/null --max-time 5 ${l(r)}; then echo healthy; exit 0; fi`," sleep 3","done",`echo "no healthy response from ${r}" >&2`,"exit 1"].join(`
|
|
16
|
+
`)}function Q(t,e){return["set -eu",`for unit in $(ls /etc/systemd/system/ 2>/dev/null | grep -E ${l(O(t,e))} || true); do`,' systemctl disable --now "$unit" 2>/dev/null || true',"done",`rm -f /etc/rpx/sites.d/${t}.json 2>/dev/null || true`,"systemctl reload rpx-gateway.service 2>/dev/null || systemctl restart rpx-gateway.service 2>/dev/null || true"].join(`
|
|
17
|
+
`)}function O(t,e){return`^${t}-${e}[-@.]`}function X(t,e){return P(O(t,e))}function Y(t){return!t.split(`
|
|
18
|
+
`).some((e)=>e.trim().startsWith("active:"))}function kt(t,e){return`/tmp/ts-cloud-move-${t}-${e}-certs.tar.gz`}function Pt(t,e){return["set -u",...e.map((n)=>`if [ -s ${l(`${t}/${n}.crt`)} ]; then echo "cert:${n}:$(sha256sum ${l(`${t}/${n}.crt`)} | cut -d' ' -f1)"; else echo "cert:${n}:absent"; fi`)].join(`
|
|
19
|
+
`)}function Ot(t){let e=new Map;for(let n of t.split(`
|
|
20
|
+
`)){let r=n.trim();if(!r.startsWith("cert:"))continue;let[,s,o]=r.split(":");if(s&&o)e.set(s,o)}return e}function Ct(t,e){for(let[n,r]of t){if(r==="absent")continue;if(e.get(n)!==r)return!1}return!0}function Dt(t,e,n){let r=e.flatMap((s)=>[`${s}.crt`,`${s}.key`]);return["set -eu",`rm -f ${l(n)}`,`cd ${l(t)} 2>/dev/null || { echo "no certs dir at ${t}" >&2; exit 0; }`,`TS_CLOUD_CERTS="$(ls ${r.map(l).join(" ")} 2>/dev/null | tr '\\n' ' ' || true)"`,'[ -n "$TS_CLOUD_CERTS" ] || { echo "no certificates to carry"; exit 0; }',`tar czf ${l(n)} $TS_CLOUD_CERTS`].join(`
|
|
21
|
+
`)}function Rt(t,e){return["set -eu",`[ -s ${l(e)} ] || { echo "no certificate archive staged"; exit 0; }`,`mkdir -p ${l(t)}`,`tar xzf ${l(e)} -C ${l(t)}`,`chmod 600 ${l(t)}/*.key 2>/dev/null || true`,`rm -f ${l(e)}`].join(`
|
|
22
|
+
`)}async function Tt(t,e){let{slug:n,siteName:r,appBase:s,from:o,to:i,targetAddress:a}=t;if(o===i)throw Error(`'${r}' is already on ${i}.`);if(t.database&&!e.database)throw Error(`'${r}' uses the on-box database '${t.database.name}', which lives in the engine's own data directory rather than in the site tree, and this move has no way to carry it. Moving the site without it would cut traffic over to an empty database.`);if(t.database&&e.database&&await e.database.targetHasData())throw Error(`${i} already has a database named '${t.database.name}' with tables in it. Restoring this site's dump over it would destroy that data. Rename or drop it on the target first, or point this project at a different database name.`);let p=[{id:"pause-workers",title:`Stop background work on ${o} so the snapshot is consistent`,satisfied:async()=>V(await e.runOnSource(F(n,r))),apply:async()=>{await e.runOnSource(W(n,r))}},...e.database?[{id:"database-dump",title:`Dump the '${t.database?.name}' database on ${o}`,satisfied:async()=>!1,apply:()=>e.database.dump()}]:[],{id:"snapshot",title:`Archive the site's tree and units on ${o}`,change:{from:`${o}:${s}`,to:h(n,r)},satisfied:async()=>!1,apply:async()=>{await e.runOnSource(q(n,r,s))}},{id:"transfer",title:`Carry the archive to ${i}`,change:{from:o,to:i},satisfied:()=>e.archiveStaged(),apply:()=>e.transferArchive()},...e.database?[{id:"database-transfer",title:`Carry the database dump to ${i}`,change:{from:o,to:i},satisfied:()=>e.database.dumpStaged(),apply:()=>e.database.transferDump()},{id:"database-restore",title:`Create and load '${t.database?.name}' on ${i}`,satisfied:async()=>!1,apply:()=>e.database.restore()}]:[],{id:"restore",title:`Unpack the site on ${i} and start it`,change:{from:h(n,r),to:`${i}:${s}`},satisfied:async()=>Z(await e.runOnTarget(K(n,r,s))),apply:async()=>{await e.runOnTarget(G(n,r,s))}}];if(t.port!=null){let{port:c}=t;p.push({id:"health",title:`Wait for the site to answer on ${i} (127.0.0.1:${c})`,satisfied:async()=>!1,apply:async()=>{await e.runOnTarget(J(c,t.healthCheckPath??"/"))}})}return p.push(...e.certificates?[{id:"certificates",title:`Carry the site's TLS material to ${i}`,satisfied:()=>e.certificates.inPlace(),apply:()=>e.certificates.carry()}]:[],{id:"gateway",title:`Route the site on ${i}`,satisfied:()=>e.targetRoutesSite(),apply:()=>e.refreshTargetGateway()},{id:"dns",title:`Point DNS at ${i}`,change:{from:`${o}`,to:a},satisfied:async()=>await e.publishedAddress()===a,apply:async()=>{let c=await e.cutoverDns();if(c.length>0)throw Error(c.join("; "))}},{id:"drain-source",title:`Stop the site on ${o}, leaving its files in place`,satisfied:async()=>Y(await e.runOnSource(X(n,r))),apply:async()=>{await e.runOnSource(Q(n,r))}}),{operation:"site:move",target:r,steps:p}}export{tt as wj,et as xj,nt as yj,R as zj,T as Aj,E as Bj,ot as Cj,j as Dj,H as Ej,st as Fj,at as Gj,A as Hj,ct as Ij,dt as Jj,b as Kj,z as Lj,pt as Mj,ut as Nj,B as Oj,ht as Pj,ft as Qj,yt as Rj,vt as Sj,bt as Tj,St as Uj,wt as Vj,h as Wj,x as Xj,W as Yj,F as Zj,V as _j,q as $j,G as ak,K as bk,Z as ck,J as dk,Q as ek,X as fk,Y as gk,kt as hk,Pt as ik,Ot as jk,Ct as kk,Dt as lk,Rt as mk,Tt as nk};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Mm as $t}from"./chunk-pb47hr0h.js";import{fn as yr,gn as Lr}from"./chunk-fsssdd5k.js";var Es=["edge.requests","edge.egress_gb","function.invocations","function.gb_seconds","build.minutes","compute.instance_hours","storage.gb_hours","object.egress_gb","object.requests","database.gb_hours","database.io_requests","telemetry.ingest_gb","image.transformations"],ut={"edge.requests":{key:"edge.requests",unit:"requests",label:"Edge requests",precision:0},"edge.egress_gb":{key:"edge.egress_gb",unit:"gb",label:"Edge egress",precision:3},"function.invocations":{key:"function.invocations",unit:"invocations",label:"Function invocations",precision:0},"function.gb_seconds":{key:"function.gb_seconds",unit:"gb_seconds",label:"Function compute",precision:2},"build.minutes":{key:"build.minutes",unit:"minutes",label:"Build minutes",precision:2},"compute.instance_hours":{key:"compute.instance_hours",unit:"hours",label:"Instance hours",precision:2},"storage.gb_hours":{key:"storage.gb_hours",unit:"gb_hours",label:"Block storage",precision:2},"object.egress_gb":{key:"object.egress_gb",unit:"gb",label:"Object storage egress",precision:3},"object.requests":{key:"object.requests",unit:"requests",label:"Object storage requests",precision:0},"database.gb_hours":{key:"database.gb_hours",unit:"gb_hours",label:"Database storage",precision:2},"database.io_requests":{key:"database.io_requests",unit:"requests",label:"Database I/O",precision:0},"telemetry.ingest_gb":{key:"telemetry.ingest_gb",unit:"gb",label:"Telemetry ingest",precision:3},"image.transformations":{key:"image.transformations",unit:"count",label:"Image transformations",precision:0}},ms=["notify","block_builds","block_deployments","throttle_requests","suspend_functions","serve_static","suspend_project"],k={notify:0,block_builds:1,block_deployments:2,throttle_requests:3,suspend_functions:4,serve_static:5,suspend_project:6};var gs=1e6;function Un(e){if(e.tiers&&e.tiers.length>0)return e.tiers;return[{upToQuantity:null,microCentsPerUnit:e.microCentsPerUnit??0}]}function lr(e,t){if(!(e>0))return 0;let r=[...t].sort((s,a)=>{if(s.upToQuantity===null)return 1;if(a.upToQuantity===null)return-1;return s.upToQuantity-a.upToQuantity}),n=e,i=0,o=0;for(let s of r){if(n<=0)break;let d=(s.upToQuantity===null?1/0:s.upToQuantity)-i;if(d<=0)continue;let c=Math.min(n,d);o+=c*s.microCentsPerUnit,n-=c,i+=c}if(n>0){let s=r.reduce((a,d)=>Math.max(a,d.microCentsPerUnit),0);o+=n*s}return o}function Dn(e,t,r,n){let i=e.entries.filter((a)=>a.meter===t);if(i.length===0)return;let o=i.filter((a)=>a.provider===r),s=o.length>0?o:i.filter((a)=>a.provider==="*");return s.find((a)=>a.region===n)??s.find((a)=>a.region==null)}function pt(e,t,r=0){let n=Dn(e,t.meter,t.provider,t.region),i=Math.max(0,t.quantity);if(!n)return{meter:t.meter,provider:t.provider??"unknown",region:t.region,quantity:i,includedQuantity:0,billableQuantity:i,costCents:0,unpriced:!0};let o=Math.max(0,n.includedQuantity??0),s=Math.max(0,r-o),a=Math.max(0,o-Math.max(0,r)),d=Math.min(i,a),c=i-d,p=Un(n),l=lr(s+c,p)-lr(s,p);return{meter:t.meter,provider:n.provider,region:n.region??t.region,quantity:i,includedQuantity:d,billableQuantity:c,costCents:l/1e6,unpriced:!1}}function _s(e,t){let r=new Map,n=[];for(let i of t){let o=`${i.meter}\x00${i.provider??""}\x00${i.region??""}`,s=r.get(o)??0,a=pt(e,i,s);r.set(o,s+a.quantity),n.push(a)}return{currency:e.currency,totalCents:n.reduce((i,o)=>i+o.costCents,0),lines:n,unpricedMeters:[...new Set(n.filter((i)=>i.unpriced).map((i)=>String(i.meter)))]}}function hs(e){return Math.round(e*100)/100}function Ns(e,...t){let r=new Map,n=(o)=>`${o.meter}\x00${o.provider}\x00${o.region??""}`;for(let o of e.entries)r.set(n(o),o);let i=e.currency;for(let o of t){i=o.currency||i;for(let s of o.entries)r.set(n(s),s)}return{currency:i,entries:[...r.values()]}}var K=(e)=>Math.round(e*1e6),j=(e)=>Math.round(e*1e6),ur={currency:"USD",entries:[{meter:"edge.requests",provider:"aws",microCentsPerUnit:j(0.00075)},{meter:"edge.egress_gb",provider:"aws",includedQuantity:100,tiers:[{upToQuantity:10240,microCentsPerUnit:K(8.5)},{upToQuantity:51200,microCentsPerUnit:K(8)},{upToQuantity:null,microCentsPerUnit:K(6)}]},{meter:"function.invocations",provider:"aws",includedQuantity:1e6,microCentsPerUnit:j(0.002)},{meter:"function.gb_seconds",provider:"aws",includedQuantity:400000,microCentsPerUnit:j(0.00166667)},{meter:"storage.gb_hours",provider:"aws",microCentsPerUnit:j(0.010958904109589041)},{meter:"object.egress_gb",provider:"aws",includedQuantity:100,microCentsPerUnit:K(9)},{meter:"object.requests",provider:"aws",microCentsPerUnit:j(0.000039999999999999996)},{meter:"database.gb_hours",provider:"aws",microCentsPerUnit:j(0.015753424657534248)},{meter:"compute.instance_hours",provider:"aws",microCentsPerUnit:j(4.16)},{meter:"edge.egress_gb",provider:"hetzner",includedQuantity:20480,microCentsPerUnit:K(0.108)},{meter:"object.egress_gb",provider:"hetzner",includedQuantity:1024,microCentsPerUnit:K(0.108)},{meter:"compute.instance_hours",provider:"hetzner",microCentsPerUnit:j(0.95)},{meter:"storage.gb_hours",provider:"hetzner",microCentsPerUnit:j(0.006027397260273972)},{meter:"edge.requests",provider:"hetzner",microCentsPerUnit:0},{meter:"edge.requests",provider:"local",microCentsPerUnit:0},{meter:"edge.egress_gb",provider:"local",microCentsPerUnit:0},{meter:"function.invocations",provider:"local",microCentsPerUnit:0},{meter:"function.gb_seconds",provider:"local",microCentsPerUnit:0},{meter:"build.minutes",provider:"*",includedQuantity:6000,microCentsPerUnit:j(0.8)},{meter:"telemetry.ingest_gb",provider:"*",includedQuantity:5,microCentsPerUnit:K(50)},{meter:"image.transformations",provider:"*",includedQuantity:5000,microCentsPerUnit:j(0.05)}]};var pr=new Map;function mr(e){let t=pr.get(e);if(!t)t=new Intl.DateTimeFormat("en-US",{timeZone:e,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",weekday:"short",hourCycle:"h23"}),pr.set(e,t);return t}var wn={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};function Ue(e){try{return mr(e),!0}catch{return!1}}function Et(e,t){let r=mr(t).formatToParts(e),n=(i)=>r.find((o)=>o.type===i)?.value??"0";return{year:Number(n("year")),month:Number(n("month")),day:Number(n("day")),hour:Number(n("hour")),minute:Number(n("minute")),second:Number(n("second")),weekday:wn[n("weekday")]??0}}function Er(e,t){let r=Et(e,t);return Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second)-Math.floor(e.getTime()/1000)*1000}function te(e,t,r,n,i=0){let o=Date.UTC(t,r-1,n,i),s=new Date(o-Er(new Date(o),e));return new Date(o-Er(s,e))}function kn(e,t){return new Date(Date.UTC(e,t-1,1)).toLocaleString("en-US",{month:"long",year:"numeric",timeZone:"UTC"})}function Q(e,t,r=new Date){let n=Ue(t)?t:"UTC",i=Et(r,n),o,s,a;if(e==="daily")o=te(n,i.year,i.month,i.day),s=te(n,i.year,i.month,i.day+1),a=`${i.year}-${String(i.month).padStart(2,"0")}-${String(i.day).padStart(2,"0")}`;else if(e==="weekly"){let p=(i.weekday+6)%7;o=te(n,i.year,i.month,i.day-p),s=te(n,i.year,i.month,i.day-p+7);let l=Et(o,n);a=`week of ${l.year}-${String(l.month).padStart(2,"0")}-${String(l.day).padStart(2,"0")}`}else o=te(n,i.year,i.month,1),s=te(n,i.year,i.month+1,1),a=kn(i.year,i.month);let d=s.getTime()-o.getTime(),c=Math.max(0,Math.min(d,r.getTime()-o.getTime()));return{start:o.toISOString(),end:s.toISOString(),elapsedMs:c,totalMs:d,label:a}}function ys(e,t,r=new Date){let n=Q(e,t,r),i=new Date(new Date(n.start).getTime()-1),o=Q(e,t,i);return{...o,elapsedMs:o.totalMs}}function ue(e){let r=(typeof e==="string"?new Date(e):e).getTime();if(!Number.isFinite(r))throw Error("hourBucket requires a valid date");return new Date(Math.floor(r/3600000)*3600000).toISOString()}function Ls(e,t,r=9600){let n=Math.floor(new Date(e).getTime()/3600000)*3600000,i=new Date(t).getTime();if(!Number.isFinite(n)||!Number.isFinite(i))throw Error("hourBucketsBetween requires valid dates");let o=[];for(let s=n;s<i&&o.length<r;s+=3600000)o.push(new Date(s).toISOString());return o}import{createHash as Xn}from"node:crypto";var De=1073741824,gr=[{match:"request.count",meter:"edge.requests"},{match:"traffic.requests",meter:"edge.requests"},{match:"http.request",meter:"edge.requests",field:"count"},{match:"traffic.bytes_out",meter:"edge.egress_gb",scale:1/De},{match:"storage.egress.day",meter:"object.egress_gb",scale:1/De},{match:"storage.egress.month",meter:"object.egress_gb",scale:1/De,cumulative:!0},{match:"storage.egress.day_downloads",meter:"object.requests"},{match:"function.invocation",meter:"function.invocations",field:"count"},{match:"function.duration_ms",meter:"function.gb_seconds",scale:0.001},{match:"build.duration_ms",meter:"build.minutes",scale:0.000016666666666666667},{match:"telemetry.ingest_bytes",meter:"telemetry.ingest_gb",scale:1/De},{match:"image.transform",meter:"image.transformations",field:"count"}];function Pn(e,t){return e.match.endsWith("*")?t.startsWith(e.match.slice(0,-1)):e.match===t}function xn(e,t=gr){return t.find((r)=>!r.match.endsWith("*")&&r.match===e)??t.find((r)=>Pn(r,e))}function jn(e,t){let r=t.field??"value",n=r==="count"?1:r==="bytesOut"?e.bytesOut:r==="bytesIn"?e.bytesIn:r==="durationMs"?e.durationMs:e.value;if(n==null||!Number.isFinite(n))return;return n*(t.scale??1)}function Fn(e,t){return Xn("sha256").update([t,e.meter,e.organizationId,e.projectId??"",e.environmentId??"",e.resourceId??"",e.timestamp].join("\x00")).digest("hex").slice(0,32)}class mt{resetToleranceRatio;last=new Map;constructor(e=0.999){this.resetToleranceRatio=e}delta(e,t,r=new Date){if(!Number.isFinite(t)||t<0)return;let n=new Date(r).getTime(),i=this.last.get(e);if(!i)return this.last.set(e,{value:t,at:n}),t>0?t:void 0;if(n<i.at)return;if(t<i.value&&t>=i.value*this.resetToleranceRatio)return;if(this.last.set(e,{value:t,at:n}),t>=i.value){let o=t-i.value;return o>0?o:void 0}return t>0?t:void 0}prune(e){let t=e.getTime(),r=0;for(let[n,i]of this.last)if(i.at<t)this.last.delete(n),r++;return r}get size(){return this.last.size}}function Tr(e,t){let r=e[t];return typeof r==="string"&&r.length>0?r:void 0}function _r(e,t,r={}){let n=r.mappings??gr,i=r.counters,o=[];for(let s of t){let a=xn(s.name,n);if(!a)continue;let d=jn(s,a);if(d==null)continue;if(a.cumulative){if(!i)continue;let p=[s.projectId,s.environmentId??"",s.resourceId??"",s.name,s.source].join("\x00"),l=i.delta(p,d,s.timestamp);if(l==null)continue;d=l}if(!(d>0))continue;let c={organizationId:e,projectId:s.projectId,environmentId:s.environmentId,resourceId:s.resourceId,provider:Tr(s.attributes,"provider")??r.defaultProvider,region:s.region??Tr(s.attributes,"region"),meter:a.meter,quantity:d,timestamp:s.timestamp,attributes:{source:s.source,signal:s.name}};o.push({...c,key:Fn(c,s.id)})}return o}function hr(e){let t=new Map;for(let r of e){let n=new Date(Math.floor(new Date(r.timestamp).getTime()/3600000)*3600000).toISOString(),i=[r.organizationId,r.projectId??"",r.environmentId??"",r.resourceId??"",r.provider??"",r.region??"",r.meter,n].join("\x00"),o=t.get(i);if(o)o.quantity+=r.quantity;else t.set(i,{...r,timestamp:n})}return[...t.values()]}import{createHash as ti}from"node:crypto";var q=40,Tt=[{version:1,name:"core_control_plane",sql:`
|
|
1
|
+
import{Jn as $t}from"./chunk-4wdxsnn2.js";import{do as yr,eo as Lr}from"./chunk-r8t25tbm.js";var Es=["edge.requests","edge.egress_gb","function.invocations","function.gb_seconds","build.minutes","compute.instance_hours","storage.gb_hours","object.egress_gb","object.requests","database.gb_hours","database.io_requests","telemetry.ingest_gb","image.transformations"],ut={"edge.requests":{key:"edge.requests",unit:"requests",label:"Edge requests",precision:0},"edge.egress_gb":{key:"edge.egress_gb",unit:"gb",label:"Edge egress",precision:3},"function.invocations":{key:"function.invocations",unit:"invocations",label:"Function invocations",precision:0},"function.gb_seconds":{key:"function.gb_seconds",unit:"gb_seconds",label:"Function compute",precision:2},"build.minutes":{key:"build.minutes",unit:"minutes",label:"Build minutes",precision:2},"compute.instance_hours":{key:"compute.instance_hours",unit:"hours",label:"Instance hours",precision:2},"storage.gb_hours":{key:"storage.gb_hours",unit:"gb_hours",label:"Block storage",precision:2},"object.egress_gb":{key:"object.egress_gb",unit:"gb",label:"Object storage egress",precision:3},"object.requests":{key:"object.requests",unit:"requests",label:"Object storage requests",precision:0},"database.gb_hours":{key:"database.gb_hours",unit:"gb_hours",label:"Database storage",precision:2},"database.io_requests":{key:"database.io_requests",unit:"requests",label:"Database I/O",precision:0},"telemetry.ingest_gb":{key:"telemetry.ingest_gb",unit:"gb",label:"Telemetry ingest",precision:3},"image.transformations":{key:"image.transformations",unit:"count",label:"Image transformations",precision:0}},ms=["notify","block_builds","block_deployments","throttle_requests","suspend_functions","serve_static","suspend_project"],k={notify:0,block_builds:1,block_deployments:2,throttle_requests:3,suspend_functions:4,serve_static:5,suspend_project:6};var gs=1e6;function Un(e){if(e.tiers&&e.tiers.length>0)return e.tiers;return[{upToQuantity:null,microCentsPerUnit:e.microCentsPerUnit??0}]}function lr(e,t){if(!(e>0))return 0;let r=[...t].sort((s,a)=>{if(s.upToQuantity===null)return 1;if(a.upToQuantity===null)return-1;return s.upToQuantity-a.upToQuantity}),n=e,i=0,o=0;for(let s of r){if(n<=0)break;let d=(s.upToQuantity===null?1/0:s.upToQuantity)-i;if(d<=0)continue;let c=Math.min(n,d);o+=c*s.microCentsPerUnit,n-=c,i+=c}if(n>0){let s=r.reduce((a,d)=>Math.max(a,d.microCentsPerUnit),0);o+=n*s}return o}function Dn(e,t,r,n){let i=e.entries.filter((a)=>a.meter===t);if(i.length===0)return;let o=i.filter((a)=>a.provider===r),s=o.length>0?o:i.filter((a)=>a.provider==="*");return s.find((a)=>a.region===n)??s.find((a)=>a.region==null)}function pt(e,t,r=0){let n=Dn(e,t.meter,t.provider,t.region),i=Math.max(0,t.quantity);if(!n)return{meter:t.meter,provider:t.provider??"unknown",region:t.region,quantity:i,includedQuantity:0,billableQuantity:i,costCents:0,unpriced:!0};let o=Math.max(0,n.includedQuantity??0),s=Math.max(0,r-o),a=Math.max(0,o-Math.max(0,r)),d=Math.min(i,a),c=i-d,p=Un(n),l=lr(s+c,p)-lr(s,p);return{meter:t.meter,provider:n.provider,region:n.region??t.region,quantity:i,includedQuantity:d,billableQuantity:c,costCents:l/1e6,unpriced:!1}}function _s(e,t){let r=new Map,n=[];for(let i of t){let o=`${i.meter}\x00${i.provider??""}\x00${i.region??""}`,s=r.get(o)??0,a=pt(e,i,s);r.set(o,s+a.quantity),n.push(a)}return{currency:e.currency,totalCents:n.reduce((i,o)=>i+o.costCents,0),lines:n,unpricedMeters:[...new Set(n.filter((i)=>i.unpriced).map((i)=>String(i.meter)))]}}function hs(e){return Math.round(e*100)/100}function Ns(e,...t){let r=new Map,n=(o)=>`${o.meter}\x00${o.provider}\x00${o.region??""}`;for(let o of e.entries)r.set(n(o),o);let i=e.currency;for(let o of t){i=o.currency||i;for(let s of o.entries)r.set(n(s),s)}return{currency:i,entries:[...r.values()]}}var K=(e)=>Math.round(e*1e6),j=(e)=>Math.round(e*1e6),ur={currency:"USD",entries:[{meter:"edge.requests",provider:"aws",microCentsPerUnit:j(0.00075)},{meter:"edge.egress_gb",provider:"aws",includedQuantity:100,tiers:[{upToQuantity:10240,microCentsPerUnit:K(8.5)},{upToQuantity:51200,microCentsPerUnit:K(8)},{upToQuantity:null,microCentsPerUnit:K(6)}]},{meter:"function.invocations",provider:"aws",includedQuantity:1e6,microCentsPerUnit:j(0.002)},{meter:"function.gb_seconds",provider:"aws",includedQuantity:400000,microCentsPerUnit:j(0.00166667)},{meter:"storage.gb_hours",provider:"aws",microCentsPerUnit:j(0.010958904109589041)},{meter:"object.egress_gb",provider:"aws",includedQuantity:100,microCentsPerUnit:K(9)},{meter:"object.requests",provider:"aws",microCentsPerUnit:j(0.000039999999999999996)},{meter:"database.gb_hours",provider:"aws",microCentsPerUnit:j(0.015753424657534248)},{meter:"compute.instance_hours",provider:"aws",microCentsPerUnit:j(4.16)},{meter:"edge.egress_gb",provider:"hetzner",includedQuantity:20480,microCentsPerUnit:K(0.108)},{meter:"object.egress_gb",provider:"hetzner",includedQuantity:1024,microCentsPerUnit:K(0.108)},{meter:"compute.instance_hours",provider:"hetzner",microCentsPerUnit:j(0.95)},{meter:"storage.gb_hours",provider:"hetzner",microCentsPerUnit:j(0.006027397260273972)},{meter:"edge.requests",provider:"hetzner",microCentsPerUnit:0},{meter:"edge.requests",provider:"local",microCentsPerUnit:0},{meter:"edge.egress_gb",provider:"local",microCentsPerUnit:0},{meter:"function.invocations",provider:"local",microCentsPerUnit:0},{meter:"function.gb_seconds",provider:"local",microCentsPerUnit:0},{meter:"build.minutes",provider:"*",includedQuantity:6000,microCentsPerUnit:j(0.8)},{meter:"telemetry.ingest_gb",provider:"*",includedQuantity:5,microCentsPerUnit:K(50)},{meter:"image.transformations",provider:"*",includedQuantity:5000,microCentsPerUnit:j(0.05)}]};var pr=new Map;function mr(e){let t=pr.get(e);if(!t)t=new Intl.DateTimeFormat("en-US",{timeZone:e,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",weekday:"short",hourCycle:"h23"}),pr.set(e,t);return t}var wn={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};function Ue(e){try{return mr(e),!0}catch{return!1}}function Et(e,t){let r=mr(t).formatToParts(e),n=(i)=>r.find((o)=>o.type===i)?.value??"0";return{year:Number(n("year")),month:Number(n("month")),day:Number(n("day")),hour:Number(n("hour")),minute:Number(n("minute")),second:Number(n("second")),weekday:wn[n("weekday")]??0}}function Er(e,t){let r=Et(e,t);return Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second)-Math.floor(e.getTime()/1000)*1000}function te(e,t,r,n,i=0){let o=Date.UTC(t,r-1,n,i),s=new Date(o-Er(new Date(o),e));return new Date(o-Er(s,e))}function kn(e,t){return new Date(Date.UTC(e,t-1,1)).toLocaleString("en-US",{month:"long",year:"numeric",timeZone:"UTC"})}function Q(e,t,r=new Date){let n=Ue(t)?t:"UTC",i=Et(r,n),o,s,a;if(e==="daily")o=te(n,i.year,i.month,i.day),s=te(n,i.year,i.month,i.day+1),a=`${i.year}-${String(i.month).padStart(2,"0")}-${String(i.day).padStart(2,"0")}`;else if(e==="weekly"){let p=(i.weekday+6)%7;o=te(n,i.year,i.month,i.day-p),s=te(n,i.year,i.month,i.day-p+7);let l=Et(o,n);a=`week of ${l.year}-${String(l.month).padStart(2,"0")}-${String(l.day).padStart(2,"0")}`}else o=te(n,i.year,i.month,1),s=te(n,i.year,i.month+1,1),a=kn(i.year,i.month);let d=s.getTime()-o.getTime(),c=Math.max(0,Math.min(d,r.getTime()-o.getTime()));return{start:o.toISOString(),end:s.toISOString(),elapsedMs:c,totalMs:d,label:a}}function ys(e,t,r=new Date){let n=Q(e,t,r),i=new Date(new Date(n.start).getTime()-1),o=Q(e,t,i);return{...o,elapsedMs:o.totalMs}}function ue(e){let r=(typeof e==="string"?new Date(e):e).getTime();if(!Number.isFinite(r))throw Error("hourBucket requires a valid date");return new Date(Math.floor(r/3600000)*3600000).toISOString()}function Ls(e,t,r=9600){let n=Math.floor(new Date(e).getTime()/3600000)*3600000,i=new Date(t).getTime();if(!Number.isFinite(n)||!Number.isFinite(i))throw Error("hourBucketsBetween requires valid dates");let o=[];for(let s=n;s<i&&o.length<r;s+=3600000)o.push(new Date(s).toISOString());return o}import{createHash as Xn}from"node:crypto";var De=1073741824,gr=[{match:"request.count",meter:"edge.requests"},{match:"traffic.requests",meter:"edge.requests"},{match:"http.request",meter:"edge.requests",field:"count"},{match:"traffic.bytes_out",meter:"edge.egress_gb",scale:1/De},{match:"storage.egress.day",meter:"object.egress_gb",scale:1/De},{match:"storage.egress.month",meter:"object.egress_gb",scale:1/De,cumulative:!0},{match:"storage.egress.day_downloads",meter:"object.requests"},{match:"function.invocation",meter:"function.invocations",field:"count"},{match:"function.duration_ms",meter:"function.gb_seconds",scale:0.001},{match:"build.duration_ms",meter:"build.minutes",scale:0.000016666666666666667},{match:"telemetry.ingest_bytes",meter:"telemetry.ingest_gb",scale:1/De},{match:"image.transform",meter:"image.transformations",field:"count"}];function Pn(e,t){return e.match.endsWith("*")?t.startsWith(e.match.slice(0,-1)):e.match===t}function xn(e,t=gr){return t.find((r)=>!r.match.endsWith("*")&&r.match===e)??t.find((r)=>Pn(r,e))}function jn(e,t){let r=t.field??"value",n=r==="count"?1:r==="bytesOut"?e.bytesOut:r==="bytesIn"?e.bytesIn:r==="durationMs"?e.durationMs:e.value;if(n==null||!Number.isFinite(n))return;return n*(t.scale??1)}function Fn(e,t){return Xn("sha256").update([t,e.meter,e.organizationId,e.projectId??"",e.environmentId??"",e.resourceId??"",e.timestamp].join("\x00")).digest("hex").slice(0,32)}class mt{resetToleranceRatio;last=new Map;constructor(e=0.999){this.resetToleranceRatio=e}delta(e,t,r=new Date){if(!Number.isFinite(t)||t<0)return;let n=new Date(r).getTime(),i=this.last.get(e);if(!i)return this.last.set(e,{value:t,at:n}),t>0?t:void 0;if(n<i.at)return;if(t<i.value&&t>=i.value*this.resetToleranceRatio)return;if(this.last.set(e,{value:t,at:n}),t>=i.value){let o=t-i.value;return o>0?o:void 0}return t>0?t:void 0}prune(e){let t=e.getTime(),r=0;for(let[n,i]of this.last)if(i.at<t)this.last.delete(n),r++;return r}get size(){return this.last.size}}function Tr(e,t){let r=e[t];return typeof r==="string"&&r.length>0?r:void 0}function _r(e,t,r={}){let n=r.mappings??gr,i=r.counters,o=[];for(let s of t){let a=xn(s.name,n);if(!a)continue;let d=jn(s,a);if(d==null)continue;if(a.cumulative){if(!i)continue;let p=[s.projectId,s.environmentId??"",s.resourceId??"",s.name,s.source].join("\x00"),l=i.delta(p,d,s.timestamp);if(l==null)continue;d=l}if(!(d>0))continue;let c={organizationId:e,projectId:s.projectId,environmentId:s.environmentId,resourceId:s.resourceId,provider:Tr(s.attributes,"provider")??r.defaultProvider,region:s.region??Tr(s.attributes,"region"),meter:a.meter,quantity:d,timestamp:s.timestamp,attributes:{source:s.source,signal:s.name}};o.push({...c,key:Fn(c,s.id)})}return o}function hr(e){let t=new Map;for(let r of e){let n=new Date(Math.floor(new Date(r.timestamp).getTime()/3600000)*3600000).toISOString(),i=[r.organizationId,r.projectId??"",r.environmentId??"",r.resourceId??"",r.provider??"",r.region??"",r.meter,n].join("\x00"),o=t.get(i);if(o)o.quantity+=r.quantity;else t.set(i,{...r,timestamp:n})}return[...t.values()]}import{createHash as ti}from"node:crypto";var q=40,Tt=[{version:1,name:"core_control_plane",sql:`
|
|
2
2
|
CREATE TABLE projects (
|
|
3
3
|
id TEXT PRIMARY KEY,
|
|
4
4
|
slug TEXT NOT NULL UNIQUE,
|
|
@@ -1614,4 +1614,4 @@ volumes:
|
|
|
1614
1614
|
`).map((o)=>o.trim()).filter(oe.test.bind(oe))){let o=await this.inspect(i);if(o)n.push(o)}return n}async create(e){let t=typeof e.desiredState.nativeName==="string"?e.desiredState.nativeName:e.name;if(!oe.test(t))throw Error("Docker volume name is invalid.");return await this.run(["volume","create","--label",`ts-cloud.volume=${e.id}`,"--label",`ts-cloud.project=${e.projectId}`,t]),await this.inspect(t)??{providerId:t}}async attach(e,t){}async detach(e,t){}async resize(){throw Error(this.capabilities().resize.reason)}async snapshot(){throw Error(this.capabilities().snapshot.reason)}async restore(e,t,r){throw Error(this.capabilities().restore.reason)}async delete(e){if(!e.providerId||!oe.test(e.providerId))throw Error("Docker volume provider identity is missing or invalid.");await this.run(["volume","rm",e.providerId])}async usage(e){let t=await this.run(["system","df","-v","--format","{{json .}}"],!0),r=t.split(`
|
|
1615
1615
|
`).find((n)=>n.includes(`"Name":"${e.providerId}"`));if(!r)return{};try{let n=JSON.parse(r);return{usedBytes:typeof n.Size==="number"?n.Size:void 0}}catch{return{}}}}class Jo{provider="server";type="server_path";root;constructor(e){this.root=In(e)}capabilities(){return ot(["create","attach","detach","delete","adopt","usage"],{resize:{supported:!1,reason:"Server paths use the capacity of their containing filesystem."},snapshot:{supported:!1,reason:"Attach a filesystem backup policy for verified recovery points."},restore:{supported:!1,reason:"Restore a filesystem recovery point into a new managed path."}})}path(e){if(!oe.test(e))throw Error("Server path volume name is invalid.");let t=In(this.root,e);if(!t.startsWith(`${this.root}${Go}`)||Yo(t)!==e)throw Error("Server path escaped the managed volume root.");return t}async discover(e,t){return await tr(this.root,{recursive:!0,mode:488}),(await Ko(this.root,{withFileTypes:!0})).filter((n)=>n.isDirectory()&&oe.test(n.name)).map((n)=>({providerId:n.name,raw:{path:this.path(n.name)}}))}async create(e){let t=typeof e.desiredState.nativeName==="string"?e.desiredState.nativeName:e.name,r=this.path(t);return await tr(this.root,{recursive:!0,mode:488}),await tr(r,{recursive:!1,mode:488}),{providerId:t,filesystem:"host",raw:{path:r}}}async attach(e,t){}async detach(e,t){}async resize(){throw Error(this.capabilities().resize.reason)}async snapshot(){throw Error(this.capabilities().snapshot.reason)}async restore(e,t,r){throw Error(this.capabilities().restore.reason)}async delete(e){if(!e.providerId)throw Error("Server path provider identity is unavailable.");await $o(this.path(e.providerId),{recursive:!0,force:!1})}async usage(e){if(!e.providerId)return{};return{usedBytes:(await Qo(this.path(e.providerId))).size}}}class Zo{provider;transport;type="ebs";constructor(e,t){this.provider=e;this.transport=t}capabilities(){return ot(["create","attach","detach","resize","snapshot","restore","delete","adopt","usage"],{resize:{supported:!0,online:!0,minimumBytes:1073741824}})}discover(e,t){return this.transport.list(e,t)}create(e){return this.transport.create({name:e.name,projectId:e.projectId,environmentId:e.environmentId,capacityBytes:e.capacityBytes,encrypted:e.encrypted,filesystem:e.filesystem})}resource(e,t){let r=e.resourceId===t.resourceId?e.observedState.resourceProviderId:void 0,n=typeof r==="string"?r:t.driverOptions.resourceProviderId;if(typeof n!=="string"||!n)throw Error("Cloud attachment requires a reviewed resourceProviderId driver option.");return n}attach(e,t){return this.transport.attach(e.providerId,this.resource(e,t),t.targetPath,t.readOnly)}detach(e,t,r){return this.transport.detach(e.providerId,this.resource(e,t),r.force)}resize(e,t){return this.transport.resize(e.providerId,t)}snapshot(e,t){return this.transport.snapshot(e.providerId,t.name)}restore(e,t,r){if(!t.providerId)throw Error("Cloud snapshot provider identity is unavailable.");return this.transport.restore(e.providerId,t.providerId,r.name)}delete(e){return this.transport.delete(e.providerId)}usage(e){return this.transport.usage(e.providerId)}}var w=(e)=>e==null?void 0:String(e),Ae=(e,t)=>{try{return JSON.parse(String(e))}catch{return t}},ir=(e)=>Number(e)===1,se=(e)=>e().toISOString();function Sn(e){return{id:String(e.id),organizationId:String(e.organization_id),projectId:String(e.project_id),environmentId:w(e.environment_id),resourceId:w(e.resource_id),name:String(e.name),provider:String(e.provider),providerId:w(e.provider_id),type:String(e.type),status:String(e.status),capacityBytes:e.capacity_bytes==null?void 0:Number(e.capacity_bytes),usedBytes:e.used_bytes==null?void 0:Number(e.used_bytes),filesystem:w(e.filesystem),encrypted:ir(e.encrypted),capabilities:Ae(e.capabilities,{}),desiredState:Ae(e.desired_state,{}),observedState:Ae(e.observed_state,{}),backupPolicyId:w(e.backup_policy_id),lastBackupAt:w(e.last_backup_at),orphanedAt:w(e.orphaned_at),adoptedAt:w(e.adopted_at),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at),deletedAt:w(e.deleted_at)}}function nr(e){return{id:String(e.id),volumeId:String(e.volume_id),resourceId:String(e.resource_id),targetPath:String(e.target_path),readOnly:ir(e.read_only),uid:e.uid==null?void 0:Number(e.uid),gid:e.gid==null?void 0:Number(e.gid),mode:w(e.mode),propagation:String(e.propagation),driverOptions:Ae(e.driver_options,{}),desiredState:String(e.desired_state),observedState:String(e.observed_state),operationId:w(e.operation_id),lastError:w(e.last_error),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function bn(e){return{id:String(e.id),volumeId:String(e.volume_id),recoveryPointId:w(e.recovery_point_id),providerId:w(e.provider_id),name:String(e.name),status:String(e.status),sizeBytes:e.size_bytes==null?void 0:Number(e.size_bytes),encrypted:ir(e.encrypted),checksum:w(e.checksum),metadata:Ae(e.metadata,{}),createdAt:String(e.created_at),updatedAt:String(e.updated_at),deletedAt:w(e.deleted_at)}}class st{controlPlane;now;id;constructor(e,t=()=>new Date,r=()=>crypto.randomUUID()){this.controlPlane=e;this.now=t;this.id=r}get(e){let t=this.controlPlane.database.query("SELECT * FROM persistent_volumes WHERE id=?").get(e);return t?Sn(t):void 0}list(e){let t=["project_id=?"],r=[e.projectId];if(e.environmentId)t.push("environment_id=?"),r.push(e.environmentId);if(!e.includeDeleted)t.push("deleted_at IS NULL");return this.controlPlane.database.query(`SELECT * FROM persistent_volumes WHERE ${t.join(" AND ")} ORDER BY name`).all(...r).map(Sn)}create(e){let t=se(this.now),r=e.id??this.id();return this.controlPlane.database.run("INSERT INTO persistent_volumes (id,organization_id,project_id,environment_id,resource_id,name,provider,provider_id,type,status,capacity_bytes,used_bytes,filesystem,encrypted,capabilities,desired_state,observed_state,backup_policy_id,last_backup_at,orphaned_at,adopted_at,created_at,updated_at,deleted_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,e.organizationId,e.projectId,e.environmentId??null,e.resourceId??null,e.name,e.provider,e.providerId??null,e.type,e.status,e.capacityBytes??null,e.usedBytes??null,e.filesystem??null,e.encrypted?1:0,JSON.stringify(e.capabilities),JSON.stringify(e.desiredState),JSON.stringify(e.observedState),e.backupPolicyId??null,e.lastBackupAt??null,e.orphanedAt??null,e.adoptedAt??null,t,t,e.deletedAt??null]),this.get(r)}update(e,t,r){let n=this.get(e);if(!n||n.version!==t)throw Error("Volume changed before this operation could be applied.");let i={...n,...r,updatedAt:se(this.now)};if(this.controlPlane.database.run("UPDATE persistent_volumes SET environment_id=?,resource_id=?,name=?,provider=?,provider_id=?,type=?,status=?,capacity_bytes=?,used_bytes=?,filesystem=?,encrypted=?,capabilities=?,desired_state=?,observed_state=?,backup_policy_id=?,last_backup_at=?,orphaned_at=?,adopted_at=?,deleted_at=?,version=version+1,updated_at=? WHERE id=? AND version=?",[i.environmentId??null,i.resourceId??null,i.name,i.provider,i.providerId??null,i.type,i.status,i.capacityBytes??null,i.usedBytes??null,i.filesystem??null,i.encrypted?1:0,JSON.stringify(i.capabilities),JSON.stringify(i.desiredState),JSON.stringify(i.observedState),i.backupPolicyId??null,i.lastBackupAt??null,i.orphanedAt??null,i.adoptedAt??null,i.deletedAt??null,i.updatedAt,e,t]).changes!==1)throw Error("Volume changed before this operation could be applied.");return this.get(e)}attachments(e){return this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE volume_id=? ORDER BY target_path").all(e).map(nr)}attachment(e){let t=this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE id=?").get(e);return t?nr(t):void 0}upsertAttachment(e){let t=this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE volume_id=? AND resource_id=? AND target_path=?").get(e.volumeId,e.resourceId,e.targetPath),r=se(this.now);if(t){let i=nr(t);return this.controlPlane.database.run("UPDATE volume_attachments SET read_only=?,uid=?,gid=?,mode=?,propagation=?,driver_options=?,desired_state=?,observed_state=?,operation_id=?,last_error=?,version=version+1,updated_at=? WHERE id=?",[e.readOnly?1:0,e.uid??null,e.gid??null,e.mode??null,e.propagation,JSON.stringify(e.driverOptions),e.desiredState,e.observedState,e.operationId??null,e.lastError??null,r,i.id]),this.attachment(i.id)}let n=e.id??this.id();return this.controlPlane.database.run("INSERT INTO volume_attachments (id,volume_id,resource_id,target_path,read_only,uid,gid,mode,propagation,driver_options,desired_state,observed_state,operation_id,last_error,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[n,e.volumeId,e.resourceId,e.targetPath,e.readOnly?1:0,e.uid??null,e.gid??null,e.mode??null,e.propagation,JSON.stringify(e.driverOptions),e.desiredState,e.observedState,e.operationId??null,e.lastError??null,r,r]),this.attachment(n)}updateAttachment(e,t){let r=this.attachment(e);if(!r)throw Error("Volume attachment was not found.");let n={...r,...t};return this.controlPlane.database.run("UPDATE volume_attachments SET desired_state=?,observed_state=?,operation_id=?,last_error=?,version=version+1,updated_at=? WHERE id=?",[n.desiredState,n.observedState,n.operationId??null,n.lastError??null,se(this.now),e]),this.attachment(e)}snapshots(e){return this.controlPlane.database.query("SELECT * FROM volume_snapshots WHERE volume_id=? AND deleted_at IS NULL ORDER BY created_at DESC").all(e).map(bn)}snapshot(e){let t=this.controlPlane.database.query("SELECT * FROM volume_snapshots WHERE id=?").get(e);return t?bn(t):void 0}createSnapshot(e){let t=e.id??this.id(),r=se(this.now);return this.controlPlane.database.run("INSERT INTO volume_snapshots (id,volume_id,recovery_point_id,provider_id,name,status,size_bytes,encrypted,checksum,metadata,created_at,updated_at,deleted_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",[t,e.volumeId,e.recoveryPointId??null,e.providerId??null,e.name,e.status,e.sizeBytes??null,e.encrypted?1:0,e.checksum??null,JSON.stringify(e.metadata),r,r,e.deletedAt??null]),this.snapshot(t)}updateSnapshot(e,t){let r=this.snapshot(e);if(!r)throw Error("Volume snapshot was not found.");let n={...r,...t};return this.controlPlane.database.run("UPDATE volume_snapshots SET recovery_point_id=?,provider_id=?,name=?,status=?,size_bytes=?,encrypted=?,checksum=?,metadata=?,deleted_at=?,updated_at=? WHERE id=?",[n.recoveryPointId??null,n.providerId??null,n.name,n.status,n.sizeBytes??null,n.encrypted?1:0,n.checksum??null,JSON.stringify(n.metadata),n.deletedAt??null,se(this.now),e]),this.snapshot(e)}inventory(e,t){return this.list({projectId:e,environmentId:t}).map((r)=>{let n=this.attachments(r.id),i=this.snapshots(r.id),o=r.lastBackupAt?Date.now()-new Date(r.lastBackupAt).getTime():1/0;return{...r,attachments:n,snapshots:i,orphaned:r.status==="orphaned",usagePercent:r.capacityBytes&&r.usedBytes!=null?Math.round(r.usedBytes/r.capacityBytes*1000)/10:void 0,backupState:r.backupPolicyId?o<=86400000?"protected":"stale":"unprotected"}})}audit(e){this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:e.projectId,resourceId:this.get(e.volumeId)?.resourceId,actorId:e.actorId,type:e.type,level:"warning",payload:{volumeId:e.volumeId,environmentId:e.environmentId??null,...e.payload}})}}function or(e,t){let r=e.getProject(t.projectId);if(!r?.organizationId)return;let n=new st(e),i=new rr,o=new Set(t.manifest.spec.volumes),s=new Set;for(let a of o){let d=`${t.slug}-${a}`.toLowerCase().replace(/[^a-z0-9_.-]/g,"-").slice(0,63),c=n.list({projectId:t.projectId,environmentId:t.environmentId,includeDeleted:!0}).find((m)=>m.name===d);if(c?.deletedAt)throw Error(`Compose volume ${d} was permanently deleted; rename it before redeploying.`);let p=c?.resourceId?e.getResource(c.resourceId):e.createResource({projectId:t.projectId,environmentId:t.environmentId,kind:"volume",slug:d,name:d,provider:"docker",providerId:d,desiredState:{composeApplicationId:t.id,composeVolume:a}}),l=c??n.create({organizationId:r.organizationId,projectId:t.projectId,environmentId:t.environmentId,resourceId:p?.id,name:d,provider:"docker",providerId:d,type:"docker",status:"available",encrypted:!1,capabilities:i.capabilities(),desiredState:{composeApplicationId:t.id,composeVolume:a,nativeName:d},observedState:{}});s.add(l.id);let u=new Map;for(let m of Object.values(t.manifest.spec.services))for(let E of m.volumes.filter((T)=>T.source===a)){let T=u.get(E.target)??[];T.push(m.name),u.set(E.target,T),n.upsertAttachment({volumeId:l.id,resourceId:t.resourceId,targetPath:E.target,readOnly:E.readOnly,propagation:"private",driverOptions:{composeServices:T},desiredState:"attached",observedState:"pending"})}}for(let a of n.list({projectId:t.projectId,environmentId:t.environmentId}).filter((d)=>d.desiredState.composeApplicationId===t.id&&!s.has(d.id)))for(let d of n.attachments(a.id))n.updateAttachment(d.id,{desiredState:"detached"})}function Rn(e,t,r){let n=new st(e);for(let i of n.list({projectId:t.projectId,environmentId:t.environmentId}).filter((o)=>o.desiredState.composeApplicationId===t.id)){for(let o of n.attachments(i.id))n.updateAttachment(o.id,{desiredState:"detached",observedState:"detached"});n.update(i.id,i.version,{status:r?"deleted":"available",deletedAt:r?new Date().toISOString():void 0})}}function ae(e){return typeof e==="string"&&e?e:void 0}function sr(e,t){try{return JSON.parse(String(e))}catch{return t}}function at(e){return{id:String(e.id),resourceId:String(e.resource_id),projectId:String(e.project_id),environmentId:String(e.environment_id),name:String(e.name),slug:String(e.slug),status:String(e.status),sourceKind:String(e.source_kind),sourceHash:String(e.source_hash),redactedSource:String(e.redacted_source),manifest:sr(e.manifest,{}),diagnostics:sr(e.diagnostics,[]),templateId:ae(e.template_id),templateVersion:ae(e.template_version),latestOperationId:ae(e.latest_operation_id),createdByActorId:ae(e.created_by_actor_id),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at),deletedAt:ae(e.deleted_at)}}function es(e){return{applicationId:String(e.application_id),serviceName:String(e.service_name),status:String(e.status),replicas:Number(e.replicas),healthyReplicas:Number(e.healthy_replicas),latestOperationId:ae(e.latest_operation_id),observedState:sr(e.observed_state,{}),updatedAt:String(e.updated_at)}}class ee{controlPlane;now;id;constructor(e,t={}){this.controlPlane=e;this.now=t.now??(()=>new Date),this.id=t.id??(()=>crypto.randomUUID())}persist(e,t){if(!e.valid)throw Error(`Compose definition contains ${e.diagnostics.filter((E)=>E.severity==="error").length} blocking diagnostic(s)`);let{projectId:r,environmentId:n,name:i,slug:o}=e.manifest.metadata;if(!this.controlPlane.listEnvironments(r).find((E)=>E.id===n))throw Error("Compose project and environment scope was not found");let a=this.getBySlug(r,n,o),d=this.now().toISOString(),c=JSON.stringify(e.manifest),p=JSON.stringify(I(e.diagnostics));if(a){if(a.status==="deleted")throw Error("A deleted Compose application cannot be overwritten; choose another slug");let E=this.controlPlane.getResource(a.resourceId);if(!E)throw Error("Compose application resource was not found");this.controlPlane.updateResource(E.id,E.version,{name:i,provider:E.provider,providerId:E.providerId,desiredState:e.manifest,discoveredState:E.discoveredState,metadata:{sourceKind:t.sourceKind,templateId:t.templateId??null,templateVersion:t.templateVersion??null,sourceHash:e.sourceHash}}),this.controlPlane.database.run("UPDATE compose_applications SET name=?, status='ready', source_kind=?, source_hash=?, redacted_source=?, manifest=?, diagnostics=?, template_id=?, template_version=?, version=version+1, updated_at=? WHERE id=?",[i,t.sourceKind,e.sourceHash,e.redactedSource,c,p,t.templateId??null,t.templateVersion??null,d,a.id]);let T=Object.keys(e.manifest.spec.services);if(T.length)this.controlPlane.database.run(`DELETE FROM compose_service_states WHERE application_id=? AND service_name NOT IN (${T.map(()=>"?").join(",")})`,[a.id,...T]);for(let h of Object.values(e.manifest.spec.services))this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, observed_state, updated_at) VALUES (?, ?, 'pending', ?, 0, '{}', ?) ON CONFLICT(application_id, service_name) DO UPDATE SET replicas=excluded.replicas, updated_at=excluded.updated_at",[a.id,h.name,h.replicas,d]);this.controlPlane.appendEvent({projectId:r,resourceId:a.resourceId,actorId:t.createdByActorId,type:"compose.application.updated",payload:{applicationId:a.id,sourceHash:e.sourceHash,diagnosticCount:e.diagnostics.length,templateId:t.templateId??null,templateVersion:t.templateVersion??null}});let _=this.get(a.id);return or(this.controlPlane,_),_}let l=this.controlPlane.createResource({projectId:r,environmentId:n,kind:"compose_application",slug:o,name:i,desiredState:e.manifest,metadata:{sourceKind:t.sourceKind,templateId:t.templateId??null,templateVersion:t.templateVersion??null,sourceHash:e.sourceHash}}),u=this.id();this.controlPlane.database.run("INSERT INTO compose_applications (id, resource_id, project_id, environment_id, name, slug, status, source_kind, source_hash, redacted_source, manifest, diagnostics, template_id, template_version, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, 'ready', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[u,l.id,r,n,i,o,t.sourceKind,e.sourceHash,e.redactedSource,c,p,t.templateId??null,t.templateVersion??null,t.createdByActorId??null,d,d]);for(let E of Object.values(e.manifest.spec.services))this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, observed_state, updated_at) VALUES (?, ?, 'pending', ?, 0, '{}', ?)",[u,E.name,E.replicas,d]);this.controlPlane.appendEvent({projectId:r,resourceId:l.id,actorId:t.createdByActorId,type:"compose.application.created",payload:{applicationId:u,sourceHash:e.sourceHash,serviceNames:Object.keys(e.manifest.spec.services),templateId:t.templateId??null}});let m=this.get(u);return or(this.controlPlane,m),m}import(e,t){let r=ie(e,t);return{application:this.persist(r,{sourceKind:"compose",createdByActorId:t.createdByActorId}),parsed:r}}fromTemplate(e,t,r){let n=Zt(e,t,r,r.version);return{application:this.persist(n,{sourceKind:"template",templateId:e,templateVersion:r.version??"1.0.0",createdByActorId:r.createdByActorId}),parsed:n}}preview(e,t){return ie(e,t)}get(e){let t=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE id=?").get(e);return t?at(t):void 0}getByResource(e){let t=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE resource_id=?").get(e);return t?at(t):void 0}getBySlug(e,t,r){let n=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE project_id=? AND environment_id=? AND slug=?").get(e,t,r);return n?at(n):void 0}list(e={}){return this.controlPlane.database.query("SELECT * FROM compose_applications ORDER BY updated_at DESC").all().map(at).filter((t)=>(!e.projectId||t.projectId===e.projectId)&&(!e.environmentId||t.environmentId===e.environmentId)&&(e.includeDeleted||t.status!=="deleted"))}services(e){return this.controlPlane.database.query("SELECT * FROM compose_service_states WHERE application_id=? ORDER BY service_name").all(e).map(es)}transition(e,t,r={}){let n=this.get(e);if(!n)throw Error(`Compose application ${e} was not found`);let i=this.now().toISOString(),o=t==="deleted"?i:null;this.controlPlane.database.run("UPDATE compose_applications SET status=?, latest_operation_id=COALESCE(?, latest_operation_id), version=version+1, updated_at=?, deleted_at=? WHERE id=?",[t,r.operationId??null,i,o,e]);for(let s of r.services??[])if(n.manifest.spec.services[s.name])this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, latest_operation_id, observed_state, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(application_id, service_name) DO UPDATE SET status=excluded.status, replicas=excluded.replicas, healthy_replicas=excluded.healthy_replicas, latest_operation_id=excluded.latest_operation_id, observed_state=excluded.observed_state, updated_at=excluded.updated_at",[e,s.name,s.status,s.replicas??n.manifest.spec.services[s.name].replicas,s.healthyReplicas??0,r.operationId??null,JSON.stringify(I(s.observedState??{})),i]);return this.controlPlane.appendEvent({projectId:n.projectId,resourceId:n.resourceId,operationId:r.operationId,type:`compose.application.${t}`,level:t==="failed"||t==="degraded"?"error":"info",payload:{applicationId:e,error:r.error??null}}),this.get(e)}}class ts{controlPlane;applications;queue;constructor(e){this.controlPlane=e;this.applications=new ee(e),this.queue=new H(e)}enqueue(e,t,r={}){if(e.status==="deleted")throw Error("Deleted Compose applications cannot be operated");if(r.service&&!e.manifest.spec.services[r.service])throw Error(`Compose service ${r.service} was not found`);if(t==="delete"){let i=r.removeVolumes?`${e.slug} delete volumes`:e.slug;if(r.confirmation!==i)throw Error(`Type ${i} to confirm ${r.removeVolumes?"persistent data removal":"stack deletion"}`)}if(t==="scale"&&(!r.service||!Number.isInteger(r.replicas)||r.replicas<0||r.replicas>100))throw Error("Scale requires a service and 0-100 replicas");let n=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:r.actorId,kind:`compose.${t}`,idempotencyKey:`compose:${e.id}:${t}:${r.service??"stack"}:${r.replicas??""}:${e.version}`,correlationId:`compose:${e.id}`,input:{applicationId:e.id,service:r.service??null,replicas:r.replicas??null,removeVolumes:!!r.removeVolumes},lockKey:`compose:${e.id}`,providerKey:this.controlPlane.getResource(e.resourceId)?.provider??"default",buildSlot:t==="deploy"||t==="redeploy",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.applications.transition(e.id,t==="delete"?"deleting":t==="stop"?"stopped":t==="start"?"deploying":t==="scale"?e.status:"deploying",{operationId:n.id}),n}}import{createHash as rs}from"node:crypto";var ns=/^[a-f0-9]{40,64}$/i,is=/^[A-Z][A-Z0-9_]{1,127}$/;function z(e){return typeof e==="string"&&e?e:void 0}function de(e){try{return JSON.parse(String(e))}catch{return{}}}function os(e){let t=de(e);return Array.isArray(t)?t.map(String):[]}function ar(e){return{id:String(e.id),projectId:String(e.project_id),resourceId:String(e.resource_id),baseEnvironmentId:String(e.base_environment_id),enabled:Number(e.enabled)===1,branchRule:z(e.branch_rule),domainPattern:String(e.domain_pattern),ttlHours:Number(e.ttl_hours),keepCount:Number(e.keep_count),publicAccess:Number(e.public_access)===1,authenticationRequired:Number(e.authentication_required)===1,allowForks:Number(e.allow_forks)===1,inheritedSecrets:os(e.inherited_secrets),resourceOverrides:de(e.resource_overrides),databaseStrategy:String(e.database_strategy),maxMonthlyCost:Number(e.max_monthly_cost),maxCpu:Number(e.max_cpu),maxMemoryMb:Number(e.max_memory_mb),cleanupOnClose:Number(e.cleanup_on_close)===1,version:Number(e.version),createdByActorId:z(e.created_by_actor_id),createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}function Oe(e){return{id:String(e.id),definitionId:String(e.definition_id),projectId:String(e.project_id),resourceId:String(e.resource_id),baseEnvironmentId:String(e.base_environment_id),identityKey:String(e.identity_key),sourceProvider:z(e.source_provider),repository:z(e.repository),branch:String(e.branch),pullRequestNumber:e.pull_request_number==null?void 0:Number(e.pull_request_number),fork:Number(e.fork)===1,commitSha:String(e.commit_sha),name:String(e.name),stackName:String(e.stack_name),url:z(e.url),status:String(e.status),expiresAt:String(e.expires_at),latestOperationId:z(e.latest_operation_id),createdByActorId:z(e.created_by_actor_id),costEstimate:e.cost_estimate==null?void 0:Number(e.cost_estimate),desiredState:de(e.desired_state),observedState:de(e.observed_state),teardownError:z(e.teardown_error),version:Number(e.version),createdAt:String(e.created_at),updatedAt:String(e.updated_at),destroyedAt:z(e.destroyed_at)}}function Cn(e){return{id:String(e.id),previewId:String(e.preview_id),provider:String(e.provider),providerResourceId:String(e.provider_resource_id),kind:String(e.kind),tags:de(e.tags),observedState:de(e.observed_state),discoveredAt:String(e.discovered_at),deletedAt:z(e.deleted_at)}}function V(e,t,r,n){return Number.isFinite(e)?Math.min(n,Math.max(r,Math.floor(e))):t}function dt(e,t,r,n){return Number.isFinite(e)?Math.min(n,Math.max(r,e)):t}function dr(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,28)||"preview"}class ce{controlPlane;now;id;constructor(e,t={}){this.controlPlane=e;this.now=t.now??(()=>new Date),this.id=t.id??(()=>crypto.randomUUID())}createDefinition(e){let t=this.controlPlane.getResource(e.resourceId),r=this.controlPlane.listEnvironments(e.projectId).find((c)=>c.id===e.baseEnvironmentId);if(!t||t.projectId!==e.projectId||t.environmentId!==r?.id)throw Error("Preview resource and base environment must belong to the same project scope");if(t.kind!=="application")throw Error("Preview environments currently support application resources only");if(!/^https:\/\//.test(e.domainPattern)||!e.domainPattern.includes("{name}"))throw Error("Preview domainPattern must be HTTPS and include {name}");let n=this.getDefinitionForResource(e.resourceId),i=e.publicAccess??n?.publicAccess??!1,o=e.authenticationRequired??n?.authenticationRequired??!0;if(i&&!o)throw Error("Public preview environments require an authentication policy");let s=[...new Set(e.inheritedSecrets??[])];if(s.some((c)=>!is.test(c)))throw Error("Inherited preview secret names must use uppercase environment-variable identifiers");let a=this.now().toISOString();if(n)return this.controlPlane.database.run("UPDATE preview_definitions SET base_environment_id=?, enabled=1, branch_rule=?, domain_pattern=?, ttl_hours=?, keep_count=?, public_access=?, authentication_required=?, allow_forks=?, inherited_secrets=?, resource_overrides=?, database_strategy=?, max_monthly_cost=?, max_cpu=?, max_memory_mb=?, cleanup_on_close=?, version=version+1, updated_at=? WHERE id=?",[e.baseEnvironmentId,e.branchRule??null,e.domainPattern,V(e.ttlHours,n.ttlHours,1,720),V(e.keepCount,n.keepCount,1,100),i?1:0,o?1:0,e.allowForks??n.allowForks?1:0,JSON.stringify(e.inheritedSecrets===void 0?n.inheritedSecrets:s),JSON.stringify(I(e.resourceOverrides??n.resourceOverrides)),e.databaseStrategy??n.databaseStrategy,dt(e.maxMonthlyCost,n.maxMonthlyCost,0,1e4),dt(e.maxCpu,n.maxCpu,0.1,64),V(e.maxMemoryMb,n.maxMemoryMb,128,131072),e.cleanupOnClose??n.cleanupOnClose?1:0,a,n.id]),this.controlPlane.appendEvent({projectId:e.projectId,resourceId:e.resourceId,actorId:e.createdByActorId,type:"preview.definition.updated",payload:{definitionId:n.id,baseEnvironmentId:e.baseEnvironmentId,version:n.version+1}}),this.getDefinition(n.id);let d=this.id();return this.controlPlane.database.run("INSERT INTO preview_definitions (id, project_id, resource_id, base_environment_id, enabled, branch_rule, domain_pattern, ttl_hours, keep_count, public_access, authentication_required, allow_forks, inherited_secrets, resource_overrides, database_strategy, max_monthly_cost, max_cpu, max_memory_mb, cleanup_on_close, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[d,e.projectId,e.resourceId,e.baseEnvironmentId,e.branchRule??null,e.domainPattern,V(e.ttlHours,24,1,720),V(e.keepCount,10,1,100),e.publicAccess?1:0,e.authenticationRequired===!1?0:1,e.allowForks?1:0,JSON.stringify(s),JSON.stringify(I(e.resourceOverrides??{})),e.databaseStrategy??"disabled",dt(e.maxMonthlyCost,25,0,1e4),dt(e.maxCpu,1,0.1,64),V(e.maxMemoryMb,1024,128,131072),e.cleanupOnClose===!1?0:1,e.createdByActorId??null,a,a]),this.controlPlane.appendEvent({projectId:e.projectId,resourceId:e.resourceId,actorId:e.createdByActorId,type:"preview.definition.created",payload:{definitionId:d,baseEnvironmentId:e.baseEnvironmentId,ttlHours:V(e.ttlHours,24,1,720),inheritedSecretNames:s}}),this.getDefinition(d)}getDefinition(e){let t=this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE id=?").get(e);return t?ar(t):void 0}getDefinitionForResource(e){let t=this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE resource_id=?").get(e);return t?ar(t):void 0}listDefinitions(e){return this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE project_id=? ORDER BY updated_at DESC").all(e).map(ar)}listInstances(e={}){return this.controlPlane.database.query("SELECT * FROM preview_instances ORDER BY created_at DESC").all().map(Oe).filter((r)=>(!e.projectId||r.projectId===e.projectId)&&(!e.definitionId||r.definitionId===e.definitionId)&&(!e.status||r.status===e.status))}getInstance(e){let t=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE id=?").get(e);return t?Oe(t):void 0}findForPullRequest(e,t,r){let n=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(e,`pr:${t}:${r}`);return n?Oe(n):void 0}findForBranch(e,t,r){let n=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(e,`branch:${t}:${r}`);return n?Oe(n):void 0}upsert(e){let t=this.getDefinition(e.definitionId);if(!t?.enabled)throw Error("Preview environments are not enabled for this application");if(!ns.test(e.commitSha))throw Error("Preview deployment requires an immutable 40-64 character commit SHA");if(e.fork&&!t.allowForks)throw Error("Untrusted fork previews are disabled");let r=e.pullRequestNumber?`pr:${e.repository??"unknown"}:${e.pullRequestNumber}`:`branch:${e.repository??"local"}:${e.branch}`,n=rs("sha256").update(`${t.id}:${r}`).digest("hex").slice(0,8),o=`${(e.pullRequestNumber?`pr-${e.pullRequestNumber}`:dr(e.branch)).slice(0,28)}-${n}`,s=`preview-${o}`.slice(0,63),a=t.domainPattern.replaceAll("{name}",o).replaceAll("{project}",dr(t.projectId)).replaceAll("{branch}",dr(e.branch)).replaceAll("{pr}",String(e.pullRequestNumber??"branch")),d=e.now??this.now(),c=d.toISOString(),p=new Date(d.getTime()+t.ttlHours*60*60*1000).toISOString(),l=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(t.id,r);if(l){let E=Oe(l),T=E.commitSha!==e.commitSha||E.status==="destroyed";if(T)this.controlPlane.database.run("UPDATE preview_instances SET commit_sha=?, branch=?, fork=?, status='queued', expires_at=?, url=?, teardown_error=NULL, destroyed_at=NULL, version=version+1, updated_at=? WHERE id=?",[e.commitSha,e.branch,e.fork?1:0,p,a,c,E.id]);return{preview:this.getInstance(E.id),created:!1,changed:T,inheritedSecrets:e.fork?[]:t.inheritedSecrets}}let u=this.id(),m=I({source:{provider:e.sourceProvider??null,repository:e.repository??null,branch:e.branch,commitSha:e.commitSha,pullRequestNumber:e.pullRequestNumber??null,fork:!!e.fork},policy:{databaseStrategy:t.databaseStrategy,resourceOverrides:t.resourceOverrides,maxMonthlyCost:t.maxMonthlyCost,maxCpu:t.maxCpu,maxMemoryMb:t.maxMemoryMb,publicAccess:t.publicAccess,authenticationRequired:t.authenticationRequired},inheritedSecretNames:e.fork?[]:t.inheritedSecrets});return this.controlPlane.database.run("INSERT INTO preview_instances (id, definition_id, project_id, resource_id, base_environment_id, identity_key, source_provider, repository, branch, pull_request_number, fork, commit_sha, name, stack_name, url, status, expires_at, created_by_actor_id, desired_state, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'queued', ?, ?, ?, ?, ?)",[u,t.id,t.projectId,t.resourceId,t.baseEnvironmentId,r,e.sourceProvider??null,e.repository??null,e.branch,e.pullRequestNumber??null,e.fork?1:0,e.commitSha,o,s,a,p,e.createdByActorId??null,JSON.stringify(m),c,c]),this.controlPlane.appendEvent({projectId:t.projectId,resourceId:t.resourceId,actorId:e.createdByActorId,type:"preview.created",payload:{previewId:u,identityKey:r,commitSha:e.commitSha,expiresAt:p,fork:!!e.fork}}),{preview:this.getInstance(u),created:!0,changed:!0,inheritedSecrets:e.fork?[]:t.inheritedSecrets}}transition(e,t,r={}){let n=this.getInstance(e);if(!n)throw Error(`Preview ${e} was not found`);let i=this.now().toISOString(),o=t==="destroyed"?i:null;return this.controlPlane.database.run("UPDATE preview_instances SET status=?, latest_operation_id=COALESCE(?, latest_operation_id), observed_state=?, teardown_error=?, cost_estimate=COALESCE(?, cost_estimate), destroyed_at=?, version=version+1, updated_at=? WHERE id=?",[t,r.operationId??null,JSON.stringify(I(r.observedState??n.observedState)),r.teardownError??null,r.costEstimate??null,o,i,e]),this.controlPlane.appendEvent({projectId:n.projectId,resourceId:n.resourceId,operationId:r.operationId,type:`preview.${t}`,level:t==="failed"||t==="cleanup_failed"?"error":"info",payload:{previewId:e,commitSha:n.commitSha,teardownError:r.teardownError??null}}),this.getInstance(e)}extend(e,t){let r=this.getInstance(e),n=r?this.getDefinition(r.definitionId):void 0;if(!r||!n)throw Error(`Preview ${e} was not found`);let i=this.now(),o=V(t,n.ttlHours,1,720),s=new Date(Math.max(i.getTime(),new Date(r.expiresAt).getTime())+o*3600000).toISOString();return this.controlPlane.database.run("UPDATE preview_instances SET expires_at=?, version=version+1, updated_at=? WHERE id=?",[s,i.toISOString(),e]),this.getInstance(e)}expired(e=this.now()){return this.listInstances().filter((t)=>["queued","deploying","active","updating","failed","cleanup_failed"].includes(t.status)&&new Date(t.expiresAt)<=e)}recordResource(e){let t=this.getInstance(e.previewId);if(!t)throw Error(`Preview ${e.previewId} was not found`);let r={"ts-cloud:preview":t.id,"ts-cloud:project":t.projectId,"ts-cloud:expires-at":t.expiresAt};for(let[s,a]of Object.entries(r))if(e.tags[s]!==a)throw Error(`Preview resource is missing immutable tag ${s}`);let n=this.id(),i=this.now().toISOString();this.controlPlane.database.run("INSERT INTO preview_resources (id, preview_id, provider, provider_resource_id, kind, tags, observed_state, discovered_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(preview_id, provider, provider_resource_id) DO UPDATE SET kind=excluded.kind, tags=excluded.tags, observed_state=excluded.observed_state, deleted_at=NULL",[n,t.id,e.provider,e.providerResourceId,e.kind,JSON.stringify(e.tags),JSON.stringify(I(e.observedState??{})),i]);let o=this.controlPlane.database.query("SELECT * FROM preview_resources WHERE preview_id=? AND provider=? AND provider_resource_id=?").get(t.id,e.provider,e.providerResourceId);return Cn(o)}listResources(e){return this.controlPlane.database.query("SELECT * FROM preview_resources WHERE preview_id=? ORDER BY kind, provider_resource_id").all(e).map(Cn)}markResourcesDeleted(e){if(!this.getInstance(e))throw Error(`Preview ${e} was not found`);return this.controlPlane.database.run("UPDATE preview_resources SET deleted_at=? WHERE preview_id=? AND deleted_at IS NULL",[this.now().toISOString(),e]).changes}}class ss{controlPlane;previews;queue;constructor(e){this.controlPlane=e;this.previews=new ce(e),this.queue=new H(e)}enqueueDeploy(e,t={}){let r=t.created?"preview.create":"preview.update",n=t.reason==="manual_rebuild"?`:${crypto.randomUUID()}`:"",i=this.queue.enqueue({projectId:e.projectId,environmentId:e.baseEnvironmentId,resourceId:e.resourceId,actorId:t.actorId,kind:r,correlationId:`preview:${e.id}`,idempotencyKey:`preview:${e.id}:${e.commitSha}${n}`,input:{previewId:e.id,reason:t.reason??(t.created?"create":"commit_update"),source:{repository:e.repository??null,branch:e.branch,commitSha:e.commitSha,pullRequestNumber:e.pullRequestNumber??null,fork:e.fork}},lockKey:`preview:${e.id}`,providerKey:"preview",buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.previews.transition(e.id,"queued",{operationId:i.id}),i}enqueueDestroy(e,t,r){if(e.status==="destroyed")throw Error("Preview is already destroyed");let n=this.queue.enqueue({projectId:e.projectId,environmentId:e.baseEnvironmentId,resourceId:e.resourceId,actorId:r,kind:"preview.destroy",correlationId:`preview:${e.id}`,idempotencyKey:`preview:${e.id}:destroy:${t}`,input:{previewId:e.id,reason:t},lockKey:`preview:${e.id}`,providerKey:"preview",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.previews.transition(e.id,"queued",{operationId:n.id}),n}cleanup(e={}){let t=e.now??new Date,r=new Map,n=this.previews.listInstances().filter((d)=>!["destroyed","destroying"].includes(d.status)),i=(d,c)=>{let p=r.get(d.id)??{preview:d,reasons:[]};if(!p.reasons.includes(c))p.reasons.push(c);r.set(d.id,p)};for(let d of n){if(new Date(d.expiresAt)<=t)i(d,"ttl_expired");if(e.maxAgeHours&&t.getTime()-new Date(d.createdAt).getTime()>=e.maxAgeHours*3600000)i(d,"max_age")}let o=new Map;for(let d of n)o.set(d.definitionId,[...o.get(d.definitionId)??[],d]);for(let[d,c]of o){let p=this.previews.getDefinition(d),l=e.keepCount??p?.keepCount;if(!l)continue;c.sort((u,m)=>m.createdAt.localeCompare(u.createdAt)).slice(l).forEach((u)=>i(u,"keep_count"))}let s=[...r.values()].sort((d,c)=>d.preview.createdAt.localeCompare(c.preview.createdAt)),a=e.dryRun?[]:s.map((d)=>this.enqueueDestroy(d.preview,d.reasons.sort().join("+"),e.actorId));if(s.length)this.controlPlane.appendEvent({actorId:e.actorId,type:e.dryRun?"preview.cleanup.planned":"preview.cleanup.queued",payload:{previewIds:s.map((d)=>d.preview.id),reasons:Object.fromEntries(s.map((d)=>[d.preview.id,d.reasons])),dryRun:!!e.dryRun}});return{candidates:s,operations:a,dryRun:!!e.dryRun}}reconcile(e){let t=[],r=[],n=[];for(let i of e){let o=i.tags["ts-cloud:preview"],s=i.tags["ts-cloud:project"],a=i.tags["ts-cloud:expires-at"];if(!o||!s||!a){n.push(i.providerResourceId);continue}let d=this.previews.getInstance(o);if(!d||d.projectId!==s||d.expiresAt!==a){r.push(i.providerResourceId);continue}if(this.previews.recordResource({...i,previewId:d.id}),i.estimatedMonthlyCost!==void 0)this.previews.transition(d.id,d.status,{costEstimate:i.estimatedMonthlyCost,observedState:{...d.observedState,lastReconciledAt:new Date().toISOString()}});t.push(i.providerResourceId)}if(r.length)this.controlPlane.appendEvent({type:"preview.reconciliation.leaks",level:"error",payload:{providerResourceIds:r}});return{matched:t,unknownPreviewResources:r,ignoredUntagged:n}}}var as=["deployment.create","deployment.rollback","application.create","deploy.source","deploy.preview","preview.create","preview.update","preview.destroy","compose.deploy","compose.redeploy","compose.start","compose.stop","compose.delete","compose.scale"];function ct(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function ds(e,t){if(!t.projectId||!t.environmentId)throw Error(`Queued ${t.kind} operation is missing its project or environment scope`);let r=e.listEnvironments(t.projectId).find((s)=>s.id===t.environmentId);if(!r)throw Error(`Environment ${t.environmentId} was not found for queued ${t.kind} operation`);let n=t.resourceId?e.getResource(t.resourceId):void 0;if(t.resourceId&&(!n||n.projectId!==t.projectId||n.environmentId!==t.environmentId))throw Error(`Resource ${t.resourceId} was not found in the queued deployment scope`);let i=ct(t.input);if(t.kind.startsWith("compose.")){let s=typeof i.applicationId==="string"?i.applicationId:void 0,a=s?new ee(e).get(s):t.resourceId?new ee(e).getByResource(t.resourceId):void 0;if(!a||a.projectId!==t.projectId||a.environmentId!==t.environmentId||a.resourceId!==t.resourceId)throw Error("Queued Compose application does not match the operation scope");let d=t.kind.slice(8),c=["compose:apply",a.id,"--action",d,"--env",r.slug];if(typeof i.service==="string"&&i.service)c.push("--service",i.service);if(typeof i.replicas==="number")c.push("--replicas",String(i.replicas));if(i.removeVolumes===!0)c.push("--remove-volumes");return{id:`queue:${t.id}`,label:`${d[0].toUpperCase()}${d.slice(1)} Compose application`,description:`${d} ${a.name}.`,command:c,mutates:!0,target:{environment:r.slug,resource:n?.slug,composeId:a.id}}}if(t.kind.startsWith("preview.")){let s=typeof i.previewId==="string"?i.previewId:void 0,a=s?new ce(e).getInstance(s):void 0;if(!a)throw Error(`Preview ${s??"(missing)"} was not found for queued ${t.kind}`);if(a.projectId!==t.projectId||a.resourceId!==t.resourceId)throw Error("Queued preview does not match the operation scope");if(t.kind==="preview.destroy")return{id:`queue:${t.id}`,label:"Destroy preview",description:`Destroy ${a.name}.`,command:["stack:delete",a.stackName,"--yes"],mutates:!0,target:{environment:r.slug,resource:n?.slug,previewId:a.id}};return{id:`queue:${t.id}`,label:t.kind==="preview.create"?"Create preview":"Update preview",description:`Deploy ${a.name} at ${a.commitSha}.`,command:["deploy","--stack",a.stackName,"--env",r.slug,"--yes","--skip-dns-verification",...n?["--site",n.slug]:[]],mutates:!0,target:{environment:r.slug,resource:n?.slug,previewId:a.id}}}if(t.kind==="deployment.rollback"){let s=["deploy:rollback"];if(n)s.push(n.slug);if(s.push("--env",r.slug),typeof i.revision==="string"&&i.revision)s.push("--to",i.revision);return{id:`queue:${t.id}`,label:"Rollback deployment",description:`Roll back ${n?.slug??r.slug}.`,command:s,mutates:!0,target:{environment:r.slug,resource:n?.slug}}}let o=["deploy","--env",r.slug,"--yes"];if(n)o.push("--site",n.slug);return{id:`queue:${t.id}`,label:t.kind==="deploy.preview"?"Deploy preview":"Deploy release",description:`Deploy ${n?.slug??r.slug}.`,command:o,mutates:!0,target:{environment:r.slug,resource:n?.slug}}}function cs(e){let t=e.stderr?.trim()||`Deployment process exited with code ${e.exitCode}`;if(/\b(?:429|rate.?limit|throttl)/i.test(t))return new J(t,"provider_throttled");if(/\b(?:502|503|504|temporar(?:y|ily)|unavailable|provider.?error)/i.test(t))return new J(t,"provider_unavailable");if(/\b(?:network|econn|enotfound|socket|timed?\s*out|fetch failed|dns)\b/i.test(t))return new J(t,"network");return Error(t)}function bc(e){let t=async(r)=>{r.checkpoint("prepare","Resolving the persisted deployment target.");let n=ds(e.store,r.operation),i=n.target.previewId?new ce(e.store):void 0,o=n.target.composeId?new ee(e.store):void 0;if(i&&n.target.previewId)i.transition(n.target.previewId,r.operation.kind==="preview.destroy"?"destroying":r.operation.kind==="preview.update"?"updating":"deploying",{operationId:r.operation.id});if(o&&n.target.composeId)o.transition(n.target.composeId,r.operation.kind==="compose.delete"?"deleting":r.operation.kind==="compose.stop"?"stopped":"deploying",{operationId:r.operation.id});r.log(`Target: ${n.target.resource??"all resources"} in ${n.target.environment}.`,{stream:"system"}),r.throwIfCancellationRequested(),r.checkpoint("execute",`Running cloud ${n.command.join(" ")}.`);let s=await e.execute(n,r);if(!s.ok){if(i&&n.target.previewId)i.transition(n.target.previewId,r.operation.kind==="preview.destroy"?"cleanup_failed":"failed",{operationId:r.operation.id,teardownError:r.operation.kind==="preview.destroy"?s.stderr?.trim()||`Process exited with ${s.exitCode}`:void 0});if(o&&n.target.composeId)o.transition(n.target.composeId,r.operation.kind==="compose.delete"?"degraded":"failed",{operationId:r.operation.id,error:s.stderr?.trim()||`Process exited with ${s.exitCode}`});throw cs(s)}if(r.throwIfCancellationRequested(),i&&n.target.previewId){let a=i.getInstance(n.target.previewId);if(r.operation.kind==="preview.destroy")i.markResourcesDeleted(a.id),i.transition(a.id,"destroyed",{operationId:r.operation.id,observedState:{reconciledResourceIds:i.listResources(a.id).map((d)=>d.providerResourceId),exactCommitSha:a.commitSha}});else{let d=e.store.getResource(a.resourceId)?.provider??"default";i.recordResource({previewId:a.id,provider:d,providerResourceId:a.stackName,kind:"stack",tags:{"ts-cloud:preview":a.id,"ts-cloud:project":a.projectId,"ts-cloud:expires-at":a.expiresAt},observedState:{command:s.command??null,exactCommitSha:a.commitSha}}),i.transition(a.id,"active",{operationId:r.operation.id,observedState:{url:a.url??null,stackName:a.stackName,exactCommitSha:a.commitSha,providerStatus:"deployed"}})}}if(o&&n.target.composeId){let a=o.get(n.target.composeId),d=typeof ct(r.operation.input).service==="string"?String(ct(r.operation.input).service):void 0,c=r.operation.kind==="compose.delete"?"deleted":r.operation.kind==="compose.stop"?"stopped":"running",p=o.transition(a.id,c,{operationId:r.operation.id,services:Object.values(a.manifest.spec.services).filter((l)=>!d||l.name===d).map((l)=>({name:l.name,status:c==="stopped"||c==="deleted"?"stopped":"running",replicas:c==="deleted"?0:l.replicas,healthyReplicas:c==="running"?l.replicas:0,observedState:{command:s.command??null,healthGatePassed:c==="running"}}))});if(c==="deleted")Rn(e.store,p,ct(r.operation.input).removeVolumes===!0)}return r.checkpoint("finalize","Deployment command completed; persisting the terminal result."),{command:s.command??`cloud ${n.command.join(" ")}`,exitCode:s.exitCode,environment:n.target.environment,resource:n.target.resource??null}};return Object.fromEntries(as.map((r)=>[r,t]))}class L extends Error{code;status;details;constructor(e,t,r,n){super(t);this.code=e;this.status=r;this.details=n}}function cr(e,t){if(e.organizationId!==t.organizationId)return!1;if(e.projectId&&e.projectId!==t.projectId)return!1;if(e.environmentId&&e.environmentId!==t.environmentId)return!1;if(e.resourceId&&e.resourceId!==t.resourceId)return!1;return!0}function us(e,t,r){return ls("sha256").update(`${e.toUpperCase()}
|
|
1616
1616
|
${t}
|
|
1617
|
-
${JSON.stringify(r)}`).digest("hex")}class ps{controlPlane;identities;queue;spendGate;constructor(e,t){this.controlPlane=e;this.identities=t;this.queue=new H(e),this.spendGate=new Ne(e)}target(e,t){let r=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,t),n=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,e.token.scope);if(!r||!n||!cr(n,r))throw new L("forbidden","The token does not grant access to this resource.",403);return r}authorize(e,t,r){if(!e.token.capabilities.includes(t))throw new L("forbidden",`The token is missing the ${t} capability.`,403);let n=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,r),i=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,e.token.scope),o=t==="project:read"&&!!n&&!!i&&cr(n,i);if(!n||!i||!cr(i,n)&&!o)throw new L("forbidden","The token does not grant access to this resource.",403);let s=o?i:n;if(!ke({membership:e.membership,grants:this.controlPlane.listGrants(e.membership.id),capability:t,target:s}).allowed)throw new L("forbidden","The service account does not have access to this resource.",403);return n}listProjects(e){return this.controlPlane.listProjects().filter((t)=>t.organizationId===e.serviceAccount.organizationId).filter((t)=>{try{return this.authorize(e,"project:read",{type:"project",id:t.id}),!0}catch{return!1}}).map((t)=>({id:t.id,slug:t.slug,name:t.name,description:t.description,version:t.version,createdAt:t.createdAt,updatedAt:t.updatedAt}))}listEnvironments(e,t){let r=this.controlPlane.getProject(t);if(!r||r.organizationId!==e.serviceAccount.organizationId)throw new L("not_found","Project was not found.",404);return this.controlPlane.listEnvironments(t).filter((n)=>{try{return this.authorize(e,"project:read",{type:"environment",id:n.id}),!0}catch{return!1}}).map((n)=>({id:n.id,projectId:n.projectId,slug:n.slug,name:n.name,kind:n.kind,region:n.region,version:n.version,createdAt:n.createdAt,updatedAt:n.updatedAt}))}listServices(e,t,r){let n=new Set(this.listEnvironments(e,t).map((i)=>String(i.id)));if(r&&!n.has(r))throw new L("not_found","Environment was not found.",404);return this.controlPlane.listResources(t,r).filter((i)=>!i.environmentId||n.has(i.environmentId)).filter((i)=>{try{return this.authorize(e,"project:read",{type:"resource",id:i.id}),!0}catch{return!1}}).map((i)=>({id:i.id,projectId:i.projectId,environmentId:i.environmentId,kind:i.kind,slug:i.slug,name:i.name,provider:i.provider,providerId:i.providerId,metadata:I(i.metadata),version:i.version,createdAt:i.createdAt,updatedAt:i.updatedAt}))}listOperations(e,t){return this.controlPlane.listOperations({projectId:t,limit:500}).filter((n)=>{let i=n.resourceId?{type:"resource",id:n.resourceId}:n.environmentId?{type:"environment",id:n.environmentId}:n.projectId?{type:"project",id:n.projectId}:{type:"organization"};try{return this.authorize(e,"deployments:read",i),!0}catch{return!1}}).map((n)=>this.operation(n))}listEvents(e,t,r){if(t)this.authorize(e,"audit:read",{type:"project",id:t});else this.authorize(e,"audit:read",e.token.scope);return this.controlPlane.listEvents({organizationId:e.serviceAccount.organizationId,projectId:t,afterSequence:r,limit:500}).filter((n)=>{let i=n.resourceId?{type:"resource",id:n.resourceId}:n.projectId?{type:"project",id:n.projectId}:{type:"organization"};try{return this.target(e,i),!0}catch{return!1}}).map((n)=>({id:n.id,sequence:n.sequence,projectId:n.projectId,operationId:n.operationId,resourceId:n.resourceId,correlationId:n.correlationId,type:n.type,level:n.level,payload:I(n.payload),createdAt:n.createdAt}))}createDeployment(e,t,r){if(!this.controlPlane.listEnvironments(t.projectId).find((p)=>p.id===t.environmentId))throw new L("not_found","Environment was not found in this project.",404);let i=t.serviceId?{type:"resource",id:t.serviceId}:{type:"environment",id:t.environmentId};this.authorize(e,"deployments:create",i);let o=this.spendGate.check("deploy",{organizationId:e.serviceAccount.organizationId,projectId:t.projectId,environmentId:t.environmentId});if(!o.allowed)throw new L("spend_cap_exceeded",o.reason??"A spend cap is blocking deployments.",402,{action:o.action,budgetId:o.budgetId});let s=us("POST","/api/v1/deployments",t),a=this.identities.getIdempotency(e.token.id,r);if(a){if(a.requestHash!==s)throw new L("idempotency_conflict","Idempotency-Key was already used for another request.",409);let p=a.operationId?this.controlPlane.getOperation(a.operationId):void 0;if(!p)throw new L("idempotency_unavailable","The original operation is no longer available.",409);return{operation:this.operation(p),replay:!0}}if(t.serviceId){let p=this.controlPlane.getResource(t.serviceId);if(!p||p.projectId!==t.projectId||p.environmentId!==t.environmentId)throw new L("not_found","Service was not found in this environment.",404)}let d=t.serviceId?this.controlPlane.getResource(t.serviceId):void 0,c=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.serviceId,actorId:e.actor.id,kind:t.action==="rollback"?"deployment.rollback":"deployment.create",idempotencyKey:`api:${e.token.id}:${r}`,input:I({action:t.action??"deploy",revision:t.revision??null}),lockKey:t.serviceId?`resource:${t.serviceId}`:`environment:${t.environmentId}`,providerKey:d?.provider??"default",buildSlot:t.action!=="rollback",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.identities.saveIdempotency({tokenId:e.token.id,key:r,requestHash:s,operationId:c.id,responseStatus:202,responseBody:{operationId:c.id}}),{operation:this.operation(c),replay:!1}}operation(e){return{id:e.id,state:e.state,kind:e.kind,projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:e.actorId,correlationId:e.correlationId,input:I(e.input),output:I(e.output),error:e.error,attempt:e.attempt,createdAt:e.createdAt,updatedAt:e.updatedAt,startedAt:e.startedAt,finishedAt:e.finishedAt}}}function lt(e){return e.serviceAccount.organizationId}function An(e){if(e==null)return;if(e==="daily"||e==="weekly"||e==="monthly")return e;throw new L("validation_error","period must be daily, weekly, or monthly.",422)}function le(e,t){if(e==null)return;let r=Number(e);if(!Number.isFinite(r)||r<0||!Number.isInteger(r))throw new L("validation_error",`${t} must be a non-negative integer.`,422);return r}function D(e,t,r,n,i){if(i)e.authorization.authorize(t,r,{type:"environment",id:i});else if(n)e.authorization.authorize(t,r,{type:"project",id:n});else e.authorization.authorize(t,r,{type:"organization"});return{organizationId:lt(t),projectId:n,environmentId:i}}async function qc(e,t,r){let{method:n,url:i}=r,o=e.now?.()??new Date,s=i.searchParams.get("projectId")??void 0,a=i.searchParams.get("environmentId")??void 0;if(n==="GET"&&i.pathname==="/api/v1/usage"){let u=D(e,t,"billing:read",s,a);return e.service.usageReport({...u,period:An(i.searchParams.get("period")),timezone:i.searchParams.get("timezone")??void 0,now:o})}if(n==="GET"&&i.pathname==="/api/v1/usage/rollups"){let u=D(e,t,"billing:read",s,a),m=i.searchParams.get("from"),E=i.searchParams.get("to");if(!m||!E)throw new L("validation_error","from and to are required.",422);if(Number.isNaN(Date.parse(m))||Number.isNaN(Date.parse(E)))throw new L("validation_error","from and to must be ISO-8601 timestamps.",422);let T=i.searchParams.getAll("meter");return{data:e.store.listRollups({...u,from:m,to:E,meters:T.length>0?T:void 0},le(i.searchParams.get("limit"),"limit")??1000)}}if(n==="GET"&&i.pathname==="/api/v1/usage/focus"){let u=D(e,t,"billing:read",s,a),m=i.searchParams.get("from"),E=i.searchParams.get("to");if(!m||!E)throw new L("validation_error","from and to are required.",422);if(Number.isNaN(Date.parse(m))||Number.isNaN(Date.parse(E)))throw new L("validation_error","from and to must be ISO-8601 timestamps.",422);if(new Date(E).getTime()-new Date(m).getTime()>31622400000)throw new L("validation_error","The range must not exceed one year.",422);let T=i.searchParams.get("granularity")==="hourly"?"hourly":"daily",_=e.store.listRollups({...u,from:m,to:E},1e4),h=Hr(_,{billingPeriodStart:m,billingPeriodEnd:E,currency:e.store.priceBook.currency,granularity:T});return{contentType:"application/x-ndjson",body:Pt(h),recordCount:h.length}}if(n==="GET"&&i.pathname==="/api/v1/spend/budgets"){let u=D(e,t,"billing:read",s,a);return{data:e.store.listBudgets({organizationId:u.organizationId,projectId:u.projectId})}}if(n==="POST"&&i.pathname==="/api/v1/spend/budgets"){let u=await r.body?.()??{},E={organizationId:D(e,t,"billing:manage",u.projectId,u.environmentId).organizationId,projectId:u.projectId,environmentId:u.environmentId,name:String(u.name??"").trim(),period:An(u.period??"monthly")??"monthly",timezone:u.timezone,currency:u.currency,softLimitCents:le(u.softLimitCents,"softLimitCents"),hardLimitCents:le(u.hardLimitCents,"hardLimitCents"),thresholds:u.thresholds,meters:u.meters,graceSeconds:le(u.graceSeconds,"graceSeconds"),hysteresisPercent:u.hysteresisPercent,dryRun:u.dryRun!==!1,enabled:u.enabled};try{return{data:e.store.createBudget(E)}}catch(T){throw new L("validation_error",T instanceof Error?T.message:String(T),422)}}let d=/^\/api\/v1\/spend\/budgets\/([^/]+)$/.exec(i.pathname);if(d&&(n==="PATCH"||n==="DELETE")){let u=e.store.getBudget(decodeURIComponent(d[1]));if(!u||u.organizationId!==lt(t))throw new L("not_found","Budget was not found.",404);if(D(e,t,"billing:manage",u.projectId,u.environmentId),n==="DELETE")return{data:{deleted:e.store.deleteBudget(u.id)}};let m=await r.body?.()??{};try{return{data:e.store.updateBudget(u.id,m,le(m.expectedVersion,"expectedVersion"))}}catch(E){let T=E instanceof Error?E.message:String(E);throw new L(T.includes("concurrently")?"conflict":"validation_error",T,T.includes("concurrently")?409:422)}}if(n==="GET"&&i.pathname==="/api/v1/spend/anomalies"){let u=D(e,t,"billing:read",s,a);return{data:e.store.listAnomalies({organizationId:u.organizationId,projectId:u.projectId,since:i.searchParams.get("since")??void 0,unacknowledgedOnly:i.searchParams.get("unacknowledged")==="true",limit:le(i.searchParams.get("limit"),"limit")})}}let c=/^\/api\/v1\/spend\/anomalies\/([^/]+)\/acknowledge$/.exec(i.pathname);if(c&&n==="POST"){let u=e.store.getAnomaly(decodeURIComponent(c[1]));if(!u||u.organizationId!==lt(t))throw new L("not_found","Anomaly was not found.",404);return D(e,t,"billing:manage",u.projectId,u.environmentId),{data:{acknowledged:e.store.acknowledgeAnomaly(u.id)}}}if(n==="GET"&&i.pathname==="/api/v1/spend/signals")return D(e,t,"billing:read",s,a),{data:he};if(i.pathname==="/api/v1/spend/anomaly-configs"){if(n==="GET"){let u=D(e,t,"billing:read",s,a);return{data:e.service.anomalyConfigs.list({organizationId:u.organizationId,projectId:u.projectId})}}if(n==="POST"){let u=await r.body?.()??{},m=D(e,t,"billing:manage",u.projectId,u.environmentId);try{return{data:e.service.anomalyConfigs.upsert({organizationId:m.organizationId,projectId:u.projectId,environmentId:u.environmentId,signal:String(u.signal??""),enabled:u.enabled,sensitivity:u.sensitivity,seasonLength:u.seasonLength==null?void 0:Number(u.seasonLength),minAbsoluteDelta:u.minAbsoluteDelta==null?void 0:Number(u.minAbsoluteDelta),detectDrops:u.detectDrops,severity:u.severity})}}catch(E){throw new L("validation_error",E instanceof Error?E.message:String(E),422)}}}let p=/^\/api\/v1\/spend\/anomaly-configs\/([^/]+)$/.exec(i.pathname);if(p&&n==="DELETE"){let u=e.service.anomalyConfigs.get(decodeURIComponent(p[1]));if(!u||u.organizationId!==lt(t))throw new L("not_found","Anomaly config was not found.",404);return D(e,t,"billing:manage",u.projectId,u.environmentId),{data:{deleted:e.service.anomalyConfigs.delete(u.id)}}}if(i.pathname==="/api/v1/spend/anomaly-silences"){if(n==="GET"){let u=D(e,t,"billing:read",s,a);return{data:e.service.anomalyConfigs.listSilences({organizationId:u.organizationId,projectId:u.projectId,includeExpired:i.searchParams.get("includeExpired")==="true"})}}if(n==="POST"){let u=await r.body?.()??{},m=D(e,t,"billing:manage",u.projectId);try{return{data:e.service.anomalyConfigs.silence({organizationId:m.organizationId,projectId:u.projectId,signal:u.signal,routePattern:u.routePattern,statusCode:u.statusCode==null?void 0:Number(u.statusCode),reason:String(u.reason??""),expiresAt:u.expiresAt})}}catch(E){throw new L("validation_error",E instanceof Error?E.message:String(E),422)}}}let l=/^\/api\/v1\/spend\/anomaly-silences\/([^/]+)$/.exec(i.pathname);if(l&&n==="DELETE")return D(e,t,"billing:manage",s),{data:{deleted:e.service.anomalyConfigs.removeSilence(decodeURIComponent(l[1]))}};if(n==="GET"&&i.pathname==="/api/v1/spend/enforcement"){let u=D(e,t,"billing:read",s,a);return{data:e.store.listEnforcements({organizationId:u.organizationId,activeOnly:i.searchParams.get("active")!=="false"})}}if(n==="GET"&&i.pathname==="/api/v1/spend/allowance"){let u=D(e,t,"billing:read",s,a),m=i.searchParams.get("operation")??"deploy";if(!["build","deploy","function_invoke","request"].includes(m))throw new L("validation_error","operation must be build, deploy, function_invoke, or request.",422);let T=e.store.listEnforcements({organizationId:u.organizationId,activeOnly:!0}).filter((f)=>(!f.projectId||f.projectId===u.projectId)&&(!f.environmentId||f.environmentId===u.environmentId)),_=jr(m,T),N=e.store.budgetsForScope(u.organizationId,u.projectId,u.environmentId).map((f)=>e.service.status(f,o));return{operation:m,allowed:_.allowed,blockedBy:_.blockedBy??null,reason:_.reason??null,budgets:N.map((f)=>({id:f.budget.id,name:f.budget.name,usedPercent:f.decision.usedPercent,projectedPercent:f.decision.projectedPercent,level:f.decision.level,timeToCap:f.timeToCap}))}}return}function Hc(){let e=[{name:"projectId",in:"query",schema:{type:"string"}},{name:"environmentId",in:"query",schema:{type:"string"}}];return{"/api/v1/usage":{get:{summary:"Current usage, cost, and every budget governing the scope.",parameters:[...e,{name:"period",in:"query",schema:{type:"string",enum:["daily","weekly","monthly"]}},{name:"timezone",in:"query",schema:{type:"string"}}],responses:{"200":{description:"Usage totals, per-meter breakdown, hourly series, and budget status."}}}},"/api/v1/usage/rollups":{get:{summary:"Itemized hourly usage rollups.",parameters:[...e,{name:"from",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"to",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"meter",in:"query",schema:{type:"array",items:{type:"string"}}},{name:"limit",in:"query",schema:{type:"integer"}}],responses:{"200":{description:"Hourly rollups, newest first."}}}},"/api/v1/usage/focus":{get:{summary:"Usage and cost in FOCUS v1.3 format, newline-delimited JSON.",parameters:[...e,{name:"from",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"to",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"granularity",in:"query",schema:{type:"string",enum:["daily","hourly"]}}],responses:{"200":{description:"FOCUS records, one JSON object per line."}}}},"/api/v1/spend/budgets":{get:{summary:"Budgets governing a scope.",parameters:e,responses:{"200":{description:"Budgets."}}},post:{summary:"Create a budget. Starts in dry run unless dryRun is explicitly false.",responses:{"201":{description:"The created budget."},"422":{description:"Validation error."}}}},"/api/v1/spend/budgets/{budgetId}":{patch:{summary:"Update a budget. Pass expectedVersion for optimistic concurrency.",responses:{"200":{description:"The updated budget."},"409":{description:"Version conflict."}}},delete:{summary:"Delete a budget.",responses:{"200":{description:"Deletion result."}}}},"/api/v1/spend/anomalies":{get:{summary:"Detected spend anomalies.",parameters:[...e,{name:"since",in:"query",schema:{type:"string",format:"date-time"}},{name:"unacknowledged",in:"query",schema:{type:"boolean"}}],responses:{"200":{description:"Anomalies, newest first."}}}},"/api/v1/spend/anomalies/{anomalyId}/acknowledge":{post:{summary:"Acknowledge an anomaly.",responses:{"200":{description:"Acknowledgement result."}}}},"/api/v1/spend/signals":{get:{summary:"Signals anomaly detection can run on, with their gap and sample rules.",responses:{"200":{description:"Signal catalog."}}}},"/api/v1/spend/anomaly-configs":{get:{summary:"Anomaly detection configuration.",parameters:e,responses:{"200":{description:"Configs."}}},post:{summary:"Create or update the config for a signal.",responses:{"200":{description:"The config."}}}},"/api/v1/spend/anomaly-configs/{configId}":{delete:{summary:"Delete an anomaly config, returning the signal to its default.",responses:{"200":{description:"Result."}}}},"/api/v1/spend/anomaly-silences":{get:{summary:"Active anomaly silences.",parameters:e,responses:{"200":{description:"Silences."}}},post:{summary:"Silence a signal, route, or status code. A reason is required.",responses:{"200":{description:"The silence."}}}},"/api/v1/spend/anomaly-silences/{silenceId}":{delete:{summary:"Remove a silence.",responses:{"200":{description:"Result."}}}},"/api/v1/spend/enforcement":{get:{summary:"Enforcement actions in force.",parameters:[...e,{name:"active",in:"query",schema:{type:"boolean"}}],responses:{"200":{description:"Enforcement records."}}}},"/api/v1/spend/allowance":{get:{summary:"Whether an operation is allowed under current spend enforcement.",parameters:[...e,{name:"operation",in:"query",schema:{type:"string",enum:["build","deploy","function_invoke","request"]}}],responses:{"200":{description:"Allowance verdict and the budgets behind it."}}}}}}export{q as Jj,Tt as Kj,re as Lj,we as Mj,_t as Nj,ke as Oj,zn as Pj,B as Qj,ht as Rj,Xe as Sj,Kn as Tj,vr as Uj,Lt as Vj,I as Wj,Sr as Xj,ei as Yj,ie as Zj,Wt as _j,Jt as $j,Xo as ak,Po as bk,Zt as ck,Ud as dk,Dd as ek,it as fk,Xd as gk,Pd as hk,xd as ik,jd as jk,Re as kk,tt as lk,J as mk,H as nk,yo as ok,ce as pk,ss as qk,as as rk,ds as sk,bc as tk,st as uk,zo as vk,ot as wk,qo as xk,Ho as yk,Bo as zk,zd as Ak,rr as Bk,Jo as Ck,Zo as Dk,or as Ek,Rn as Fk,ee as Gk,ts as Hk,Es as Ik,ut as Jk,ms as Kk,k as Lk,gs as Mk,lr as Nk,Dn as Ok,pt as Pk,_s as Qk,hs as Rk,Ns as Sk,ur as Tk,Ue as Uk,Et as Vk,Er as Wk,te as Xk,Q as Yk,ys as Zk,ue as _k,Ls as $k,gr as al,xn as bl,Fn as cl,mt as dl,_r as el,hr as fl,G as gl,ni as hl,ii as il,Ur as jl,Ct as kl,ge as ll,ai as ml,Qe as nl,Dr as ol,wr as pl,Ye as ql,li as rl,Xr as sl,Pr as tl,xr as ul,jr as vl,At as wl,pi as xl,Ei as yl,na as zl,Ti as Al,Fr as Bl,Ge as Cl,gi as Dl,hi as El,Ut as Fl,he as Gl,wt as Hl,kt as Il,Xt as Jl,Mr as Kl,fi as Ll,Hr as Ml,Pt as Nl,la as Ol,xt as Pl,ya as Ql,Br as Rl,Ne as Sl,Vr as Tl,Sa as Ul,$r as Vl,Ai as Wl,wi as Xl,fe as Yl,qt as Zl,Bi as _l,Qi as $l,Yi as am,nn as bm,on as cm,Gi as dm,Fa as em,Ma as fm,Bt as gm,ye as hm,sn as im,cn as jm,io as km,oo as lm,Vt as mm,Ja as nm,cd as om,Ie as pm,ao as qm,Kt as rm,ud as sm,po as tm,Eo as um,mo as vm,_d as wm,To as xm,go as ym,fd as zm,L as Am,us as Bm,ps as Cm,qc as Dm,Hc as Em};
|
|
1617
|
+
${JSON.stringify(r)}`).digest("hex")}class ps{controlPlane;identities;queue;spendGate;constructor(e,t){this.controlPlane=e;this.identities=t;this.queue=new H(e),this.spendGate=new Ne(e)}target(e,t){let r=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,t),n=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,e.token.scope);if(!r||!n||!cr(n,r))throw new L("forbidden","The token does not grant access to this resource.",403);return r}authorize(e,t,r){if(!e.token.capabilities.includes(t))throw new L("forbidden",`The token is missing the ${t} capability.`,403);let n=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,r),i=this.controlPlane.resolveAuthorizationTarget(e.serviceAccount.organizationId,e.token.scope),o=t==="project:read"&&!!n&&!!i&&cr(n,i);if(!n||!i||!cr(i,n)&&!o)throw new L("forbidden","The token does not grant access to this resource.",403);let s=o?i:n;if(!ke({membership:e.membership,grants:this.controlPlane.listGrants(e.membership.id),capability:t,target:s}).allowed)throw new L("forbidden","The service account does not have access to this resource.",403);return n}listProjects(e){return this.controlPlane.listProjects().filter((t)=>t.organizationId===e.serviceAccount.organizationId).filter((t)=>{try{return this.authorize(e,"project:read",{type:"project",id:t.id}),!0}catch{return!1}}).map((t)=>({id:t.id,slug:t.slug,name:t.name,description:t.description,version:t.version,createdAt:t.createdAt,updatedAt:t.updatedAt}))}listEnvironments(e,t){let r=this.controlPlane.getProject(t);if(!r||r.organizationId!==e.serviceAccount.organizationId)throw new L("not_found","Project was not found.",404);return this.controlPlane.listEnvironments(t).filter((n)=>{try{return this.authorize(e,"project:read",{type:"environment",id:n.id}),!0}catch{return!1}}).map((n)=>({id:n.id,projectId:n.projectId,slug:n.slug,name:n.name,kind:n.kind,region:n.region,version:n.version,createdAt:n.createdAt,updatedAt:n.updatedAt}))}listServices(e,t,r){let n=new Set(this.listEnvironments(e,t).map((i)=>String(i.id)));if(r&&!n.has(r))throw new L("not_found","Environment was not found.",404);return this.controlPlane.listResources(t,r).filter((i)=>!i.environmentId||n.has(i.environmentId)).filter((i)=>{try{return this.authorize(e,"project:read",{type:"resource",id:i.id}),!0}catch{return!1}}).map((i)=>({id:i.id,projectId:i.projectId,environmentId:i.environmentId,kind:i.kind,slug:i.slug,name:i.name,provider:i.provider,providerId:i.providerId,metadata:I(i.metadata),version:i.version,createdAt:i.createdAt,updatedAt:i.updatedAt}))}listOperations(e,t){return this.controlPlane.listOperations({projectId:t,limit:500}).filter((n)=>{let i=n.resourceId?{type:"resource",id:n.resourceId}:n.environmentId?{type:"environment",id:n.environmentId}:n.projectId?{type:"project",id:n.projectId}:{type:"organization"};try{return this.authorize(e,"deployments:read",i),!0}catch{return!1}}).map((n)=>this.operation(n))}listEvents(e,t,r){if(t)this.authorize(e,"audit:read",{type:"project",id:t});else this.authorize(e,"audit:read",e.token.scope);return this.controlPlane.listEvents({organizationId:e.serviceAccount.organizationId,projectId:t,afterSequence:r,limit:500}).filter((n)=>{let i=n.resourceId?{type:"resource",id:n.resourceId}:n.projectId?{type:"project",id:n.projectId}:{type:"organization"};try{return this.target(e,i),!0}catch{return!1}}).map((n)=>({id:n.id,sequence:n.sequence,projectId:n.projectId,operationId:n.operationId,resourceId:n.resourceId,correlationId:n.correlationId,type:n.type,level:n.level,payload:I(n.payload),createdAt:n.createdAt}))}createDeployment(e,t,r){if(!this.controlPlane.listEnvironments(t.projectId).find((p)=>p.id===t.environmentId))throw new L("not_found","Environment was not found in this project.",404);let i=t.serviceId?{type:"resource",id:t.serviceId}:{type:"environment",id:t.environmentId};this.authorize(e,"deployments:create",i);let o=this.spendGate.check("deploy",{organizationId:e.serviceAccount.organizationId,projectId:t.projectId,environmentId:t.environmentId});if(!o.allowed)throw new L("spend_cap_exceeded",o.reason??"A spend cap is blocking deployments.",402,{action:o.action,budgetId:o.budgetId});let s=us("POST","/api/v1/deployments",t),a=this.identities.getIdempotency(e.token.id,r);if(a){if(a.requestHash!==s)throw new L("idempotency_conflict","Idempotency-Key was already used for another request.",409);let p=a.operationId?this.controlPlane.getOperation(a.operationId):void 0;if(!p)throw new L("idempotency_unavailable","The original operation is no longer available.",409);return{operation:this.operation(p),replay:!0}}if(t.serviceId){let p=this.controlPlane.getResource(t.serviceId);if(!p||p.projectId!==t.projectId||p.environmentId!==t.environmentId)throw new L("not_found","Service was not found in this environment.",404)}let d=t.serviceId?this.controlPlane.getResource(t.serviceId):void 0,c=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.serviceId,actorId:e.actor.id,kind:t.action==="rollback"?"deployment.rollback":"deployment.create",idempotencyKey:`api:${e.token.id}:${r}`,input:I({action:t.action??"deploy",revision:t.revision??null}),lockKey:t.serviceId?`resource:${t.serviceId}`:`environment:${t.environmentId}`,providerKey:d?.provider??"default",buildSlot:t.action!=="rollback",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.identities.saveIdempotency({tokenId:e.token.id,key:r,requestHash:s,operationId:c.id,responseStatus:202,responseBody:{operationId:c.id}}),{operation:this.operation(c),replay:!1}}operation(e){return{id:e.id,state:e.state,kind:e.kind,projectId:e.projectId,environmentId:e.environmentId,resourceId:e.resourceId,actorId:e.actorId,correlationId:e.correlationId,input:I(e.input),output:I(e.output),error:e.error,attempt:e.attempt,createdAt:e.createdAt,updatedAt:e.updatedAt,startedAt:e.startedAt,finishedAt:e.finishedAt}}}function lt(e){return e.serviceAccount.organizationId}function An(e){if(e==null)return;if(e==="daily"||e==="weekly"||e==="monthly")return e;throw new L("validation_error","period must be daily, weekly, or monthly.",422)}function le(e,t){if(e==null)return;let r=Number(e);if(!Number.isFinite(r)||r<0||!Number.isInteger(r))throw new L("validation_error",`${t} must be a non-negative integer.`,422);return r}function D(e,t,r,n,i){if(i)e.authorization.authorize(t,r,{type:"environment",id:i});else if(n)e.authorization.authorize(t,r,{type:"project",id:n});else e.authorization.authorize(t,r,{type:"organization"});return{organizationId:lt(t),projectId:n,environmentId:i}}async function qc(e,t,r){let{method:n,url:i}=r,o=e.now?.()??new Date,s=i.searchParams.get("projectId")??void 0,a=i.searchParams.get("environmentId")??void 0;if(n==="GET"&&i.pathname==="/api/v1/usage"){let u=D(e,t,"billing:read",s,a);return e.service.usageReport({...u,period:An(i.searchParams.get("period")),timezone:i.searchParams.get("timezone")??void 0,now:o})}if(n==="GET"&&i.pathname==="/api/v1/usage/rollups"){let u=D(e,t,"billing:read",s,a),m=i.searchParams.get("from"),E=i.searchParams.get("to");if(!m||!E)throw new L("validation_error","from and to are required.",422);if(Number.isNaN(Date.parse(m))||Number.isNaN(Date.parse(E)))throw new L("validation_error","from and to must be ISO-8601 timestamps.",422);let T=i.searchParams.getAll("meter");return{data:e.store.listRollups({...u,from:m,to:E,meters:T.length>0?T:void 0},le(i.searchParams.get("limit"),"limit")??1000)}}if(n==="GET"&&i.pathname==="/api/v1/usage/focus"){let u=D(e,t,"billing:read",s,a),m=i.searchParams.get("from"),E=i.searchParams.get("to");if(!m||!E)throw new L("validation_error","from and to are required.",422);if(Number.isNaN(Date.parse(m))||Number.isNaN(Date.parse(E)))throw new L("validation_error","from and to must be ISO-8601 timestamps.",422);if(new Date(E).getTime()-new Date(m).getTime()>31622400000)throw new L("validation_error","The range must not exceed one year.",422);let T=i.searchParams.get("granularity")==="hourly"?"hourly":"daily",_=e.store.listRollups({...u,from:m,to:E},1e4),h=Hr(_,{billingPeriodStart:m,billingPeriodEnd:E,currency:e.store.priceBook.currency,granularity:T});return{contentType:"application/x-ndjson",body:Pt(h),recordCount:h.length}}if(n==="GET"&&i.pathname==="/api/v1/spend/budgets"){let u=D(e,t,"billing:read",s,a);return{data:e.store.listBudgets({organizationId:u.organizationId,projectId:u.projectId})}}if(n==="POST"&&i.pathname==="/api/v1/spend/budgets"){let u=await r.body?.()??{},E={organizationId:D(e,t,"billing:manage",u.projectId,u.environmentId).organizationId,projectId:u.projectId,environmentId:u.environmentId,name:String(u.name??"").trim(),period:An(u.period??"monthly")??"monthly",timezone:u.timezone,currency:u.currency,softLimitCents:le(u.softLimitCents,"softLimitCents"),hardLimitCents:le(u.hardLimitCents,"hardLimitCents"),thresholds:u.thresholds,meters:u.meters,graceSeconds:le(u.graceSeconds,"graceSeconds"),hysteresisPercent:u.hysteresisPercent,dryRun:u.dryRun!==!1,enabled:u.enabled};try{return{data:e.store.createBudget(E)}}catch(T){throw new L("validation_error",T instanceof Error?T.message:String(T),422)}}let d=/^\/api\/v1\/spend\/budgets\/([^/]+)$/.exec(i.pathname);if(d&&(n==="PATCH"||n==="DELETE")){let u=e.store.getBudget(decodeURIComponent(d[1]));if(!u||u.organizationId!==lt(t))throw new L("not_found","Budget was not found.",404);if(D(e,t,"billing:manage",u.projectId,u.environmentId),n==="DELETE")return{data:{deleted:e.store.deleteBudget(u.id)}};let m=await r.body?.()??{};try{return{data:e.store.updateBudget(u.id,m,le(m.expectedVersion,"expectedVersion"))}}catch(E){let T=E instanceof Error?E.message:String(E);throw new L(T.includes("concurrently")?"conflict":"validation_error",T,T.includes("concurrently")?409:422)}}if(n==="GET"&&i.pathname==="/api/v1/spend/anomalies"){let u=D(e,t,"billing:read",s,a);return{data:e.store.listAnomalies({organizationId:u.organizationId,projectId:u.projectId,since:i.searchParams.get("since")??void 0,unacknowledgedOnly:i.searchParams.get("unacknowledged")==="true",limit:le(i.searchParams.get("limit"),"limit")})}}let c=/^\/api\/v1\/spend\/anomalies\/([^/]+)\/acknowledge$/.exec(i.pathname);if(c&&n==="POST"){let u=e.store.getAnomaly(decodeURIComponent(c[1]));if(!u||u.organizationId!==lt(t))throw new L("not_found","Anomaly was not found.",404);return D(e,t,"billing:manage",u.projectId,u.environmentId),{data:{acknowledged:e.store.acknowledgeAnomaly(u.id)}}}if(n==="GET"&&i.pathname==="/api/v1/spend/signals")return D(e,t,"billing:read",s,a),{data:he};if(i.pathname==="/api/v1/spend/anomaly-configs"){if(n==="GET"){let u=D(e,t,"billing:read",s,a);return{data:e.service.anomalyConfigs.list({organizationId:u.organizationId,projectId:u.projectId})}}if(n==="POST"){let u=await r.body?.()??{},m=D(e,t,"billing:manage",u.projectId,u.environmentId);try{return{data:e.service.anomalyConfigs.upsert({organizationId:m.organizationId,projectId:u.projectId,environmentId:u.environmentId,signal:String(u.signal??""),enabled:u.enabled,sensitivity:u.sensitivity,seasonLength:u.seasonLength==null?void 0:Number(u.seasonLength),minAbsoluteDelta:u.minAbsoluteDelta==null?void 0:Number(u.minAbsoluteDelta),detectDrops:u.detectDrops,severity:u.severity})}}catch(E){throw new L("validation_error",E instanceof Error?E.message:String(E),422)}}}let p=/^\/api\/v1\/spend\/anomaly-configs\/([^/]+)$/.exec(i.pathname);if(p&&n==="DELETE"){let u=e.service.anomalyConfigs.get(decodeURIComponent(p[1]));if(!u||u.organizationId!==lt(t))throw new L("not_found","Anomaly config was not found.",404);return D(e,t,"billing:manage",u.projectId,u.environmentId),{data:{deleted:e.service.anomalyConfigs.delete(u.id)}}}if(i.pathname==="/api/v1/spend/anomaly-silences"){if(n==="GET"){let u=D(e,t,"billing:read",s,a);return{data:e.service.anomalyConfigs.listSilences({organizationId:u.organizationId,projectId:u.projectId,includeExpired:i.searchParams.get("includeExpired")==="true"})}}if(n==="POST"){let u=await r.body?.()??{},m=D(e,t,"billing:manage",u.projectId);try{return{data:e.service.anomalyConfigs.silence({organizationId:m.organizationId,projectId:u.projectId,signal:u.signal,routePattern:u.routePattern,statusCode:u.statusCode==null?void 0:Number(u.statusCode),reason:String(u.reason??""),expiresAt:u.expiresAt})}}catch(E){throw new L("validation_error",E instanceof Error?E.message:String(E),422)}}}let l=/^\/api\/v1\/spend\/anomaly-silences\/([^/]+)$/.exec(i.pathname);if(l&&n==="DELETE")return D(e,t,"billing:manage",s),{data:{deleted:e.service.anomalyConfigs.removeSilence(decodeURIComponent(l[1]))}};if(n==="GET"&&i.pathname==="/api/v1/spend/enforcement"){let u=D(e,t,"billing:read",s,a);return{data:e.store.listEnforcements({organizationId:u.organizationId,activeOnly:i.searchParams.get("active")!=="false"})}}if(n==="GET"&&i.pathname==="/api/v1/spend/allowance"){let u=D(e,t,"billing:read",s,a),m=i.searchParams.get("operation")??"deploy";if(!["build","deploy","function_invoke","request"].includes(m))throw new L("validation_error","operation must be build, deploy, function_invoke, or request.",422);let T=e.store.listEnforcements({organizationId:u.organizationId,activeOnly:!0}).filter((f)=>(!f.projectId||f.projectId===u.projectId)&&(!f.environmentId||f.environmentId===u.environmentId)),_=jr(m,T),N=e.store.budgetsForScope(u.organizationId,u.projectId,u.environmentId).map((f)=>e.service.status(f,o));return{operation:m,allowed:_.allowed,blockedBy:_.blockedBy??null,reason:_.reason??null,budgets:N.map((f)=>({id:f.budget.id,name:f.budget.name,usedPercent:f.decision.usedPercent,projectedPercent:f.decision.projectedPercent,level:f.decision.level,timeToCap:f.timeToCap}))}}return}function Hc(){let e=[{name:"projectId",in:"query",schema:{type:"string"}},{name:"environmentId",in:"query",schema:{type:"string"}}];return{"/api/v1/usage":{get:{summary:"Current usage, cost, and every budget governing the scope.",parameters:[...e,{name:"period",in:"query",schema:{type:"string",enum:["daily","weekly","monthly"]}},{name:"timezone",in:"query",schema:{type:"string"}}],responses:{"200":{description:"Usage totals, per-meter breakdown, hourly series, and budget status."}}}},"/api/v1/usage/rollups":{get:{summary:"Itemized hourly usage rollups.",parameters:[...e,{name:"from",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"to",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"meter",in:"query",schema:{type:"array",items:{type:"string"}}},{name:"limit",in:"query",schema:{type:"integer"}}],responses:{"200":{description:"Hourly rollups, newest first."}}}},"/api/v1/usage/focus":{get:{summary:"Usage and cost in FOCUS v1.3 format, newline-delimited JSON.",parameters:[...e,{name:"from",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"to",in:"query",required:!0,schema:{type:"string",format:"date-time"}},{name:"granularity",in:"query",schema:{type:"string",enum:["daily","hourly"]}}],responses:{"200":{description:"FOCUS records, one JSON object per line."}}}},"/api/v1/spend/budgets":{get:{summary:"Budgets governing a scope.",parameters:e,responses:{"200":{description:"Budgets."}}},post:{summary:"Create a budget. Starts in dry run unless dryRun is explicitly false.",responses:{"201":{description:"The created budget."},"422":{description:"Validation error."}}}},"/api/v1/spend/budgets/{budgetId}":{patch:{summary:"Update a budget. Pass expectedVersion for optimistic concurrency.",responses:{"200":{description:"The updated budget."},"409":{description:"Version conflict."}}},delete:{summary:"Delete a budget.",responses:{"200":{description:"Deletion result."}}}},"/api/v1/spend/anomalies":{get:{summary:"Detected spend anomalies.",parameters:[...e,{name:"since",in:"query",schema:{type:"string",format:"date-time"}},{name:"unacknowledged",in:"query",schema:{type:"boolean"}}],responses:{"200":{description:"Anomalies, newest first."}}}},"/api/v1/spend/anomalies/{anomalyId}/acknowledge":{post:{summary:"Acknowledge an anomaly.",responses:{"200":{description:"Acknowledgement result."}}}},"/api/v1/spend/signals":{get:{summary:"Signals anomaly detection can run on, with their gap and sample rules.",responses:{"200":{description:"Signal catalog."}}}},"/api/v1/spend/anomaly-configs":{get:{summary:"Anomaly detection configuration.",parameters:e,responses:{"200":{description:"Configs."}}},post:{summary:"Create or update the config for a signal.",responses:{"200":{description:"The config."}}}},"/api/v1/spend/anomaly-configs/{configId}":{delete:{summary:"Delete an anomaly config, returning the signal to its default.",responses:{"200":{description:"Result."}}}},"/api/v1/spend/anomaly-silences":{get:{summary:"Active anomaly silences.",parameters:e,responses:{"200":{description:"Silences."}}},post:{summary:"Silence a signal, route, or status code. A reason is required.",responses:{"200":{description:"The silence."}}}},"/api/v1/spend/anomaly-silences/{silenceId}":{delete:{summary:"Remove a silence.",responses:{"200":{description:"Result."}}}},"/api/v1/spend/enforcement":{get:{summary:"Enforcement actions in force.",parameters:[...e,{name:"active",in:"query",schema:{type:"boolean"}}],responses:{"200":{description:"Enforcement records."}}}},"/api/v1/spend/allowance":{get:{summary:"Whether an operation is allowed under current spend enforcement.",parameters:[...e,{name:"operation",in:"query",schema:{type:"string",enum:["build","deploy","function_invoke","request"]}}],responses:{"200":{description:"Allowance verdict and the budgets behind it."}}}}}}export{q as Gk,Tt as Hk,re as Ik,we as Jk,_t as Kk,ke as Lk,zn as Mk,B as Nk,ht as Ok,Xe as Pk,Kn as Qk,vr as Rk,Lt as Sk,I as Tk,Sr as Uk,ei as Vk,ie as Wk,Wt as Xk,Jt as Yk,Xo as Zk,Po as _k,Zt as $k,Ud as al,Dd as bl,it as cl,Xd as dl,Pd as el,xd as fl,jd as gl,Re as hl,tt as il,J as jl,H as kl,yo as ll,ce as ml,ss as nl,as as ol,ds as pl,bc as ql,st as rl,zo as sl,ot as tl,qo as ul,Ho as vl,Bo as wl,zd as xl,rr as yl,Jo as zl,Zo as Al,or as Bl,Rn as Cl,ee as Dl,ts as El,Es as Fl,ut as Gl,ms as Hl,k as Il,gs as Jl,lr as Kl,Dn as Ll,pt as Ml,_s as Nl,hs as Ol,Ns as Pl,ur as Ql,Ue as Rl,Et as Sl,Er as Tl,te as Ul,Q as Vl,ys as Wl,ue as Xl,Ls as Yl,gr as Zl,xn as _l,Fn as $l,mt as am,_r as bm,hr as cm,G as dm,ni as em,ii as fm,Ur as gm,Ct as hm,ge as im,ai as jm,Qe as km,Dr as lm,wr as mm,Ye as nm,li as om,Xr as pm,Pr as qm,xr as rm,jr as sm,At as tm,pi as um,Ei as vm,na as wm,Ti as xm,Fr as ym,Ge as zm,gi as Am,hi as Bm,Ut as Cm,he as Dm,wt as Em,kt as Fm,Xt as Gm,Mr as Hm,fi as Im,Hr as Jm,Pt as Km,la as Lm,xt as Mm,ya as Nm,Br as Om,Ne as Pm,Vr as Qm,Sa as Rm,$r as Sm,Ai as Tm,wi as Um,fe as Vm,qt as Wm,Bi as Xm,Qi as Ym,Yi as Zm,nn as _m,on as $m,Gi as an,Fa as bn,Ma as cn,Bt as dn,ye as en,sn as fn,cn as gn,io as hn,oo as in,Vt as jn,Ja as kn,cd as ln,Ie as mn,ao as nn,Kt as on,ud as pn,po as qn,Eo as rn,mo as sn,_d as tn,To as un,go as vn,fd as wn,L as xn,us as yn,ps as zn,qc as An,Hc as Bn};
|