@stacksjs/ts-cloud 0.16.48 → 0.16.50
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/bin/{chunk-z8k9mcn5.js → chunk-0wtshht7.js} +2 -2
- package/dist/bin/{chunk-v7t6f8aw.js → chunk-11y7yang.js} +2 -2
- package/dist/bin/chunk-2wh45zhk.js +2 -0
- package/dist/bin/chunk-334jngt2.js +1 -0
- package/dist/bin/{chunk-4yym8xm4.js → chunk-33ntxz01.js} +5 -5
- package/dist/bin/chunk-3k7y1h18.js +1 -0
- package/dist/bin/chunk-512ecg6y.js +1 -0
- package/dist/bin/{chunk-vhyp4xj0.js → chunk-5ny7rggt.js} +1 -1
- package/dist/bin/chunk-626npmtj.js +1 -0
- package/dist/bin/{chunk-zvbc92pc.js → chunk-734n0gkw.js} +1 -1
- package/dist/bin/chunk-74wppexz.js +1 -0
- package/dist/bin/chunk-7cs9nnjy.js +111 -0
- package/dist/bin/{chunk-q4dywv80.js → chunk-7czb1kgg.js} +2 -2
- package/dist/bin/chunk-7ewbxsan.js +1 -0
- package/dist/bin/{chunk-g2kmr82n.js → chunk-7jj0g6jk.js} +158 -158
- package/dist/bin/{chunk-kbwm0sqv.js → chunk-811k54jq.js} +2 -2
- package/dist/bin/chunk-8ya34jz7.js +1 -0
- package/dist/bin/chunk-964xmgb6.js +1 -0
- package/dist/bin/{chunk-gyvkravq.js → chunk-9ehb4hc6.js} +5 -5
- package/dist/bin/chunk-azarn24c.js +1 -0
- package/dist/bin/chunk-cw3rhg1c.js +1 -0
- package/dist/bin/chunk-d2fq60kd.js +1 -0
- package/dist/bin/{chunk-01w4zbex.js → chunk-da6dmacg.js} +2 -2
- package/dist/bin/chunk-dpk5r544.js +1 -0
- package/dist/bin/{chunk-12x968en.js → chunk-dv2he3vc.js} +3 -3
- package/dist/bin/chunk-e6ewfmbp.js +1 -0
- package/dist/bin/{chunk-psmpw0ap.js → chunk-e7pce8jb.js} +3 -3
- package/dist/bin/{chunk-cf3jn2ey.js → chunk-f2t67d76.js} +3 -3
- package/dist/bin/chunk-f4mpkpbf.js +1 -0
- package/dist/bin/chunk-f9469h6q.js +1 -0
- package/dist/bin/chunk-fjbhvhqb.js +1 -0
- package/dist/bin/{chunk-nj9x0tb8.js → chunk-gr1ra9nj.js} +2 -2
- package/dist/bin/{chunk-3pazrfsf.js → chunk-hdqxyxs0.js} +7 -7
- package/dist/bin/{chunk-xdk0gmxt.js → chunk-hhmqsrfc.js} +1 -1
- package/dist/bin/{chunk-4mecfcjk.js → chunk-j2wkxp7d.js} +3 -3
- package/dist/bin/{chunk-dj03v81n.js → chunk-k9f94hg4.js} +113 -113
- package/dist/bin/{chunk-znd507q9.js → chunk-kmpvqby6.js} +8 -8
- package/dist/bin/{chunk-n7yefy09.js → chunk-m3xap663.js} +5 -5
- package/dist/bin/chunk-m7pbssep.js +1 -0
- package/dist/{chunk-6rcj3km0.js → bin/chunk-mcg4wg4j.js} +7 -7
- package/dist/bin/{chunk-nd8vnqk5.js → chunk-mdkd46c5.js} +86 -86
- package/dist/bin/chunk-n7xadeqe.js +1 -0
- package/dist/bin/{chunk-xe527q1k.js → chunk-ppd463ev.js} +2 -2
- package/dist/bin/{chunk-23m8kbwh.js → chunk-q2rqmc2x.js} +3 -3
- package/dist/bin/chunk-q9awn1n3.js +1 -0
- package/dist/bin/chunk-qsfhb3x7.js +1 -0
- package/dist/bin/chunk-r524t8v8.js +1 -0
- package/dist/bin/{chunk-7qbxq0be.js → chunk-rwbdtxte.js} +1 -1
- package/dist/bin/{chunk-v09tfezh.js → chunk-sa9c8vb5.js} +5 -5
- package/dist/bin/{chunk-6y6g726g.js → chunk-t970yjvz.js} +5 -5
- package/dist/bin/{chunk-cz2wq0tf.js → chunk-tcj1z34y.js} +5 -5
- package/dist/bin/{chunk-q8b77zgw.js → chunk-te52z1wk.js} +1 -1
- package/dist/bin/chunk-v2qk9jeb.js +1 -0
- package/dist/bin/{chunk-rdkr74y2.js → chunk-vavwhhrp.js} +1 -1
- package/dist/bin/chunk-w89fyres.js +1 -0
- package/dist/bin/{chunk-frzpqsbj.js → chunk-we2raqk3.js} +2 -2
- package/dist/bin/chunk-wgh66c5r.js +1 -0
- package/dist/bin/chunk-xaqkj8fn.js +1 -0
- package/dist/bin/{chunk-w29z877b.js → chunk-y12vn1h1.js} +2 -2
- package/dist/bin/{chunk-xx9mrcfs.js → chunk-yfa84s0c.js} +1 -1
- package/dist/bin/{chunk-5nmt4s5w.js → chunk-ytzcsskk.js} +2 -2
- package/dist/bin/{chunk-psvqpztv.js → chunk-z06jkvvr.js} +5 -5
- package/dist/bin/cli.js +203 -203
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/chunk-09d6pdgx.js +1 -0
- package/dist/{chunk-yme6q7k4.js → chunk-0cz2s19h.js} +2 -2
- package/dist/{chunk-nryh43p1.js → chunk-0qgfe5ff.js} +3 -3
- package/dist/{chunk-kr8aeva1.js → chunk-18h7na1g.js} +549 -549
- package/dist/chunk-21mmcmm7.js +1 -0
- package/dist/{bin/chunk-k343q24p.js → chunk-3ncnrrvm.js} +7 -7
- package/dist/chunk-4abbccq7.js +2 -0
- package/dist/{chunk-rpng90t9.js → chunk-4yqd62rd.js} +1 -1
- package/dist/chunk-5hgcr7r2.js +709 -0
- package/dist/{chunk-x0ep5ybv.js → chunk-6m8p1n88.js} +13 -13
- package/dist/chunk-85fyadq0.js +448 -0
- package/dist/{chunk-fpkpwbv3.js → chunk-8b2mxhcm.js} +5 -5
- package/dist/{chunk-r3m1fjd4.js → chunk-9ggg2ktx.js} +2 -2
- package/dist/chunk-a8hs75xd.js +5 -0
- package/dist/chunk-ca191b00.js +6 -0
- package/dist/{chunk-jhtp3m31.js → chunk-cpba1hz2.js} +2 -2
- package/dist/{chunk-ynprwawa.js → chunk-erfh93dq.js} +2 -2
- package/dist/{chunk-22hfejjs.js → chunk-ffyx50xx.js} +1 -1
- package/dist/chunk-fqgvackc.js +138 -0
- package/dist/{chunk-jpdpr7k6.js → chunk-j99nkav5.js} +3 -3
- package/dist/chunk-jgsey18z.js +1 -0
- package/dist/{chunk-vb4t2r4r.js → chunk-jtvw9d4x.js} +1 -1
- package/dist/chunk-jytama4e.js +111 -0
- package/dist/chunk-m9r0a1v9.js +2 -0
- package/dist/{chunk-6mp1fyxe.js → chunk-nmnf1ha6.js} +4 -4
- package/dist/{chunk-e8k29wen.js → chunk-nnnhq6sx.js} +19 -19
- package/dist/chunk-qbsrs1gp.js +1 -0
- package/dist/{chunk-xzcpzxtj.js → chunk-qcj3hkba.js} +2 -2
- package/dist/chunk-r4kedmas.js +1 -0
- package/dist/{chunk-p7myt05d.js → chunk-r5mk071y.js} +5 -5
- package/dist/{chunk-xxq1ygp9.js → chunk-thdfk76k.js} +3 -3
- package/dist/chunk-tnqj2en4.js +1 -0
- package/dist/{chunk-da62knsv.js → chunk-zbx9yehq.js} +83 -83
- package/dist/{chunk-vjph4eh0.js → chunk-zf5wdx6v.js} +1 -1
- package/dist/deploy/index.js +1 -1
- package/dist/dns/index.js +1 -1
- package/dist/drivers/aws/provision.d.ts +2 -2
- package/dist/drivers/index.js +1 -1
- package/dist/drivers/shared/mail-provision.d.ts +2 -18
- package/dist/drivers/shared/rpx-gateway.d.ts +3 -1
- package/dist/index.js +60 -60
- package/dist/mail/index.d.ts +5 -0
- package/dist/mail/index.js +3 -0
- package/dist/mail/webmail.d.ts +35 -0
- package/dist/mail/webmail.test.d.ts +1 -0
- package/dist/operations/index.js +1 -1
- package/dist/protection/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 +1 -1
- package/dist/ui/account/automation.html +6 -6
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +6 -6
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +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 +5 -5
- package/dist/ui/operations/maintenance.html +6 -6
- package/dist/ui/operations/observability.html +6 -6
- package/dist/ui/operations/previews.html +6 -6
- package/dist/ui/operations/queue.html +6 -6
- package/dist/ui/operations/regions.html +6 -6
- package/dist/ui/operations/releases.html +6 -6
- package/dist/ui/operations/spend.html +6 -6
- package/dist/ui/operations/workloads.html +6 -6
- package/dist/ui/security.html +2 -2
- package/dist/ui/server/actions.html +6 -6
- package/dist/ui/server/activity.html +2 -2
- package/dist/ui/server/capacity.html +6 -6
- package/dist/ui/server/database.html +6 -6
- package/dist/ui/server/deployments.html +6 -6
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +6 -6
- package/dist/ui/server/fleet.html +6 -6
- package/dist/ui/server/logs.html +6 -6
- package/dist/ui/server/metrics.html +6 -6
- package/dist/ui/server/security.html +2 -2
- package/dist/ui/server/services.html +1 -1
- package/dist/ui/server/sites.html +6 -6
- package/dist/ui/server/ssh-keys.html +6 -6
- package/dist/ui/server/team.html +6 -6
- package/dist/ui/server/terminal.html +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 +1 -1
- package/dist/ui/serverless/firewall.html +1 -1
- package/dist/ui/serverless/functions.html +6 -6
- package/dist/ui/serverless/logs.html +6 -6
- package/dist/ui/serverless/metrics.html +2 -2
- package/dist/ui/serverless/queues.html +6 -6
- package/dist/ui/serverless/secrets.html +6 -6
- package/dist/ui/serverless/traces.html +6 -6
- package/dist/ui/serverless.html +6 -6
- package/package.json +7 -3
- package/dist/bin/chunk-1fj03993.js +0 -1
- package/dist/bin/chunk-1xxmyx0r.js +0 -1
- package/dist/bin/chunk-2pzh0wxc.js +0 -1
- package/dist/bin/chunk-45qr2bd3.js +0 -1
- package/dist/bin/chunk-4nn00brw.js +0 -1
- package/dist/bin/chunk-5f1n5d80.js +0 -1
- package/dist/bin/chunk-5mm6qn6m.js +0 -1
- package/dist/bin/chunk-5xr76cms.js +0 -1
- package/dist/bin/chunk-65yvjecx.js +0 -2
- package/dist/bin/chunk-akf9j8ps.js +0 -1
- package/dist/bin/chunk-d0tmmzy5.js +0 -1
- package/dist/bin/chunk-fqghdpvr.js +0 -1
- package/dist/bin/chunk-gkdr09xx.js +0 -1
- package/dist/bin/chunk-hhhrze6m.js +0 -1
- package/dist/bin/chunk-jrztbsnb.js +0 -1
- package/dist/bin/chunk-kqxk1pds.js +0 -1
- package/dist/bin/chunk-m8p7mw67.js +0 -1
- package/dist/bin/chunk-n2c6y0k1.js +0 -1
- package/dist/bin/chunk-pr1dg1km.js +0 -1
- package/dist/bin/chunk-pzj1ac7x.js +0 -1
- package/dist/bin/chunk-rgcrsd5m.js +0 -1
- package/dist/bin/chunk-thph4z3k.js +0 -1
- package/dist/bin/chunk-txykq6f1.js +0 -1
- package/dist/bin/chunk-vjg2fymw.js +0 -1
- package/dist/bin/chunk-ym9h629y.js +0 -111
- package/dist/bin/chunk-z8scg2vy.js +0 -1
- package/dist/bin/chunk-zjvg5pg8.js +0 -1
- package/dist/chunk-25sw2s70.js +0 -1
- package/dist/chunk-2pns2rkf.js +0 -111
- package/dist/chunk-2sc0s7pc.js +0 -6
- package/dist/chunk-8vtrjmmj.js +0 -709
- package/dist/chunk-fh7apa5n.js +0 -2
- package/dist/chunk-gh0ghb21.js +0 -2
- package/dist/chunk-gqadvddh.js +0 -1
- package/dist/chunk-kpmxvpcv.js +0 -1
- package/dist/chunk-ksqhsz52.js +0 -1
- package/dist/chunk-ndrpehf8.js +0 -584
- package/dist/chunk-p588apka.js +0 -1
- package/dist/chunk-vnarc5gc.js +0 -5
- package/dist/chunk-x7d93rxb.js +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{n}from"./chunk-ca191b00.js";import{I}from"./chunk-jtvw9d4x.js";var pt=new Set(["A","AAAA","CNAME"]);function V(e,t=""){return e===408||e===409||e===425||e===429||e>=500||/rate limit|temporar|timed? ?out|try again/i.test(t)}async function b(e,t){let r=t?.headers.get("retry-after"),s=r===null||r===void 0?void 0:Number(r)*1000,i=Number.isFinite(s)?Math.max(0,s):Math.min(1000*2**(e-1),30000);await new Promise((o)=>setTimeout(o,i))}class he{name="porkbun";apiKey;secretKey;requestTimeoutMs;constructor(e,t,r=15000){this.apiKey=e,this.secretKey=t,this.requestTimeoutMs=r}async request(e,t={}){let r;for(let s=1;s<=8;s+=1){let i,o=new AbortController,a=setTimeout(()=>{o.abort(Error(`Porkbun API request timed out after ${this.requestTimeoutMs}ms`))},this.requestTimeoutMs);try{i=await fetch(`https://api.porkbun.com/api/json/v3${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apikey:this.apiKey,secretapikey:this.secretKey,...t}),signal:o.signal})}catch(d){if(r=d,s===8)throw d;await b(s);continue}finally{clearTimeout(a)}if(!i.ok){let d=await i.clone().json().then((u)=>u?.message).catch(()=>{return});if(r=Error(`Porkbun API error: ${i.status} ${i.statusText}${d?`: ${d}`:""}`),!V(i.status)||s===8)throw r;await b(s,i);continue}let c=await i.json();if(c.status==="ERROR"){if(r=Error(`Porkbun API error: ${c.message||"Unknown error"}`),!V(0,c.message)||s===8)throw r;await b(s,i);continue}return c}throw r}getSubdomain(e,t){let r=e.replace(/\.$/,""),s=t.replace(/\.$/,"");if(r===s)return"";if(r.endsWith(`.${s}`))return r.slice(0,-(s.length+1));return r}getRootDomain(e){let t=e.replace(/\.$/,"").split(".");if(t.length>=2)return t.slice(-2).join(".");return e}static ADDRESS_TYPES=new Set(["A","AAAA"]);async clearConflictingAliases(e,t){if(!he.ADDRESS_TYPES.has(t.type))return[];let r=this.getRootDomain(e),s=this.getSubdomain(t.name,r),i=await this.listRecords(e);if(!i.success)return[`could not list records to clear ALIAS/CNAME conflicts: ${i.message??"unknown provider error"}`];let o=[];for(let a of i.records){if(a.type!=="ALIAS"&&a.type!=="CNAME")continue;if(this.getSubdomain(a.name,r)!==s)continue;let c=await this.deleteRecord(e,a);if(!c.success)o.push(`could not remove conflicting ${a.type} on ${a.name}: ${c.message??"unknown provider error"}`)}return o}async addressRecordExists(e,t){let r=this.getRootDomain(e),s=this.getSubdomain(t.name,r),i=await this.listRecords(e);if(!i.success)return!0;return i.records.some((o)=>o.type===t.type&&this.getSubdomain(o.name,r)===s&&o.content===t.content)}async createRecord(e,t){try{let r=this.getRootDomain(e),s=this.getSubdomain(t.name,r),i={type:t.type,content:t.content,ttl:String(t.ttl||600)};if(s)i.name=s;if((t.type==="MX"||t.type==="SRV")&&t.priority!==void 0)i.prio=String(t.priority);if(t.type==="SRV"&&t.weight!==void 0&&t.port!==void 0)i.content=`${t.weight} ${t.port} ${t.content}`;let o=await this.clearConflictingAliases(e,t),a=await this.request(`/dns/create/${r}`,i);if(he.ADDRESS_TYPES.has(t.type)&&!await this.addressRecordExists(e,t))return{success:!1,message:`Porkbun reported success but no ${t.type} record for ${t.name} exists${o.length>0?` (${o.join("; ")})`:""}. A conflicting ALIAS/CNAME on the same name silently voids the write.`};return{success:!0,id:a.id?.toString(),message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(e,t){try{let r=this.getRootDomain(e),s=this.getSubdomain(t.name,r),i=await this.listRecords(e);if(i.success){let o=i.records.find((a)=>this.getSubdomain(a.name,r)===s&&a.type===t.type);if(o?.id&&o.content===t.content&&(t.ttl===void 0||o.ttl===t.ttl)&&(t.type!=="MX"&&t.type!=="SRV"||t.priority===void 0||o.priority===t.priority))return{success:!0,id:o.id,message:"Record already up to date"};if(o?.id){let a={type:t.type,content:t.content,ttl:String(t.ttl||600)};if(s)a.name=s;if((t.type==="MX"||t.type==="SRV")&&t.priority!==void 0)a.prio=String(t.priority);if(t.type==="SRV"&&t.weight!==void 0&&t.port!==void 0)a.content=`${t.weight} ${t.port} ${t.content}`;return await this.request(`/dns/edit/${r}/${o.id}`,a),{success:!0,id:o.id,message:"Record updated successfully"}}}return this.createRecord(e,t)}catch(r){return this.createRecord(e,t)}}async deleteRecord(e,t){try{let r=this.getRootDomain(e);if("id"in t&&t.id)return await this.request(`/dns/delete/${r}/${t.id}`),{success:!0,message:"Record deleted successfully"};let s=this.getSubdomain(t.name,r),i=await this.listRecords(e);if(!i.success)return{success:!1,message:"Failed to list records"};let o=i.records.find((a)=>this.getSubdomain(a.name,r)===s&&a.type===t.type&&a.content===t.content);if(!o?.id)return{success:!1,message:"Record not found"};return await this.request(`/dns/delete/${r}/${o.id}`),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(e,t){try{let r=this.getRootDomain(e),s=`/dns/retrieve/${r}`;if(t)s=`/dns/retrieveByNameType/${r}/${t}`;return{success:!0,records:((await this.request(s)).records||[]).map((a)=>({id:a.id,name:a.name||r,type:a.type,content:a.content,ttl:Number.parseInt(a.ttl,10),priority:a.prio?Number.parseInt(a.prio,10):void 0}))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(e){try{let t=this.getRootDomain(e);return await this.request(`/dns/retrieve/${t}`),!0}catch{return!1}}async listDomains(){try{return((await this.request("/domain/listAll")).domains||[]).map((t)=>t.domain)}catch{return[]}}async getNameServers(e){try{let t=this.getRootDomain(e);return(await this.request(`/domain/getNs/${t}`)).ns||[]}catch{return[]}}async updateNameServers(e,t){try{let r=this.getRootDomain(e);return await this.request(`/domain/updateNs/${r}`,{ns:t}),!0}catch{return!1}}}class Ge{name="godaddy";apiKey;apiSecret;baseUrl;constructor(e,t="",r="production"){this.apiKey=e,this.apiSecret=t,this.baseUrl=r==="ote"?"https://api.ote-godaddy.com":"https://api.godaddy.com"}authorization(){if(!this.apiSecret||this.apiKey.startsWith("gd_pat_"))return`Bearer ${this.apiKey}`;return`sso-key ${this.apiKey}:${this.apiSecret}`}async request(e,t,r){let s=`${this.baseUrl}${t}`,i={Authorization:this.authorization(),"Content-Type":"application/json",Accept:"application/json"},o={method:e,headers:i};if(r)o.body=JSON.stringify(r);let a=await fetch(s,o);if(a.status===204)return{};if(a.ok){let d=await a.text();if(d)return JSON.parse(d);return{}}let c=`GoDaddy API error: ${a.status} ${a.statusText}`;try{let d=await a.json();if(d.message)c=`GoDaddy API error: ${d.message}`;if(d.fields)c+=` - Fields: ${JSON.stringify(d.fields)}`}catch{}throw Error(c)}getSubdomain(e,t){let r=e.replace(/\.$/,""),s=t.replace(/\.$/,"");if(r===s)return"@";if(r.endsWith(`.${s}`))return r.slice(0,-(s.length+1));return r}getRootDomain(e){let t=e.replace(/\.$/,"").split(".");if(t.length>=2)return t.slice(-2).join(".");return e}toGoDaddyRecord(e,t){let r=this.getRootDomain(t),s=this.getSubdomain(e.name,r),i={type:e.type,name:s,data:e.content,ttl:e.ttl||600};if(e.type==="MX"&&e.priority!==void 0)i.priority=e.priority;return i}fromGoDaddyRecord(e,t){let r=this.getRootDomain(t),s=e.name;if(s==="@")s=r;else if(!s.endsWith(r))s=`${s}.${r}`;return{name:s,type:e.type,content:e.data,ttl:e.ttl,priority:e.priority}}async createRecord(e,t){try{let r=this.getRootDomain(e),s=this.toGoDaddyRecord(t,e);return await this.request("PATCH",`/v1/domains/${r}/records`,[s]),{success:!0,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(e,t){try{let r=this.getRootDomain(e),s=this.toGoDaddyRecord(t,e);return await this.request("PUT",`/v1/domains/${r}/records/${t.type}/${s.name}`,[s]),{success:!0,message:"Record upserted successfully"}}catch(r){return this.createRecord(e,t)}}async deleteRecord(e,t){try{let r=this.getRootDomain(e),s=this.getSubdomain(t.name,r),i=await this.request("GET",`/v1/domains/${r}/records/${t.type}/${s}`),o=i.filter((a)=>a.data!==t.content);if(o.length===i.length)return{success:!1,message:"Record not found"};if(o.length===0)try{await this.request("DELETE",`/v1/domains/${r}/records/${t.type}/${s}`)}catch{}else await this.request("PUT",`/v1/domains/${r}/records/${t.type}/${s}`,o);return{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(e,t){try{let r=this.getRootDomain(e),s=`/v1/domains/${r}/records`;if(t)s=`/v1/domains/${r}/records/${t}`;return{success:!0,records:(await this.request("GET",s)).map((o)=>this.fromGoDaddyRecord(o,e))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(e){try{let t=this.getRootDomain(e);return await this.request("GET",`/v1/domains/${t}`),!0}catch{return!1}}async listDomains(){try{return(await this.request("GET","/v1/domains")).map((t)=>t.domain)}catch{return[]}}async getDomainDetails(e){try{let t=this.getRootDomain(e),r=await this.request("GET",`/v1/domains/${t}`);return{domain:r.domain,status:r.status,nameServers:r.nameServers,expires:r.expires}}catch{return null}}async getNameServers(e){return(await this.getDomainDetails(e))?.nameServers??[]}async updateNameServers(e,t){try{let r=this.getRootDomain(e);return await this.request("PATCH",`/v1/domains/${r}`,{nameServers:t}),!0}catch{return!1}}async checkDomainAvailability(e){try{let t=await this.request("GET",`/v1/domains/available?domain=${encodeURIComponent(e)}`);return{available:t.available,price:t.price,currency:t.currency}}catch{return{available:!1}}}}var yg=["js","mjs","cjs","css","map","woff","woff2","ttf","otf","eot","png","jpg","jpeg","gif","webp","avif","svg","ico","mp4","webm","ogg","mp3","wav","pdf","wasm"],U=[{name:"x-stx-router",value:"true"}];function C(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`}function Z(e){return`{${e.map(C).join(" ")}}`}function j(e){let t=`http.request.headers[${C(e.name.toLowerCase())}]`;return e.value===void 0?`len(${t}) > 0`:`any(${t}[*] == ${C(e.value)})`}function Ht(e){if(e.length===1)return`http.host eq ${C(e[0])}`;return`http.host in ${Z(e)}`}function Ic(e,t={}){if(t.enabled===!1||e.length===0)return[];let r=Ht(e),s=[],o=(t.bypassPaths??[]).map((v)=>`starts_with(http.request.uri.path, ${C(v)})`),c=(t.negotiatedRequestHeaders??U).map(j),d=[...o,...c],u=d.length>0?`(${d.join(" or ")})`:void 0;if(u)s.push({action:"set_cache_settings",description:"bypass cache",expression:`(${r} and ${u})`,enabled:!0,action_parameters:{cache:!1}});let g=u?`${r} and not ${u}`:r,m=t.assetExtensions??yg,p=m.length>0?`lower(http.request.uri.path.extension) in ${Z([...m])}`:void 0;if(p)s.push({action:"set_cache_settings",description:"cache fingerprinted assets",expression:`(${g} and ${p})`,enabled:!0,action_parameters:{cache:!0,edge_ttl:{mode:"override_origin",default:t.assetEdgeTtl??2592000},browser_ttl:{mode:"override_origin",default:t.assetBrowserTtl??31536000}}});let y=p?`(${g} and not ${p})`:`(${g})`;if(t.documentEdgeTtl===0)return s.push({action:"set_cache_settings",description:"bypass documents",expression:y,enabled:!0,action_parameters:{cache:!1}}),s;return s.push({action:"set_cache_settings",description:"cache documents",expression:y,enabled:!0,action_parameters:{cache:!0,edge_ttl:{mode:"override_origin",default:t.documentEdgeTtl??3600},browser_ttl:{mode:"override_origin",default:t.documentBrowserTtl??0}}}),s}function bc(e,t,r){if(e.length===0||!t||!r)return[];return[{action:"rewrite",description:"origin guard header",expression:`(${Ht(e)})`,enabled:!0,action_parameters:{headers:{[t]:{operation:"set",value:r}}}}]}var F="https://api.cloudflare.com/client/v4",Gt="[ts-cloud]";class H{name="cloudflare";apiToken;zoneCache=new Map;configuredZoneId;accountId;configuredZoneName;constructor(e,t={}){this.apiToken=e,this.configuredZoneId=t.zoneId,this.accountId=t.accountId}async request(e,t,r){let s=`${F}${t}`,i={Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},o={method:e,headers:i};if(r)o.body=JSON.stringify(r);let c=await(await fetch(s,o)).json();if(!c.success){let d=c.errors.map((u)=>u.message).join(", ");throw Error(`Cloudflare API error: ${d}`)}return c}getRootDomain(e){let t=e.replace(/\.$/,"").split(".");if(t.length>=2)return t.slice(-2).join(".");return e}async resolveZone(e){let t=e.replace(/\.$/,"").toLowerCase();if(this.configuredZoneId){let a=await this.resolveConfiguredZoneName();if(a&&(t===a||t.endsWith(`.${a}`)))return{id:this.configuredZoneId,name:a}}let r=this.getRootDomain(t),s=this.zoneCache.get(r);if(s)return{id:s,name:r};let i=await this.request("GET",`/zones?name=${encodeURIComponent(r)}`);if(!i.result||i.result.length===0)throw Error(`Zone not found for domain: ${r}. `+"If the API token is scoped to a single zone, set its zone id (CLOUDFLARE_ZONE_ID) — "+"zone lookup by name needs account-wide Zone:Read.");let o=i.result[0].id;return this.zoneCache.set(r,o),{id:o,name:i.result[0].name||r}}async resolveConfiguredZoneName(){if(!this.configuredZoneId)return;if(this.configuredZoneName)return this.configuredZoneName;try{let t=(await this.request("GET",`/zones/${this.configuredZoneId}`)).result?.name?.toLowerCase();if(!t)return;return this.configuredZoneName=t,this.zoneCache.set(t,this.configuredZoneId),t}catch{return}}async getZoneId(e){return(await this.resolveZone(e)).id}getFullRecordName(e,t){let r=e.replace(/\.$/,"");if(!r||r===t||r==="@")return t;if(r.endsWith(`.${t}`))return r;return`${r}.${t}`}toCloudflareRecord(e,t,r){let s={type:e.type,name:this.getFullRecordName(e.name,t),content:e.content||e.value||"",ttl:e.ttl||1},i=r??e.proxied;if(i!==void 0&&pt.has(e.type)){if(s.proxied=i,i)s.ttl=1}if(e.type==="MX"&&e.priority!==void 0)s.priority=e.priority;if(e.type==="SRV"){let o=W(e);if(o)s.data=o,delete s.content,delete s.priority;else if(e.priority!==void 0)s.priority=e.priority}return s}fromCloudflareRecord(e){return{id:e.id,name:e.name,type:e.type,content:e.content,ttl:e.ttl,priority:e.priority,proxied:e.proxied}}async createRecord(e,t){try{let r=await this.resolveZone(e),s=this.toCloudflareRecord(t,r.name);return{success:!0,id:(await this.request("POST",`/zones/${r.id}/dns_records`,s)).result.id,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(e,t){try{let r=await this.resolveZone(e),s=this.getFullRecordName(t.name,r.name),o=(await this.request("GET",`/zones/${r.id}/dns_records?type=${t.type}&name=${encodeURIComponent(s)}`)).result?.[0],a=t.proxied??o?.proxied,c=this.toCloudflareRecord(t,r.name,a);if(o)return{success:!0,id:(await this.request("PUT",`/zones/${r.id}/dns_records/${o.id}`,c)).result.id,message:"Record updated successfully"};return{success:!0,id:(await this.request("POST",`/zones/${r.id}/dns_records`,c)).result.id,message:"Record created successfully"}}catch(r){return this.createRecord(e,t)}}async deleteRecord(e,t){try{let r=await this.resolveZone(e),s=r.id,i=this.getFullRecordName(t.name,r.name),o=await this.request("GET",`/zones/${s}/dns_records?type=${t.type}&name=${encodeURIComponent(i)}`);if(!o.result||o.result.length===0)return{success:!1,message:"Record not found"};let a=o.result.find((c)=>c.content===t.content);if(!a)return{success:!1,message:"Record with matching content not found"};return await this.request("DELETE",`/zones/${s}/dns_records/${a.id}`),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(e,t){try{let s=`/zones/${await this.getZoneId(e)}/dns_records?per_page=100`;if(t)s+=`&type=${t}`;let i=[],o=1,a=!0;while(a){let c=await this.request("GET",`${s}&page=${o}`);if(i.push(...c.result||[]),c.result_info)a=o<c.result_info.total_pages,o++;else a=!1}return{success:!0,records:i.map((c)=>this.fromCloudflareRecord(c))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(e){try{return await this.getZoneId(e),!0}catch{return!1}}async listDomains(){try{let e=[],t=1,r=!0;while(r){let s=await this.request("GET",`/zones?per_page=50&page=${t}`);if(e.push(...s.result||[]),s.result_info)r=t<s.result_info.total_pages,t++;else r=!1}return e.map((s)=>s.name)}catch{return[]}}async createZone(e,t={}){let r=e.replace(/\.$/,"").toLowerCase(),s=t.accountId??this.accountId;if(!s)throw Error(`Cannot create zone ${r}: no Cloudflare account id. Set CLOUDFLARE_ACCOUNT_ID, or pass accountId.`);let i=await this.getZoneDetails(r);if(i)return{...i,created:!1};try{let a=(await this.request("POST","/zones",{name:r,account:{id:s},jump_start:t.jumpStart??!1})).result;return this.zoneCache.set(a.name,a.id),{id:a.id,name:a.name,status:a.status,nameServers:a.name_servers??[],created:!0}}catch(o){let a=o instanceof Error?o.message:String(o);if(!/already exists|1061/i.test(a))throw o;let c=await this.getZoneDetails(r);if(!c)throw o;return{...c,created:!1}}}async getZoneDetails(e){try{let t=await this.getZoneId(e),r=await this.request("GET",`/zones/${t}`);return{id:r.result.id,name:r.result.name,status:r.result.status,nameServers:r.result.name_servers,paused:r.result.paused}}catch{return null}}async listEdgeCertificateHosts(e){try{let t=await this.getZoneId(e),r=await this.request("GET",`/zones/${t}/ssl/certificate_packs?per_page=50`),s=new Set;for(let i of r.result||[]){if(i.status!=="active")continue;for(let o of i.hosts||[])s.add(o.toLowerCase())}return[...s]}catch{return null}}async purgeCache(e,t){try{let r=await this.getZoneId(e),s={};if(t?.purgeEverything)s.purge_everything=!0;else{if(t?.files)s.files=t.files;if(t?.tags)s.tags=t.tags;if(t?.hosts)s.hosts=t.hosts}if(Object.keys(s).length===0)s.purge_everything=!0;return await this.request("POST",`/zones/${r}/purge_cache`,s),!0}catch{return!1}}async getRecordProxyStatus(e,t){try{let r=await this.resolveZone(e),s=r.id,i=this.getFullRecordName(t.name,r.name),o=await this.request("GET",`/zones/${s}/dns_records?type=${t.type}&name=${encodeURIComponent(i)}`);if(o.result&&o.result.length>0)return o.result.find((c)=>c.content===t.content)?.proxied??null;return null}catch{return null}}async setRecordProxyStatus(e,t,r){try{let s=await this.resolveZone(e),i=s.id,o=this.getFullRecordName(t.name,s.name),a=await this.request("GET",`/zones/${i}/dns_records?type=${t.type}&name=${encodeURIComponent(o)}`);if(!a.result||a.result.length===0)return!1;let c=a.result.find((d)=>d.content===t.content);if(!c)return!1;return await this.request("PATCH",`/zones/${i}/dns_records/${c.id}`,{proxied:r}),!0}catch{return!1}}async zoneIdFor(e){return this.getZoneId(e)}get account(){return this.accountId}async getZoneSettings(e){let t=await this.getZoneId(e),r=await this.request("GET",`/zones/${t}/settings`),s={};for(let i of r.result||[])s[i.id]=i.value;return s}async applyZoneSettings(e,t){let r=await this.getZoneId(e),s=await this.getZoneSettings(e).catch(()=>({})),i=[],o=[];for(let[a,c]of Object.entries(t)){if(c===void 0)continue;let d=s[a];if(d!==void 0&&x(d,c))continue;try{await this.request("PATCH",`/zones/${r}/settings/${a}`,{value:c}),i.push({id:a,from:d,to:c})}catch(u){o.push({id:a,error:u instanceof Error?u.message:String(u)})}}return{changed:i,failed:o}}async getManagedRequestHeaders(e){let t=await this.getZoneId(e),r=await this.request("GET",`/zones/${t}/managed_headers`),s={};for(let i of r.result?.managed_request_headers||[])s[i.id]=i.enabled===!0;return s}async applyTieredCache(e,t){let r=[],s=[],i=await this.getZoneId(e),o=[["tiered_caching",`/zones/${i}/argo/tiered_caching`,t==="off"?"off":"on"],["tiered_cache_smart_topology_enable",`/zones/${i}/cache/tiered_cache_smart_topology_enable`,t==="smart"?"on":"off"]];if(t==="off")o.reverse();for(let[a,c,d]of o)try{let g=(await this.request("GET",c)).result?.value;if(g===d)continue;await this.request("PATCH",c,{value:d}),r.push({id:a,from:g,to:d})}catch(u){s.push({id:a,error:u instanceof Error?u.message:String(u)})}return{changed:r,failed:s}}async applyManagedRequestHeaders(e,t){let r=[],s=[],i=Object.entries(t).filter(([,d])=>d!==void 0);if(i.length===0)return{changed:r,failed:s};let o=await this.getZoneId(e),a;try{a=await this.getManagedRequestHeaders(e)}catch(d){let u=d instanceof Error?d.message:String(d);for(let[g]of i)s.push({id:g,error:`could not read managed headers — ${u}`});return{changed:r,failed:s}}let c=[];for(let[d,u]of i){if(!(d in a)){s.push({id:d,error:"not a managed request header transform on this zone"});continue}if(a[d]!==u)c.push([d,u])}if(c.length===0)return{changed:r,failed:s};try{await this.request("PATCH",`/zones/${o}/managed_headers`,{managed_request_headers:c.map(([d,u])=>({id:d,enabled:u})),managed_response_headers:[]});for(let[d,u]of c)r.push({id:d,from:a[d],to:u})}catch(d){let u=d instanceof Error?d.message:String(d);for(let[g]of c)s.push({id:g,error:u})}return{changed:r,failed:s}}async getPhaseRules(e,t){let r=await this.getZoneId(e);try{return(await this.request("GET",`/zones/${r}/rulesets/phases/${t}/entrypoint`)).result?.rules||[]}catch{return[]}}async putManagedPhaseRules(e,t,r){try{let s=await this.getZoneId(e),i=await this.getPhaseRules(e,t),o=r.map((d)=>({...d,description:d.description?.startsWith(Gt)?d.description:`${Gt} ${d.description||t}`})),c=K(i,o).map(({id:d,...u})=>u);return await this.request("PUT",`/zones/${s}/rulesets/phases/${t}/entrypoint`,{rules:c}),{success:!0}}catch(s){return{success:!1,message:s instanceof Error?s.message:String(s)}}}}var E=/http\.host (?:eq "[^"]+"|in \{[^}]*\})/;function Vn(e){return E.test(e)?e.replace(E,"\x00hosts\x00"):null}function O(e,t){return e.replace(E,Ht(t))}function P(e){if(Array.isArray(e))return`[${e.map(P).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).filter(([,r])=>r!==void 0).sort(([r],[s])=>r.localeCompare(s)).map(([r,s])=>`${JSON.stringify(r)}:${P(s)}`).join(",")}}`;return JSON.stringify(e)}function G(e,t){let r=Vn(e.expression);return r!==null&&r===Vn(t.expression)&&e.action===t.action&&e.description===t.description&&(e.enabled??!0)===(t.enabled??!0)&&P(e.action_parameters)===P(t.action_parameters)}function K(e,t){let r=new Set(t.flatMap((o)=>Vt(o.expression))),s=(o)=>(o.description||"").startsWith(Gt),i=[];for(let o of e){if(!s(o)){i.push(o);continue}let a=Vt(o.expression);if(a.length===0){if(r.size>0)i.push(o);continue}let c=a.filter((d)=>!r.has(d));if(c.length===a.length)i.push(o);else if(c.length>0)i.push({...o,expression:O(o.expression,c)})}for(let o of t){let a=Vt(o.expression),c=a.length>0?i.findIndex((g)=>s(g)&&G(g,o)):-1;if(c===-1){i.push(o);continue}let d=i[c],u=[...new Set([...Vt(d.expression),...a])];i[c]={...d,expression:O(d.expression,u)}}return i}function Vt(e){let t=[];for(let r of e.matchAll(/http\.host eq "([^"]+)"/g))t.push(r[1]);for(let r of e.matchAll(/http\.host in \{([^}]*)\}/g))for(let s of r[1].matchAll(/"([^"]+)"/g))t.push(s[1]);return t}function x(e,t){if(e===t)return!0;if(typeof e!==typeof t||e===null||t===null)return!1;if(typeof e!=="object")return!1;if(Array.isArray(e)||Array.isArray(t)){if(!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length)return!1;return e.every((i,o)=>x(i,t[o]))}let r=e,s=t;return Object.keys(s).every((i)=>x(r[i],s[i]))}function W(e){let t=(e.content||e.value||"").trim();if(e.weight!==void 0&&e.port!==void 0&&e.priority!==void 0&&t)return{priority:e.priority,weight:e.weight,port:e.port,target:M(t)};let r=t.split(/\s+/);if(r.length<4)return null;let[s,i,o]=r.slice(0,3).map(Number);if(![s,i,o].every(Number.isFinite))return null;return{priority:s,weight:i,port:o,target:M(r.slice(3).join(" "))}}function M(e){return e.replace(/\.$/,"")}var B=new Set(["A","AAAA","CNAME","ALIAS"]);function qt(e){let t=e.trim().replace(/^"|"$/g,"").toLowerCase();if(t.startsWith("v=spf1"))return"v=spf1";if(t.startsWith("v=dmarc1"))return"v=dmarc1";return}function R(e){return e.trim().replace(/^"(.*)"$/s,"$1")}function w(e){return e.replace(/\.$/,"").toLowerCase()}function qn(e,t){let r=w(t),s=(e??"@").trim();if(!s||s==="@")return r;let i=w(s);if(i===r||i.endsWith(`.${r}`))return i;return`${i}.${r}`}function Bs(e,t){return e.map((r)=>({...r,name:qn(r.name,t),proxied:r.proxied??!1}))}function X(e,t){if(e.type!==t.type)return!1;if(w(e.name)!==w(t.name))return!1;if(B.has(t.type))return!0;if(t.type==="TXT"){let r=qt(t.content);if(r)return qt(R(e.content))===r;return R(e.content)===R(t.content)}return R(e.content)===R(t.content)}function Y(e,t){if(R(e.content)!==R(t.content))return!1;if(t.priority!==void 0&&e.priority!==t.priority)return!1;if(t.proxied!==void 0&&e.proxied!==void 0&&e.proxied!==t.proxied)return!1;return!0}async function xs(e){let{provider:t,zone:r,records:s}=e,i={outcomes:[],warnings:[]};if(s.length===0)return i;let o=await t.listRecords(r);if(!o.success)return i.warnings.push(`could not list ${r}: ${o.message||"unknown provider error"} — records not reconciled`),i;let a=o.records;for(let c of s){let d=a.filter((p)=>X(p,c));if(d.length>0&&d.every((p)=>Y(p,c))){i.outcomes.push({record:c,action:"unchanged"});continue}let u={name:c.name,type:c.type,content:c.content,ttl:c.ttl??3600,...c.priority!==void 0?{priority:c.priority}:{},...c.proxied!==void 0?{proxied:c.proxied}:{}},g=c.type==="TXT"&&qt(c.content)!==void 0;if(g)for(let p of d){let y=await t.deleteRecord(r,{name:p.name,type:p.type,content:p.content});if(!y.success)i.warnings.push(`could not remove superseded ${p.type} at ${p.name}: ${y.message||"unknown error"}`)}let m=g||d.length===0?await t.createRecord(r,u):await t.upsertRecord(r,u);if(m.success)i.outcomes.push({record:c,action:d.length>0?"updated":"created"});else i.outcomes.push({record:c,action:"failed",message:m.message})}for(let c of["MX"]){let d=new Set(s.filter((u)=>u.type===c).map((u)=>w(u.name)));for(let u of d){let g=new Set(s.filter((p)=>p.type===c&&w(p.name)===u).map((p)=>R(p.content).toLowerCase())),m=a.filter((p)=>p.type===c&&w(p.name)===u&&!g.has(R(p.content).toLowerCase()));for(let p of m)i.warnings.push(`${u} has an undeclared ${c} record (${p.content}) alongside the declared one — mail will be split between them. Remove it at the provider if it is stale.`)}}return i}function Tr(e){if(!e||typeof e!=="object")return!1;let t=e;return typeof t.getNameServers==="function"&&typeof t.updateNameServers==="function"}function wr(e){return Boolean(e&&typeof e.createZone==="function")}var J=new Set(["NS"]);function D(e){return e.replace(/\.$/,"").toLowerCase()}function jn(e,t){if(e.length===0||t.length===0)return!1;let r=new Set(e.map(D)),s=new Set(t.map(D));if(r.size!==s.size)return!1;for(let i of r)if(!s.has(i))return!1;return!0}function Q(e){let t=e.content.trim(),r=t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1):t;return e.type==="TXT"?r:D(r)}var ee=new Set(["MX","SRV"]),te=new Set(["A","AAAA","CNAME"]);function S(e){let t=ee.has(e.type)&&e.priority!==void 0&&e.priority!==null?String(Number(e.priority)):"";return`${e.type}|${D(e.name)}|${Q(e)}|${t}`}function re(e,t){return S(e)===S(t)}async function Rr(e){let{domain:t,registrar:r,host:s,dryRun:i=!1}=e,o=new Set([...e.proxiedHosts??[]].map(D)),a=[],c=await s.createZone(t,{accountId:e.accountId,jumpStart:!1}),d=await r.getNameServers(t),u={status:"ready",domain:t,zoneId:c.id,targetNameservers:c.nameServers,currentNameservers:d,records:[],missing:[],warnings:a};if(jn(d,c.nameServers))return u.status="already-delegated",u;if(c.nameServers.length===0)return a.push(`${s.name} did not report nameservers for ${t}; cannot delegate.`),u.status="blocked",u;let g=await r.listRecords(t);if(!g.success)return a.push(`Could not read ${t} from ${r.name}: ${g.message??"unknown error"}`),u.status="blocked",u;let m=[];for(let l of g.records){if(J.has(l.type)){u.records.push({record:l,status:"skipped",reason:`${l.type} describes the delegation itself; ${s.name} owns it`});continue}let f=pt.has(l.type)&&o.has(D(l.name));m.push({name:l.name,type:l.type,content:l.content,ttl:l.ttl,priority:l.priority,...pt.has(l.type)?{proxied:f}:{}})}if(i){for(let l of m)u.records.push({record:l,status:"copied",reason:"dry run"});return u}let p=new Map;for(let l of m){let f=`${l.type}|${D(l.name)}`;p.set(f,(p.get(f)??0)+1)}let y=new Set;try{let l=await s.listRecords(t);for(let f of l.records??[])y.add(S(f))}catch{}for(let l of m){let f=te.has(l.type)&&p.get(`${l.type}|${D(l.name)}`)===1;if(!f&&y.has(S(l))){u.records.push({record:l,status:"present"});continue}let A;try{A=f?await s.upsertRecord(t,l):await s.createRecord(t,l)}catch(N){A={success:!1,message:N instanceof Error?N.message:String(N)}}if(A.success)y.add(S(l));u.records.push(A.success?{record:l,status:"copied"}:{record:l,status:"failed",reason:A.message})}let v=await s.listRecords(t);if(!v.success)return a.push(`Could not read back ${t} from ${s.name}: ${v.message??"unknown error"}`),u.status="blocked",u;for(let l of m)if(!v.records.some((f)=>re(l,f)))u.missing.push(l);if(u.missing.length>0)return a.push(`${u.missing.length} record(s) did not arrive at ${s.name}; leaving ${r.name}'s nameservers alone. Delegating now would take the domain off a complete zone and onto an incomplete one.`),u.status="blocked",u;if(!await r.updateNameServers(t,c.nameServers))return a.push(`${r.name} refused the nameserver update for ${t}.`),u.status="blocked",u;return u.status="delegated",u}var ne={add_visitor_location_headers:"visitorLocationHeaders"};function z(e){return{porkbunApiKey:e.PORKBUN_API_KEY,porkbunSecretKey:e.PORKBUN_SECRET_KEY,godaddyApiKey:e.GODADDY_API_KEY,godaddyApiSecret:e.GODADDY_API_SECRET,cloudflareApiToken:e.CLOUDFLARE_API_TOKEN,cloudflareAccountId:e.CLOUDFLARE_ACCOUNT_ID}}function se(e,t){if(e==="porkbun"){if(!t.porkbunApiKey||!t.porkbunSecretKey)return"PORKBUN_API_KEY / PORKBUN_SECRET_KEY are not set";return new he(t.porkbunApiKey,t.porkbunSecretKey)}if(!t.godaddyApiKey||!t.godaddyApiSecret)return"GODADDY_API_KEY / GODADDY_API_SECRET are not set";let r=new Ge(t.godaddyApiKey,t.godaddyApiSecret);if(!Tr(r))return"the GoDaddy provider cannot change nameservers";return r}async function Os(e,t={}){let r=e.registrar;if(!r)return{status:"skipped",reason:"no dns.registrar configured"};if(r.delegate===!1)return{status:"skipped",reason:"dns.registrar.delegate is false"};if(!e.domain)return{status:"skipped",reason:"no dns.domain configured"};if(!e.provider||e.provider===r.provider)return{status:"skipped",reason:`dns.provider is already ${r.provider}`};if(e.provider!=="cloudflare")return{status:"skipped",reason:`delegation to ${e.provider} is not supported yet`};let s=t.credentials??z(t.env??process.env);if(!s.cloudflareApiToken)return{status:"skipped",reason:"CLOUDFLARE_API_TOKEN is not set"};let i=se(r.provider,s);if(typeof i==="string")return{status:"skipped",reason:i};let o=new H(s.cloudflareApiToken,{accountId:s.cloudflareAccountId});if(!wr(o))return{status:"skipped",reason:"the Cloudflare provider cannot create zones"};return Rr({domain:e.domain,registrar:i,host:o,proxiedHosts:r.proxied,accountId:s.cloudflareAccountId,dryRun:r.dryRun})}function _s(e){if(e.status==="skipped")return[`dns: delegation skipped — ${e.reason}`];let t=[];switch(e.status){case"already-delegated":t.push(`dns: ${e.domain} already delegated to ${e.targetNameservers.join(", ")}`);break;case"delegated":t.push(`dns: ${e.domain} delegated to ${e.targetNameservers.join(", ")} (${e.records.filter((r)=>r.status==="copied").length} record(s) copied)`),t.push("dns: nameserver changes take up to 24h to propagate; the old zone answers until then");break;case"ready":t.push(`dns: ${e.domain} would delegate to ${e.targetNameservers.join(", ")} (dry run)`);break;case"blocked":t.push(`dns: ${e.domain} NOT delegated — nameservers left at ${e.currentNameservers.join(", ")}`);for(let r of e.missing)t.push(` missing at destination: ${r.type} ${r.name}`);break}for(let r of e.warnings)t.push(` ${r}`);return t}function oe(e){let t={};if(e.ssl!==void 0)t.ssl=e.ssl;if(e.alwaysUseHttps!==void 0)t.always_use_https=e.alwaysUseHttps?"on":"off";if(e.minTlsVersion!==void 0)t.min_tls_version=e.minTlsVersion;return t}function ae(e){let t={};for(let[r,s]of Object.entries(ne)){let i=e[s];if(typeof i==="boolean")t[r]=i}return t}async function Ls(e,t={}){if(!e.zone)return{status:"skipped",reason:"no dns.zone configured"};if(!e.domain)return{status:"skipped",reason:"no dns.domain configured"};if(e.provider!=="cloudflare")return{status:"skipped",reason:`zone settings are not supported for ${e.provider??"this provider"}`};let r=oe(e.zone),s=ae(e.zone);if(Object.keys(r).length===0&&Object.keys(s).length===0&&!e.zone.tieredCache)return{status:"skipped",reason:"dns.zone declares no settings"};let i=t.credentials??z(t.env??process.env);if(!i.cloudflareApiToken)return{status:"skipped",reason:"CLOUDFLARE_API_TOKEN is not set"};let o=new H(i.cloudflareApiToken,{accountId:i.cloudflareAccountId}),a=await o.applyZoneSettings(e.domain,r),c=Object.keys(s).length>0?await o.applyManagedRequestHeaders(e.domain,s):{changed:[],failed:[]},d=e.zone.tieredCache?await o.applyTieredCache(e.domain,e.zone.tieredCache):{changed:[],failed:[]},u=[...a.changed,...c.changed,...d.changed],g=[...a.failed,...c.failed,...d.failed];return{status:u.length>0?"applied":"unchanged",domain:e.domain,changed:u,failed:g}}function $s(e){if(e.status==="skipped")return[`dns: zone settings skipped — ${e.reason}`];let t=[];for(let r of e.changed)t.push(`dns: ${e.domain} ${r.id}: ${String(r.from)} → ${String(r.to)}`);if(e.status==="unchanged"&&e.failed.length===0)t.push(`dns: ${e.domain} zone settings already as declared`);for(let r of e.failed)t.push(`dns: ${e.domain} could not set ${r.id} — ${r.error}`);return t}class ie{name="route53";client;hostedZoneCache=new Map;providedHostedZoneId;constructor(e="us-east-1",t){this.client=new I(e),this.providedHostedZoneId=t}getRootDomain(e){let t=e.replace(/\.$/,"").split(".");if(t.length>=2)return t.slice(-2).join(".");return e}async getHostedZoneId(e){if(this.providedHostedZoneId)return this.providedHostedZoneId;let t=this.getRootDomain(e),r=this.hostedZoneCache.get(t);if(r)return r;let s=await this.client.findHostedZoneForDomain(e);if(s){let i=s.Id.replace("/hostedzone/","");return this.hostedZoneCache.set(t,i),i}return null}normalizeName(e,t){let r=e.replace(/\.$/,""),s=t.replace(/\.$/,"");if(!s||s==="@")return`${r}.`;if(s===r||s.endsWith(`.${r}`))return`${s}.`;return`${s}.${r}.`}formatValue(e){let t=e.content;if(e.type==="TXT"&&!t.startsWith('"'))t=ce(t);if(e.type==="MX"&&e.priority!==void 0)t=`${e.priority} ${t}`;return t}sameValue(e,t,r){return e==="TXT"?_(t)===_(r):t===r}async currentSet(e,t,r){let i=(await this.client.listResourceRecordSets({HostedZoneId:e,StartRecordName:t,StartRecordType:r,MaxItems:"1"})).ResourceRecordSets?.[0];if(!i||i.Name.toLowerCase()!==t.toLowerCase()||i.Type!==r||i.AliasTarget||i.SetIdentifier)return null;return{ttl:i.TTL??300,values:(i.ResourceRecords??[]).map((o)=>o.Value)}}async createRecord(e,t){try{let r=await this.getHostedZoneId(e);if(!r)return{success:!1,message:`No hosted zone found for domain: ${e}`};let s=this.normalizeName(e,t.name),i=this.formatValue(t),o=await this.currentSet(r,s,t.type);if(o?.values.some((d)=>this.sameValue(t.type,d,i)))return{success:!0,message:"Record already present"};let a=[...o?.values??[],i];return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Created by ts-cloud DNS provider",Changes:[{Action:o?"UPSERT":"CREATE",ResourceRecordSet:{Name:s,Type:t.type,TTL:o?.ttl??t.ttl??300,ResourceRecords:a.map((d)=>({Value:d}))}}]}})).ChangeInfo?.Id,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(e,t){try{let r=await this.getHostedZoneId(e);if(!r)return{success:!1,message:`No hosted zone found for domain: ${e}`};let s=this.normalizeName(e,t.name),i=this.formatValue(t);return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Upserted by ts-cloud DNS provider",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:s,Type:t.type,TTL:t.ttl||300,ResourceRecords:[{Value:i}]}}]}})).ChangeInfo?.Id,message:"Record upserted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async deleteRecord(e,t){try{let r=await this.getHostedZoneId(e);if(!r)return{success:!1,message:`No hosted zone found for domain: ${e}`};let s=this.normalizeName(e,t.name),i=this.formatValue(t),o=await this.currentSet(r,s,t.type);if(!o||!o.values.some((c)=>this.sameValue(t.type,c,i)))return{success:!0,message:"Record already absent"};let a=o.values.filter((c)=>!this.sameValue(t.type,c,i));return await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Deleted by ts-cloud DNS provider",Changes:[{Action:a.length>0?"UPSERT":"DELETE",ResourceRecordSet:{Name:s,Type:t.type,TTL:o.ttl,ResourceRecords:(a.length>0?a:o.values).map((c)=>({Value:c}))}}]}}),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(e,t){try{let r=await this.getHostedZoneId(e);if(!r)return{success:!1,records:[],message:`No hosted zone found for domain: ${e}`};let s=await this.client.listResourceRecordSets({HostedZoneId:r,StartRecordType:t}),i=[];for(let o of s.ResourceRecordSets){if(t&&o.Type!==t)continue;if(o.AliasTarget)continue;for(let a of o.ResourceRecords||[]){let c=a.Value,d;if(o.Type==="MX"){let u=c.split(" ");if(u.length>=2)d=Number.parseInt(u[0],10),c=u.slice(1).join(" ")}if(o.Type==="TXT"&&c.startsWith('"'))c=_(c);i.push({name:o.Name.replace(/\.$/,""),type:o.Type,content:c,ttl:o.TTL,priority:d})}}return{success:!0,records:i}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(e){return await this.getHostedZoneId(e)!==null}async listDomains(){try{return(await this.client.listHostedZones()).HostedZones.map((t)=>t.Name.replace(/\.$/,""))}catch{return[]}}getRoute53Client(){return this.client}async createAliasRecord(e){try{let t=await this.getHostedZoneId(e.domain);if(!t)return{success:!1,message:`No hosted zone found for domain: ${e.domain}`};return{success:!0,id:(await this.client.createAliasRecord({HostedZoneId:t,Name:this.normalizeName(e.domain,e.name),TargetHostedZoneId:e.targetHostedZoneId,TargetDNSName:e.targetDnsName,EvaluateTargetHealth:e.evaluateTargetHealth,Type:e.type})).ChangeInfo?.Id,message:"Alias record created successfully"}}catch(t){return{success:!1,message:t instanceof Error?t.message:"Unknown error"}}}async createCloudFrontAlias(e){return this.createAliasRecord({domain:e.domain,name:e.name,targetHostedZoneId:I.CloudFrontHostedZoneId,targetDnsName:e.cloudFrontDomainName,evaluateTargetHealth:!1})}async createAlbAlias(e){let t=I.ALBHostedZoneIds[e.region];if(!t)return{success:!1,message:`Unknown region for ALB: ${e.region}`};return this.createAliasRecord({domain:e.domain,name:e.name,targetHostedZoneId:t,targetDnsName:e.albDnsName,evaluateTargetHealth:!0})}}var q=255;function ce(e){let t=[];for(let r=0;r<e.length;r+=q)t.push(e.slice(r,r+q));if(t.length===0)t.push("");return t.map((r)=>`"${r.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}"`).join(" ")}function _(e){if(!e.startsWith('"'))return e;let t="",r=!1;for(let s=0;s<e.length;s++){let i=e[s];if(!r){if(i==='"')r=!0;continue}if(i==="\\"&&s+1<e.length){t+=e[++s];continue}if(i==='"'){r=!1;continue}t+=i}return t}async function Ms(e,t){let r=[],s,i;for(;;){let o=await e.listResourceRecordSets({HostedZoneId:t,StartRecordName:s,StartRecordType:i,MaxItems:"100"});if(r.push(...o.ResourceRecordSets),!o.IsTruncated)break;if(s=o.NextRecordName,i=o.NextRecordType,!s)break}return r}function h(e){return e.replace(/\.$/,"").toLowerCase()}function L(e){return e.replace(/\.$/,"")}function T(e){if(e.type==="SRV"&&e.weight!==void 0&&e.port!==void 0)return`${e.weight} ${e.port} ${L(e.content)}`;return L(e.content)}function de(e){let t=e.match(/"(?:[^"\\]|\\.)*"/g);if(!t)return e;return t.map((r)=>r.slice(1,-1).replace(/\\(.)/g,"$1")).join("")}function Fs(e,t){let r=h(t),s=[],i=[],o=[],a=new Set;for(let c of e){let d=h(c.Name),u=c.Type;if(u==="SOA"||u==="NS"&&d===r){i.push({name:d,type:u,reason:"owned by the destination provider"});continue}if(c.SetIdentifier){i.push({name:d,type:u,reason:`routing policy record (SetIdentifier=${c.SetIdentifier}) has no equivalent — recreate by hand`}),o.push(`${u} ${d} is part of a Route53 routing policy and was NOT migrated`);continue}if(c.AliasTarget){if(a.has(d))continue;a.add(d);let g=h(c.AliasTarget.DNSName);if(s.push({name:d,type:"CNAME",content:g,ttl:300,translatedFrom:`${u} ALIAS → ${g}`}),c.AliasTarget.EvaluateTargetHealth)o.push(`${d} was an ALIAS with health evaluation enabled; the CNAME that replaces it has no health check`);continue}for(let g of c.ResourceRecords||[]){let m=ue(d,u,g.Value,c.TTL);if("reason"in m){i.push({name:d,type:u,reason:m.reason}),o.push(`${u} ${d}: ${m.reason}`);continue}s.push(m)}}return{zone:r,records:s,skipped:i,warnings:o}}function ue(e,t,r,s){let i={name:e,ttl:s};switch(t){case"A":case"AAAA":case"CNAME":case"PTR":return{...i,type:t==="PTR"?"CNAME":t,content:h(r)};case"TXT":return{...i,type:"TXT",content:de(r)};case"MX":{let[o,...a]=r.trim().split(/\s+/);if(!a.length)return{reason:`malformed MX value "${r}"`};return{...i,type:"MX",content:h(a.join(" ")),priority:Number(o)}}case"SRV":{let o=r.trim().split(/\s+/);if(o.length<4)return{reason:`malformed SRV value "${r}"`};let[a,c,d]=o.slice(0,3).map(Number);return{...i,type:"SRV",content:h(o.slice(3).join(" ")),priority:a,weight:c,port:d}}case"NS":return{...i,type:"NS",content:h(r)};case"CAA":return{...i,type:"CAA",content:r.trim()};default:return{reason:`unsupported record type ${t}`}}}var le=new Set(["TXT","MX","SRV","NS","CAA"]);async function Us(e,t){let r=[],s=[],i=new Set;try{let o=await e.listRecords(t.zone);for(let a of o.records||[])i.add(`${h(a.name)}|${a.type}|${T(a)}`)}catch{}for(let o of t.records){let a={...o,proxied:!1},c=`${h(o.name)}|${o.type}|${T(o)}`;if(!le.has(o.type)){let u=await e.upsertRecord(t.zone,a);if(u.success)r.push(o);else s.push({record:o,message:u.message||"unknown provider error"});continue}if(i.has(c)){r.push(o);continue}let d=await e.createRecord(t.zone,a);if(d.success)i.add(c),r.push(o);else s.push({record:o,message:d.message||"unknown provider error"})}return{applied:r,failed:s}}async function Qs(e,t){let r=await e.listRecords(t.zone),s=[],i=[],o=new Map;for(let a of r.records||[]){let c=`${h(a.name)}|${a.type}`,d=o.get(c)??[];d.push(T(a)),o.set(c,d)}for(let a of t.records){let c=o.get(`${h(a.name)}|${a.type}`),d=T(a);if(c?.some((u)=>u===d))s.push(a);else i.push({record:a,found:c?.join(", ")})}return{matched:s,missing:i,ok:i.length===0}}class Ae{acm;dnsProvider;constructor(e,t="us-east-1"){if(this.acm=new ye(t),"provider"in e)this.dnsProvider=k(e);else this.dnsProvider=e}getProvider(){return this.dnsProvider}async requestAndValidate(e){let{domainName:t,subjectAlternativeNames:r=[],waitForValidation:s=!1,maxWaitMinutes:i=30}=e,{CertificateArn:o}=await this.acm.requestCertificate({DomainName:t,SubjectAlternativeNames:r.length>0?[t,...r]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(o);let a=await this.acm.getDnsValidationRecords(o);for(let d of a){let u=await this.dnsProvider.upsertRecord(t,{name:d.recordName,type:d.recordType,content:d.recordValue,ttl:300});if(!u.success)console.warn(`Failed to create validation record for ${d.domainName}: ${u.message}`)}let c="pending";if(s)c=(await this.acm.waitForCertificateValidation(o,i*2,30000))?.Status==="ISSUED"?"issued":"failed";return{certificateArn:o,validationRecords:a.map((d)=>({domainName:d.domainName,recordName:d.recordName,recordType:d.recordType,recordValue:d.recordValue})),isNew:!0,status:c}}async createValidationRecords(e){let{certificateArn:t,domain:r}=e,s=[],i=await this.acm.getDnsValidationRecords(t);for(let o of i){let a=await this.dnsProvider.upsertRecord(r,{name:o.recordName,type:o.recordType,content:o.recordValue,ttl:300});if(!a.success)s.push(`Failed to create record for ${o.domainName}: ${a.message}`)}return{success:s.length===0,records:i.map((o)=>({domainName:o.domainName,recordName:o.recordName,recordType:o.recordType,recordValue:o.recordValue})),errors:s}}async deleteValidationRecords(e){let{certificateArn:t,domain:r}=e,s=[],i=await this.acm.getDnsValidationRecords(t);for(let o of i){let a=await this.dnsProvider.deleteRecord(r,{name:o.recordName,type:o.recordType,content:o.recordValue});if(!a.success)s.push(`Failed to delete record for ${o.domainName}: ${a.message}`)}return{success:s.length===0,errors:s}}async findOrCreateCertificate(e){let{domainName:t,subjectAlternativeNames:r=[],waitForValidation:s=!0,maxWaitMinutes:i}=e,o=await this.acm.findCertificateByDomain(t);if(o&&o.Status==="ISSUED"){let a=o.SubjectAlternativeNames||[o.DomainName],c=a.some((u)=>u===`*.${t}`);if(r.every((u)=>a.includes(u)||c))return{certificateArn:o.CertificateArn,validationRecords:[],isNew:!1,status:"issued"};console.log("Existing certificate doesn't cover all required SANs, requesting new certificate...")}return this.requestAndValidate({domainName:t,subjectAlternativeNames:r,waitForValidation:s,maxWaitMinutes:i})}async requestCertificateWithCommonSans(e){let{domainName:t,includeWww:r=!0,includeWildcard:s=!1,additionalSans:i=[],waitForValidation:o=!1}=e,a=[];if(r)a.push(`www.${t}`);if(s)a.push(`*.${t}`);return a.push(...i),this.requestAndValidate({domainName:t,subjectAlternativeNames:a,waitForValidation:o})}async waitForValidationOptions(e,t=30){for(let r=0;r<t;r++){let s=await this.acm.describeCertificate({CertificateArn:e});if(s.DomainValidationOptions&&s.DomainValidationOptions.length>0&&s.DomainValidationOptions[0].ResourceRecord)return;await new Promise((i)=>setTimeout(i,2000))}throw Error("Timeout waiting for DNS validation options")}async getCertificateStatus(e){let t=await this.acm.describeCertificate({CertificateArn:e});return{status:t.Status,domainValidations:(t.DomainValidationOptions||[]).map((r)=>({domain:r.DomainName,status:r.ValidationStatus||"UNKNOWN"}))}}}function Hs(e,t,r){return new Ae({provider:"porkbun",apiKey:e,secretKey:t},r)}function Gs(e,t,r,s){return new Ae({provider:"godaddy",apiKey:e,apiSecret:t,environment:s},r)}function Vs(e,t,r){return new Ae({provider:"route53",region:e,hostedZoneId:t},r||e)}function k(e){switch(e.provider){case"route53":return new ie(e.region,e.hostedZoneId);case"porkbun":return new he(e.apiKey,e.secretKey);case"godaddy":return new Ge(e.apiKey,e.apiSecret,e.environment);case"cloudflare":return new H(e.apiToken,{zoneId:e.zoneId,accountId:e.accountId});default:throw Error(`Unknown DNS provider: ${e.provider}`)}}async function Cc(e,t){for(let r of t){let s=k(r);if(await s.canManageDomain(e))return s}return null}class zn{providers=new Map;configs=[];addConfig(e){return this.configs.push(e),this}addRoute53(e,t){return this.configs.push({provider:"route53",region:e,hostedZoneId:t}),this}addPorkbun(e,t){return this.configs.push({provider:"porkbun",apiKey:e,secretKey:t}),this}addGoDaddy(e,t,r){return this.configs.push({provider:"godaddy",apiKey:e,apiSecret:t,environment:r}),this}addCloudflare(e,t={}){return this.configs.push({provider:"cloudflare",apiToken:e,zoneId:t.zoneId,accountId:t.accountId}),this}loadFromEnv(){if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE||process.env.AWS_REGION)this.addRoute53(process.env.AWS_REGION);let e=process.env.PORKBUN_API_KEY,t=process.env.PORKBUN_SECRET_KEY;if(e&&t)this.addPorkbun(e,t);let r=process.env.GODADDY_API_KEY,s=process.env.GODADDY_API_SECRET;if(r&&s){let o=process.env.GODADDY_ENVIRONMENT;this.addGoDaddy(r,s,o)}let i=process.env.CLOUDFLARE_API_TOKEN;if(i)this.addCloudflare(i,{zoneId:process.env.CLOUDFLARE_ZONE_ID,accountId:process.env.CLOUDFLARE_ACCOUNT_ID});return this}getProvider(e){let t=this.providers.get(e);if(t)return t;let r=this.configs.find((i)=>i.provider===e);if(!r)return null;let s=k(r);return this.providers.set(e,s),s}async getProviderForDomain(e){for(let t of this.configs){let r=k(t);if(await r.canManageDomain(e))return r}return null}getAllProviders(){return this.configs.map((e)=>k(e))}}var Ec=new zn;class ye{client;region;constructor(e="us-east-1"){this.client=new n,this.region=e}async requestCertificate(e){let t={DomainName:e.DomainName,ValidationMethod:e.ValidationMethod||"DNS"};if(e.SubjectAlternativeNames)t.SubjectAlternativeNames=e.SubjectAlternativeNames;return{CertificateArn:(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.RequestCertificate"},body:JSON.stringify(t)})).CertificateArn||""}}async describeCertificate(e){let r=(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.DescribeCertificate"},body:JSON.stringify({CertificateArn:e.CertificateArn})})).Certificate||{};return{CertificateArn:r.CertificateArn||"",DomainName:r.DomainName||"",SubjectAlternativeNames:r.SubjectAlternativeNames,Status:r.Status||"PENDING_VALIDATION",Type:r.Type,DomainValidationOptions:r.DomainValidationOptions?.map((s)=>({DomainName:s.DomainName,ValidationDomain:s.ValidationDomain,ValidationStatus:s.ValidationStatus,ResourceRecord:s.ResourceRecord?{Name:s.ResourceRecord.Name,Type:s.ResourceRecord.Type,Value:s.ResourceRecord.Value}:void 0,ValidationMethod:s.ValidationMethod})),CreatedAt:r.CreatedAt,IssuedAt:r.IssuedAt,NotBefore:r.NotBefore,NotAfter:r.NotAfter}}async listCertificates(e){let t={};if(e?.CertificateStatuses)t.CertificateStatuses=e.CertificateStatuses;if(e?.MaxItems)t.MaxItems=e.MaxItems;if(e?.NextToken)t.NextToken=e.NextToken;let r=await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ListCertificates"},body:JSON.stringify(t)});return{CertificateSummaryList:(r.CertificateSummaryList||[]).map((s)=>({CertificateArn:s.CertificateArn,DomainName:s.DomainName})),NextToken:r.NextToken}}async deleteCertificate(e){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.DeleteCertificate"},body:JSON.stringify({CertificateArn:e.CertificateArn})})}async listTagsForCertificate(e){return{Tags:(await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ListTagsForCertificate"},body:JSON.stringify({CertificateArn:e.CertificateArn})})).Tags||[]}}async addTagsToCertificate(e){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.AddTagsToCertificate"},body:JSON.stringify({CertificateArn:e.CertificateArn,Tags:e.Tags})})}async resendValidationEmail(e){await this.client.request({service:"acm",region:this.region,method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"CertificateManager.ResendValidationEmail"},body:JSON.stringify({CertificateArn:e.CertificateArn,Domain:e.Domain,ValidationDomain:e.ValidationDomain})})}async findCertificateByDomain(e){let r=(await this.listCertificates({CertificateStatuses:["ISSUED"]})).CertificateSummaryList.find((s)=>s.DomainName===e||s.DomainName===`*.${e.split(".").slice(1).join(".")}`);if(!r)return null;return this.describeCertificate({CertificateArn:r.CertificateArn})}async waitForCertificateValidation(e,t=60,r=30000){for(let s=0;s<t;s++){let i=await this.describeCertificate({CertificateArn:e});if(i.Status==="ISSUED")return i;if(i.Status==="FAILED"||i.Status==="VALIDATION_TIMED_OUT")return null;await new Promise((o)=>setTimeout(o,r))}return null}async getDnsValidationRecords(e){let t=await this.describeCertificate({CertificateArn:e});if(!t.DomainValidationOptions)return[];return t.DomainValidationOptions.filter((r)=>r.ResourceRecord&&r.ValidationMethod==="DNS").map((r)=>({domainName:r.DomainName,recordName:r.ResourceRecord.Name,recordType:r.ResourceRecord.Type,recordValue:r.ResourceRecord.Value}))}async requestCertificateWithSans(e){let t=new Set;if(t.add(e.DomainName),e.IncludeWww!==!1)t.add(`www.${e.DomainName}`);if(e.IncludeWildcard)t.add(`*.${e.DomainName}`);if(e.AdditionalSans)for(let r of e.AdditionalSans)t.add(r);return this.requestCertificate({DomainName:e.DomainName,SubjectAlternativeNames:Array.from(t),ValidationMethod:"DNS"})}async isCertificateValidForDomain(e,t){let r=await this.describeCertificate({CertificateArn:e});if(r.Status!=="ISSUED")return!1;if(r.DomainName===t)return!0;if(r.DomainName?.startsWith("*.")){let s=r.DomainName.slice(2),i=t.split("."),o=s.split(".");if(i.slice(-o.length).join(".")===s)return!0}if(r.SubjectAlternativeNames)for(let s of r.SubjectAlternativeNames){if(s===t)return!0;if(s.startsWith("*.")){let i=s.slice(2),o=t.split("."),a=i.split(".");if(o.slice(-a.length).join(".")===i)return!0}}return!1}}class Dr{acm;route53;dnsProvider;constructor(e="us-east-1",t){if(this.acm=new ye(e),this.route53=new I,t&&t.provider!=="route53")this.dnsProvider=k(t)}async requestAndValidate(e){let{domainName:t,hostedZoneId:r,subjectAlternativeNames:s=[],waitForValidation:i=!1,maxWaitMinutes:o=30}=e;if(!this.dnsProvider&&!r)throw Error("Either hostedZoneId or external DNS provider configuration is required");let{CertificateArn:a}=await this.acm.requestCertificate({DomainName:t,SubjectAlternativeNames:s.length>0?[t,...s]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(a);let c=await this.acm.getDnsValidationRecords(a);if(this.dnsProvider)for(let d of c){let u=await this.dnsProvider.upsertRecord(t,{name:d.recordName,type:d.recordType,content:d.recordValue,ttl:300});if(!u.success)console.warn(`Failed to create validation record for ${d.domainName}: ${u.message}`)}else if(r)for(let d of c)await this.route53.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:`ACM DNS validation for ${d.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:d.recordName,Type:d.recordType,TTL:300,ResourceRecords:[{Value:d.recordValue}]}}]}});if(i){if(!await this.acm.waitForCertificateValidation(a,o*2,30000))throw Error(`Certificate validation timed out after ${o} minutes`)}return{certificateArn:a,validationRecords:c}}async waitForValidationOptions(e,t=30){for(let r=0;r<t;r++){let s=await this.acm.describeCertificate({CertificateArn:e});if(s.DomainValidationOptions&&s.DomainValidationOptions.length>0&&s.DomainValidationOptions[0].ResourceRecord)return;await new Promise((i)=>setTimeout(i,2000))}throw Error("Timeout waiting for DNS validation options")}async createValidationRecords(e){let{certificateArn:t,hostedZoneId:r,domain:s}=e;if(!this.dnsProvider&&!r)throw Error("Either hostedZoneId or external DNS provider configuration is required");let i=await this.acm.getDnsValidationRecords(t),o=[];if(this.dnsProvider){let a=s||i[0]?.domainName;for(let c of i){let d=await this.dnsProvider.upsertRecord(a,{name:c.recordName,type:c.recordType,content:c.recordValue,ttl:300});o.push({...c,changeId:d.success?d.id:void 0})}}else if(r)for(let a of i){let c=await this.route53.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:`ACM DNS validation for ${a.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:a.recordName,Type:a.recordType,TTL:300,ResourceRecords:[{Value:a.recordValue}]}}]}});o.push({...a,changeId:c.ChangeInfo?.Id})}return o}async deleteValidationRecords(e){let{certificateArn:t,hostedZoneId:r,domain:s}=e,i=await this.acm.getDnsValidationRecords(t);if(this.dnsProvider){let o=s||i[0]?.domainName;for(let a of i)try{await this.dnsProvider.deleteRecord(o,{name:a.recordName,type:a.recordType,content:a.recordValue})}catch{}}else if(r)for(let o of i)try{await this.route53.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:`Cleanup ACM DNS validation for ${o.domainName}`,Changes:[{Action:"DELETE",ResourceRecordSet:{Name:o.recordName,Type:o.recordType,TTL:300,ResourceRecords:[{Value:o.recordValue}]}}]}})}catch{}}async findOrCreateCertificate(e){let{domainName:t,hostedZoneId:r,subjectAlternativeNames:s,waitForValidation:i=!0}=e;if(!this.dnsProvider&&!r)throw Error("Either hostedZoneId or external DNS provider configuration is required");let o=await this.acm.findCertificateByDomain(t);if(o&&o.Status==="ISSUED")return{certificateArn:o.CertificateArn,isNew:!1};let{certificateArn:a}=await this.requestAndValidate({domainName:t,hostedZoneId:r,subjectAlternativeNames:s,waitForValidation:i});return{certificateArn:a,isNew:!0}}hasExternalDnsProvider(){return this.dnsProvider!==void 0}getDnsProviderName(){return this.dnsProvider?.name||"route53"}}
|
|
2
|
+
export{pt,he,Ge,yg,Ht,Ic,bc,Gt,H,Vn,Vt,qt,qn,Bs,xs,Tr,wr,jn,Rr,Os,_s,Ls,$s,ie,Ms,Fs,Us,Qs,Ae,Hs,Gs,Vs,k,Cc,zn,Ec,ye,Dr};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)}function
|
|
3
|
-
`)){let n=e.trim();if(!n)continue;try{let o=JSON.parse(Buffer.from(n,"base64").toString("utf8"));if(o&&typeof o==="object"&&!Array.isArray(o))r.push(o)}catch{continue}}return r}function
|
|
4
|
-
export{
|
|
1
|
+
import{d}from"./chunk-cpba1hz2.js";var It="/etc/rpx/sites.d",gA={start:3000,end:3999};function g(t){return t.slug?.trim()||"app"}function sd(t){let r=t.lastIndexOf(":");if(r<0||r===t.length-1)return;let e=t.slice(r+1).trim();if(!/^\d+$/.test(e))return;let n=Number(e);return n>=1&&n<=65535?n:void 0}function Ti(t,r={}){let e=r.ignoreSlug?.trim(),n=new Map;for(let o of t){let c=g(o);if(e&&c===e)continue;for(let a of o.proxies??[]){let f=typeof a.from==="string"?[a.from]:a.from??[];for(let i of f){let u=sd(i);if(u!==void 0&&!n.has(u))n.set(u,c)}}}return n}function wi(t=It){return[`for __tsc_fragment in ${t}/*.json; do`,' [ -f "$__tsc_fragment" ] || continue',` base64 < "$__tsc_fragment" | tr -d '\\n'`," printf '\\n'","done"].join(`
|
|
2
|
+
`)}function Ri(t){let r=[];for(let e of t.split(`
|
|
3
|
+
`)){let n=e.trim();if(!n)continue;try{let o=JSON.parse(Buffer.from(n,"base64").toString("utf8"));if(o&&typeof o==="object"&&!Array.isArray(o))r.push(o)}catch{continue}}return r}function Np(t,r,e=gA){let n=[],o=[],c=new Set(r.keys());for(let[a,f]of Object.entries(t.sites??{})){if(!f||d(f)!=="server-app")continue;let i=typeof f.port==="number"?f.port:void 0,u=Math.max(i??e.start,e.start),p;for(let s=u;s<=e.end;s++)if(!c.has(s)){p=s;break}if(p===void 0){let s=i!==void 0?r.get(i):void 0;o.push(`No free port for site '${a}' in ${e.start}-${e.end}${i!==void 0?` (wanted ${i}${s?`, held by '${s}'`:""})`:""}. Widen the range or free a port on the box.`);continue}c.add(p),n.push({site:a,port:p,declared:i,moved:i!==void 0&&p!==i})}return{allocations:n,errors:o}}
|
|
4
|
+
export{It,gA,sd,Ti,wi,Ri,Np};
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import{
|
|
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
|
|
1
|
+
import{It,Ti,wi,Ri}from"./chunk-nmnf1ha6.js";function S(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Hh(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 "^${S(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 Gh(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 Vh(t,e,n){let r=t.map((o)=>` ${e}-${o.name} (${o.size})`).join(`
|
|
3
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
4
|
${r}
|
|
5
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
|
|
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:
|
|
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
|
|
9
|
-
`)}function
|
|
10
|
-
`)}function m(t,e){return`^${t}-${e}-((queue|daemon)-.*|scheduler)\\.service$`}function
|
|
11
|
-
`)}function
|
|
12
|
-
`).some((e)=>e.trim().startsWith("active:"))}function
|
|
13
|
-
`)}function
|
|
14
|
-
`)}function
|
|
15
|
-
`)}function
|
|
16
|
-
`)}function
|
|
17
|
-
`)}function v(t,e){return`^${t}-${e}[-@.]`}function
|
|
18
|
-
`).some((e)=>e.trim().startsWith("active:"))}function
|
|
19
|
-
`)}function
|
|
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
|
|
21
|
-
`)}function
|
|
22
|
-
`)}async function
|
|
6
|
+
Verify the site is serving from its new home first, then re-run with ${n} to destroy it anyway.`}var up="ts-cloud/project",gp="ts-cloud/environment",pp="ts-cloud/role";function d(t){return typeof t==="string"&&t.trim()?t.trim():void 0}function h(t){if(typeof t==="string")return d(t);if(t&&typeof t==="object")return d(t.name);return}function qh(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:h(t?.location)??h(t?.datacenter?.location)??h(t?.datacenter),labels:e,project:d(e[up]),environment:d(e[gp]),role:d(e[pp])}}function w(t){return t.slug?.trim()||"app"}function mp(t){let e=[];for(let n of t){let r=w(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)??"/",...x(s)})}}return e.sort((n,r)=>n.slug.localeCompare(r.slug)||n.host.localeCompare(r.host)||n.path.localeCompare(r.path))}function x(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 fp(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 jh(t,e,n=It){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,wi(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:mp(Ri(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 zh(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 hp(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 Kh(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(` ${k(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 ${It}: ${c.unavailable}`);else o.push(...P(c,e));o.push("")}return o.push(...C(t)),o}function k(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 P(t,e){let n=fp(t.routes);if(n.length===0)return[` serves nothing: ${It} 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} -> ${O(o)}`)}return r}function O(t){if(t.kind==="redirect")return`redirect to ${t.target}`;if(t.kind==="static")return`static ${t.target}`;return t.target}function C(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=hp(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((b)=>b.name).join(", ")}`);let c=r.length-a.length,g=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(g>0)o.push(` Either they were never deployed, or they are on one of the ${g} server${g===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 Wh(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 nd(t){return t.filter((e)=>e.state!=="satisfied")}function Ap(t){return nd(t).some((e)=>e.step.destructive===!0)}function Jh(t,e){let n=nd(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 Xh(t,e,n={}){let r={operation:t.operation,target:t.target,steps:[],success:!0};if(Ap(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 yp(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 Yh(t,e,n){if(yp(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 Zh(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 eA(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 tA(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 f(t,e){let n=e==="/"?"/":e.replace(/\/+$/,"");return`${t.toLowerCase()}${n||"/"}`}function rA(t,e,n){let r=[],s=Ti(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(f(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(f(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 nA(t){return t.registryRead&&t.conflicts.length===0}function iA(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 vi(t,e){return`/tmp/ts-cloud-move-${t}-${e}.tar.gz`}function id(t,e){return`${t}-${e}*.service`}function l(t){return`'${t.split("'").join("'\\''")}'`}function Sp(t,e){return["set -eu",`for unit in $(ls /etc/systemd/system/ 2>/dev/null | grep -E ${l(m(t,e))} || true); do`,' systemctl stop "$unit" 2>/dev/null || true',"done"].join(`
|
|
10
|
+
`)}function m(t,e){return`^${t}-${e}-((queue|daemon)-.*|scheduler)\\.service$`}function Ip(t,e){return y(m(t,e))}function y(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 bp(t){return!t.split(`
|
|
12
|
+
`).some((e)=>e.trim().startsWith("active:"))}function Cp(t,e,n){let r=vi(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 ${id(t,e)} 2>/dev/null | tr '\\n' ' ')`,`sha256sum ${l(r)} | cut -d' ' -f1`].join(`
|
|
13
|
+
`)}function Ep(t,e,n){let r=vi(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(id(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 vp(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 Tp(t){return t.includes("tree:present")&&t.includes("unit:active")}function wp(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 Rp(t,e){return["set -eu",`for unit in $(ls /etc/systemd/system/ 2>/dev/null | grep -E ${l(v(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 v(t,e){return`^${t}-${e}[-@.]`}function Dp(t,e){return y(v(t,e))}function Pp(t){return!t.split(`
|
|
18
|
+
`).some((e)=>e.trim().startsWith("active:"))}function sA(t,e){return`/tmp/ts-cloud-move-${t}-${e}-certs.tar.gz`}function oA(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 aA(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 cA(t,e){for(let[n,r]of t){if(r==="absent")continue;if(e.get(n)!==r)return!1}return!0}function dA(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 lA(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 uA(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()=>bp(await e.runOnSource(Ip(n,r))),apply:async()=>{await e.runOnSource(Sp(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:vi(n,r)},satisfied:async()=>!1,apply:async()=>{await e.runOnSource(Cp(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:vi(n,r),to:`${i}:${s}`},satisfied:async()=>Tp(await e.runOnTarget(vp(n,r,s))),apply:async()=>{await e.runOnTarget(Ep(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(wp(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()=>Pp(await e.runOnSource(Dp(n,r))),apply:async()=>{await e.runOnSource(Rp(n,r))}}),{operation:"site:move",target:r,steps:p}}export{Hh,Gh,Vh,up,gp,pp,qh,mp,fp,jh,zh,hp,Kh,Wh,nd,Ap,Jh,Xh,yp,Yh,Zh,eA,tA,rA,nA,iA,vi,id,Sp,Ip,bp,Cp,Ep,vp,Tp,wp,Rp,Dp,Pp,sA,oA,aA,cA,dA,lA,uA};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ne}from"./chunk-4abbccq7.js";import"./chunk-ca191b00.js";export{ne as RDSClient};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n}from"./chunk-
|
|
2
|
-
export{
|
|
1
|
+
import{n}from"./chunk-ca191b00.js";class He{client;region;constructor(e="us-east-1",r){this.region=e,this.client=new n(void 0,{profile:r})}async createRepository(e){let r={repositoryName:e.repositoryName};if(e.imageTagMutability)r.imageTagMutability=e.imageTagMutability;if(e.imageScanningConfiguration)r.imageScanningConfiguration=e.imageScanningConfiguration;if(e.encryptionConfiguration)r.encryptionConfiguration=e.encryptionConfiguration;if(e.tags&&e.tags.length>0)r.tags=e.tags;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.CreateRepository","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{repository:t.repository?this.parseRepository(t.repository):void 0}}async describeRepositories(e){let r={};if(e?.repositoryNames&&e.repositoryNames.length>0)r.repositoryNames=e.repositoryNames;if(e?.registryId)r.registryId=e.registryId;if(e?.maxResults)r.maxResults=e.maxResults;if(e?.nextToken)r.nextToken=e.nextToken;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.DescribeRepositories","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{repositories:t.repositories?.map((i)=>this.parseRepository(i)),nextToken:t.nextToken}}async getAuthorizationToken(e){let r={};if(e&&e.length>0)r.registryIds=e;return{authorizationData:(await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.GetAuthorizationToken","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})).authorizationData?.map((i)=>({authorizationToken:i.authorizationToken,expiresAt:i.expiresAt,proxyEndpoint:i.proxyEndpoint}))}}async deleteRepository(e){let r={repositoryName:e.repositoryName};if(e.registryId)r.registryId=e.registryId;if(e.force!==void 0)r.force=e.force;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.DeleteRepository","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{repository:t.repository?this.parseRepository(t.repository):void 0}}async describeImages(e){let r={repositoryName:e.repositoryName};if(e.registryId)r.registryId=e.registryId;if(e.imageIds&&e.imageIds.length>0)r.imageIds=e.imageIds;if(e.filter)r.filter=e.filter;if(e.maxResults)r.maxResults=e.maxResults;if(e.nextToken)r.nextToken=e.nextToken;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.DescribeImages","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{imageDetails:t.imageDetails?.map((i)=>this.parseImageDetail(i)),nextToken:t.nextToken}}async batchDeleteImage(e){let r={repositoryName:e.repositoryName,imageIds:e.imageIds};if(e.registryId)r.registryId=e.registryId;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.BatchDeleteImage","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{imageIds:t.imageIds,failures:t.failures}}async putLifecyclePolicy(e){let r={repositoryName:e.repositoryName,lifecyclePolicyText:e.lifecyclePolicyText};if(e.registryId)r.registryId=e.registryId;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.PutLifecyclePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{registryId:t.registryId,repositoryName:t.repositoryName,lifecyclePolicyText:t.lifecyclePolicyText}}async getLifecyclePolicy(e){let r={repositoryName:e.repositoryName};if(e.registryId)r.registryId=e.registryId;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.GetLifecyclePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{registryId:t.registryId,repositoryName:t.repositoryName,lifecyclePolicyText:t.lifecyclePolicyText,lastEvaluatedAt:t.lastEvaluatedAt}}async setRepositoryPolicy(e){let r={repositoryName:e.repositoryName,policyText:e.policyText};if(e.registryId)r.registryId=e.registryId;if(e.force!==void 0)r.force=e.force;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.SetRepositoryPolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{registryId:t.registryId,repositoryName:t.repositoryName,policyText:t.policyText}}async getRepositoryPolicy(e){let r={repositoryName:e.repositoryName};if(e.registryId)r.registryId=e.registryId;let t=await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.GetRepositoryPolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)});return{registryId:t.registryId,repositoryName:t.repositoryName,policyText:t.policyText}}async tagResource(e){let r={resourceArn:e.resourceArn,tags:e.tags};await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.TagResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async listTagsForResource(e){let r={resourceArn:e};return{tags:(await this.client.request({service:"ecr",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerRegistry_V20150921.ListTagsForResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})).tags}}createLifecyclePolicyText(e){return JSON.stringify({rules:e.map((r)=>({rulePriority:r.rulePriority,description:r.description,selection:r.selection,action:r.action}))})}async getDockerLoginCommand(){let e=await this.getAuthorizationToken();if(!e.authorizationData?.[0])throw Error("Failed to get authorization token");let r=e.authorizationData[0],t=r.authorizationToken||"",i=r.proxyEndpoint||"";return`echo "${Buffer.from(t,"base64").toString("utf8").split(":")[1]}" | docker login --username AWS --password-stdin ${i}`}getRegistryUri(e){return`${e}.dkr.ecr.${this.region}.amazonaws.com`}parseRepository(e){return{repositoryArn:e.repositoryArn,registryId:e.registryId,repositoryName:e.repositoryName,repositoryUri:e.repositoryUri,createdAt:e.createdAt,imageTagMutability:e.imageTagMutability,imageScanningConfiguration:e.imageScanningConfiguration,encryptionConfiguration:e.encryptionConfiguration}}parseImageDetail(e){return{registryId:e.registryId,repositoryName:e.repositoryName,imageDigest:e.imageDigest,imageTags:e.imageTags,imageSizeInBytes:e.imageSizeInBytes,imagePushedAt:e.imagePushedAt,imageScanStatus:e.imageScanStatus,imageScanFindingsSummary:e.imageScanFindingsSummary}}}
|
|
2
|
+
export{He};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ac}from"./chunk-a8hs75xd.js";import"./chunk-qcj3hkba.js";import"./chunk-ca191b00.js";import"./chunk-18h7na1g.js";import"./chunk-6m8p1n88.js";export{ac as buildAndPushServerlessImage};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var l={mode:"detection",paranoiaLevel:1,inboundThreshold:5,outboundThreshold:4,maxBodyBytes:13107200,rejectOversizedBody:!0,auditLogPath:"/var/log/ts-cloud/waf-audit.log",blockStatus:403},d={bypassBase:1e5,exclusionBase:101000,rateLimitBase:102000,customBase:109000};function
|
|
1
|
+
var l={mode:"detection",paranoiaLevel:1,inboundThreshold:5,outboundThreshold:4,maxBodyBytes:13107200,rejectOversizedBody:!0,auditLogPath:"/var/log/ts-cloud/waf-audit.log",blockStatus:403},d={bypassBase:1e5,exclusionBase:101000,rateLimitBase:102000,customBase:109000};function oe(e){return e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/[\r\n]+/g," ")}function bi(e){if(e.length>1000)return!1;if(/\([^)]*[+*]\)[+*]/.test(e))return!1;if(/\[[^\]]*\][+*]\{/.test(e))return!1;try{return new RegExp(e),!0}catch{return!1}}function b(e,r){let t=[],o=[],s=r;for(let n of e){if(n.enabled===!1)continue;if(n.key&&(n.key.source==="cookie"||n.key.source==="header")&&!n.key.name){o.push({ruleId:n.id,reason:"The rule keys on a header or cookie but names none."});continue}let c=n.path?eo(n.path):".*";if(!bi(c)){o.push({ruleId:n.id,reason:"The path pattern compiles to an unsafe regular expression."});continue}let u=[`SecRule REQUEST_URI "@rx ${oe(c)}"`];if(n.methods?.length)u.push(` "chain,id:${s},phase:1,pass,nolog,setvar:'tx.ts_cloud_ratelimit=${oe(n.id)}'"`);else u.push(` "id:${s},phase:1,pass,nolog,setvar:'tx.ts_cloud_ratelimit=${oe(n.id)}'"`);if(t.push(`# Marks requests governed by the ts-cloud rate limit "${oe(n.id)}".`),t.push(u.join(" \\\n")),n.methods?.length)t.push(` SecRule REQUEST_METHOD "@within ${oe(n.methods.join(" ").toUpperCase())}" "t:none"`);t.push(""),s++}return{lines:t,unmapped:o}}function eo(e){return`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"\x01").replace(/\*/g,"[^/]*").replace(/\u0001/g,".*")}$`}function Xc(e={},r=[]){let t=e.mode??l.mode,o=[],s=e.paranoiaLevel??l.paranoiaLevel,n=e.inboundThreshold??l.inboundThreshold,c=e.outboundThreshold??l.outboundThreshold,u=e.maxBodyBytes??l.maxBodyBytes,h=e.rejectOversizedBody!==!1;if(t==="blocking"&&s>=3)o.push(`Paranoia level ${s} blocks legitimate traffic on most applications until it is tuned. Run it in detection mode first.`);if(t==="blocking")o.push("zig-waf is pre-alpha. Blocking mode makes it a failure path for every request.");if(!h)o.push("Oversized bodies are passed through uninspected, so padding a request bypasses every rule.");if(e.bypassPaths?.length)o.push(`${e.bypassPaths.length} path(s) bypass inspection entirely.`);let i=["# Managed by ts-cloud. Edits are overwritten on the next deploy.",`# Mode: ${t}. Paranoia level: ${s}.`,""];if(t==="off")return i.push("SecRuleEngine Off",""),{config:`${i.join(`
|
|
2
2
|
`)}
|
|
3
|
-
`,unmappedRateLimits:[],warnings:o,mode:t};i.push(`SecRuleEngine ${t==="blocking"?"On":"DetectionOnly"}`,"SecRequestBodyAccess On","SecResponseBodyAccess Off",`SecRequestBodyLimit ${u}`,`SecRequestBodyNoFilesLimit ${Math.min(u,131072)}`,`SecRequestBodyLimitAction ${h?"Reject":"ProcessPartial"}`,"SecRequestBodyInMemoryLimit 131072",`SecAuditEngine ${t==="blocking"?"RelevantOnly":"On"}`,"SecAuditLogParts ABIJDEFHZ",`SecAuditLog ${
|
|
3
|
+
`,unmappedRateLimits:[],warnings:o,mode:t};i.push(`SecRuleEngine ${t==="blocking"?"On":"DetectionOnly"}`,"SecRequestBodyAccess On","SecResponseBodyAccess Off",`SecRequestBodyLimit ${u}`,`SecRequestBodyNoFilesLimit ${Math.min(u,131072)}`,`SecRequestBodyLimitAction ${h?"Reject":"ProcessPartial"}`,"SecRequestBodyInMemoryLimit 131072",`SecAuditEngine ${t==="blocking"?"RelevantOnly":"On"}`,"SecAuditLogParts ABIJDEFHZ",`SecAuditLog ${oe(e.auditLogPath??l.auditLogPath)}`,"SecAuditLogType Serial",`SecDefaultAction "phase:1,log,auditlog,${t==="blocking"?`deny,status:${e.blockStatus??l.blockStatus}`:"pass"}"`,"","# CRS anomaly scoring setup.",`SecAction "id:900000,phase:1,pass,nolog,t:none,setvar:tx.paranoia_level=${s}"`,`SecAction "id:900001,phase:1,pass,nolog,t:none,setvar:tx.inbound_anomaly_score_threshold=${n}"`,`SecAction "id:900002,phase:1,pass,nolog,t:none,setvar:tx.outbound_anomaly_score_threshold=${c}"`,'SecAction "id:900003,phase:1,pass,nolog,t:none,setvar:tx.critical_anomaly_score=5,setvar:tx.error_anomaly_score=4,setvar:tx.warning_anomaly_score=3,setvar:tx.notice_anomaly_score=2"','SecAction "id:900004,phase:1,pass,nolog,t:none,setvar:tx.anomaly_score=0"',"");let g=d.bypassBase;for(let a of e.bypassPaths??[]){let y=eo(a);if(!bi(y)){o.push(`Bypass path "${a}" was dropped: it compiles to an unsafe regular expression.`);continue}i.push(`# Inspection bypass for ${oe(a)}. Every bypass is an unguarded route.`,`SecRule REQUEST_URI "@rx ${oe(y)}" "id:${g},phase:1,pass,nolog,ctl:ruleEngine=Off"`,""),g++}let m=d.exclusionBase;for(let a of e.exclusions??[]){if(!Number.isInteger(a.ruleId)||a.ruleId<=0){o.push(`Exclusion with rule id "${a.ruleId}" was dropped: the id is not a positive integer.`);continue}if(i.push(`# ${oe(a.reason)}`),a.pathPattern){if(!bi(a.pathPattern)){o.push(`Exclusion for rule ${a.ruleId} was dropped: its path pattern is unsafe.`);continue}i.push(`SecRule REQUEST_URI "@rx ${oe(a.pathPattern)}" "id:${m},phase:1,pass,nolog,ctl:ruleRemoveById=${a.ruleId}"`),m++}else i.push(`SecRuleRemoveById ${a.ruleId}`);i.push("")}let p=b(r,d.rateLimitBase);if(p.lines.length>0)i.push("# Rate-limit route markers. SecLang has no counters, so the tag is set","# here and the counting stays in the ts-cloud limiter.",...p.lines);let f=d.customBase;for(let a of e.customRules??[])i.push(`# Operator-supplied rule ${f}.`,a.trim(),""),f++;if(t==="blocking")i.push("# Blocking decision: one rule, at the end, on the accumulated score.",`SecRule TX:ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" "id:949110,phase:2,deny,status:${e.blockStatus??l.blockStatus},log,msg:'Inbound anomaly score exceeded (total: %{tx.anomaly_score})'"`,"");return{config:`${i.join(`
|
|
4
4
|
`)}
|
|
5
|
-
`,unmappedRateLimits:p.unmapped,warnings:o,mode:t}}function
|
|
5
|
+
`,unmappedRateLimits:p.unmapped,warnings:o,mode:t}}function Ci(e={},r=[],t={}){let o=t.binary??"/usr/local/bin/zig-waf",s=t.configPath??"/etc/ts-cloud/waf.conf",n=Xc(e,r);return`#!/usr/bin/env bash
|
|
6
6
|
# Managed by ts-cloud. Installs the zig-waf ruleset.
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
|
|
@@ -33,5 +33,5 @@ fi
|
|
|
33
33
|
|
|
34
34
|
mv "${s}.new" "${s}"
|
|
35
35
|
echo "ts-cloud: WAF config installed (mode: ${n.mode})"
|
|
36
|
-
`}function
|
|
37
|
-
export{
|
|
36
|
+
`}function sp(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{oe,bi,eo,Xc,Ci,sp};
|