@stacksjs/ts-cloud 0.2.17 → 0.2.19

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.
Files changed (3) hide show
  1. package/dist/bin/cli.js +151 -151
  2. package/dist/index.js +15 -10
  3. package/package.json +3 -3
package/dist/bin/cli.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
  import{createRequire as BU}from"node:module";var FU=Object.defineProperty;var AU=($)=>$;function KU($,J){this[$]=AU.bind(null,J)}var Z1=($,J)=>{for(var Y in J)FU($,Y,{get:J[Y],enumerable:!0,configurable:!0,set:KU.bind(J,Y)})};var S0=($,J)=>()=>($&&(J=$($=0)),J);var e=BU(import.meta.url);class MJ{customEntities={};useHtmlEntities;constructor($=!1){this.useHtmlEntities=$}addEntity($,J){this.customEntities[$]=J}decodeEntities($){let J=$.indexOf("&");if(J===-1)return $;let Y=$.length,Q="",Z=0;while(J!==-1&&J<Y){if(J>Z)Q+=$.substring(Z,J);let U=$.indexOf(";",J+1);if(U===-1||U-J>32){Q+="&",Z=J+1,J=$.indexOf("&",Z);continue}let W=$.substring(J+1,U);if(W.charCodeAt(0)===35){let z=W.length,G=0,H=!1;if(z>2&&(W.charCodeAt(1)===120||W.charCodeAt(1)===88)){H=!0;for(let A=2;A<z;A++){let K=W.charCodeAt(A);if(K>=48&&K<=57)G=G<<4|K-48;else if(K>=65&&K<=70)G=G<<4|K-55;else if(K>=97&&K<=102)G=G<<4|K-87;else{H=!1;break}}}else if(z>1){H=!0;for(let A=1;A<z;A++){let K=W.charCodeAt(A);if(K>=48&&K<=57)G=G*10+(K-48);else{H=!1;break}}}if(H)Q+=String.fromCodePoint(G);else Q+=$.substring(J,U+1)}else{let z=this.customEntities[W];if(z===void 0){let G=W.length;if(G>=2&&G<=4){let H=W.charCodeAt(0);if(H===108&&G===2&&W.charCodeAt(1)===116)z="<";else if(H===103&&G===2&&W.charCodeAt(1)===116)z=">";else if(H===97&&G===3&&W.charCodeAt(1)===109&&W.charCodeAt(2)===112)z="&";else if(H===113&&G===4)z=W==="quot"?'"':void 0;else if(H===97&&G===4)z=W==="apos"?"'":void 0}if(z===void 0)z=EW[W]??(this.useHtmlEntities?wW[W]:void 0)}if(z!==void 0)Q+=z;else Q+=$.substring(J,U+1)}Z=U+1,J=$.indexOf("&",Z)}if(Z<Y)Q+=$.substring(Z);return Q}}function U1($){return $===32||$===9||$===10||$===13}function W8($){return $>=65&&$<=90||$>=97&&$<=122||$===95||$===58||$>=192&&$<=214||$>=216&&$<=246||$>=248&&$<=767||$>=880&&$<=893||$>=895&&$<=8191||$>=8204&&$<=8205||$>=8304&&$<=8591||$>=11264&&$<=12271||$>=12289&&$<=55295||$>=63744&&$<=64975||$>=65008&&$<=65533}function TJ($){return W8($)||$===45||$===46||$>=48&&$<=57||$===183||$>=768&&$<=879||$>=8255&&$<=8256}function VJ($,J){return $.charCodeAt(J)===91&&$.charCodeAt(J+1)===67&&$.charCodeAt(J+2)===68&&$.charCodeAt(J+3)===65&&$.charCodeAt(J+4)===84&&$.charCodeAt(J+5)===65&&$.charCodeAt(J+6)===91}function LJ($,J){let Y=$.charCodeAt(J),Q=$.charCodeAt(J+1),Z=$.charCodeAt(J+2),U=$.charCodeAt(J+3),W=$.charCodeAt(J+4),z=$.charCodeAt(J+5),G=$.charCodeAt(J+6);return(Y===68||Y===100)&&(Q===79||Q===111)&&(Z===67||Z===99)&&(U===84||U===116)&&(W===89||W===121)&&(z===80||z===112)&&(G===69||G===101)}function RW($,J,Y){if(J>=Y||!W8($.charCodeAt(J)))return J;J++;while(J<Y&&TJ($.charCodeAt(J)))J++;return J}class z8{options;entityDecoder;unpairedSet;exactStopNodes;wildcardStopSuffixes;needsJPath;_ignoreAttributes=!0;_textNodeName="#text";_commentPropName=!1;_cdataPropName=!1;_piPropName=!1;_alwaysCreateTextNode=!1;_trimValues=!0;_processEntities=!0;_parseTagValue=!0;_parseAttributeValue=!1;_removeNSPrefix=!1;_attrPrefix="@_";_attrsGroupName=!1;_ignorePiTags=!1;_ignoreDeclaration=!1;constructor($){this.options={...VW,...$},this.entityDecoder=new MJ(this.options.htmlEntities),this.unpairedSet=new Set(this.options.unpairedTags),this.exactStopNodes=new Set,this.wildcardStopSuffixes=[];for(let J of this.options.stopNodes)if(J.startsWith("*."))this.wildcardStopSuffixes.push(J.substring(2));else this.exactStopNodes.add(J);this._ignoreAttributes=this.options.ignoreAttributes,this._textNodeName=this.options.textNodeName,this._commentPropName=this.options.commentPropName,this._cdataPropName=this.options.cdataPropName,this._piPropName=this.options.piPropName,this._alwaysCreateTextNode=this.options.alwaysCreateTextNode,this._trimValues=this.options.trimValues,this._processEntities=this.options.processEntities,this._parseTagValue=this.options.parseTagValue,this._parseAttributeValue=this.options.parseAttributeValue,this._removeNSPrefix=this.options.removeNSPrefix,this._attrPrefix=this.options.attributeNamePrefix,this._attrsGroupName=this.options.attributesGroupName,this._ignorePiTags=this.options.ignorePiTags,this._ignoreDeclaration=this.options.ignoreDeclaration,this.needsJPath=this.options.stopNodes.length>0||this.options.isArray!==void 0||this.options.updateTag!==void 0||this.options.tagValueProcessor!==void 0||this.options.attributeValueProcessor!==void 0}addEntity($,J){this.entityDecoder.addEntity($,J)}parse($){if($ instanceof Uint8Array)$=new TextDecoder().decode($);let J=$;if(this.options.preserveOrder)return this.parseOrdered(J);return this.parseUnordered(J)}parseUnordered($){let J={},Y=$.length,Q=0;if(Y>0&&$.charCodeAt(0)===65279)Q=1;return Q=this.parseChildren($,Q,Y,J,"",[]),J}parseOrdered($){let J=$.length,Y=0;if(J>0&&$.charCodeAt(0)===65279)Y=1;let Q=[];return this.parseChildrenOrdered($,Y,J,Q,""),Q}readTagName($,J,Y){return RW($,J,Y)}extractTagName($,J,Y){let Q=$.substring(J,Y);if(this._removeNSPrefix){let Z=Q.indexOf(":");if(Z!==-1)Q=Q.substring(Z+1)}if(this.options.transformTagName)Q=this.options.transformTagName(Q);return Q}parseAttributes($,J,Y,Q,Z){let U=0,W=this._removeNSPrefix,z=this.options.transformAttributeName,G=this._trimValues,H=this._processEntities,A=this.options.attributeValueProcessor;while(J<Y){let K=$.charCodeAt(J);while(K===32||K===9||K===10||K===13){if(J++,J>=Y)break;K=$.charCodeAt(J)}if(J>=Y)break;if(K===62||K===47)break;let B=J;if(!W8(K))break;J++;while(J<Y&&TJ($.charCodeAt(J)))J++;let j=$.substring(B,J);if(W){let X=j.indexOf(":");if(X!==-1)j=j.substring(X+1)}if(z)j=z(j);while(J<Y&&U1($.charCodeAt(J)))J++;if(J<Y&&$.charCodeAt(J)===61){J++;while(J<Y&&U1($.charCodeAt(J)))J++;if(J>=Y)break;let X=$.charCodeAt(J);if(X===34||X===39){J++;let O=J;while(J<Y&&$.charCodeAt(J)!==X)J++;let _=$.substring(O,J);if(G&&_.length>0){let w=_.charCodeAt(0),E=_.charCodeAt(_.length-1);if(w<=32||E<=32)_=_.trim()}if(H)_=this.entityDecoder.decodeEntities(_);if(A)_=A(j,_,Q)??_;if(Z[j]=_,U++,J<Y)J++}}else Z[j]="true",U++}return U>0?-J-1:J}processTagValue($,J,Y,Q,Z){if(this._trimValues){let U=$.length;if(U>0){let W=$.charCodeAt(0),z=$.charCodeAt(U-1);if(W<=32||z<=32)$=$.trim()}}if(this._processEntities)$=this.entityDecoder.decodeEntities($);if(this.options.tagValueProcessor){let U=this.options.tagValueProcessor(J,$,Y,Q,Z);if(U!==void 0)$=U}if(!$)return $;if(this._parseTagValue)return this.parseValue($);return $}parseValue($){if($==="true")return!0;if($==="false")return!1;if(!$)return $;let J=$.charCodeAt(0);if(!(J>=48&&J<=57||J===43||J===45||J===46))return $;let Q=this.options.numberParseOptions;if(Q.skipLike?.test($))return $;if(Q.hex&&J===48&&LW.test($))return Number.parseInt($,16);if($.length>1&&J===48&&$.charCodeAt(1)!==46){if(Q.leadingZeros)return $}if(Q.scientific&&MW.test($)){let Z=Number($);if(!Number.isNaN(Z))return Z}if(TW.test($)){let Z=Number($);if(!Number.isNaN(Z))return Z}return $}parseAttributeValue($){if(!this._parseAttributeValue)return $;return this.parseValue($)}isStopNode($){if(this.exactStopNodes.has($))return!0;for(let J of this.wildcardStopSuffixes)if($.endsWith(`.${J}`)||$===J)return!0;return!1}readStopNodeContent($,J,Y,Q){let Z=`</${Q}`,U=$.indexOf(Z,J);if(U===-1)return{content:$.substring(J),pos:Y};let W=$.substring(J,U),z=U+Z.length;while(z<Y&&$.charCodeAt(z)!==62)z++;if(z<Y)z++;return{content:W,pos:z}}addToObj($,J,Y,Q,Z,U){let W=$[J];if(W!==void 0)if(!Array.isArray(W))$[J]=[W,Y];else W.push(Y);else if(this.options.isArray?.(J,Q,Z,U))$[J]=[Y];else $[J]=Y}flushText($,J,Y,Q){if(!$&&!J)return;let Z=this._textNodeName;if(J){let U=$;if(U&&this._processEntities)U=this.entityDecoder.decodeEntities(U);let W=J+U;if(this._trimValues&&W.length>0){let z=W.charCodeAt(0),G=W.charCodeAt(W.length-1);if(z<=32||G<=32)W=W.trim()}if(this.options.tagValueProcessor){let z=this.options.tagValueProcessor(Z,W,Y,!1,!0);if(z!==void 0)W=z}if(W){let z=this._parseTagValue?this.parseValue(W):W;if(z!==void 0&&z!=="")this.addToObj(Q,Z,z,Y,!0,!1)}}else{let U=this.processTagValue($,Z,Y,!1,!0);if(U!==void 0&&U!=="")this.addToObj(Q,Z,U,Y,!0,!1)}}parseChildren($,J,Y,Q,Z,U){let W="",z="",G=this.needsJPath;while(J<Y){if($.charCodeAt(J)!==60){let w=J;J++;while(J<Y&&$.charCodeAt(J)!==60)J++;if(!W)W=$.substring(w,J);else W+=$.substring(w,J);continue}if(J+1>=Y)break;let A=$.charCodeAt(J+1);if(A===33&&J+3<Y&&$.charCodeAt(J+2)===45&&$.charCodeAt(J+3)===45){if(W||z)this.flushText(W,z,Z,Q),W="",z="";J+=4;let w=$.indexOf("-->",J);if(w===-1){J=Y;break}if(this._commentPropName){let E=$.substring(J,w);this.addToObj(Q,this._commentPropName,E,Z,!0,!1)}J=w+3;continue}if(A===33&&J+8<Y&&VJ($,J+2)){J+=9;let w=$.indexOf("]]>",J);if(w===-1){J=Y;break}let E=$.substring(J,w);if(this._cdataPropName)this.flushText(W,z,Z,Q),W="",z="",this.addToObj(Q,this._cdataPropName,E,Z,!0,!1);else{if(W){let M=W;if(this._processEntities)M=this.entityDecoder.decodeEntities(M);z+=M,W=""}z+=E}J=w+3;continue}if(A===33&&J+9<Y&&LJ($,J+2)){J+=9;let w=1;while(J<Y&&w>0){let E=$.charCodeAt(J);if(E===60)w++;else if(E===62)w--;J++}continue}if(A===63){J+=2;let w=J;while(J<Y&&!U1($.charCodeAt(J))&&$.charCodeAt(J)!==63)J++;let E=$.substring(w,J),M=$.indexOf("?>",J);if(M===-1){J=Y;break}let T=$.substring(J,M).trim();if(E==="xml"){if(!this._ignoreDeclaration&&this._piPropName){let D=this.parsePiAttributes(T);this.addToObj(Q,this._piPropName,{[E]:D},Z,!0,!1)}}else if(!this._ignorePiTags&&this._piPropName)this.addToObj(Q,this._piPropName,{[E]:T},Z,!0,!1);J=M+2;continue}if(A===47){if(W||z)this.flushText(W,z,Z,Q),W="",z="";J+=2;let w=J,E=this.readTagName($,J,Y),M=this.extractTagName($,w,E);J=E;while(J<Y&&U1($.charCodeAt(J)))J++;if(J<Y&&$.charCodeAt(J)===62)J++;if(U.length>0&&U[U.length-1]===M){U.pop();continue}return J}if(W||z)this.flushText(W,z,Z,Q),W="",z="";J++;let K=J,B=this.readTagName($,J,Y),j=this.extractTagName($,K,B);if(!j){J=B+1;continue}J=B;let X=G?Z?`${Z}.${j}`:j:"",O={},_=!1;if(!this._ignoreAttributes){let w=this.parseAttributes($,J,Y,X,O);if(w<0)J=-w-1,_=!0;else J=w}else while(J<Y){let w=$.charCodeAt(J);if(w===62||w===47)break;if(w===34||w===39){J++;while(J<Y&&$.charCodeAt(J)!==w)J++}J++}if(this.options.updateTag){if(this.options.updateTag(j,X,O)===!1){while(J<Y&&U1($.charCodeAt(J)))J++;if(J<Y&&$.charCodeAt(J)===47)J+=2;else if(J<Y&&$.charCodeAt(J)===62){J++;let E=`</${j}>`,M=$.indexOf(E,J);if(M!==-1)J=M+E.length}continue}}while(J<Y&&U1($.charCodeAt(J)))J++;if(J<Y&&$.charCodeAt(J)===47){if(J+=2,_||this._alwaysCreateTextNode){let w={};if(_)this.applyAttributes(w,O,X);if(this._alwaysCreateTextNode)w[this._textNodeName]="";this.addToObj(Q,j,w,X,!0,!1)}else this.addToObj(Q,j,"",X,!0,!1);continue}if(J<Y&&$.charCodeAt(J)===62){if(J++,this.unpairedSet.has(j)){if(_){let T={};this.applyAttributes(T,O,X),this.addToObj(Q,j,T,X,!0,!1)}else this.addToObj(Q,j,"",X,!0,!1);U.push(j);continue}if(this.exactStopNodes.size>0||this.wildcardStopSuffixes.length>0){if(this.isStopNode(X)){let T=this.readStopNodeContent($,J,Y,j),D={};if(_)this.applyAttributes(D,O,X);if(T.content)D[this._textNodeName]=T.content;this.addToObj(Q,j,D,X,!0,!1),J=T.pos;continue}}let w={};if(_)this.applyAttributes(w,O,X);J=this.parseChildren($,J,Y,w,X,U);let E=this._textNodeName,M=w[E];if(!_&&!this._alwaysCreateTextNode){let T=!0;for(let D in w)if(D!==E){T=!1;break}if(T){this.addToObj(Q,j,M!==void 0?M:"",X,!0,!1);continue}}this.addToObj(Q,j,w,X,!1,!1)}}if(W||z)this.flushText(W,z,Z,Q);return J}parseChildrenOrdered($,J,Y,Q,Z){let U="",W=this.needsJPath;while(J<Y){if($.charCodeAt(J)!==60){let _=J;J++;while(J<Y&&$.charCodeAt(J)!==60)J++;if(!U)U=$.substring(_,J);else U+=$.substring(_,J);continue}if(J+1>=Y)break;let G=$.charCodeAt(J+1);if(G===33&&J+3<Y&&$.charCodeAt(J+2)===45&&$.charCodeAt(J+3)===45){if(U){let w=this.processTagValue(U,this._textNodeName,Z,!1,!0);if(w!==void 0&&w!=="")Q.push({[this._textNodeName]:w});U=""}J+=4;let _=$.indexOf("-->",J);if(_===-1){J=Y;break}if(this._commentPropName)Q.push({[this._commentPropName]:[{[this._textNodeName]:$.substring(J,_)}]});J=_+3;continue}if(G===33&&J+8<Y&&VJ($,J+2)){J+=9;let _=$.indexOf("]]>",J);if(_===-1){J=Y;break}let w=$.substring(J,_);if(this._cdataPropName){if(U){let E=this.processTagValue(U,this._textNodeName,Z,!1,!0);if(E!==void 0&&E!=="")Q.push({[this._textNodeName]:E});U=""}Q.push({[this._cdataPropName]:[{[this._textNodeName]:w}]})}else U+=w;J=_+3;continue}if(G===33&&J+9<Y&&LJ($,J+2)){J+=9;let _=1;while(J<Y&&_>0){let w=$.charCodeAt(J);if(w===60)_++;else if(w===62)_--;J++}continue}if(G===63){J+=2;let _=$.indexOf("?>",J);if(_===-1){J=Y;break}J=_+2;continue}if(G===47){if(U){let w=this.processTagValue(U,this._textNodeName,Z,!1,!0);if(w!==void 0&&w!=="")Q.push({[this._textNodeName]:w});U=""}J+=2,J=this.readTagName($,J,Y);while(J<Y&&U1($.charCodeAt(J)))J++;if(J<Y&&$.charCodeAt(J)===62)J++;return J}if(U){let _=this.processTagValue(U,this._textNodeName,Z,!1,!0);if(_!==void 0&&_!=="")Q.push({[this._textNodeName]:_});U=""}J++;let H=J,A=this.readTagName($,J,Y),K=this.extractTagName($,H,A);if(!K){J=A+1;continue}J=A;let B=W?Z?`${Z}.${K}`:K:"",j={},X=!1;if(!this._ignoreAttributes){let _=this.parseAttributes($,J,Y,B,j);if(_<0)J=-_-1,X=!0;else J=_}else while(J<Y){let _=$.charCodeAt(J);if(_===62||_===47)break;if(_===34||_===39){J++;while(J<Y&&$.charCodeAt(J)!==_)J++}J++}while(J<Y&&U1($.charCodeAt(J)))J++;let O={[K]:[]};if(X){O[":@"]={};for(let w in j)O[":@"][this._attrPrefix+w]=this.parseAttributeValue(j[w])}if(J<Y&&$.charCodeAt(J)===47){J+=2,Q.push(O);continue}if(J<Y&&$.charCodeAt(J)===62)J++,J=this.parseChildrenOrdered($,J,Y,O[K],B),Q.push(O)}if(U){let z=this.processTagValue(U,this._textNodeName,Z,!1,!0);if(z!==void 0&&z!=="")Q.push({[this._textNodeName]:z})}return J}applyAttributes($,J,Y){let Q=this._attrPrefix;if(this._attrsGroupName){let Z={};for(let U in J)Z[Q+U]=this.parseAttributeValue(J[U]);$[this._attrsGroupName]=Z}else for(let Z in J)$[Q+Z]=this.parseAttributeValue(J[Z])}parsePiAttributes($){let J={},Y=0,Q=$.length;while(Y<Q){while(Y<Q&&U1($.charCodeAt(Y)))Y++;if(Y>=Q)break;let Z=Y;while(Y<Q&&!U1($.charCodeAt(Y))&&$.charCodeAt(Y)!==61)Y++;let U=$.substring(Z,Y);if(!U)break;while(Y<Q&&U1($.charCodeAt(Y)))Y++;if(Y<Q&&$.charCodeAt(Y)===61){Y++;while(Y<Q&&U1($.charCodeAt(Y)))Y++;if(Y<Q){let W=$.charCodeAt(Y);if(W===34||W===39){Y++;let z=Y;while(Y<Q&&$.charCodeAt(Y)!==W)Y++;if(J[U]=$.substring(z,Y),Y<Q)Y++}}}}return J}}var EW,wW,i2,VW,LW,MW,TW;var RJ=S0(()=>{EW={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"},wW={nbsp:" ",copy:"©",reg:"®",trade:"™",euro:"€",pound:"£",yen:"¥",cent:"¢",deg:"°",micro:"µ",middot:"·",bull:"•",hellip:"…",prime:"′",Prime:"″",laquo:"«",raquo:"»",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",ndash:"–",mdash:"—",iexcl:"¡",iquest:"¿",sect:"§",para:"¶",dagger:"†",Dagger:"‡",lsaquo:"‹",rsaquo:"›",oline:"‾",frasl:"⁄",ensp:" ",emsp:" ",thinsp:" ",zwnj:"‌",zwj:"‍",lrm:"‎",rlm:"‏",times:"×",divide:"÷",plusmn:"±",ne:"≠",le:"≤",ge:"≥",infin:"∞",fnof:"ƒ",Alpha:"Α",Beta:"Β",Gamma:"Γ",Delta:"Δ",Epsilon:"Ε",Zeta:"Ζ",Eta:"Η",Theta:"Θ",Iota:"Ι",Kappa:"Κ",Lambda:"Λ",Mu:"Μ",Nu:"Ν",Xi:"Ξ",Omicron:"Ο",Pi:"Π",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Υ",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lArr:"⇐",uArr:"⇑",rArr:"⇒",dArr:"⇓",hArr:"⇔",forall:"∀",part:"∂",exist:"∃",empty:"∅",nabla:"∇",isin:"∈",notin:"∉",ni:"∋",prod:"∏",sum:"∑",minus:"−",lowast:"∗",radic:"√",prop:"∝",ang:"∠",and:"∧",or:"∨",cap:"∩",cup:"∪",int:"∫",there4:"∴",sim:"∼",cong:"≅",asymp:"≈",equiv:"≡",sub:"⊂",sup:"⊃",nsub:"⊄",sube:"⊆",supe:"⊇",oplus:"⊕",otimes:"⊗",perp:"⊥",sdot:"⋅",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",lang:"〈",rang:"〉",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦",Agrave:"À",Aacute:"Á",Acirc:"Â",Atilde:"Ã",Auml:"Ä",Aring:"Å",AElig:"Æ",Ccedil:"Ç",Egrave:"È",Eacute:"É",Ecirc:"Ê",Euml:"Ë",Igrave:"Ì",Iacute:"Í",Icirc:"Î",Iuml:"Ï",ETH:"Ð",Ntilde:"Ñ",Ograve:"Ò",Oacute:"Ó",Ocirc:"Ô",Otilde:"Õ",Ouml:"Ö",Oslash:"Ø",Ugrave:"Ù",Uacute:"Ú",Ucirc:"Û",Uuml:"Ü",Yacute:"Ý",THORN:"Þ",szlig:"ß",agrave:"à",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"å",aelig:"æ",ccedil:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"í",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",circ:"ˆ",tilde:"˜"};i2=[];i2[38]="&amp;";i2[60]="&lt;";i2[62]="&gt;";i2[34]="&quot;";i2[39]="&apos;";VW={attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,removeNSPrefix:!1,allowBooleanAttributes:!1,alwaysCreateTextNode:!1,trimValues:!0,parseTagValue:!0,parseAttributeValue:!1,processEntities:!0,htmlEntities:!1,commentPropName:!1,cdataPropName:!1,piPropName:!1,preserveOrder:!1,stopNodes:[],unpairedTags:[],isArray:void 0,tagValueProcessor:void 0,attributeValueProcessor:void 0,updateTag:void 0,numberParseOptions:{hex:!0,leadingZeros:!0,scientific:!0},ignorePiTags:!1,transformAttributeName:void 0,transformTagName:void 0,ignoreDeclaration:!1};LW=/^0x[\da-fA-F]+$/,MW=/^[+-]?\d+(\.\d+)?[eE][+-]?\d+$/,TW=/^[+-]?(\d+\.?\d*|\.\d+)$/});var F2={};Z1(F2,{resolveS3Endpoint:()=>G8,detectCredentialSource:()=>H8,buildQueryParams:()=>g0,AWSClient:()=>t});import*as a1 from"node:crypto";import{existsSync as DJ,readFileSync as DW}from"node:fs";import{homedir as NJ}from"node:os";import{join as SJ}from"node:path";function G8($){let J=$.endpoint||`s3.${$.region}.amazonaws.com`;if(!$.bucket)return{host:J,path:$.path};if($.forcePathStyle){let Y=$.path==="/"?`/${$.bucket}`:`/${$.bucket}${$.path}`;return{host:J,path:Y}}return{host:`${$.bucket}.${J}`,path:$.path}}class t{credentials;config;cache;xmlParser;constructor($,J){this.credentials=$||this.loadCredentials(),this.config={maxRetries:3,retryDelay:1000,cacheEnabled:!0,defaultCacheTTL:60000,...J},this.cache=new Map,this.xmlParser=new z8({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}loadCredentials(){let $=process.env.AWS_ACCESS_KEY_ID,J=process.env.AWS_SECRET_ACCESS_KEY,Y=process.env.AWS_SESSION_TOKEN;if($&&J)return{accessKeyId:$,secretAccessKey:J,sessionToken:Y};let Q=this.loadCredentialsFromFile();if(Q)return Q;return{accessKeyId:"",secretAccessKey:""}}loadCredentialsFromFile(){let $=process.env.AWS_PROFILE||"default",J=process.env.AWS_SHARED_CREDENTIALS_FILE||SJ(NJ(),".aws","credentials");if(!DJ(J))return null;try{let Y=DW(J,"utf-8"),Q=this.parseCredentialsFile(Y,$);if(Q.accessKeyId&&Q.secretAccessKey)return Q}catch{}return null}parseCredentialsFile($,J){let Y=$.split(`
4
- `),Q="",Z="",U="",W;for(let z of Y){let G=z.trim();if(!G||G.startsWith("#"))continue;let H=G.match(/^\[([^\]]+)\]$/);if(H){Q=H[1];continue}if(Q===J){let[A,...K]=G.split("="),B=K.join("=").trim();if(A.trim()==="aws_access_key_id")Z=B;else if(A.trim()==="aws_secret_access_key")U=B;else if(A.trim()==="aws_session_token")W=B}}return{accessKeyId:Z,secretAccessKey:U,sessionToken:W}}ec2CredentialsCache;async getCredentials(){let $=process.env.AWS_ACCESS_KEY_ID,J=process.env.AWS_SECRET_ACCESS_KEY;if($&&J)return{accessKeyId:$,secretAccessKey:J,sessionToken:process.env.AWS_SESSION_TOKEN};let Y=this.loadCredentialsFromFile();if(Y)return Y;if(this.ec2CredentialsCache){let Q=Date.now();if(this.ec2CredentialsCache.expiration>Q+300000)return this.ec2CredentialsCache.credentials}try{let Z=await(await fetch("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}})).text(),W=await(await fetch("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":Z}})).text(),G=await(await fetch(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${W}`,{headers:{"X-aws-ec2-metadata-token":Z}})).json(),H={accessKeyId:G.AccessKeyId,secretAccessKey:G.SecretAccessKey,sessionToken:G.Token};return this.ec2CredentialsCache={credentials:H,expiration:new Date(G.Expiration).getTime()},H}catch(Q){throw Error("AWS credentials not found. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or run on an EC2 instance with an IAM role.")}}async request($){if($.method==="GET"&&this.config.cacheEnabled&&$.cacheKey){let Q=this.getFromCache($.cacheKey);if(Q!==null)return Q}let J=$.retries??this.config.maxRetries??3,Y=null;for(let Q=0;Q<=J;Q++)try{let Z=await this.makeRequest($);if($.method==="GET"&&this.config.cacheEnabled&&$.cacheKey)this.setInCache($.cacheKey,Z,$.cacheTTL??this.config.defaultCacheTTL??60000);return Z}catch(Z){if(Y=Z,!this.shouldRetry(Z))throw Z;if(Q===J)throw Z;let W=this.calculateRetryDelay(Q);await this.sleep(W)}throw Y||Error("Request failed after retries")}async makeRequest($){let J=$.credentials||(this.credentials?.accessKeyId?this.credentials:await this.getCredentials());if(!J||!J.accessKeyId||!J.secretAccessKey)throw Error("AWS credentials not provided");let Y=this.buildUrl($),Q=this.signRequest($,J),Z=await fetch(Y,{method:$.method,headers:Q,body:$.body}),U=await Z.text();if(!Z.ok)throw this.parseError(U,Z.status,Z.headers);if(!U||U.trim()===""){if($.returnHeaders)return{body:null,headers:this.headersToObject(Z.headers)};return null}if($.rawResponse){if($.returnHeaders)return{body:U,headers:this.headersToObject(Z.headers)};return U}let W;if(U.startsWith("<"))W=this.parseXmlResponse(U);else try{W=JSON.parse(U)}catch{W=U}if($.returnHeaders)return{body:W,headers:this.headersToObject(Z.headers)};return W}headersToObject($){let J={};return $.forEach((Y,Q)=>{J[Q]=Y}),J}buildUrl($){let{service:J,region:Y,queryParams:Q}=$,{path:Z}=$,U;if(J==="s3"){let z=G8({region:Y,path:Z,bucket:$.bucket,endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle});U=z.host,Z=z.path}else if(J==="cloudfront")U="cloudfront.amazonaws.com";else if(J==="iam")U="iam.amazonaws.com";else if(J==="route53")U="route53.amazonaws.com";else if(J==="route53domains")U="route53domains.us-east-1.amazonaws.com";else if(J==="ecr")U=`api.ecr.${Y}.amazonaws.com`;else if(J==="ses")U=`email.${Y}.amazonaws.com`;else U=`${J}.${Y}.amazonaws.com`;let W=`https://${U}${Z}`;if(Q&&Object.keys(Q).length>0){let z=Object.keys(Q).map((G)=>`${this.uriEncode(G)}=${this.uriEncode(Q[G])}`).join("&");W+=`?${z}`}return W}signRequest($,J){let{service:Y,region:Q,method:Z,queryParams:U,body:W}=$,{path:z}=$,G=new Date,H=this.getAmzDate(G),A=this.getDateStamp(G),K;if(Y==="s3"){let I=G8({region:Q,path:z,bucket:$.bucket,endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle});K=I.host,z=I.path}else if(Y==="cloudfront")K="cloudfront.amazonaws.com";else if(Y==="iam")K="iam.amazonaws.com";else if(Y==="route53")K="route53.amazonaws.com";else if(Y==="route53domains")K="route53domains.us-east-1.amazonaws.com";else if(Y==="ecr")K=`api.ecr.${Q}.amazonaws.com`;else if(Y==="ses")K=`email.${Q}.amazonaws.com`;else K=`${Y}.${Q}.amazonaws.com`;let B={host:K,"x-amz-date":H,...$.headers||{}};if(J.sessionToken)B["x-amz-security-token"]=J.sessionToken;if(W){if(!Object.keys(B).some((f)=>f.toLowerCase()==="content-type"))B["content-type"]="application/x-www-form-urlencoded";B["content-length"]=Buffer.byteLength(W).toString()}let j=this.sha256(W||"");B["x-amz-content-sha256"]=j;let X=z,O=U?Object.keys(U).sort().map((I)=>`${this.uriEncode(I)}=${this.uriEncode(U[I])}`).join("&"):"",_=Object.keys(B).sort((I,f)=>I.toLowerCase().localeCompare(f.toLowerCase())),w=_.map((I)=>`${I.toLowerCase()}:${B[I].trim()}
5
- `).join(""),E=_.map((I)=>I.toLowerCase()).join(";"),M=[Z,X,O,w,E,j].join(`
4
+ `),Q="",Z="",U="",W;for(let z of Y){let G=z.trim();if(!G||G.startsWith("#"))continue;let H=G.match(/^\[([^\]]+)\]$/);if(H){Q=H[1];continue}if(Q===J){let[A,...K]=G.split("="),B=K.join("=").trim();if(A.trim()==="aws_access_key_id")Z=B;else if(A.trim()==="aws_secret_access_key")U=B;else if(A.trim()==="aws_session_token")W=B}}return{accessKeyId:Z,secretAccessKey:U,sessionToken:W}}ec2CredentialsCache;async getCredentials(){let $=process.env.AWS_ACCESS_KEY_ID,J=process.env.AWS_SECRET_ACCESS_KEY;if($&&J)return{accessKeyId:$,secretAccessKey:J,sessionToken:process.env.AWS_SESSION_TOKEN};let Y=this.loadCredentialsFromFile();if(Y)return Y;if(this.ec2CredentialsCache){let Q=Date.now();if(this.ec2CredentialsCache.expiration>Q+300000)return this.ec2CredentialsCache.credentials}try{let Z=await(await fetch("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}})).text(),W=await(await fetch("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":Z}})).text(),G=await(await fetch(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${W}`,{headers:{"X-aws-ec2-metadata-token":Z}})).json(),H={accessKeyId:G.AccessKeyId,secretAccessKey:G.SecretAccessKey,sessionToken:G.Token};return this.ec2CredentialsCache={credentials:H,expiration:new Date(G.Expiration).getTime()},H}catch(Q){throw Error("AWS credentials not found. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or run on an EC2 instance with an IAM role.")}}async request($){if($.method==="GET"&&this.config.cacheEnabled&&$.cacheKey){let Q=this.getFromCache($.cacheKey);if(Q!==null)return Q}let J=$.retries??this.config.maxRetries??3,Y=null;for(let Q=0;Q<=J;Q++)try{let Z=await this.makeRequest($);if($.method==="GET"&&this.config.cacheEnabled&&$.cacheKey)this.setInCache($.cacheKey,Z,$.cacheTTL??this.config.defaultCacheTTL??60000);return Z}catch(Z){if(Y=Z,!this.shouldRetry(Z))throw Z;if(Q===J)throw Z;let W=this.calculateRetryDelay(Q);await this.sleep(W)}throw Y||Error("Request failed after retries")}async makeRequest($){let J=$.credentials||(this.credentials?.accessKeyId?this.credentials:await this.getCredentials());if(!J||!J.accessKeyId||!J.secretAccessKey)throw Error("AWS credentials not provided");let Y=this.buildUrl($),Q=this.signRequest($,J),Z=await fetch(Y,{method:$.method,headers:Q,body:$.body}),U=await Z.text();if(!Z.ok)throw this.parseError(U,Z.status,Z.headers);if(!U||U.trim()===""){if($.returnHeaders)return{body:null,headers:this.headersToObject(Z.headers)};return null}if($.rawResponse){if($.returnHeaders)return{body:U,headers:this.headersToObject(Z.headers)};return U}let W;if(U.startsWith("<"))W=this.parseXmlResponse(U);else try{W=JSON.parse(U)}catch{W=U}if($.returnHeaders)return{body:W,headers:this.headersToObject(Z.headers)};return W}headersToObject($){let J={};return $.forEach((Y,Q)=>{J[Q]=Y}),J}buildUrl($){let{service:J,region:Y,queryParams:Q}=$,{path:Z}=$,U;if(J==="s3"){let z=G8({region:Y,path:Z,bucket:$.bucket,endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle});U=z.host,Z=z.path}else if(J==="cloudfront")U="cloudfront.amazonaws.com";else if(J==="iam")U="iam.amazonaws.com";else if(J==="route53")U="route53.amazonaws.com";else if(J==="route53domains")U="route53domains.us-east-1.amazonaws.com";else if(J==="ecr")U=`api.ecr.${Y}.amazonaws.com`;else if(J==="ses")U=`email.${Y}.amazonaws.com`;else U=`${J}.${Y}.amazonaws.com`;let W=`https://${U}${Z}`;if(Q&&Object.keys(Q).length>0){let z=Object.keys(Q).map((G)=>`${this.uriEncode(G)}=${this.uriEncode(Q[G])}`).join("&");W+=`?${z}`}return W}signRequest($,J){let{service:Y,region:Q,method:Z,queryParams:U,body:W}=$,{path:z}=$,G=new Date,H=this.getAmzDate(G),A=this.getDateStamp(G),K;if(Y==="s3"){let k=G8({region:Q,path:z,bucket:$.bucket,endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle});K=k.host,z=k.path}else if(Y==="cloudfront")K="cloudfront.amazonaws.com";else if(Y==="iam")K="iam.amazonaws.com";else if(Y==="route53")K="route53.amazonaws.com";else if(Y==="route53domains")K="route53domains.us-east-1.amazonaws.com";else if(Y==="ecr")K=`api.ecr.${Q}.amazonaws.com`;else if(Y==="ses")K=`email.${Q}.amazonaws.com`;else K=`${Y}.${Q}.amazonaws.com`;let B={host:K,"x-amz-date":H,...$.headers||{}};if(J.sessionToken)B["x-amz-security-token"]=J.sessionToken;if(W){if(!Object.keys(B).some((y)=>y.toLowerCase()==="content-type"))B["content-type"]="application/x-www-form-urlencoded";B["content-length"]=Buffer.byteLength(W).toString()}let j=this.sha256(W||"");B["x-amz-content-sha256"]=j;let X=z,O=U?Object.keys(U).sort().map((k)=>`${this.uriEncode(k)}=${this.uriEncode(U[k])}`).join("&"):"",_=Object.keys(B).sort((k,y)=>k.toLowerCase().localeCompare(y.toLowerCase())),w=_.map((k)=>`${k.toLowerCase()}:${B[k].trim()}
5
+ `).join(""),E=_.map((k)=>k.toLowerCase()).join(";"),M=[Z,X,O,w,E,j].join(`
6
6
  `),T="AWS4-HMAC-SHA256",D=Y;if(Y==="email")D="ses";let N=`${A}/${Q}/${D}/aws4_request`,x=[T,H,N,this.sha256(M)].join(`
7
- `),h=this.getSignatureKey(J.secretAccessKey,A,Q,D),k=this.hmac(h,x),b=`${T} Credential=${J.accessKeyId}/${N}, SignedHeaders=${E}, Signature=${k}`;return{...B,Authorization:b}}getAmzDate($){return $.toISOString().replace(/[:-]|\.\d{3}/g,"")}getDateStamp($){return $.toISOString().slice(0,10).replace(/-/g,"")}uriEncode($){return encodeURIComponent($).replace(/[!'()*]/g,(J)=>`%${J.charCodeAt(0).toString(16).toUpperCase()}`)}sha256($){return a1.createHash("sha256").update($,"utf8").digest("hex")}hmac($,J){return a1.createHmac("sha256",$).update(J,"utf8").digest("hex")}getSignatureKey($,J,Y,Q){let Z=a1.createHmac("sha256",`AWS4${$}`).update(J).digest(),U=a1.createHmac("sha256",Z).update(Y).digest(),W=a1.createHmac("sha256",U).update(Q).digest();return a1.createHmac("sha256",W).update("aws4_request").digest()}parseXmlResponse($){try{let J=this.xmlParser.parse($);if(J.ErrorResponse)throw this.createErrorFromXml(J.ErrorResponse.Error);let Y=Object.keys(J);if(Y.length===1)return J[Y[0]];return J}catch(J){if(J.code||J.statusCode)throw J;return{}}}parseError($,J,Y){let Q=Error();if(Q.statusCode=J,Q.requestId=Y.get("x-amzn-requestid")||Y.get("x-amz-request-id")||void 0,$.startsWith("<"))try{let Z=this.xmlParser.parse($);if(Z.ErrorResponse?.Error){let U=Z.ErrorResponse.Error;return Q.code=U.Code,Q.message=`AWS Error [${U.Code}]: ${U.Message||"Unknown error"}`,Q.type=U.Type,Q}if(Z.Error)return Q.code=Z.Error.Code,Q.message=`AWS Error [${Z.Error.Code}]: ${Z.Error.Message||"Unknown error"}`,Q}catch{}try{let Z=JSON.parse($);if(Z.__type||Z.code)return Q.code=Z.__type||Z.code,Q.message=`AWS Error [${Q.code}]: ${Z.message||Z.Message||"Unknown error"}`,Q}catch{}return Q.message=`AWS API Error (${J}): ${$}`,Q}createErrorFromXml($){let J=Error();return J.code=$.Code,J.message=`AWS Error [${$.Code}]: ${$.Message||"Unknown error"}`,J.type=$.Type,J}isRetryableError($){return["RequestTimeout","RequestTimeoutException","PriorRequestNotComplete","ConnectionError","ThrottlingException","Throttling","TooManyRequestsException","ProvisionedThroughputExceededException","RequestLimitExceeded","BandwidthLimitExceeded","SlowDown","ServiceUnavailable","ServiceUnavailableException","InternalError","InternalFailure","InternalServerError","InternalServiceException","TransientError","TransientFailure","IDPCommunicationErrorException","NetworkError","ConnectionRefusedException","EC2ThrottledException","503 Slow Down","500 InternalError"].includes($)}isRetryableStatusCode($){return $>=500||$===429}shouldRetry($){if($.name==="FetchError"||$.name==="TypeError"||$.code==="ECONNRESET")return!0;if($.code&&this.isRetryableError($.code))return!0;if($.statusCode&&this.isRetryableStatusCode($.statusCode))return!0;if($.statusCode&&$.statusCode>=400&&$.statusCode<500&&$.statusCode!==429)return!1;if($.statusCode)return!1;return!0}calculateRetryDelay($){let J=this.config.retryDelay??1000,Y=30000,Q=Math.min(J*2**$,30000),Z=Math.random()*0.3*Q;return Q+Z}sleep($){return new Promise((J)=>setTimeout(J,$))}getFromCache($){let J=this.cache.get($);if(!J)return null;if(Date.now()>J.expires)return this.cache.delete($),null;return J.data}setInCache($,J,Y){this.cache.set($,{data:J,expires:Date.now()+Y})}clearCache(){this.cache.clear()}clearExpiredCache(){let $=Date.now();for(let[J,Y]of this.cache.entries())if($>Y.expires)this.cache.delete(J)}}function g0($){let J={};for(let[Y,Q]of Object.entries($)){if(Q===void 0||Q===null)continue;if(Array.isArray(Q))Q.forEach((Z,U)=>{J[`${Y}.${U+1}`]=String(Z)});else if(typeof Q==="object")for(let[Z,U]of Object.entries(Q))J[`${Y}.${Z}`]=String(U);else J[Y]=String(Q)}return J}function H8(){let $=process.env.AWS_ACCESS_KEY_ID,J=process.env.AWS_SECRET_ACCESS_KEY,Y=$==="",Q=J==="";if($&&J)return{source:"env",emptyEnvKey:Y,emptyEnvSecret:Q,description:"environment variables (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)"};let Z=process.env.AWS_PROFILE||"default",U=process.env.AWS_SHARED_CREDENTIALS_FILE||SJ(NJ(),".aws","credentials");if(DJ(U))return{source:"file",profile:Z,emptyEnvKey:Y,emptyEnvSecret:Q,description:`~/.aws/credentials (profile: ${Z})`};return{source:"ec2",emptyEnvKey:Y,emptyEnvSecret:Q,description:"EC2 instance metadata service (IMDSv2)"}}var z0=S0(()=>{RJ()});class F9{name="porkbun";apiKey;secretKey;constructor($,J){this.apiKey=$,this.secretKey=J}async request($,J={}){let Y=await fetch(`https://api.porkbun.com/api/json/v3${$}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apikey:this.apiKey,secretapikey:this.secretKey,...J})});if(!Y.ok)throw Error(`Porkbun API error: ${Y.status} ${Y.statusText}`);let Q=await Y.json();if(Q.status==="ERROR")throw Error(`Porkbun API error: ${Q.message||"Unknown error"}`);return Q}getSubdomain($,J){let Y=$.replace(/\.$/,""),Q=J.replace(/\.$/,"");if(Y===Q)return"";if(Y.endsWith(`.${Q}`))return Y.slice(0,-(Q.length+1));return Y}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}async createRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z={type:J.type,content:J.content,ttl:String(J.ttl||600)};if(Q)Z.name=Q;if((J.type==="MX"||J.type==="SRV")&&J.priority!==void 0)Z.prio=String(J.priority);if(J.type==="SRV"&&J.weight!==void 0&&J.port!==void 0)Z.content=`${J.weight} ${J.port} ${J.content}`;return{success:!0,id:(await this.request(`/dns/create/${Y}`,Z)).id?.toString(),message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z=await this.listRecords($,J.type);if(Z.success){let U=Z.records.find((W)=>{return this.getSubdomain(W.name,Y)===Q&&W.type===J.type});if(U?.id){let W={type:J.type,content:J.content,ttl:String(J.ttl||600)};if(Q)W.name=Q;if((J.type==="MX"||J.type==="SRV")&&J.priority!==void 0)W.prio=String(J.priority);if(J.type==="SRV"&&J.weight!==void 0&&J.port!==void 0)W.content=`${J.weight} ${J.port} ${J.content}`;return await this.request(`/dns/edit/${Y}/${U.id}`,W),{success:!0,id:U.id,message:"Record updated successfully"}}}return this.createRecord($,J)}catch(Y){return this.createRecord($,J)}}async deleteRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z=await this.listRecords($,J.type);if(!Z.success)return{success:!1,message:"Failed to list records"};let U=Z.records.find((W)=>{return this.getSubdomain(W.name,Y)===Q&&W.type===J.type&&W.content===J.content});if(!U?.id)return{success:!1,message:"Record not found"};return await this.request(`/dns/delete/${Y}/${U.id}`),{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Y=this.getRootDomain($),Q=`/dns/retrieve/${Y}`;if(J)Q=`/dns/retrieveByNameType/${Y}/${J}`;return{success:!0,records:((await this.request(Q)).records||[]).map((W)=>({id:W.id,name:W.name||Y,type:W.type,content:W.content,ttl:Number.parseInt(W.ttl,10),priority:W.prio?Number.parseInt(W.prio,10):void 0}))}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){try{let J=this.getRootDomain($);return await this.request(`/dns/retrieve/${J}`),!0}catch{return!1}}async listDomains(){try{return((await this.request("/domain/listAll")).domains||[]).map((J)=>J.domain)}catch{return[]}}async getNameServers($){try{let J=this.getRootDomain($);return(await this.request(`/dns/getNS/${J}`)).ns||[]}catch{return[]}}async updateNameServers($,J){try{let Y=this.getRootDomain($);return await this.request(`/dns/updateNS/${Y}`,{ns:J}),!0}catch{return!1}}}class A9{name="godaddy";apiKey;apiSecret;baseUrl;constructor($,J,Y="production"){this.apiKey=$,this.apiSecret=J,this.baseUrl=Y==="ote"?"https://api.ote-godaddy.com":"https://api.godaddy.com"}async request($,J,Y){let Q=`${this.baseUrl}${J}`,Z={Authorization:`sso-key ${this.apiKey}:${this.apiSecret}`,"Content-Type":"application/json",Accept:"application/json"},U={method:$,headers:Z};if(Y)U.body=JSON.stringify(Y);let W=await fetch(Q,U);if(W.status===204)return{};if(W.ok){let G=await W.text();if(G)return JSON.parse(G);return{}}let z=`GoDaddy API error: ${W.status} ${W.statusText}`;try{let G=await W.json();if(G.message)z=`GoDaddy API error: ${G.message}`;if(G.fields)z+=` - Fields: ${JSON.stringify(G.fields)}`}catch{}throw Error(z)}getSubdomain($,J){let Y=$.replace(/\.$/,""),Q=J.replace(/\.$/,"");if(Y===Q)return"@";if(Y.endsWith(`.${Q}`))return Y.slice(0,-(Q.length+1));return Y}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}toGoDaddyRecord($,J){let Y=this.getRootDomain(J),Q=this.getSubdomain($.name,Y),Z={type:$.type,name:Q,data:$.content,ttl:$.ttl||600};if($.type==="MX"&&$.priority!==void 0)Z.priority=$.priority;return Z}fromGoDaddyRecord($,J){let Y=this.getRootDomain(J),Q=$.name;if(Q==="@")Q=Y;else if(!Q.endsWith(Y))Q=`${Q}.${Y}`;return{name:Q,type:$.type,content:$.data,ttl:$.ttl,priority:$.priority}}async createRecord($,J){try{let Y=this.getRootDomain($),Q=this.toGoDaddyRecord(J,$);return await this.request("PATCH",`/v1/domains/${Y}/records`,[Q]),{success:!0,message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=this.getRootDomain($),Q=this.toGoDaddyRecord(J,$);return await this.request("PUT",`/v1/domains/${Y}/records/${J.type}/${Q.name}`,[Q]),{success:!0,message:"Record upserted successfully"}}catch(Y){return this.createRecord($,J)}}async deleteRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z=await this.request("GET",`/v1/domains/${Y}/records/${J.type}/${Q}`),U=Z.filter((W)=>W.data!==J.content);if(U.length===Z.length)return{success:!1,message:"Record not found"};if(U.length===0)try{await this.request("DELETE",`/v1/domains/${Y}/records/${J.type}/${Q}`)}catch{}else await this.request("PUT",`/v1/domains/${Y}/records/${J.type}/${Q}`,U);return{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Y=this.getRootDomain($),Q=`/v1/domains/${Y}/records`;if(J)Q=`/v1/domains/${Y}/records/${J}`;return{success:!0,records:(await this.request("GET",Q)).map((U)=>this.fromGoDaddyRecord(U,$))}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){try{let J=this.getRootDomain($);return await this.request("GET",`/v1/domains/${J}`),!0}catch{return!1}}async listDomains(){try{return(await this.request("GET","/v1/domains")).map((J)=>J.domain)}catch{return[]}}async getDomainDetails($){try{let J=this.getRootDomain($),Y=await this.request("GET",`/v1/domains/${J}`);return{domain:Y.domain,status:Y.status,nameServers:Y.nameServers,expires:Y.expires}}catch{return null}}async updateNameServers($,J){try{let Y=this.getRootDomain($);return await this.request("PUT",`/v1/domains/${Y}/records/NS`,J.map((Q)=>({type:"NS",name:"@",data:Q,ttl:3600}))),!0}catch{return!1}}async checkDomainAvailability($){try{let J=await this.request("GET",`/v1/domains/available?domain=${encodeURIComponent($)}`);return{available:J.available,price:J.price,currency:J.currency}}catch{return{available:!1}}}}class K9{name="cloudflare";apiToken;zoneCache=new Map;constructor($){this.apiToken=$}async request($,J,Y){let Q=`https://api.cloudflare.com/client/v4${J}`,Z={Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},U={method:$,headers:Z};if(Y)U.body=JSON.stringify(Y);let z=await(await fetch(Q,U)).json();if(!z.success){let G=z.errors.map((H)=>H.message).join(", ");throw Error(`Cloudflare API error: ${G}`)}return z}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}async getZoneId($){let J=this.getRootDomain($),Y=this.zoneCache.get(J);if(Y)return Y;let Q=await this.request("GET",`/zones?name=${encodeURIComponent(J)}`);if(!Q.result||Q.result.length===0)throw Error(`Zone not found for domain: ${J}`);let Z=Q.result[0].id;return this.zoneCache.set(J,Z),Z}getFullRecordName($,J){let Y=this.getRootDomain(J),Q=$.replace(/\.$/,"");if(!Q||Q===Y||Q==="@")return Y;if(Q.endsWith(`.${Y}`))return Q;return`${Q}.${Y}`}toCloudflareRecord($,J){let Y={type:$.type,name:this.getFullRecordName($.name,J),content:$.content||$.value||"",ttl:$.ttl||1};if($.type==="MX"&&$.priority!==void 0)Y.priority=$.priority;if($.type==="SRV"){if($.priority!==void 0)Y.priority=$.priority}return Y}fromCloudflareRecord($){return{id:$.id,name:$.name,type:$.type,content:$.content,ttl:$.ttl,priority:$.priority}}async createRecord($,J){try{let Y=await this.getZoneId($),Q=this.toCloudflareRecord(J,$);return{success:!0,id:(await this.request("POST",`/zones/${Y}/dns_records`,Q)).result.id,message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=await this.getZoneId($),Q=this.getFullRecordName(J.name,$),Z=await this.request("GET",`/zones/${Y}/dns_records?type=${J.type}&name=${encodeURIComponent(Q)}`),U=this.toCloudflareRecord(J,$);if(Z.result&&Z.result.length>0){let z=Z.result[0].id;return{success:!0,id:(await this.request("PUT",`/zones/${Y}/dns_records/${z}`,U)).result.id,message:"Record updated successfully"}}return{success:!0,id:(await this.request("POST",`/zones/${Y}/dns_records`,U)).result.id,message:"Record created successfully"}}catch(Y){return this.createRecord($,J)}}async deleteRecord($,J){try{let Y=await this.getZoneId($),Q=this.getFullRecordName(J.name,$),Z=await this.request("GET",`/zones/${Y}/dns_records?type=${J.type}&name=${encodeURIComponent(Q)}`);if(!Z.result||Z.result.length===0)return{success:!1,message:"Record not found"};let U=Z.result.find((W)=>W.content===J.content);if(!U)return{success:!1,message:"Record with matching content not found"};return await this.request("DELETE",`/zones/${Y}/dns_records/${U.id}`),{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Q=`/zones/${await this.getZoneId($)}/dns_records?per_page=100`;if(J)Q+=`&type=${J}`;let Z=[],U=1,W=!0;while(W){let z=await this.request("GET",`${Q}&page=${U}`);if(Z.push(...z.result||[]),z.result_info)W=U<z.result_info.total_pages,U++;else W=!1}return{success:!0,records:Z.map((z)=>this.fromCloudflareRecord(z))}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){try{return await this.getZoneId($),!0}catch{return!1}}async listDomains(){try{let $=[],J=1,Y=!0;while(Y){let Q=await this.request("GET",`/zones?per_page=50&page=${J}`);if($.push(...Q.result||[]),Q.result_info)Y=J<Q.result_info.total_pages,J++;else Y=!1}return $.map((Q)=>Q.name)}catch{return[]}}async getZoneDetails($){try{let J=await this.getZoneId($),Y=await this.request("GET",`/zones/${J}`);return{id:Y.result.id,name:Y.result.name,status:Y.result.status,nameServers:Y.result.name_servers,paused:Y.result.paused}}catch{return null}}async purgeCache($,J){try{let Y=await this.getZoneId($),Q={};if(J?.purgeEverything)Q.purge_everything=!0;else{if(J?.files)Q.files=J.files;if(J?.tags)Q.tags=J.tags;if(J?.hosts)Q.hosts=J.hosts}if(Object.keys(Q).length===0)Q.purge_everything=!0;return await this.request("POST",`/zones/${Y}/purge_cache`,Q),!0}catch{return!1}}async getRecordProxyStatus($,J){try{let Y=await this.getZoneId($),Q=this.getFullRecordName(J.name,$),Z=await this.request("GET",`/zones/${Y}/dns_records?type=${J.type}&name=${encodeURIComponent(Q)}`);if(Z.result&&Z.result.length>0)return Z.result.find((W)=>W.content===J.content)?.proxied??null;return null}catch{return null}}async setRecordProxyStatus($,J,Y){try{let Q=await this.getZoneId($),Z=this.getFullRecordName(J.name,$),U=await this.request("GET",`/zones/${Q}/dns_records?type=${J.type}&name=${encodeURIComponent(Z)}`);if(!U.result||U.result.length===0)return!1;let W=U.result.find((z)=>z.content===J.content);if(!W)return!1;return await this.request("PATCH",`/zones/${Q}/dns_records/${W.id}`,{proxied:Y}),!0}catch{return!1}}}var o0;var B9=S0(()=>{z0();o0=class o0{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}async createHostedZone($){let J=$.CallerReference||`${Date.now()}-${Math.random().toString(36).slice(2)}`,Y=`<?xml version="1.0" encoding="UTF-8"?>
7
+ `),h=this.getSignatureKey(J.secretAccessKey,A,Q,D),I=this.hmac(h,x),b=`${T} Credential=${J.accessKeyId}/${N}, SignedHeaders=${E}, Signature=${I}`;return{...B,Authorization:b}}getAmzDate($){return $.toISOString().replace(/[:-]|\.\d{3}/g,"")}getDateStamp($){return $.toISOString().slice(0,10).replace(/-/g,"")}uriEncode($){return encodeURIComponent($).replace(/[!'()*]/g,(J)=>`%${J.charCodeAt(0).toString(16).toUpperCase()}`)}sha256($){return a1.createHash("sha256").update($,"utf8").digest("hex")}hmac($,J){return a1.createHmac("sha256",$).update(J,"utf8").digest("hex")}getSignatureKey($,J,Y,Q){let Z=a1.createHmac("sha256",`AWS4${$}`).update(J).digest(),U=a1.createHmac("sha256",Z).update(Y).digest(),W=a1.createHmac("sha256",U).update(Q).digest();return a1.createHmac("sha256",W).update("aws4_request").digest()}parseXmlResponse($){try{let J=this.xmlParser.parse($);if(J.ErrorResponse)throw this.createErrorFromXml(J.ErrorResponse.Error);let Y=Object.keys(J);if(Y.length===1)return J[Y[0]];return J}catch(J){if(J.code||J.statusCode)throw J;return{}}}parseError($,J,Y){let Q=Error();if(Q.statusCode=J,Q.requestId=Y.get("x-amzn-requestid")||Y.get("x-amz-request-id")||void 0,$.startsWith("<"))try{let Z=this.xmlParser.parse($);if(Z.ErrorResponse?.Error){let U=Z.ErrorResponse.Error;return Q.code=U.Code,Q.message=`AWS Error [${U.Code}]: ${U.Message||"Unknown error"}`,Q.type=U.Type,Q}if(Z.Error)return Q.code=Z.Error.Code,Q.message=`AWS Error [${Z.Error.Code}]: ${Z.Error.Message||"Unknown error"}`,Q}catch{}try{let Z=JSON.parse($);if(Z.__type||Z.code)return Q.code=Z.__type||Z.code,Q.message=`AWS Error [${Q.code}]: ${Z.message||Z.Message||"Unknown error"}`,Q}catch{}return Q.message=`AWS API Error (${J}): ${$}`,Q}createErrorFromXml($){let J=Error();return J.code=$.Code,J.message=`AWS Error [${$.Code}]: ${$.Message||"Unknown error"}`,J.type=$.Type,J}isRetryableError($){return["RequestTimeout","RequestTimeoutException","PriorRequestNotComplete","ConnectionError","ThrottlingException","Throttling","TooManyRequestsException","ProvisionedThroughputExceededException","RequestLimitExceeded","BandwidthLimitExceeded","SlowDown","ServiceUnavailable","ServiceUnavailableException","InternalError","InternalFailure","InternalServerError","InternalServiceException","TransientError","TransientFailure","IDPCommunicationErrorException","NetworkError","ConnectionRefusedException","EC2ThrottledException","503 Slow Down","500 InternalError"].includes($)}isRetryableStatusCode($){return $>=500||$===429}shouldRetry($){if($.name==="FetchError"||$.name==="TypeError"||$.code==="ECONNRESET")return!0;if($.code&&this.isRetryableError($.code))return!0;if($.statusCode&&this.isRetryableStatusCode($.statusCode))return!0;if($.statusCode&&$.statusCode>=400&&$.statusCode<500&&$.statusCode!==429)return!1;if($.statusCode)return!1;return!0}calculateRetryDelay($){let J=this.config.retryDelay??1000,Y=30000,Q=Math.min(J*2**$,30000),Z=Math.random()*0.3*Q;return Q+Z}sleep($){return new Promise((J)=>setTimeout(J,$))}getFromCache($){let J=this.cache.get($);if(!J)return null;if(Date.now()>J.expires)return this.cache.delete($),null;return J.data}setInCache($,J,Y){this.cache.set($,{data:J,expires:Date.now()+Y})}clearCache(){this.cache.clear()}clearExpiredCache(){let $=Date.now();for(let[J,Y]of this.cache.entries())if($>Y.expires)this.cache.delete(J)}}function g0($){let J={};for(let[Y,Q]of Object.entries($)){if(Q===void 0||Q===null)continue;if(Array.isArray(Q))Q.forEach((Z,U)=>{J[`${Y}.${U+1}`]=String(Z)});else if(typeof Q==="object")for(let[Z,U]of Object.entries(Q))J[`${Y}.${Z}`]=String(U);else J[Y]=String(Q)}return J}function H8(){let $=process.env.AWS_ACCESS_KEY_ID,J=process.env.AWS_SECRET_ACCESS_KEY,Y=$==="",Q=J==="";if($&&J)return{source:"env",emptyEnvKey:Y,emptyEnvSecret:Q,description:"environment variables (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)"};let Z=process.env.AWS_PROFILE||"default",U=process.env.AWS_SHARED_CREDENTIALS_FILE||SJ(NJ(),".aws","credentials");if(DJ(U))return{source:"file",profile:Z,emptyEnvKey:Y,emptyEnvSecret:Q,description:`~/.aws/credentials (profile: ${Z})`};return{source:"ec2",emptyEnvKey:Y,emptyEnvSecret:Q,description:"EC2 instance metadata service (IMDSv2)"}}var z0=S0(()=>{RJ()});class F9{name="porkbun";apiKey;secretKey;constructor($,J){this.apiKey=$,this.secretKey=J}async request($,J={}){let Y=await fetch(`https://api.porkbun.com/api/json/v3${$}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apikey:this.apiKey,secretapikey:this.secretKey,...J})});if(!Y.ok)throw Error(`Porkbun API error: ${Y.status} ${Y.statusText}`);let Q=await Y.json();if(Q.status==="ERROR")throw Error(`Porkbun API error: ${Q.message||"Unknown error"}`);return Q}getSubdomain($,J){let Y=$.replace(/\.$/,""),Q=J.replace(/\.$/,"");if(Y===Q)return"";if(Y.endsWith(`.${Q}`))return Y.slice(0,-(Q.length+1));return Y}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}async createRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z={type:J.type,content:J.content,ttl:String(J.ttl||600)};if(Q)Z.name=Q;if((J.type==="MX"||J.type==="SRV")&&J.priority!==void 0)Z.prio=String(J.priority);if(J.type==="SRV"&&J.weight!==void 0&&J.port!==void 0)Z.content=`${J.weight} ${J.port} ${J.content}`;return{success:!0,id:(await this.request(`/dns/create/${Y}`,Z)).id?.toString(),message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z=await this.listRecords($,J.type);if(Z.success){let U=Z.records.find((W)=>{return this.getSubdomain(W.name,Y)===Q&&W.type===J.type});if(U?.id){let W={type:J.type,content:J.content,ttl:String(J.ttl||600)};if(Q)W.name=Q;if((J.type==="MX"||J.type==="SRV")&&J.priority!==void 0)W.prio=String(J.priority);if(J.type==="SRV"&&J.weight!==void 0&&J.port!==void 0)W.content=`${J.weight} ${J.port} ${J.content}`;return await this.request(`/dns/edit/${Y}/${U.id}`,W),{success:!0,id:U.id,message:"Record updated successfully"}}}return this.createRecord($,J)}catch(Y){return this.createRecord($,J)}}async deleteRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z=await this.listRecords($,J.type);if(!Z.success)return{success:!1,message:"Failed to list records"};let U=Z.records.find((W)=>{return this.getSubdomain(W.name,Y)===Q&&W.type===J.type&&W.content===J.content});if(!U?.id)return{success:!1,message:"Record not found"};return await this.request(`/dns/delete/${Y}/${U.id}`),{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Y=this.getRootDomain($),Q=`/dns/retrieve/${Y}`;if(J)Q=`/dns/retrieveByNameType/${Y}/${J}`;return{success:!0,records:((await this.request(Q)).records||[]).map((W)=>({id:W.id,name:W.name||Y,type:W.type,content:W.content,ttl:Number.parseInt(W.ttl,10),priority:W.prio?Number.parseInt(W.prio,10):void 0}))}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){try{let J=this.getRootDomain($);return await this.request(`/dns/retrieve/${J}`),!0}catch{return!1}}async listDomains(){try{return((await this.request("/domain/listAll")).domains||[]).map((J)=>J.domain)}catch{return[]}}async getNameServers($){try{let J=this.getRootDomain($);return(await this.request(`/dns/getNS/${J}`)).ns||[]}catch{return[]}}async updateNameServers($,J){try{let Y=this.getRootDomain($);return await this.request(`/dns/updateNS/${Y}`,{ns:J}),!0}catch{return!1}}}class A9{name="godaddy";apiKey;apiSecret;baseUrl;constructor($,J,Y="production"){this.apiKey=$,this.apiSecret=J,this.baseUrl=Y==="ote"?"https://api.ote-godaddy.com":"https://api.godaddy.com"}async request($,J,Y){let Q=`${this.baseUrl}${J}`,Z={Authorization:`sso-key ${this.apiKey}:${this.apiSecret}`,"Content-Type":"application/json",Accept:"application/json"},U={method:$,headers:Z};if(Y)U.body=JSON.stringify(Y);let W=await fetch(Q,U);if(W.status===204)return{};if(W.ok){let G=await W.text();if(G)return JSON.parse(G);return{}}let z=`GoDaddy API error: ${W.status} ${W.statusText}`;try{let G=await W.json();if(G.message)z=`GoDaddy API error: ${G.message}`;if(G.fields)z+=` - Fields: ${JSON.stringify(G.fields)}`}catch{}throw Error(z)}getSubdomain($,J){let Y=$.replace(/\.$/,""),Q=J.replace(/\.$/,"");if(Y===Q)return"@";if(Y.endsWith(`.${Q}`))return Y.slice(0,-(Q.length+1));return Y}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}toGoDaddyRecord($,J){let Y=this.getRootDomain(J),Q=this.getSubdomain($.name,Y),Z={type:$.type,name:Q,data:$.content,ttl:$.ttl||600};if($.type==="MX"&&$.priority!==void 0)Z.priority=$.priority;return Z}fromGoDaddyRecord($,J){let Y=this.getRootDomain(J),Q=$.name;if(Q==="@")Q=Y;else if(!Q.endsWith(Y))Q=`${Q}.${Y}`;return{name:Q,type:$.type,content:$.data,ttl:$.ttl,priority:$.priority}}async createRecord($,J){try{let Y=this.getRootDomain($),Q=this.toGoDaddyRecord(J,$);return await this.request("PATCH",`/v1/domains/${Y}/records`,[Q]),{success:!0,message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=this.getRootDomain($),Q=this.toGoDaddyRecord(J,$);return await this.request("PUT",`/v1/domains/${Y}/records/${J.type}/${Q.name}`,[Q]),{success:!0,message:"Record upserted successfully"}}catch(Y){return this.createRecord($,J)}}async deleteRecord($,J){try{let Y=this.getRootDomain($),Q=this.getSubdomain(J.name,Y),Z=await this.request("GET",`/v1/domains/${Y}/records/${J.type}/${Q}`),U=Z.filter((W)=>W.data!==J.content);if(U.length===Z.length)return{success:!1,message:"Record not found"};if(U.length===0)try{await this.request("DELETE",`/v1/domains/${Y}/records/${J.type}/${Q}`)}catch{}else await this.request("PUT",`/v1/domains/${Y}/records/${J.type}/${Q}`,U);return{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Y=this.getRootDomain($),Q=`/v1/domains/${Y}/records`;if(J)Q=`/v1/domains/${Y}/records/${J}`;return{success:!0,records:(await this.request("GET",Q)).map((U)=>this.fromGoDaddyRecord(U,$))}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){try{let J=this.getRootDomain($);return await this.request("GET",`/v1/domains/${J}`),!0}catch{return!1}}async listDomains(){try{return(await this.request("GET","/v1/domains")).map((J)=>J.domain)}catch{return[]}}async getDomainDetails($){try{let J=this.getRootDomain($),Y=await this.request("GET",`/v1/domains/${J}`);return{domain:Y.domain,status:Y.status,nameServers:Y.nameServers,expires:Y.expires}}catch{return null}}async updateNameServers($,J){try{let Y=this.getRootDomain($);return await this.request("PUT",`/v1/domains/${Y}/records/NS`,J.map((Q)=>({type:"NS",name:"@",data:Q,ttl:3600}))),!0}catch{return!1}}async checkDomainAvailability($){try{let J=await this.request("GET",`/v1/domains/available?domain=${encodeURIComponent($)}`);return{available:J.available,price:J.price,currency:J.currency}}catch{return{available:!1}}}}class K9{name="cloudflare";apiToken;zoneCache=new Map;constructor($){this.apiToken=$}async request($,J,Y){let Q=`https://api.cloudflare.com/client/v4${J}`,Z={Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},U={method:$,headers:Z};if(Y)U.body=JSON.stringify(Y);let z=await(await fetch(Q,U)).json();if(!z.success){let G=z.errors.map((H)=>H.message).join(", ");throw Error(`Cloudflare API error: ${G}`)}return z}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}async getZoneId($){let J=this.getRootDomain($),Y=this.zoneCache.get(J);if(Y)return Y;let Q=await this.request("GET",`/zones?name=${encodeURIComponent(J)}`);if(!Q.result||Q.result.length===0)throw Error(`Zone not found for domain: ${J}`);let Z=Q.result[0].id;return this.zoneCache.set(J,Z),Z}getFullRecordName($,J){let Y=this.getRootDomain(J),Q=$.replace(/\.$/,"");if(!Q||Q===Y||Q==="@")return Y;if(Q.endsWith(`.${Y}`))return Q;return`${Q}.${Y}`}toCloudflareRecord($,J){let Y={type:$.type,name:this.getFullRecordName($.name,J),content:$.content||$.value||"",ttl:$.ttl||1};if($.type==="MX"&&$.priority!==void 0)Y.priority=$.priority;if($.type==="SRV"){if($.priority!==void 0)Y.priority=$.priority}return Y}fromCloudflareRecord($){return{id:$.id,name:$.name,type:$.type,content:$.content,ttl:$.ttl,priority:$.priority}}async createRecord($,J){try{let Y=await this.getZoneId($),Q=this.toCloudflareRecord(J,$);return{success:!0,id:(await this.request("POST",`/zones/${Y}/dns_records`,Q)).result.id,message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=await this.getZoneId($),Q=this.getFullRecordName(J.name,$),Z=await this.request("GET",`/zones/${Y}/dns_records?type=${J.type}&name=${encodeURIComponent(Q)}`),U=this.toCloudflareRecord(J,$);if(Z.result&&Z.result.length>0){let z=Z.result[0].id;return{success:!0,id:(await this.request("PUT",`/zones/${Y}/dns_records/${z}`,U)).result.id,message:"Record updated successfully"}}return{success:!0,id:(await this.request("POST",`/zones/${Y}/dns_records`,U)).result.id,message:"Record created successfully"}}catch(Y){return this.createRecord($,J)}}async deleteRecord($,J){try{let Y=await this.getZoneId($),Q=this.getFullRecordName(J.name,$),Z=await this.request("GET",`/zones/${Y}/dns_records?type=${J.type}&name=${encodeURIComponent(Q)}`);if(!Z.result||Z.result.length===0)return{success:!1,message:"Record not found"};let U=Z.result.find((W)=>W.content===J.content);if(!U)return{success:!1,message:"Record with matching content not found"};return await this.request("DELETE",`/zones/${Y}/dns_records/${U.id}`),{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Q=`/zones/${await this.getZoneId($)}/dns_records?per_page=100`;if(J)Q+=`&type=${J}`;let Z=[],U=1,W=!0;while(W){let z=await this.request("GET",`${Q}&page=${U}`);if(Z.push(...z.result||[]),z.result_info)W=U<z.result_info.total_pages,U++;else W=!1}return{success:!0,records:Z.map((z)=>this.fromCloudflareRecord(z))}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){try{return await this.getZoneId($),!0}catch{return!1}}async listDomains(){try{let $=[],J=1,Y=!0;while(Y){let Q=await this.request("GET",`/zones?per_page=50&page=${J}`);if($.push(...Q.result||[]),Q.result_info)Y=J<Q.result_info.total_pages,J++;else Y=!1}return $.map((Q)=>Q.name)}catch{return[]}}async getZoneDetails($){try{let J=await this.getZoneId($),Y=await this.request("GET",`/zones/${J}`);return{id:Y.result.id,name:Y.result.name,status:Y.result.status,nameServers:Y.result.name_servers,paused:Y.result.paused}}catch{return null}}async purgeCache($,J){try{let Y=await this.getZoneId($),Q={};if(J?.purgeEverything)Q.purge_everything=!0;else{if(J?.files)Q.files=J.files;if(J?.tags)Q.tags=J.tags;if(J?.hosts)Q.hosts=J.hosts}if(Object.keys(Q).length===0)Q.purge_everything=!0;return await this.request("POST",`/zones/${Y}/purge_cache`,Q),!0}catch{return!1}}async getRecordProxyStatus($,J){try{let Y=await this.getZoneId($),Q=this.getFullRecordName(J.name,$),Z=await this.request("GET",`/zones/${Y}/dns_records?type=${J.type}&name=${encodeURIComponent(Q)}`);if(Z.result&&Z.result.length>0)return Z.result.find((W)=>W.content===J.content)?.proxied??null;return null}catch{return null}}async setRecordProxyStatus($,J,Y){try{let Q=await this.getZoneId($),Z=this.getFullRecordName(J.name,$),U=await this.request("GET",`/zones/${Q}/dns_records?type=${J.type}&name=${encodeURIComponent(Z)}`);if(!U.result||U.result.length===0)return!1;let W=U.result.find((z)=>z.content===J.content);if(!W)return!1;return await this.request("PATCH",`/zones/${Q}/dns_records/${W.id}`,{proxied:Y}),!0}catch{return!1}}}var o0;var B9=S0(()=>{z0();o0=class o0{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}async createHostedZone($){let J=$.CallerReference||`${Date.now()}-${Math.random().toString(36).slice(2)}`,Y=`<?xml version="1.0" encoding="UTF-8"?>
8
8
  <CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
9
9
  <Name>${$.Name}</Name>
10
10
  <CallerReference>${J}</CallerReference>`;if($.HostedZoneConfig){if(Y+=`
@@ -52,11 +52,11 @@ import{createRequire as BU}from"node:module";var FU=Object.defineProperty;var AU
52
52
  </Change>`}Y+=`
53
53
  </Changes>
54
54
  </ChangeBatch>
55
- </ChangeResourceRecordSetsRequest>`;let Q=await this.client.request({service:"route53",region:this.region,method:"POST",path:`/2013-04-01/hostedzone/${J}/rrset`,headers:{"content-type":"application/xml"},body:Y});return this.parseChangeResourceRecordSetsResponse(Q)}escapeXml($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}parseCreateHostedZoneResponse($){let J=$.CreateHostedZoneResponse||$;return{HostedZone:this.parseHostedZone(J.HostedZone),ChangeInfo:{Id:J.ChangeInfo?.Id||"",Status:J.ChangeInfo?.Status||"",SubmittedAt:J.ChangeInfo?.SubmittedAt||""},DelegationSet:this.parseDelegationSet(J.DelegationSet),Location:J.Location||""}}parseListHostedZonesResponse($){let J=$.ListHostedZonesResponse||$.ListHostedZonesByNameResponse||$,Y=J.HostedZones?.HostedZone||J.HostedZones||[];if(!Array.isArray(Y))Y=Y?[Y]:[];return{HostedZones:Y.map((Q)=>this.parseHostedZone(Q)),IsTruncated:J.IsTruncated==="true"||J.IsTruncated===!0,MaxItems:J.MaxItems||"100",Marker:J.Marker,NextMarker:J.NextMarker}}parseGetHostedZoneResponse($){let J=$.GetHostedZoneResponse||$;return{HostedZone:this.parseHostedZone(J.HostedZone),DelegationSet:this.parseDelegationSet(J.DelegationSet),VPCs:J.VPCs?.VPC?Array.isArray(J.VPCs.VPC)?J.VPCs.VPC:[J.VPCs.VPC]:void 0}}parseListResourceRecordSetsResponse($){let J=$.ListResourceRecordSetsResponse||$,Y=J.ResourceRecordSets?.ResourceRecordSet||J.ResourceRecordSets||[];if(!Array.isArray(Y))Y=Y?[Y]:[];return{ResourceRecordSets:Y.map((Q)=>this.parseResourceRecordSet(Q)),IsTruncated:J.IsTruncated==="true"||J.IsTruncated===!0,MaxItems:J.MaxItems||"100",NextRecordName:J.NextRecordName,NextRecordType:J.NextRecordType,NextRecordIdentifier:J.NextRecordIdentifier}}parseChangeResourceRecordSetsResponse($){let J=$.ChangeResourceRecordSetsResponse||$;return{ChangeInfo:{Id:J.ChangeInfo?.Id||"",Status:J.ChangeInfo?.Status||"",SubmittedAt:J.ChangeInfo?.SubmittedAt||"",Comment:J.ChangeInfo?.Comment}}}parseHostedZone($){if(!$)return{Id:"",Name:""};return{Id:$.Id||"",Name:$.Name||"",CallerReference:$.CallerReference,Config:$.Config?{Comment:$.Config.Comment,PrivateZone:$.Config.PrivateZone==="true"||$.Config.PrivateZone===!0}:void 0,ResourceRecordSetCount:$.ResourceRecordSetCount?Number($.ResourceRecordSetCount):void 0}}parseDelegationSet($){if(!$)return{NameServers:[]};let J=$.NameServers?.NameServer||$.NameServers||[];if(!Array.isArray(J))J=J?[J]:[];return{Id:$.Id,CallerReference:$.CallerReference,NameServers:J}}parseResourceRecordSet($){if(!$)return{Name:"",Type:""};let J=$.ResourceRecords?.ResourceRecord||$.ResourceRecords||[];if(!Array.isArray(J))J=J?[J]:[];return{Name:$.Name||"",Type:$.Type||"",TTL:$.TTL?Number($.TTL):void 0,ResourceRecords:J.map((Y)=>({Value:Y.Value||Y})),AliasTarget:$.AliasTarget?{HostedZoneId:$.AliasTarget.HostedZoneId,DNSName:$.AliasTarget.DNSName,EvaluateTargetHealth:$.AliasTarget.EvaluateTargetHealth==="true"||$.AliasTarget.EvaluateTargetHealth===!0}:void 0,SetIdentifier:$.SetIdentifier,Weight:$.Weight?Number($.Weight):void 0,Region:$.Region,GeoLocation:$.GeoLocation,Failover:$.Failover,HealthCheckId:$.HealthCheckId}}async findHostedZoneByName($){let J=$.endsWith(".")?$:`${$}.`;return(await this.listHostedZonesByName({DNSName:J})).HostedZones.find((Z)=>Z.Name===J)||null}async createARecord($){let J=Array.isArray($.Value)?$.Value:[$.Value];return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"A",TTL:$.TTL||300,ResourceRecords:J.map((Y)=>({Value:Y}))}}]}})}async createCnameRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"CNAME",TTL:$.TTL||300,ResourceRecords:[{Value:$.Value}]}}]}})}async createAliasRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:$.Type||"A",AliasTarget:{HostedZoneId:$.TargetHostedZoneId,DNSName:$.TargetDNSName,EvaluateTargetHealth:$.EvaluateTargetHealth??!1}}}]}})}async createTxtRecord($){let Y=(Array.isArray($.Value)?$.Value:[$.Value]).map((Q)=>{if(!Q.startsWith('"'))return`"${Q}"`;return Q});return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"TXT",TTL:$.TTL||300,ResourceRecords:Y.map((Q)=>({Value:Q}))}}]}})}async createMxRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"MX",TTL:$.TTL||300,ResourceRecords:$.Values.map((J)=>({Value:`${J.priority} ${J.mailServer}`}))}}]}})}async deleteRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"DELETE",ResourceRecordSet:$.RecordSet}]}})}async waitForChange($,J=60,Y=5000){let Q=$.replace("/change/","");for(let Z=0;Z<J;Z++){let U=await this.client.request({service:"route53",region:this.region,method:"GET",path:`/2013-04-01/change/${Q}`});if((U.GetChangeResponse?.ChangeInfo?.Status||U.ChangeInfo?.Status)==="INSYNC")return!0;await new Promise((z)=>setTimeout(z,Y))}return!1}async findOrCreateHostedZone($){let J=$.domainName.endsWith(".")?$.domainName:`${$.domainName}.`,Y=await this.findHostedZoneByName(J);if(Y){let Z=await this.getHostedZone({Id:Y.Id});return{hostedZone:Y,nameServers:Z.DelegationSet.NameServers,isNew:!1}}let Q=await this.createHostedZone({Name:J,HostedZoneConfig:{Comment:$.comment||`Hosted zone for ${$.domainName}`,PrivateZone:$.privateZone},VPC:$.vpc});return{hostedZone:Q.HostedZone,nameServers:Q.DelegationSet.NameServers,isNew:!0}}static getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length<=2)return $;return J.slice(-2).join(".")}async findHostedZoneForDomain($){let Y=$.replace(/\.$/,"").split(".");for(let Q=0;Q<Y.length-1;Q++){let Z=Y.slice(Q).join("."),U=await this.findHostedZoneByName(Z);if(U)return U}return null}async ensureHostedZone($){let J=await this.findOrCreateHostedZone({domainName:$.domainName,comment:$.comment});return{hostedZoneId:J.hostedZone.Id.replace("/hostedzone/",""),nameServers:J.nameServers,isNew:J.isNew,action:J.isNew?"created":"found"}}async setupDomainDns($){let{domain:J,createIfNotExists:Y=!0}=$,Q=await this.findHostedZoneByName(J);if(Q){let U=await this.getHostedZone({Id:Q.Id});return{success:!0,hostedZoneId:Q.Id.replace("/hostedzone/",""),nameServers:U.DelegationSet.NameServers,isNew:!1,message:`Found existing hosted zone for ${J}`}}if(!Y)return{success:!1,hostedZoneId:null,nameServers:[],isNew:!1,message:`No hosted zone found for ${J} and createIfNotExists is false`};let Z=await this.createHostedZone({Name:J,HostedZoneConfig:{Comment:`Created automatically by ts-cloud for ${J}`}});return{success:!0,hostedZoneId:Z.HostedZone.Id.replace("/hostedzone/",""),nameServers:Z.DelegationSet.NameServers,isNew:!0,message:`Created new hosted zone for ${J}. Please update your domain registrar with these name servers: ${Z.DelegationSet.NameServers.join(", ")}`}}static CloudFrontHostedZoneId="Z2FDTNDATAQYW2";static S3WebsiteHostedZoneIds={"us-east-1":"Z3AQBSTGFYJSTF","us-east-2":"Z2O1EMRO9K5GLX","us-west-1":"Z2F56UZL2M1ACD","us-west-2":"Z3BJ6K6RIION7M","ap-east-1":"ZNB98KWMFR0R6","ap-south-1":"Z11RGJOFQNVJUP","ap-northeast-1":"Z2M4EHUR26P7ZW","ap-northeast-2":"Z3W03O7B5YMIYP","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"Z3O0J2DXBE1FTB","ap-southeast-2":"Z1WCIGYICN2BYD","ca-central-1":"Z1QDHH18159H29","eu-central-1":"Z21DNDUVLTQW6Q","eu-west-1":"Z1BKCTXD74EZPE","eu-west-2":"Z3GKZC51ZF0DB4","eu-west-3":"Z3R1K369G5AVDG","eu-north-1":"Z3BAZG2TWCNX0D","sa-east-1":"Z7KQH4QJS55SO"};static ALBHostedZoneIds={"us-east-1":"Z35SXDOTRQ7X7K","us-east-2":"Z3AADJGX6KTTL2","us-west-1":"Z368ELLRRE2KJ0","us-west-2":"Z1H1FL5HABSF5","ap-east-1":"Z3DQVH9N71FHZ0","ap-south-1":"ZP97RAFLXTNZK","ap-northeast-1":"Z14GRHDCWA56QT","ap-northeast-2":"ZWKZPGTI48KDX","ap-northeast-3":"Z5LXEBD8Y73MNV","ap-southeast-1":"Z1LMS91P8CMLE5","ap-southeast-2":"Z1GM3OXH4ZPM65","ca-central-1":"ZQSVJUPU6J1EY","eu-central-1":"Z215JYRZR1TBD5","eu-west-1":"Z32O12XQLNTSW2","eu-west-2":"ZHURV8PSTC4K8","eu-west-3":"Z3Q77PNBQS71R4","eu-north-1":"Z23TAZ6LKFMNIO","sa-east-1":"Z2P70J7HTTTPLU"};static APIGatewayHostedZoneIds={"us-east-1":"Z1UJRXOUMOOFQ8","us-east-2":"ZOJJZC49E0EPZ","us-west-1":"Z2MUQ32089INYE","us-west-2":"Z2OJLYMUO9EFXC","ap-east-1":"Z3FD1VL90ND7K5","ap-south-1":"Z3VO1THU9YC4UR","ap-northeast-1":"Z1YSHQZHG15GKL","ap-northeast-2":"Z20JF4UZKIW1U8","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"ZL327KTPIQFUL","ap-southeast-2":"Z2RPCDW04V8134","ca-central-1":"Z19DQILCV0OWEC","eu-central-1":"Z1U9ULNL0V5AJ3","eu-west-1":"ZLY8HYME6SFDD","eu-west-2":"ZJ5UAJN8Y3Z2Q","eu-west-3":"Z3KY65QIEKYHQQ","eu-north-1":"Z3UWIKFBOOGXPP","sa-east-1":"ZCMLWB8V5SYIT"}}});class v2{name="route53";client;hostedZoneCache=new Map;providedHostedZoneId;constructor($="us-east-1",J){this.client=new o0($),this.providedHostedZoneId=J}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}async getHostedZoneId($){if(this.providedHostedZoneId)return this.providedHostedZoneId;let J=this.getRootDomain($),Y=this.hostedZoneCache.get(J);if(Y)return Y;let Q=await this.client.findHostedZoneForDomain($);if(Q){let Z=Q.Id.replace("/hostedzone/","");return this.hostedZoneCache.set(J,Z),Z}return null}normalizeName($){return $.endsWith(".")?$:`${$}.`}async createRecord($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,message:`No hosted zone found for domain: ${$}`};let Q=this.normalizeName(J.name),Z=J.content;if(J.type==="TXT"&&!Z.startsWith('"'))Z=`"${Z}"`;if(J.type==="MX"&&J.priority!==void 0)Z=`${J.priority} ${Z}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:"Created by ts-cloud DNS provider",Changes:[{Action:"CREATE",ResourceRecordSet:{Name:Q,Type:J.type,TTL:J.ttl||300,ResourceRecords:[{Value:Z}]}}]}})).ChangeInfo?.Id,message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,message:`No hosted zone found for domain: ${$}`};let Q=this.normalizeName(J.name),Z=J.content;if(J.type==="TXT"&&!Z.startsWith('"'))Z=`"${Z}"`;if(J.type==="MX"&&J.priority!==void 0)Z=`${J.priority} ${Z}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:"Upserted by ts-cloud DNS provider",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:Q,Type:J.type,TTL:J.ttl||300,ResourceRecords:[{Value:Z}]}}]}})).ChangeInfo?.Id,message:"Record upserted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async deleteRecord($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,message:`No hosted zone found for domain: ${$}`};let Q=this.normalizeName(J.name),Z=J.content;if(J.type==="TXT"&&!Z.startsWith('"'))Z=`"${Z}"`;if(J.type==="MX"&&J.priority!==void 0)Z=`${J.priority} ${Z}`;return await this.client.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:"Deleted by ts-cloud DNS provider",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:Q,Type:J.type,TTL:J.ttl||300,ResourceRecords:[{Value:Z}]}}]}}),{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,records:[],message:`No hosted zone found for domain: ${$}`};let Q=await this.client.listResourceRecordSets({HostedZoneId:Y,StartRecordType:J}),Z=[];for(let U of Q.ResourceRecordSets){if(J&&U.Type!==J)continue;if(U.AliasTarget)continue;for(let W of U.ResourceRecords||[]){let z=W.Value,G;if(U.Type==="MX"){let H=z.split(" ");if(H.length>=2)G=Number.parseInt(H[0],10),z=H.slice(1).join(" ")}if(U.Type==="TXT"&&z.startsWith('"')&&z.endsWith('"'))z=z.slice(1,-1);Z.push({name:U.Name.replace(/\.$/,""),type:U.Type,content:z,ttl:U.TTL,priority:G})}}return{success:!0,records:Z}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){return await this.getHostedZoneId($)!==null}async listDomains(){try{return(await this.client.listHostedZones()).HostedZones.map((J)=>J.Name.replace(/\.$/,""))}catch{return[]}}getRoute53Client(){return this.client}async createAliasRecord($){try{let J=await this.getHostedZoneId($.domain);if(!J)return{success:!1,message:`No hosted zone found for domain: ${$.domain}`};return{success:!0,id:(await this.client.createAliasRecord({HostedZoneId:J,Name:this.normalizeName($.name),TargetHostedZoneId:$.targetHostedZoneId,TargetDNSName:$.targetDnsName,EvaluateTargetHealth:$.evaluateTargetHealth,Type:$.type})).ChangeInfo?.Id,message:"Alias record created successfully"}}catch(J){return{success:!1,message:J instanceof Error?J.message:"Unknown error"}}}async createCloudFrontAlias($){return this.createAliasRecord({domain:$.domain,name:$.name,targetHostedZoneId:o0.CloudFrontHostedZoneId,targetDnsName:$.cloudFrontDomainName,evaluateTargetHealth:!1})}async createAlbAlias($){let J=o0.ALBHostedZoneIds[$.region];if(!J)return{success:!1,message:`Unknown region for ALB: ${$.region}`};return this.createAliasRecord({domain:$.domain,name:$.name,targetHostedZoneId:J,targetDnsName:$.albDnsName,evaluateTargetHealth:!0})}}var j9=S0(()=>{B9()});var UQ={};Z1(UQ,{ACMDnsValidator:()=>X9,ACMClient:()=>y0});class y0{client;region;constructor($="us-east-1"){this.client=new t,this.region=$}async requestCertificate($){let J={DomainName:$.DomainName,ValidationMethod:$.ValidationMethod||"DNS"};if($.SubjectAlternativeNames)J.SubjectAlternativeNames=$.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(J)})).CertificateArn||""}}async describeCertificate($){let Y=(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:$.CertificateArn})})).Certificate||{};return{CertificateArn:Y.CertificateArn||"",DomainName:Y.DomainName||"",SubjectAlternativeNames:Y.SubjectAlternativeNames,Status:Y.Status||"PENDING_VALIDATION",Type:Y.Type,DomainValidationOptions:Y.DomainValidationOptions?.map((Q)=>({DomainName:Q.DomainName,ValidationDomain:Q.ValidationDomain,ValidationStatus:Q.ValidationStatus,ResourceRecord:Q.ResourceRecord?{Name:Q.ResourceRecord.Name,Type:Q.ResourceRecord.Type,Value:Q.ResourceRecord.Value}:void 0,ValidationMethod:Q.ValidationMethod})),CreatedAt:Y.CreatedAt,IssuedAt:Y.IssuedAt,NotBefore:Y.NotBefore,NotAfter:Y.NotAfter}}async listCertificates($){let J={};if($?.CertificateStatuses)J.CertificateStatuses=$.CertificateStatuses;if($?.MaxItems)J.MaxItems=$.MaxItems;if($?.NextToken)J.NextToken=$.NextToken;let Y=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(J)});return{CertificateSummaryList:(Y.CertificateSummaryList||[]).map((Q)=>({CertificateArn:Q.CertificateArn,DomainName:Q.DomainName})),NextToken:Y.NextToken}}async deleteCertificate($){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:$.CertificateArn})})}async listTagsForCertificate($){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:$.CertificateArn})})).Tags||[]}}async addTagsToCertificate($){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:$.CertificateArn,Tags:$.Tags})})}async resendValidationEmail($){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:$.CertificateArn,Domain:$.Domain,ValidationDomain:$.ValidationDomain})})}async findCertificateByDomain($){let Y=(await this.listCertificates({CertificateStatuses:["ISSUED"]})).CertificateSummaryList.find((Q)=>Q.DomainName===$||Q.DomainName===`*.${$.split(".").slice(1).join(".")}`);if(!Y)return null;return this.describeCertificate({CertificateArn:Y.CertificateArn})}async waitForCertificateValidation($,J=60,Y=30000){for(let Q=0;Q<J;Q++){let Z=await this.describeCertificate({CertificateArn:$});if(Z.Status==="ISSUED")return Z;if(Z.Status==="FAILED"||Z.Status==="VALIDATION_TIMED_OUT")return null;await new Promise((U)=>setTimeout(U,Y))}return null}async getDnsValidationRecords($){let J=await this.describeCertificate({CertificateArn:$});if(!J.DomainValidationOptions)return[];return J.DomainValidationOptions.filter((Y)=>Y.ResourceRecord&&Y.ValidationMethod==="DNS").map((Y)=>({domainName:Y.DomainName,recordName:Y.ResourceRecord.Name,recordType:Y.ResourceRecord.Type,recordValue:Y.ResourceRecord.Value}))}async requestCertificateWithSans($){let J=new Set;if(J.add($.DomainName),$.IncludeWww!==!1)J.add(`www.${$.DomainName}`);if($.IncludeWildcard)J.add(`*.${$.DomainName}`);if($.AdditionalSans)for(let Y of $.AdditionalSans)J.add(Y);return this.requestCertificate({DomainName:$.DomainName,SubjectAlternativeNames:Array.from(J),ValidationMethod:"DNS"})}async isCertificateValidForDomain($,J){let Y=await this.describeCertificate({CertificateArn:$});if(Y.Status!=="ISSUED")return!1;if(Y.DomainName===J)return!0;if(Y.DomainName?.startsWith("*.")){let Q=Y.DomainName.slice(2),Z=J.split("."),U=Q.split(".");if(Z.slice(-U.length).join(".")===Q)return!0}if(Y.SubjectAlternativeNames)for(let Q of Y.SubjectAlternativeNames){if(Q===J)return!0;if(Q.startsWith("*.")){let Z=Q.slice(2),U=J.split("."),W=Z.split(".");if(U.slice(-W.length).join(".")===Z)return!0}}return!1}}class X9{acm;route53;dnsProvider;constructor($="us-east-1",J){if(this.acm=new y0($),this.route53=new o0,J&&J.provider!=="route53")this.dnsProvider=e0(J)}async requestAndValidate($){let{domainName:J,hostedZoneId:Y,subjectAlternativeNames:Q=[],waitForValidation:Z=!1,maxWaitMinutes:U=30}=$;if(!this.dnsProvider&&!Y)throw Error("Either hostedZoneId or external DNS provider configuration is required");let{CertificateArn:W}=await this.acm.requestCertificate({DomainName:J,SubjectAlternativeNames:Q.length>0?[J,...Q]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(W);let z=await this.acm.getDnsValidationRecords(W);if(this.dnsProvider)for(let G of z){let H=await this.dnsProvider.upsertRecord(J,{name:G.recordName,type:G.recordType,content:G.recordValue,ttl:300});if(!H.success)console.warn(`Failed to create validation record for ${G.domainName}: ${H.message}`)}else if(Y)for(let G of z)await this.route53.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:`ACM DNS validation for ${G.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:G.recordName,Type:G.recordType,TTL:300,ResourceRecords:[{Value:G.recordValue}]}}]}});if(Z){if(!await this.acm.waitForCertificateValidation(W,U*2,30000))throw Error(`Certificate validation timed out after ${U} minutes`)}return{certificateArn:W,validationRecords:z}}async waitForValidationOptions($,J=30){for(let Y=0;Y<J;Y++){let Q=await this.acm.describeCertificate({CertificateArn:$});if(Q.DomainValidationOptions&&Q.DomainValidationOptions.length>0&&Q.DomainValidationOptions[0].ResourceRecord)return;await new Promise((Z)=>setTimeout(Z,2000))}throw Error("Timeout waiting for DNS validation options")}async createValidationRecords($){let{certificateArn:J,hostedZoneId:Y,domain:Q}=$;if(!this.dnsProvider&&!Y)throw Error("Either hostedZoneId or external DNS provider configuration is required");let Z=await this.acm.getDnsValidationRecords(J),U=[];if(this.dnsProvider){let W=Q||Z[0]?.domainName;for(let z of Z){let G=await this.dnsProvider.upsertRecord(W,{name:z.recordName,type:z.recordType,content:z.recordValue,ttl:300});U.push({...z,changeId:G.success?G.id:void 0})}}else if(Y)for(let W of Z){let z=await this.route53.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:`ACM DNS validation for ${W.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:W.recordName,Type:W.recordType,TTL:300,ResourceRecords:[{Value:W.recordValue}]}}]}});U.push({...W,changeId:z.ChangeInfo?.Id})}return U}async deleteValidationRecords($){let{certificateArn:J,hostedZoneId:Y,domain:Q}=$,Z=await this.acm.getDnsValidationRecords(J);if(this.dnsProvider){let U=Q||Z[0]?.domainName;for(let W of Z)try{await this.dnsProvider.deleteRecord(U,{name:W.recordName,type:W.recordType,content:W.recordValue})}catch{}}else if(Y)for(let U of Z)try{await this.route53.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:`Cleanup ACM DNS validation for ${U.domainName}`,Changes:[{Action:"DELETE",ResourceRecordSet:{Name:U.recordName,Type:U.recordType,TTL:300,ResourceRecords:[{Value:U.recordValue}]}}]}})}catch{}}async findOrCreateCertificate($){let{domainName:J,hostedZoneId:Y,subjectAlternativeNames:Q,waitForValidation:Z=!0}=$;if(!this.dnsProvider&&!Y)throw Error("Either hostedZoneId or external DNS provider configuration is required");let U=await this.acm.findCertificateByDomain(J);if(U&&U.Status==="ISSUED")return{certificateArn:U.CertificateArn,isNew:!1};let{certificateArn:W}=await this.requestAndValidate({domainName:J,hostedZoneId:Y,subjectAlternativeNames:Q,waitForValidation:Z});return{certificateArn:W,isNew:!0}}hasExternalDnsProvider(){return this.dnsProvider!==void 0}getDnsProviderName(){return this.dnsProvider?.name||"route53"}}var s1=S0(()=>{z0();B9();B2()});class f2{acm;dnsProvider;constructor($,J="us-east-1"){if(this.acm=new y0(J),"provider"in $)this.dnsProvider=e0($);else this.dnsProvider=$}getProvider(){return this.dnsProvider}async requestAndValidate($){let{domainName:J,subjectAlternativeNames:Y=[],waitForValidation:Q=!1,maxWaitMinutes:Z=30}=$,{CertificateArn:U}=await this.acm.requestCertificate({DomainName:J,SubjectAlternativeNames:Y.length>0?[J,...Y]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(U);let W=await this.acm.getDnsValidationRecords(U);for(let G of W){let H=await this.dnsProvider.upsertRecord(J,{name:G.recordName,type:G.recordType,content:G.recordValue,ttl:300});if(!H.success)console.warn(`Failed to create validation record for ${G.domainName}: ${H.message}`)}let z="pending";if(Q)z=(await this.acm.waitForCertificateValidation(U,Z*2,30000))?.Status==="ISSUED"?"issued":"failed";return{certificateArn:U,validationRecords:W.map((G)=>({domainName:G.domainName,recordName:G.recordName,recordType:G.recordType,recordValue:G.recordValue})),isNew:!0,status:z}}async createValidationRecords($){let{certificateArn:J,domain:Y}=$,Q=[],Z=await this.acm.getDnsValidationRecords(J);for(let U of Z){let W=await this.dnsProvider.upsertRecord(Y,{name:U.recordName,type:U.recordType,content:U.recordValue,ttl:300});if(!W.success)Q.push(`Failed to create record for ${U.domainName}: ${W.message}`)}return{success:Q.length===0,records:Z.map((U)=>({domainName:U.domainName,recordName:U.recordName,recordType:U.recordType,recordValue:U.recordValue})),errors:Q}}async deleteValidationRecords($){let{certificateArn:J,domain:Y}=$,Q=[],Z=await this.acm.getDnsValidationRecords(J);for(let U of Z){let W=await this.dnsProvider.deleteRecord(Y,{name:U.recordName,type:U.recordType,content:U.recordValue});if(!W.success)Q.push(`Failed to delete record for ${U.domainName}: ${W.message}`)}return{success:Q.length===0,errors:Q}}async findOrCreateCertificate($){let{domainName:J,subjectAlternativeNames:Y=[],waitForValidation:Q=!0,maxWaitMinutes:Z}=$,U=await this.acm.findCertificateByDomain(J);if(U&&U.Status==="ISSUED"){let W=U.SubjectAlternativeNames||[U.DomainName],z=W.some((H)=>H===`*.${J}`);if(Y.every((H)=>W.includes(H)||z))return{certificateArn:U.CertificateArn,validationRecords:[],isNew:!1,status:"issued"};console.log("Existing certificate doesn't cover all required SANs, requesting new certificate...")}return this.requestAndValidate({domainName:J,subjectAlternativeNames:Y,waitForValidation:Q,maxWaitMinutes:Z})}async requestCertificateWithCommonSans($){let{domainName:J,includeWww:Y=!0,includeWildcard:Q=!1,additionalSans:Z=[],waitForValidation:U=!1}=$,W=[];if(Y)W.push(`www.${J}`);if(Q)W.push(`*.${J}`);return W.push(...Z),this.requestAndValidate({domainName:J,subjectAlternativeNames:W,waitForValidation:U})}async waitForValidationOptions($,J=30){for(let Y=0;Y<J;Y++){let Q=await this.acm.describeCertificate({CertificateArn:$});if(Q.DomainValidationOptions&&Q.DomainValidationOptions.length>0&&Q.DomainValidationOptions[0].ResourceRecord)return;await new Promise((Z)=>setTimeout(Z,2000))}throw Error("Timeout waiting for DNS validation options")}async getCertificateStatus($){let J=await this.acm.describeCertificate({CertificateArn:$});return{status:J.Status,domainValidations:(J.DomainValidationOptions||[]).map((Y)=>({domain:Y.DomainName,status:Y.ValidationStatus||"UNKNOWN"}))}}}var Q6=S0(()=>{s1();B2()});function e0($){switch($.provider){case"route53":return new v2($.region,$.hostedZoneId);case"porkbun":return new F9($.apiKey,$.secretKey);case"godaddy":return new A9($.apiKey,$.apiSecret,$.environment);case"cloudflare":return new K9($.apiToken);default:throw Error(`Unknown DNS provider: ${$.provider}`)}}class O9{providers=new Map;configs=[];addConfig($){return this.configs.push($),this}addRoute53($,J){return this.configs.push({provider:"route53",region:$,hostedZoneId:J}),this}addPorkbun($,J){return this.configs.push({provider:"porkbun",apiKey:$,secretKey:J}),this}addGoDaddy($,J,Y){return this.configs.push({provider:"godaddy",apiKey:$,apiSecret:J,environment:Y}),this}addCloudflare($){return this.configs.push({provider:"cloudflare",apiToken:$}),this}loadFromEnv(){if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)this.addRoute53(process.env.AWS_REGION);let $=process.env.PORKBUN_API_KEY,J=process.env.PORKBUN_SECRET_KEY;if($&&J)this.addPorkbun($,J);let Y=process.env.GODADDY_API_KEY,Q=process.env.GODADDY_API_SECRET;if(Y&&Q){let U=process.env.GODADDY_ENVIRONMENT;this.addGoDaddy(Y,Q,U)}let Z=process.env.CLOUDFLARE_API_TOKEN;if(Z)this.addCloudflare(Z);return this}getProvider($){let J=this.providers.get($);if(J)return J;let Y=this.configs.find((Z)=>Z.provider===$);if(!Y)return null;let Q=e0(Y);return this.providers.set($,Q),Q}async getProviderForDomain($){for(let J of this.configs){let Y=e0(J);if(await Y.canManageDomain($))return Y}return null}getAllProviders(){return this.configs.map(($)=>e0($))}}var U_;var B2=S0(()=>{j9();Q6();j9();U_=new O9});var MZ={};Z1(MZ,{xrayManager:()=>$K,withTimeout:()=>XF,withSecurity:()=>SH,withQueue:()=>IH,withMonitoring:()=>NH,withDatabase:()=>PH,withCache:()=>xH,withCDN:()=>CH,validateTemplateSize:()=>Z4,validateTemplate:()=>aG,validateResourceLimits:()=>U4,validateCredentials:()=>nH,validateConfiguration:()=>pH,validateCommand:()=>JA,validateAgainstSchema:()=>RF,validateAccountStructure:()=>NA,templateCache:()=>JF,syntheticsManager:()=>QK,suggestRegions:()=>XA,suggestRegionPairs:()=>OA,suggestQuotaIncrease:()=>oH,suggestIAMPolicy:()=>iH,suggestFlags:()=>oF,suggestCommand:()=>v6,storageAdvancedManager:()=>bK,staticSiteManager:()=>hK,stackDependencyManager:()=>GA,signRequestAsync:()=>D9,signRequest:()=>v0,serviceMeshManager:()=>XK,sequence:()=>jF,senderReputationManager:()=>NK,securityScanningManager:()=>AK,securityHubManager:()=>iA,secretsRotationManager:()=>GK,secretsManager:()=>HK,searchCommands:()=>tF,sanitizeName:()=>G4,route53RoutingManager:()=>LK,route53ResolverManager:()=>TK,resourceManagementManager:()=>fK,resolveStorageBucketName:()=>H4,resolveSiteStackName:()=>X6,resolveSiteResourceName:()=>O6,resolveSiteBucketName:()=>_6,resolveRegion:()=>nQ,resolveProjectStackName:()=>A1,resolveDeployBucketName:()=>kQ,resolveCredentials:()=>C9,resolveCloudProvider:()=>w2,requiresReplacement:()=>EF,replicaManager:()=>UK,regionPairManager:()=>zA,quickHash:()=>HF,queueManagementManager:()=>kK,progressiveDeploymentManager:()=>eA,processInChunks:()=>OF,previewNotifications:()=>bF,previewManager:()=>CF,performanceManager:()=>WK,parseXMLResponse:()=>G$,parseJSONResponse:()=>RQ,parallelWithRetry:()=>BF,parallelMap:()=>KF,parallel:()=>I9,organizationManager:()=>LA,networkSecurityManager:()=>vK,multiRegionManager:()=>ZA,multiAccountManager:()=>VA,migrationManager:()=>ZK,metricsManager:()=>JK,mergeInfrastructure:()=>V2,makeAWSRequestOnce:()=>MQ,makeAWSRequestAsync:()=>TQ,makeAWSRequest:()=>_2,logsManager:()=>YK,lambdaVersionsManager:()=>_K,lambdaVPCManager:()=>wK,lambdaLayersManager:()=>OK,lambdaDestinationsManager:()=>EK,lambdaDLQManager:()=>VK,lambdaConcurrencyManager:()=>qK,isWebCryptoAvailable:()=>PQ,isValidRegion:()=>BA,isNodeCryptoAvailable:()=>SQ,isLocalDevelopment:()=>DF,isLikelyTypo:()=>aF,imageScanningManager:()=>KK,healthCheckManager:()=>yK,hashString:()=>x6,hashManifest:()=>GF,hashFile:()=>P6,hashDirectory:()=>zF,hashBuffer:()=>WF,guardDutyManager:()=>aA,globalResourceManager:()=>WA,getTimestamp:()=>z4,getSigningKeyCacheSize:()=>NQ,getRequiredPermissions:()=>JZ,getRegionsByPricingTier:()=>KA,getRegionsByLocation:()=>FA,getRegionsByCompliance:()=>AA,getRegionStats:()=>wA,getRegion:()=>u2,getRecommendedStructure:()=>RA,getQuotaUsageSummary:()=>sH,getLocalEnvVars:()=>PF,getLocalEndpoint:()=>NF,getLocalCredentials:()=>SF,getLocalConfig:()=>k9,getErrorDetails:()=>$Z,getDiffSummary:()=>qF,getDiffStats:()=>MF,getDeploymentStrategy:()=>LF,getCredentials:()=>q$,getContextualHelp:()=>iF,getCommandUsage:()=>$A,getClosestRegion:()=>jA,getAllRegions:()=>HA,getAccountId:()=>aQ,generateScheduledWorkflow:()=>IA,generateScheduledPipeline:()=>vA,generateScheduledConfig:()=>dA,generateResourceName:()=>v,generatePreviewWorkflow:()=>IF,generatePreviewPipeline:()=>yA,generateParallelConfig:()=>cA,generatePRPreviewWorkflow:()=>CA,generateMultiEnvWorkflow:()=>xA,generateMultiEnvPipeline:()=>bA,generateMultiEnvConfig:()=>uA,generateMatrixWorkflow:()=>kA,generateManualPipeline:()=>fA,generateLogicalId:()=>S,generateDeploymentWorkflow:()=>PA,generateDeploymentPipeline:()=>hA,generateDeploymentConfig:()=>gA,generateCrossAccountRoleCF:()=>DA,generateCostReportWorkflow:()=>hF,generateCleanupWorkflow:()=>kF,generateApprovalConfig:()=>mA,fromWebIdentity:()=>rQ,fromSharedCredentials:()=>cQ,fromEnvironment:()=>mQ,fromECSMetadata:()=>pQ,fromEC2Metadata:()=>lQ,formatTree:()=>gF,formatTable:()=>yF,formatSuggestion:()=>nF,formatRegionList:()=>EA,formatRegion:()=>OZ,formatProgressBar:()=>uF,formatList:()=>cF,formatKeyValue:()=>lF,formatHistoryStats:()=>QA,formatHistory:()=>YA,formatFlagSuggestions:()=>eF,formatDuration:()=>mF,formatDiff:()=>B4,formatBytes:()=>dF,formatAccountStructure:()=>SA,findChangedFiles:()=>FF,fifoQueueManager:()=>xK,extendPreset:()=>A6,emailTemplateManager:()=>SK,emailAnalyticsManager:()=>DK,drManager:()=>pA,dnssecManager:()=>MK,dlqMonitoringManager:()=>CK,diffTemplates:()=>_F,detectServiceRegion:()=>R9,detectMisconfigurations:()=>rH,defaultLocalConfig:()=>C6,databaseUserManager:()=>zK,crossRegionReferenceManager:()=>UA,createWordPressPreset:()=>qH,createTraditionalWebAppPreset:()=>TH,createStaticSitePreset:()=>BH,createS3Client:()=>lH,createRealtimeAppPreset:()=>VH,createPresignedUrlAsync:()=>OQ,createPresignedUrl:()=>j6,createPreset:()=>DH,createNodeJsServerlessPreset:()=>XH,createNodeJsServerPreset:()=>jH,createMockAWS:()=>xF,createMicroservicesPreset:()=>wH,createMLApiPreset:()=>MH,createJamstackPreset:()=>EH,createFullStackAppPreset:()=>OH,createError:()=>B6,createDataPipelinePreset:()=>LH,createCredentialProvider:()=>hH,createApiBackendPreset:()=>_H,containerRegistryManager:()=>jK,composePresets:()=>RH,cloudTrailManager:()=>nA,cloudConfigSchema:()=>TF,clearSigningKeyCache:()=>DQ,chunk:()=>WZ,checkServiceQuotas:()=>tH,checkIAMPermissions:()=>aH,certificateManager:()=>FK,categorizeChanges:()=>VF,canaryManager:()=>sA,buildOptimizationManager:()=>BK,buildCloudFormationTemplate:()=>KH,bounceComplaintHandler:()=>RK,blueGreenManager:()=>tA,batchProcessingManager:()=>IK,batch:()=>AF,backupManager:()=>lA,awsConfigManager:()=>rA,autocomplete:()=>sF,analyzeStackDiff:()=>F4,abTestManager:()=>oA,XRayManager:()=>e6,Workflow:()=>fQ,ValidationError:()=>R6,TemplateCache:()=>N6,TemplateBuilder:()=>P9,TaskList:()=>AZ,SyntheticsManager:()=>O2,StorageAdvancedManager:()=>l7,Storage:()=>X1,StaticSiteManager:()=>c7,StacksIntegration:()=>q4,StackDependencyManager:()=>m6,Spinner:()=>FZ,SmsHandlers:()=>vQ,SmsAdvanced:()=>LZ,ServiceMeshManager:()=>B7,SenderReputationManager:()=>R7,SecurityScanningManager:()=>H7,SecurityHubManager:()=>X2,Security:()=>L0,SecretsRotationManager:()=>W7,SecretsManager:()=>z7,Secrets:()=>g2,Search:()=>Y2,SMS:()=>r0,S3Error:()=>J1,S3Client:()=>T6,Route53RoutingManager:()=>w7,Route53ResolverManager:()=>L7,ResourceManagementManager:()=>n7,ReplicaManager:()=>Q7,Registry:()=>T1,RegionPairManager:()=>d6,Redirects:()=>c1,RealtimePresets:()=>nG,RateLimiter:()=>UZ,REPLContext:()=>BZ,REPLCommandBuilder:()=>jZ,REPL:()=>KZ,RECOMMENDED_SCPS:()=>MA,RECOMMENDED_ACCOUNT_STRUCTURES:()=>_Z,QueuePresets:()=>rG,QueueManagementManager:()=>m7,Queue:()=>t0,Pseudo:()=>W4,ProgressiveDeploymentManager:()=>o6,ProgressBar:()=>GZ,PreviewNotificationService:()=>y6,PreviewEnvironmentManager:()=>b6,PhoneHandlers:()=>yQ,PhoneAdvanced:()=>VZ,Phone:()=>R1,Permissions:()=>Y1,PerformanceManager:()=>Z7,ParameterStore:()=>D0,OrganizationManager:()=>l6,NetworkSecurityManager:()=>r7,Network:()=>E0,MultiStepProgress:()=>HZ,MultiRegionManager:()=>f6,MultiAccountManager:()=>c6,Monitoring:()=>_$,MockS3:()=>k6,MockDynamoDB:()=>h6,MockCloudFormation:()=>I6,MigrationManager:()=>Y7,MetricsManager:()=>$7,Messaging:()=>$1,LogsManager:()=>J7,LambdaVersionsManager:()=>X7,LambdaVPCManager:()=>q7,LambdaLayersManager:()=>j7,LambdaDestinationsManager:()=>_7,LambdaDLQManager:()=>E7,LambdaConcurrencyManager:()=>O7,JobLoader:()=>m1,ImageScanningManager:()=>F7,HealthCheckManager:()=>p7,HashCache:()=>QZ,GuardDutyManager:()=>i6,GlobalResourceManager:()=>u6,Fn:()=>q,FileSystem:()=>D1,FileCache:()=>D6,FIFOQueueManager:()=>g7,ErrorCodes:()=>eQ,EmailTemplateManager:()=>D7,EmailHandlers:()=>EZ,EmailAnalyticsManager:()=>T7,EmailAdvanced:()=>qZ,Email:()=>H0,DisasterRecoveryManager:()=>r6,DeploymentError:()=>sQ,Deployment:()=>a0,DependencyGraph:()=>hQ,DebugLogger:()=>Q1,DatabaseUserManager:()=>U7,Database:()=>Q2,DNSSECManager:()=>V7,DNS:()=>p0,DLQMonitoringManager:()=>u7,DEFAULT_SERVICE_LIMITS:()=>l0,CrossRegionReferenceManager:()=>g6,CredentialError:()=>$2,ContainerRegistryManager:()=>K7,ConfigurationError:()=>F$,Compute:()=>n,Communication:()=>i0,CommandHistory:()=>XZ,CloudTrailManager:()=>a6,CloudFrontClient:()=>tQ,CloudFormationClient:()=>iQ,CloudFormationBuilder:()=>V6,CloudError:()=>N1,CertificateManager:()=>G7,CanaryManager:()=>j$,Cache:()=>O$,COMMON_CROSS_ACCOUNT_ROLES:()=>TA,CDN:()=>j1,BuildOptimizationManager:()=>A7,BounceComplaintHandler:()=>M7,BlueGreenManager:()=>t6,BatchProcessingManager:()=>d7,BackupManager:()=>p6,Auth:()=>n0,AssetHasher:()=>h0,Arn:()=>K$,ApiGateway:()=>x9,AWS_REGIONS:()=>_1,AWS_PSEUDO_PARAMETERS:()=>N4,AWSConfigManager:()=>n6,AWSAPIError:()=>oQ,AI:()=>O1,ABTestManager:()=>s6});import{createRequire as fG}from"node:module";import{existsSync as Q$,readdirSync as j4}from"node:fs";import{join as e1}from"node:path";import{createHash as L4}from"node:crypto";import{readFileSync as _9,readdirSync as M4,statSync as T4,existsSync as U6,writeFileSync as q9,copyFileSync as R4}from"node:fs";import{join as Z$,basename as D4,dirname as WQ,extname as zQ}from"node:path";import{readFileSync as M6,existsSync as gQ}from"node:fs";import{homedir as uQ}from"node:os";import{join as dQ}from"node:path";import{createHash as YZ}from"node:crypto";import{existsSync as AQ,mkdirSync as eH,readFileSync as KQ,readdirSync as BQ,unlinkSync as U$,writeFileSync as $F}from"node:fs";import{join as z6}from"node:path";import{createHash as S6}from"node:crypto";import{createReadStream as YF,readdirSync as QF,statSync as M9}from"node:fs";import{join as ZF,relative as UF}from"node:path";function dG($,J){this[$]=uG.bind(null,J)}function R9($){let J=typeof $==="string"?new URL($):$,{hostname:Y,pathname:Q}=J;if(Y.endsWith(".on.aws")){let z=Y.match(/^[^.]+\.lambda-url\.([^.]+)\.on\.aws$/);if(z)return{service:"lambda",region:z[1]};return{service:"",region:""}}if(Y.endsWith(".r2.cloudflarestorage.com"))return{service:"s3",region:"auto"};if(Y.endsWith(".backblazeb2.com")){let z=Y.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);if(z)return{service:"s3",region:z[1]};return{service:"",region:""}}let Z=Y.replace("dualstack.","").match(/([^.]+)\.(?:([^.]+)\.)?amazonaws\.com(?:\.cn)?$/);if(!Z)return{service:"",region:""};let U=Z[1],W=Z[2]||"";if(W==="us-gov")W="us-gov-west-1";else if(W==="s3"||W==="s3-accelerate")W="us-east-1",U="s3";else if(U==="iot")if(Y.startsWith("iot."))U="execute-api";else if(Y.startsWith("data.jobs.iot."))U="iot-jobs-data";else U=Q==="/mqtt"?"iotdevicegateway":"iotdata";else if(U==="autoscaling");else if(!W&&U.startsWith("s3-"))W=U.slice(3).replace(/^fips-|^external-1/,""),U="s3";else if(U.endsWith("-fips"))U=U.slice(0,-5);else if(W&&/-\d$/.test(U)&&!/-\d$/.test(W))[U,W]=[W,U];return U=CQ[U]||U,{service:U,region:W||"us-east-1"}}function v0($){let{method:J,url:Y,body:Q="",accessKeyId:Z,secretAccessKey:U,sessionToken:W,signQuery:z=!1,expiresIn:G=86400,datetime:H}=$,A=new URL(Y),K=A.hostname,B=R9(A),j=$.service||B.service,X=$.region||B.region;if(!j)throw Error("Could not detect service from URL. Please provide service explicitly.");if(!X)throw Error("Could not detect region from URL. Please provide region explicitly.");let O=H||new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),_=O.substring(0,8),w=[_,X,j,"aws4_request"].join("/"),E="AWS4-HMAC-SHA256";if(z)return lG({urlObj:A,method:J,body:Q,accessKeyId:Z,secretAccessKey:U,sessionToken:W,service:j,region:X,timestamp:O,date:_,credentialScope:w,algorithm:E,expiresIn:G,cache:$.cache});let M=A.pathname||"/",T=N9(A.searchParams),D={host:K,"x-amz-date":O,...$.headers};if(W)D["x-amz-security-token"]=W;let N=Object.keys(D).some((r)=>r.toLowerCase()==="content-type");if(Q&&!N)D["content-type"]="application/x-amz-json-1.0";if(j==="s3"&&!D["x-amz-content-sha256"])D["x-amz-content-sha256"]=z$(Q);let x=_Q(D),h=qQ(D),k=D["x-amz-content-sha256"]||z$(Q),b=[J,S9(M),T,x,h,k].join(`
56
- `),I=z$(b),f=[E,O,w,I].join(`
57
- `),m=$.cache??E2,l=wQ(U,_,X,j,f,m),p=[`${E} Credential=${Z}/${w}`,`SignedHeaders=${h}`,`Signature=${l}`].join(", ");return D.authorization=p,{url:Y,method:J,headers:D,body:Q||void 0}}async function D9($){let{method:J,url:Y,body:Q="",accessKeyId:Z,secretAccessKey:U,sessionToken:W,signQuery:z=!1,expiresIn:G=86400,datetime:H}=$,A=new URL(Y),K=A.hostname,B=R9(A),j=$.service||B.service,X=$.region||B.region;if(!j)throw Error("Could not detect service from URL. Please provide service explicitly.");if(!X)throw Error("Could not detect region from URL. Please provide region explicitly.");let O=H||new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),_=O.substring(0,8),w=[_,X,j,"aws4_request"].join("/"),E="AWS4-HMAC-SHA256";if(z)return pG({urlObj:A,method:J,body:Q,accessKeyId:Z,secretAccessKey:U,sessionToken:W,service:j,region:X,timestamp:O,date:_,credentialScope:w,algorithm:E,expiresIn:G,cache:$.cache});let M=A.pathname||"/",T=N9(A.searchParams),D={host:K,"x-amz-date":O,...$.headers};if(W)D["x-amz-security-token"]=W;let N=Object.keys(D).some((s)=>s.toLowerCase()==="content-type");if(Q&&!N)D["content-type"]="application/x-amz-json-1.0";let x=await w9(Q);if(j==="s3"&&!D["x-amz-content-sha256"])D["x-amz-content-sha256"]=x;let h=_Q(D),k=qQ(D),b=D["x-amz-content-sha256"]||x,I=[J,S9(M),T,h,k,b].join(`
58
- `),f=await w9(I),m=[E,O,w,f].join(`
59
- `),l=$.cache??E2,p=await VQ(U,_,X,j,m,l),r=[`${E} Credential=${Z}/${w}`,`SignedHeaders=${k}`,`Signature=${p}`].join(", ");return D.authorization=r,{url:Y,method:J,headers:D,body:Q||void 0}}function lG($){let{urlObj:J,method:Y,body:Q,accessKeyId:Z,secretAccessKey:U,sessionToken:W,service:z,region:G,timestamp:H,date:A,credentialScope:K,algorithm:B,expiresIn:j,cache:X}=$,O=new URL(J.toString());O.searchParams.set("X-Amz-Algorithm",B),O.searchParams.set("X-Amz-Credential",`${Z}/${K}`),O.searchParams.set("X-Amz-Date",H),O.searchParams.set("X-Amz-Expires",String(j));let _=z==="s3"?"UNSIGNED-PAYLOAD":z$(Q);if(z==="s3")O.searchParams.set("X-Amz-Content-Sha256",_);let w="host";if(O.searchParams.set("X-Amz-SignedHeaders",w),W)O.searchParams.set("X-Amz-Security-Token",W);let E=S9(O.pathname||"/"),M=`host:${O.hostname}
55
+ </ChangeResourceRecordSetsRequest>`;let Q=await this.client.request({service:"route53",region:this.region,method:"POST",path:`/2013-04-01/hostedzone/${J}/rrset`,headers:{"content-type":"application/xml"},body:Y});return this.parseChangeResourceRecordSetsResponse(Q)}escapeXml($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}parseCreateHostedZoneResponse($){let J=$.CreateHostedZoneResponse||$;return{HostedZone:this.parseHostedZone(J.HostedZone),ChangeInfo:{Id:J.ChangeInfo?.Id||"",Status:J.ChangeInfo?.Status||"",SubmittedAt:J.ChangeInfo?.SubmittedAt||""},DelegationSet:this.parseDelegationSet(J.DelegationSet),Location:J.Location||""}}parseListHostedZonesResponse($){let J=$.ListHostedZonesResponse||$.ListHostedZonesByNameResponse||$,Y=J.HostedZones?.HostedZone||J.HostedZones||[];if(!Array.isArray(Y))Y=Y?[Y]:[];return{HostedZones:Y.map((Q)=>this.parseHostedZone(Q)),IsTruncated:J.IsTruncated==="true"||J.IsTruncated===!0,MaxItems:J.MaxItems||"100",Marker:J.Marker,NextMarker:J.NextMarker}}parseGetHostedZoneResponse($){let J=$.GetHostedZoneResponse||$;return{HostedZone:this.parseHostedZone(J.HostedZone),DelegationSet:this.parseDelegationSet(J.DelegationSet),VPCs:J.VPCs?.VPC?Array.isArray(J.VPCs.VPC)?J.VPCs.VPC:[J.VPCs.VPC]:void 0}}parseListResourceRecordSetsResponse($){let J=$.ListResourceRecordSetsResponse||$,Y=J.ResourceRecordSets?.ResourceRecordSet||J.ResourceRecordSets||[];if(!Array.isArray(Y))Y=Y?[Y]:[];return{ResourceRecordSets:Y.map((Q)=>this.parseResourceRecordSet(Q)),IsTruncated:J.IsTruncated==="true"||J.IsTruncated===!0,MaxItems:J.MaxItems||"100",NextRecordName:J.NextRecordName,NextRecordType:J.NextRecordType,NextRecordIdentifier:J.NextRecordIdentifier}}parseChangeResourceRecordSetsResponse($){let J=$.ChangeResourceRecordSetsResponse||$;return{ChangeInfo:{Id:J.ChangeInfo?.Id||"",Status:J.ChangeInfo?.Status||"",SubmittedAt:J.ChangeInfo?.SubmittedAt||"",Comment:J.ChangeInfo?.Comment}}}parseHostedZone($){if(!$)return{Id:"",Name:""};return{Id:$.Id||"",Name:$.Name||"",CallerReference:$.CallerReference,Config:$.Config?{Comment:$.Config.Comment,PrivateZone:$.Config.PrivateZone==="true"||$.Config.PrivateZone===!0}:void 0,ResourceRecordSetCount:$.ResourceRecordSetCount?Number($.ResourceRecordSetCount):void 0}}parseDelegationSet($){if(!$)return{NameServers:[]};let J=$.NameServers?.NameServer||$.NameServers||[];if(!Array.isArray(J))J=J?[J]:[];return{Id:$.Id,CallerReference:$.CallerReference,NameServers:J}}parseResourceRecordSet($){if(!$)return{Name:"",Type:""};let J=$.ResourceRecords?.ResourceRecord||$.ResourceRecords||[];if(!Array.isArray(J))J=J?[J]:[];return{Name:$.Name||"",Type:$.Type||"",TTL:$.TTL?Number($.TTL):void 0,ResourceRecords:J.map((Y)=>({Value:Y.Value||Y})),AliasTarget:$.AliasTarget?{HostedZoneId:$.AliasTarget.HostedZoneId,DNSName:$.AliasTarget.DNSName,EvaluateTargetHealth:$.AliasTarget.EvaluateTargetHealth==="true"||$.AliasTarget.EvaluateTargetHealth===!0}:void 0,SetIdentifier:$.SetIdentifier,Weight:$.Weight?Number($.Weight):void 0,Region:$.Region,GeoLocation:$.GeoLocation,Failover:$.Failover,HealthCheckId:$.HealthCheckId}}async findHostedZoneByName($){let J=$.endsWith(".")?$:`${$}.`;return(await this.listHostedZonesByName({DNSName:J})).HostedZones.find((Z)=>Z.Name===J)||null}async createARecord($){let J=Array.isArray($.Value)?$.Value:[$.Value];return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"A",TTL:$.TTL||300,ResourceRecords:J.map((Y)=>({Value:Y}))}}]}})}async createCnameRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"CNAME",TTL:$.TTL||300,ResourceRecords:[{Value:$.Value}]}}]}})}async createAliasRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:$.Type||"A",AliasTarget:{HostedZoneId:$.TargetHostedZoneId,DNSName:$.TargetDNSName,EvaluateTargetHealth:$.EvaluateTargetHealth??!1}}}]}})}async createTxtRecord($){let Y=(Array.isArray($.Value)?$.Value:[$.Value]).map((Q)=>{if(!Q.startsWith('"'))return`"${Q}"`;return Q});return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"TXT",TTL:$.TTL||300,ResourceRecords:Y.map((Q)=>({Value:Q}))}}]}})}async createMxRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:$.Name,Type:"MX",TTL:$.TTL||300,ResourceRecords:$.Values.map((J)=>({Value:`${J.priority} ${J.mailServer}`}))}}]}})}async deleteRecord($){return this.changeResourceRecordSets({HostedZoneId:$.HostedZoneId,ChangeBatch:{Changes:[{Action:"DELETE",ResourceRecordSet:$.RecordSet}]}})}async waitForChange($,J=60,Y=5000){let Q=$.replace("/change/","");for(let Z=0;Z<J;Z++){let U=await this.client.request({service:"route53",region:this.region,method:"GET",path:`/2013-04-01/change/${Q}`});if((U.GetChangeResponse?.ChangeInfo?.Status||U.ChangeInfo?.Status)==="INSYNC")return!0;await new Promise((z)=>setTimeout(z,Y))}return!1}async findOrCreateHostedZone($){let J=$.domainName.endsWith(".")?$.domainName:`${$.domainName}.`,Y=await this.findHostedZoneByName(J);if(Y){let Z=await this.getHostedZone({Id:Y.Id});return{hostedZone:Y,nameServers:Z.DelegationSet.NameServers,isNew:!1}}let Q=await this.createHostedZone({Name:J,HostedZoneConfig:{Comment:$.comment||`Hosted zone for ${$.domainName}`,PrivateZone:$.privateZone},VPC:$.vpc});return{hostedZone:Q.HostedZone,nameServers:Q.DelegationSet.NameServers,isNew:!0}}static getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length<=2)return $;return J.slice(-2).join(".")}async findHostedZoneForDomain($){let Y=$.replace(/\.$/,"").split(".");for(let Q=0;Q<Y.length-1;Q++){let Z=Y.slice(Q).join("."),U=await this.findHostedZoneByName(Z);if(U)return U}return null}async ensureHostedZone($){let J=await this.findOrCreateHostedZone({domainName:$.domainName,comment:$.comment});return{hostedZoneId:J.hostedZone.Id.replace("/hostedzone/",""),nameServers:J.nameServers,isNew:J.isNew,action:J.isNew?"created":"found"}}async setupDomainDns($){let{domain:J,createIfNotExists:Y=!0}=$,Q=await this.findHostedZoneByName(J);if(Q){let U=await this.getHostedZone({Id:Q.Id});return{success:!0,hostedZoneId:Q.Id.replace("/hostedzone/",""),nameServers:U.DelegationSet.NameServers,isNew:!1,message:`Found existing hosted zone for ${J}`}}if(!Y)return{success:!1,hostedZoneId:null,nameServers:[],isNew:!1,message:`No hosted zone found for ${J} and createIfNotExists is false`};let Z=await this.createHostedZone({Name:J,HostedZoneConfig:{Comment:`Created automatically by ts-cloud for ${J}`}});return{success:!0,hostedZoneId:Z.HostedZone.Id.replace("/hostedzone/",""),nameServers:Z.DelegationSet.NameServers,isNew:!0,message:`Created new hosted zone for ${J}. Please update your domain registrar with these name servers: ${Z.DelegationSet.NameServers.join(", ")}`}}static CloudFrontHostedZoneId="Z2FDTNDATAQYW2";static S3WebsiteHostedZoneIds={"us-east-1":"Z3AQBSTGFYJSTF","us-east-2":"Z2O1EMRO9K5GLX","us-west-1":"Z2F56UZL2M1ACD","us-west-2":"Z3BJ6K6RIION7M","ap-east-1":"ZNB98KWMFR0R6","ap-south-1":"Z11RGJOFQNVJUP","ap-northeast-1":"Z2M4EHUR26P7ZW","ap-northeast-2":"Z3W03O7B5YMIYP","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"Z3O0J2DXBE1FTB","ap-southeast-2":"Z1WCIGYICN2BYD","ca-central-1":"Z1QDHH18159H29","eu-central-1":"Z21DNDUVLTQW6Q","eu-west-1":"Z1BKCTXD74EZPE","eu-west-2":"Z3GKZC51ZF0DB4","eu-west-3":"Z3R1K369G5AVDG","eu-north-1":"Z3BAZG2TWCNX0D","sa-east-1":"Z7KQH4QJS55SO"};static ALBHostedZoneIds={"us-east-1":"Z35SXDOTRQ7X7K","us-east-2":"Z3AADJGX6KTTL2","us-west-1":"Z368ELLRRE2KJ0","us-west-2":"Z1H1FL5HABSF5","ap-east-1":"Z3DQVH9N71FHZ0","ap-south-1":"ZP97RAFLXTNZK","ap-northeast-1":"Z14GRHDCWA56QT","ap-northeast-2":"ZWKZPGTI48KDX","ap-northeast-3":"Z5LXEBD8Y73MNV","ap-southeast-1":"Z1LMS91P8CMLE5","ap-southeast-2":"Z1GM3OXH4ZPM65","ca-central-1":"ZQSVJUPU6J1EY","eu-central-1":"Z215JYRZR1TBD5","eu-west-1":"Z32O12XQLNTSW2","eu-west-2":"ZHURV8PSTC4K8","eu-west-3":"Z3Q77PNBQS71R4","eu-north-1":"Z23TAZ6LKFMNIO","sa-east-1":"Z2P70J7HTTTPLU"};static APIGatewayHostedZoneIds={"us-east-1":"Z1UJRXOUMOOFQ8","us-east-2":"ZOJJZC49E0EPZ","us-west-1":"Z2MUQ32089INYE","us-west-2":"Z2OJLYMUO9EFXC","ap-east-1":"Z3FD1VL90ND7K5","ap-south-1":"Z3VO1THU9YC4UR","ap-northeast-1":"Z1YSHQZHG15GKL","ap-northeast-2":"Z20JF4UZKIW1U8","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"ZL327KTPIQFUL","ap-southeast-2":"Z2RPCDW04V8134","ca-central-1":"Z19DQILCV0OWEC","eu-central-1":"Z1U9ULNL0V5AJ3","eu-west-1":"ZLY8HYME6SFDD","eu-west-2":"ZJ5UAJN8Y3Z2Q","eu-west-3":"Z3KY65QIEKYHQQ","eu-north-1":"Z3UWIKFBOOGXPP","sa-east-1":"ZCMLWB8V5SYIT"}}});class v2{name="route53";client;hostedZoneCache=new Map;providedHostedZoneId;constructor($="us-east-1",J){this.client=new o0($),this.providedHostedZoneId=J}getRootDomain($){let J=$.replace(/\.$/,"").split(".");if(J.length>=2)return J.slice(-2).join(".");return $}async getHostedZoneId($){if(this.providedHostedZoneId)return this.providedHostedZoneId;let J=this.getRootDomain($),Y=this.hostedZoneCache.get(J);if(Y)return Y;let Q=await this.client.findHostedZoneForDomain($);if(Q){let Z=Q.Id.replace("/hostedzone/","");return this.hostedZoneCache.set(J,Z),Z}return null}normalizeName($){return $.endsWith(".")?$:`${$}.`}async createRecord($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,message:`No hosted zone found for domain: ${$}`};let Q=this.normalizeName(J.name),Z=J.content;if(J.type==="TXT"&&!Z.startsWith('"'))Z=`"${Z}"`;if(J.type==="MX"&&J.priority!==void 0)Z=`${J.priority} ${Z}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:"Created by ts-cloud DNS provider",Changes:[{Action:"CREATE",ResourceRecordSet:{Name:Q,Type:J.type,TTL:J.ttl||300,ResourceRecords:[{Value:Z}]}}]}})).ChangeInfo?.Id,message:"Record created successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async upsertRecord($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,message:`No hosted zone found for domain: ${$}`};let Q=this.normalizeName(J.name),Z=J.content;if(J.type==="TXT"&&!Z.startsWith('"'))Z=`"${Z}"`;if(J.type==="MX"&&J.priority!==void 0)Z=`${J.priority} ${Z}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:"Upserted by ts-cloud DNS provider",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:Q,Type:J.type,TTL:J.ttl||300,ResourceRecords:[{Value:Z}]}}]}})).ChangeInfo?.Id,message:"Record upserted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async deleteRecord($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,message:`No hosted zone found for domain: ${$}`};let Q=this.normalizeName(J.name),Z=J.content;if(J.type==="TXT"&&!Z.startsWith('"'))Z=`"${Z}"`;if(J.type==="MX"&&J.priority!==void 0)Z=`${J.priority} ${Z}`;return await this.client.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:"Deleted by ts-cloud DNS provider",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:Q,Type:J.type,TTL:J.ttl||300,ResourceRecords:[{Value:Z}]}}]}}),{success:!0,message:"Record deleted successfully"}}catch(Y){return{success:!1,message:Y instanceof Error?Y.message:"Unknown error"}}}async listRecords($,J){try{let Y=await this.getHostedZoneId($);if(!Y)return{success:!1,records:[],message:`No hosted zone found for domain: ${$}`};let Q=await this.client.listResourceRecordSets({HostedZoneId:Y,StartRecordType:J}),Z=[];for(let U of Q.ResourceRecordSets){if(J&&U.Type!==J)continue;if(U.AliasTarget)continue;for(let W of U.ResourceRecords||[]){let z=W.Value,G;if(U.Type==="MX"){let H=z.split(" ");if(H.length>=2)G=Number.parseInt(H[0],10),z=H.slice(1).join(" ")}if(U.Type==="TXT"&&z.startsWith('"')&&z.endsWith('"'))z=z.slice(1,-1);Z.push({name:U.Name.replace(/\.$/,""),type:U.Type,content:z,ttl:U.TTL,priority:G})}}return{success:!0,records:Z}}catch(Y){return{success:!1,records:[],message:Y instanceof Error?Y.message:"Unknown error"}}}async canManageDomain($){return await this.getHostedZoneId($)!==null}async listDomains(){try{return(await this.client.listHostedZones()).HostedZones.map((J)=>J.Name.replace(/\.$/,""))}catch{return[]}}getRoute53Client(){return this.client}async createAliasRecord($){try{let J=await this.getHostedZoneId($.domain);if(!J)return{success:!1,message:`No hosted zone found for domain: ${$.domain}`};return{success:!0,id:(await this.client.createAliasRecord({HostedZoneId:J,Name:this.normalizeName($.name),TargetHostedZoneId:$.targetHostedZoneId,TargetDNSName:$.targetDnsName,EvaluateTargetHealth:$.evaluateTargetHealth,Type:$.type})).ChangeInfo?.Id,message:"Alias record created successfully"}}catch(J){return{success:!1,message:J instanceof Error?J.message:"Unknown error"}}}async createCloudFrontAlias($){return this.createAliasRecord({domain:$.domain,name:$.name,targetHostedZoneId:o0.CloudFrontHostedZoneId,targetDnsName:$.cloudFrontDomainName,evaluateTargetHealth:!1})}async createAlbAlias($){let J=o0.ALBHostedZoneIds[$.region];if(!J)return{success:!1,message:`Unknown region for ALB: ${$.region}`};return this.createAliasRecord({domain:$.domain,name:$.name,targetHostedZoneId:J,targetDnsName:$.albDnsName,evaluateTargetHealth:!0})}}var j9=S0(()=>{B9()});var UQ={};Z1(UQ,{ACMDnsValidator:()=>X9,ACMClient:()=>y0});class y0{client;region;constructor($="us-east-1"){this.client=new t,this.region=$}async requestCertificate($){let J={DomainName:$.DomainName,ValidationMethod:$.ValidationMethod||"DNS"};if($.SubjectAlternativeNames)J.SubjectAlternativeNames=$.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(J)})).CertificateArn||""}}async describeCertificate($){let Y=(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:$.CertificateArn})})).Certificate||{};return{CertificateArn:Y.CertificateArn||"",DomainName:Y.DomainName||"",SubjectAlternativeNames:Y.SubjectAlternativeNames,Status:Y.Status||"PENDING_VALIDATION",Type:Y.Type,DomainValidationOptions:Y.DomainValidationOptions?.map((Q)=>({DomainName:Q.DomainName,ValidationDomain:Q.ValidationDomain,ValidationStatus:Q.ValidationStatus,ResourceRecord:Q.ResourceRecord?{Name:Q.ResourceRecord.Name,Type:Q.ResourceRecord.Type,Value:Q.ResourceRecord.Value}:void 0,ValidationMethod:Q.ValidationMethod})),CreatedAt:Y.CreatedAt,IssuedAt:Y.IssuedAt,NotBefore:Y.NotBefore,NotAfter:Y.NotAfter}}async listCertificates($){let J={};if($?.CertificateStatuses)J.CertificateStatuses=$.CertificateStatuses;if($?.MaxItems)J.MaxItems=$.MaxItems;if($?.NextToken)J.NextToken=$.NextToken;let Y=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(J)});return{CertificateSummaryList:(Y.CertificateSummaryList||[]).map((Q)=>({CertificateArn:Q.CertificateArn,DomainName:Q.DomainName})),NextToken:Y.NextToken}}async deleteCertificate($){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:$.CertificateArn})})}async listTagsForCertificate($){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:$.CertificateArn})})).Tags||[]}}async addTagsToCertificate($){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:$.CertificateArn,Tags:$.Tags})})}async resendValidationEmail($){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:$.CertificateArn,Domain:$.Domain,ValidationDomain:$.ValidationDomain})})}async findCertificateByDomain($){let Y=(await this.listCertificates({CertificateStatuses:["ISSUED"]})).CertificateSummaryList.find((Q)=>Q.DomainName===$||Q.DomainName===`*.${$.split(".").slice(1).join(".")}`);if(!Y)return null;return this.describeCertificate({CertificateArn:Y.CertificateArn})}async waitForCertificateValidation($,J=60,Y=30000){for(let Q=0;Q<J;Q++){let Z=await this.describeCertificate({CertificateArn:$});if(Z.Status==="ISSUED")return Z;if(Z.Status==="FAILED"||Z.Status==="VALIDATION_TIMED_OUT")return null;await new Promise((U)=>setTimeout(U,Y))}return null}async getDnsValidationRecords($){let J=await this.describeCertificate({CertificateArn:$});if(!J.DomainValidationOptions)return[];return J.DomainValidationOptions.filter((Y)=>Y.ResourceRecord&&Y.ValidationMethod==="DNS").map((Y)=>({domainName:Y.DomainName,recordName:Y.ResourceRecord.Name,recordType:Y.ResourceRecord.Type,recordValue:Y.ResourceRecord.Value}))}async requestCertificateWithSans($){let J=new Set;if(J.add($.DomainName),$.IncludeWww!==!1)J.add(`www.${$.DomainName}`);if($.IncludeWildcard)J.add(`*.${$.DomainName}`);if($.AdditionalSans)for(let Y of $.AdditionalSans)J.add(Y);return this.requestCertificate({DomainName:$.DomainName,SubjectAlternativeNames:Array.from(J),ValidationMethod:"DNS"})}async isCertificateValidForDomain($,J){let Y=await this.describeCertificate({CertificateArn:$});if(Y.Status!=="ISSUED")return!1;if(Y.DomainName===J)return!0;if(Y.DomainName?.startsWith("*.")){let Q=Y.DomainName.slice(2),Z=J.split("."),U=Q.split(".");if(Z.slice(-U.length).join(".")===Q)return!0}if(Y.SubjectAlternativeNames)for(let Q of Y.SubjectAlternativeNames){if(Q===J)return!0;if(Q.startsWith("*.")){let Z=Q.slice(2),U=J.split("."),W=Z.split(".");if(U.slice(-W.length).join(".")===Z)return!0}}return!1}}class X9{acm;route53;dnsProvider;constructor($="us-east-1",J){if(this.acm=new y0($),this.route53=new o0,J&&J.provider!=="route53")this.dnsProvider=e0(J)}async requestAndValidate($){let{domainName:J,hostedZoneId:Y,subjectAlternativeNames:Q=[],waitForValidation:Z=!1,maxWaitMinutes:U=30}=$;if(!this.dnsProvider&&!Y)throw Error("Either hostedZoneId or external DNS provider configuration is required");let{CertificateArn:W}=await this.acm.requestCertificate({DomainName:J,SubjectAlternativeNames:Q.length>0?[J,...Q]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(W);let z=await this.acm.getDnsValidationRecords(W);if(this.dnsProvider)for(let G of z){let H=await this.dnsProvider.upsertRecord(J,{name:G.recordName,type:G.recordType,content:G.recordValue,ttl:300});if(!H.success)console.warn(`Failed to create validation record for ${G.domainName}: ${H.message}`)}else if(Y)for(let G of z)await this.route53.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:`ACM DNS validation for ${G.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:G.recordName,Type:G.recordType,TTL:300,ResourceRecords:[{Value:G.recordValue}]}}]}});if(Z){if(!await this.acm.waitForCertificateValidation(W,U*2,30000))throw Error(`Certificate validation timed out after ${U} minutes`)}return{certificateArn:W,validationRecords:z}}async waitForValidationOptions($,J=30){for(let Y=0;Y<J;Y++){let Q=await this.acm.describeCertificate({CertificateArn:$});if(Q.DomainValidationOptions&&Q.DomainValidationOptions.length>0&&Q.DomainValidationOptions[0].ResourceRecord)return;await new Promise((Z)=>setTimeout(Z,2000))}throw Error("Timeout waiting for DNS validation options")}async createValidationRecords($){let{certificateArn:J,hostedZoneId:Y,domain:Q}=$;if(!this.dnsProvider&&!Y)throw Error("Either hostedZoneId or external DNS provider configuration is required");let Z=await this.acm.getDnsValidationRecords(J),U=[];if(this.dnsProvider){let W=Q||Z[0]?.domainName;for(let z of Z){let G=await this.dnsProvider.upsertRecord(W,{name:z.recordName,type:z.recordType,content:z.recordValue,ttl:300});U.push({...z,changeId:G.success?G.id:void 0})}}else if(Y)for(let W of Z){let z=await this.route53.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:`ACM DNS validation for ${W.domainName}`,Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:W.recordName,Type:W.recordType,TTL:300,ResourceRecords:[{Value:W.recordValue}]}}]}});U.push({...W,changeId:z.ChangeInfo?.Id})}return U}async deleteValidationRecords($){let{certificateArn:J,hostedZoneId:Y,domain:Q}=$,Z=await this.acm.getDnsValidationRecords(J);if(this.dnsProvider){let U=Q||Z[0]?.domainName;for(let W of Z)try{await this.dnsProvider.deleteRecord(U,{name:W.recordName,type:W.recordType,content:W.recordValue})}catch{}}else if(Y)for(let U of Z)try{await this.route53.changeResourceRecordSets({HostedZoneId:Y,ChangeBatch:{Comment:`Cleanup ACM DNS validation for ${U.domainName}`,Changes:[{Action:"DELETE",ResourceRecordSet:{Name:U.recordName,Type:U.recordType,TTL:300,ResourceRecords:[{Value:U.recordValue}]}}]}})}catch{}}async findOrCreateCertificate($){let{domainName:J,hostedZoneId:Y,subjectAlternativeNames:Q,waitForValidation:Z=!0}=$;if(!this.dnsProvider&&!Y)throw Error("Either hostedZoneId or external DNS provider configuration is required");let U=await this.acm.findCertificateByDomain(J);if(U&&U.Status==="ISSUED")return{certificateArn:U.CertificateArn,isNew:!1};let{certificateArn:W}=await this.requestAndValidate({domainName:J,hostedZoneId:Y,subjectAlternativeNames:Q,waitForValidation:Z});return{certificateArn:W,isNew:!0}}hasExternalDnsProvider(){return this.dnsProvider!==void 0}getDnsProviderName(){return this.dnsProvider?.name||"route53"}}var s1=S0(()=>{z0();B9();B2()});class f2{acm;dnsProvider;constructor($,J="us-east-1"){if(this.acm=new y0(J),"provider"in $)this.dnsProvider=e0($);else this.dnsProvider=$}getProvider(){return this.dnsProvider}async requestAndValidate($){let{domainName:J,subjectAlternativeNames:Y=[],waitForValidation:Q=!1,maxWaitMinutes:Z=30}=$,{CertificateArn:U}=await this.acm.requestCertificate({DomainName:J,SubjectAlternativeNames:Y.length>0?[J,...Y]:void 0,ValidationMethod:"DNS"});await this.waitForValidationOptions(U);let W=await this.acm.getDnsValidationRecords(U);for(let G of W){let H=await this.dnsProvider.upsertRecord(J,{name:G.recordName,type:G.recordType,content:G.recordValue,ttl:300});if(!H.success)console.warn(`Failed to create validation record for ${G.domainName}: ${H.message}`)}let z="pending";if(Q)z=(await this.acm.waitForCertificateValidation(U,Z*2,30000))?.Status==="ISSUED"?"issued":"failed";return{certificateArn:U,validationRecords:W.map((G)=>({domainName:G.domainName,recordName:G.recordName,recordType:G.recordType,recordValue:G.recordValue})),isNew:!0,status:z}}async createValidationRecords($){let{certificateArn:J,domain:Y}=$,Q=[],Z=await this.acm.getDnsValidationRecords(J);for(let U of Z){let W=await this.dnsProvider.upsertRecord(Y,{name:U.recordName,type:U.recordType,content:U.recordValue,ttl:300});if(!W.success)Q.push(`Failed to create record for ${U.domainName}: ${W.message}`)}return{success:Q.length===0,records:Z.map((U)=>({domainName:U.domainName,recordName:U.recordName,recordType:U.recordType,recordValue:U.recordValue})),errors:Q}}async deleteValidationRecords($){let{certificateArn:J,domain:Y}=$,Q=[],Z=await this.acm.getDnsValidationRecords(J);for(let U of Z){let W=await this.dnsProvider.deleteRecord(Y,{name:U.recordName,type:U.recordType,content:U.recordValue});if(!W.success)Q.push(`Failed to delete record for ${U.domainName}: ${W.message}`)}return{success:Q.length===0,errors:Q}}async findOrCreateCertificate($){let{domainName:J,subjectAlternativeNames:Y=[],waitForValidation:Q=!0,maxWaitMinutes:Z}=$,U=await this.acm.findCertificateByDomain(J);if(U&&U.Status==="ISSUED"){let W=U.SubjectAlternativeNames||[U.DomainName],z=W.some((H)=>H===`*.${J}`);if(Y.every((H)=>W.includes(H)||z))return{certificateArn:U.CertificateArn,validationRecords:[],isNew:!1,status:"issued"};console.log("Existing certificate doesn't cover all required SANs, requesting new certificate...")}return this.requestAndValidate({domainName:J,subjectAlternativeNames:Y,waitForValidation:Q,maxWaitMinutes:Z})}async requestCertificateWithCommonSans($){let{domainName:J,includeWww:Y=!0,includeWildcard:Q=!1,additionalSans:Z=[],waitForValidation:U=!1}=$,W=[];if(Y)W.push(`www.${J}`);if(Q)W.push(`*.${J}`);return W.push(...Z),this.requestAndValidate({domainName:J,subjectAlternativeNames:W,waitForValidation:U})}async waitForValidationOptions($,J=30){for(let Y=0;Y<J;Y++){let Q=await this.acm.describeCertificate({CertificateArn:$});if(Q.DomainValidationOptions&&Q.DomainValidationOptions.length>0&&Q.DomainValidationOptions[0].ResourceRecord)return;await new Promise((Z)=>setTimeout(Z,2000))}throw Error("Timeout waiting for DNS validation options")}async getCertificateStatus($){let J=await this.acm.describeCertificate({CertificateArn:$});return{status:J.Status,domainValidations:(J.DomainValidationOptions||[]).map((Y)=>({domain:Y.DomainName,status:Y.ValidationStatus||"UNKNOWN"}))}}}var Q6=S0(()=>{s1();B2()});function e0($){switch($.provider){case"route53":return new v2($.region,$.hostedZoneId);case"porkbun":return new F9($.apiKey,$.secretKey);case"godaddy":return new A9($.apiKey,$.apiSecret,$.environment);case"cloudflare":return new K9($.apiToken);default:throw Error(`Unknown DNS provider: ${$.provider}`)}}class O9{providers=new Map;configs=[];addConfig($){return this.configs.push($),this}addRoute53($,J){return this.configs.push({provider:"route53",region:$,hostedZoneId:J}),this}addPorkbun($,J){return this.configs.push({provider:"porkbun",apiKey:$,secretKey:J}),this}addGoDaddy($,J,Y){return this.configs.push({provider:"godaddy",apiKey:$,apiSecret:J,environment:Y}),this}addCloudflare($){return this.configs.push({provider:"cloudflare",apiToken:$}),this}loadFromEnv(){if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)this.addRoute53(process.env.AWS_REGION);let $=process.env.PORKBUN_API_KEY,J=process.env.PORKBUN_SECRET_KEY;if($&&J)this.addPorkbun($,J);let Y=process.env.GODADDY_API_KEY,Q=process.env.GODADDY_API_SECRET;if(Y&&Q){let U=process.env.GODADDY_ENVIRONMENT;this.addGoDaddy(Y,Q,U)}let Z=process.env.CLOUDFLARE_API_TOKEN;if(Z)this.addCloudflare(Z);return this}getProvider($){let J=this.providers.get($);if(J)return J;let Y=this.configs.find((Z)=>Z.provider===$);if(!Y)return null;let Q=e0(Y);return this.providers.set($,Q),Q}async getProviderForDomain($){for(let J of this.configs){let Y=e0(J);if(await Y.canManageDomain($))return Y}return null}getAllProviders(){return this.configs.map(($)=>e0($))}}var U_;var B2=S0(()=>{j9();Q6();j9();U_=new O9});var MZ={};Z1(MZ,{xrayManager:()=>$K,withTimeout:()=>XF,withSecurity:()=>SH,withQueue:()=>IH,withMonitoring:()=>NH,withDatabase:()=>PH,withCache:()=>xH,withCDN:()=>CH,validateTemplateSize:()=>Z4,validateTemplate:()=>aG,validateResourceLimits:()=>U4,validateCredentials:()=>nH,validateConfiguration:()=>pH,validateCommand:()=>JA,validateAgainstSchema:()=>RF,validateAccountStructure:()=>NA,templateCache:()=>JF,syntheticsManager:()=>QK,suggestRegions:()=>XA,suggestRegionPairs:()=>OA,suggestQuotaIncrease:()=>oH,suggestIAMPolicy:()=>iH,suggestFlags:()=>oF,suggestCommand:()=>v6,storageAdvancedManager:()=>bK,staticSiteManager:()=>hK,stackDependencyManager:()=>GA,signRequestAsync:()=>D9,signRequest:()=>v0,serviceMeshManager:()=>XK,sequence:()=>jF,senderReputationManager:()=>NK,securityScanningManager:()=>AK,securityHubManager:()=>iA,secretsRotationManager:()=>GK,secretsManager:()=>HK,searchCommands:()=>tF,sanitizeName:()=>G4,route53RoutingManager:()=>LK,route53ResolverManager:()=>TK,resourceManagementManager:()=>fK,resolveStorageBucketName:()=>H4,resolveSiteStackName:()=>X6,resolveSiteResourceName:()=>O6,resolveSiteBucketName:()=>_6,resolveRegion:()=>nQ,resolveProjectStackName:()=>A1,resolveDeployBucketName:()=>kQ,resolveCredentials:()=>C9,resolveCloudProvider:()=>w2,requiresReplacement:()=>EF,replicaManager:()=>UK,regionPairManager:()=>zA,quickHash:()=>HF,queueManagementManager:()=>kK,progressiveDeploymentManager:()=>eA,processInChunks:()=>OF,previewNotifications:()=>bF,previewManager:()=>CF,performanceManager:()=>WK,parseXMLResponse:()=>G$,parseJSONResponse:()=>RQ,parallelWithRetry:()=>BF,parallelMap:()=>KF,parallel:()=>I9,organizationManager:()=>LA,networkSecurityManager:()=>vK,multiRegionManager:()=>ZA,multiAccountManager:()=>VA,migrationManager:()=>ZK,metricsManager:()=>JK,mergeInfrastructure:()=>V2,makeAWSRequestOnce:()=>MQ,makeAWSRequestAsync:()=>TQ,makeAWSRequest:()=>_2,logsManager:()=>YK,lambdaVersionsManager:()=>_K,lambdaVPCManager:()=>wK,lambdaLayersManager:()=>OK,lambdaDestinationsManager:()=>EK,lambdaDLQManager:()=>VK,lambdaConcurrencyManager:()=>qK,isWebCryptoAvailable:()=>PQ,isValidRegion:()=>BA,isNodeCryptoAvailable:()=>SQ,isLocalDevelopment:()=>DF,isLikelyTypo:()=>aF,imageScanningManager:()=>KK,healthCheckManager:()=>yK,hashString:()=>x6,hashManifest:()=>GF,hashFile:()=>P6,hashDirectory:()=>zF,hashBuffer:()=>WF,guardDutyManager:()=>aA,globalResourceManager:()=>WA,getTimestamp:()=>z4,getSigningKeyCacheSize:()=>NQ,getRequiredPermissions:()=>JZ,getRegionsByPricingTier:()=>KA,getRegionsByLocation:()=>FA,getRegionsByCompliance:()=>AA,getRegionStats:()=>wA,getRegion:()=>u2,getRecommendedStructure:()=>RA,getQuotaUsageSummary:()=>sH,getLocalEnvVars:()=>PF,getLocalEndpoint:()=>NF,getLocalCredentials:()=>SF,getLocalConfig:()=>k9,getErrorDetails:()=>$Z,getDiffSummary:()=>qF,getDiffStats:()=>MF,getDeploymentStrategy:()=>LF,getCredentials:()=>q$,getContextualHelp:()=>iF,getCommandUsage:()=>$A,getClosestRegion:()=>jA,getAllRegions:()=>HA,getAccountId:()=>aQ,generateScheduledWorkflow:()=>IA,generateScheduledPipeline:()=>vA,generateScheduledConfig:()=>dA,generateResourceName:()=>f,generatePreviewWorkflow:()=>IF,generatePreviewPipeline:()=>yA,generateParallelConfig:()=>cA,generatePRPreviewWorkflow:()=>CA,generateMultiEnvWorkflow:()=>xA,generateMultiEnvPipeline:()=>bA,generateMultiEnvConfig:()=>uA,generateMatrixWorkflow:()=>kA,generateManualPipeline:()=>fA,generateLogicalId:()=>S,generateDeploymentWorkflow:()=>PA,generateDeploymentPipeline:()=>hA,generateDeploymentConfig:()=>gA,generateCrossAccountRoleCF:()=>DA,generateCostReportWorkflow:()=>hF,generateCleanupWorkflow:()=>kF,generateApprovalConfig:()=>mA,fromWebIdentity:()=>rQ,fromSharedCredentials:()=>cQ,fromEnvironment:()=>mQ,fromECSMetadata:()=>pQ,fromEC2Metadata:()=>lQ,formatTree:()=>gF,formatTable:()=>yF,formatSuggestion:()=>nF,formatRegionList:()=>EA,formatRegion:()=>OZ,formatProgressBar:()=>uF,formatList:()=>cF,formatKeyValue:()=>lF,formatHistoryStats:()=>QA,formatHistory:()=>YA,formatFlagSuggestions:()=>eF,formatDuration:()=>mF,formatDiff:()=>B4,formatBytes:()=>dF,formatAccountStructure:()=>SA,findChangedFiles:()=>FF,fifoQueueManager:()=>xK,extendPreset:()=>A6,emailTemplateManager:()=>SK,emailAnalyticsManager:()=>DK,drManager:()=>pA,dnssecManager:()=>MK,dlqMonitoringManager:()=>CK,diffTemplates:()=>_F,detectServiceRegion:()=>R9,detectMisconfigurations:()=>rH,defaultLocalConfig:()=>C6,databaseUserManager:()=>zK,crossRegionReferenceManager:()=>UA,createWordPressPreset:()=>qH,createTraditionalWebAppPreset:()=>TH,createStaticSitePreset:()=>BH,createS3Client:()=>lH,createRealtimeAppPreset:()=>VH,createPresignedUrlAsync:()=>OQ,createPresignedUrl:()=>j6,createPreset:()=>DH,createNodeJsServerlessPreset:()=>XH,createNodeJsServerPreset:()=>jH,createMockAWS:()=>xF,createMicroservicesPreset:()=>wH,createMLApiPreset:()=>MH,createJamstackPreset:()=>EH,createFullStackAppPreset:()=>OH,createError:()=>B6,createDataPipelinePreset:()=>LH,createCredentialProvider:()=>hH,createApiBackendPreset:()=>_H,containerRegistryManager:()=>jK,composePresets:()=>RH,cloudTrailManager:()=>nA,cloudConfigSchema:()=>TF,clearSigningKeyCache:()=>DQ,chunk:()=>WZ,checkServiceQuotas:()=>tH,checkIAMPermissions:()=>aH,certificateManager:()=>FK,categorizeChanges:()=>VF,canaryManager:()=>sA,buildOptimizationManager:()=>BK,buildCloudFormationTemplate:()=>KH,bounceComplaintHandler:()=>RK,blueGreenManager:()=>tA,batchProcessingManager:()=>IK,batch:()=>AF,backupManager:()=>lA,awsConfigManager:()=>rA,autocomplete:()=>sF,analyzeStackDiff:()=>F4,abTestManager:()=>oA,XRayManager:()=>e6,Workflow:()=>fQ,ValidationError:()=>R6,TemplateCache:()=>N6,TemplateBuilder:()=>P9,TaskList:()=>AZ,SyntheticsManager:()=>O2,StorageAdvancedManager:()=>l7,Storage:()=>X1,StaticSiteManager:()=>c7,StacksIntegration:()=>q4,StackDependencyManager:()=>m6,Spinner:()=>FZ,SmsHandlers:()=>vQ,SmsAdvanced:()=>LZ,ServiceMeshManager:()=>B7,SenderReputationManager:()=>R7,SecurityScanningManager:()=>H7,SecurityHubManager:()=>X2,Security:()=>L0,SecretsRotationManager:()=>W7,SecretsManager:()=>z7,Secrets:()=>g2,Search:()=>Y2,SMS:()=>r0,S3Error:()=>J1,S3Client:()=>T6,Route53RoutingManager:()=>w7,Route53ResolverManager:()=>L7,ResourceManagementManager:()=>n7,ReplicaManager:()=>Q7,Registry:()=>T1,RegionPairManager:()=>d6,Redirects:()=>c1,RealtimePresets:()=>nG,RateLimiter:()=>UZ,REPLContext:()=>BZ,REPLCommandBuilder:()=>jZ,REPL:()=>KZ,RECOMMENDED_SCPS:()=>MA,RECOMMENDED_ACCOUNT_STRUCTURES:()=>_Z,QueuePresets:()=>rG,QueueManagementManager:()=>m7,Queue:()=>t0,Pseudo:()=>W4,ProgressiveDeploymentManager:()=>o6,ProgressBar:()=>GZ,PreviewNotificationService:()=>y6,PreviewEnvironmentManager:()=>b6,PhoneHandlers:()=>yQ,PhoneAdvanced:()=>VZ,Phone:()=>R1,Permissions:()=>Y1,PerformanceManager:()=>Z7,ParameterStore:()=>D0,OrganizationManager:()=>l6,NetworkSecurityManager:()=>r7,Network:()=>E0,MultiStepProgress:()=>HZ,MultiRegionManager:()=>f6,MultiAccountManager:()=>c6,Monitoring:()=>_$,MockS3:()=>k6,MockDynamoDB:()=>h6,MockCloudFormation:()=>I6,MigrationManager:()=>Y7,MetricsManager:()=>$7,Messaging:()=>$1,LogsManager:()=>J7,LambdaVersionsManager:()=>X7,LambdaVPCManager:()=>q7,LambdaLayersManager:()=>j7,LambdaDestinationsManager:()=>_7,LambdaDLQManager:()=>E7,LambdaConcurrencyManager:()=>O7,JobLoader:()=>m1,ImageScanningManager:()=>F7,HealthCheckManager:()=>p7,HashCache:()=>QZ,GuardDutyManager:()=>i6,GlobalResourceManager:()=>u6,Fn:()=>q,FileSystem:()=>D1,FileCache:()=>D6,FIFOQueueManager:()=>g7,ErrorCodes:()=>eQ,EmailTemplateManager:()=>D7,EmailHandlers:()=>EZ,EmailAnalyticsManager:()=>T7,EmailAdvanced:()=>qZ,Email:()=>H0,DisasterRecoveryManager:()=>r6,DeploymentError:()=>sQ,Deployment:()=>a0,DependencyGraph:()=>hQ,DebugLogger:()=>Q1,DatabaseUserManager:()=>U7,Database:()=>Q2,DNSSECManager:()=>V7,DNS:()=>p0,DLQMonitoringManager:()=>u7,DEFAULT_SERVICE_LIMITS:()=>l0,CrossRegionReferenceManager:()=>g6,CredentialError:()=>$2,ContainerRegistryManager:()=>K7,ConfigurationError:()=>F$,Compute:()=>n,Communication:()=>i0,CommandHistory:()=>XZ,CloudTrailManager:()=>a6,CloudFrontClient:()=>tQ,CloudFormationClient:()=>iQ,CloudFormationBuilder:()=>V6,CloudError:()=>N1,CertificateManager:()=>G7,CanaryManager:()=>j$,Cache:()=>O$,COMMON_CROSS_ACCOUNT_ROLES:()=>TA,CDN:()=>j1,BuildOptimizationManager:()=>A7,BounceComplaintHandler:()=>M7,BlueGreenManager:()=>t6,BatchProcessingManager:()=>d7,BackupManager:()=>p6,Auth:()=>n0,AssetHasher:()=>h0,Arn:()=>K$,ApiGateway:()=>x9,AWS_REGIONS:()=>_1,AWS_PSEUDO_PARAMETERS:()=>N4,AWSConfigManager:()=>n6,AWSAPIError:()=>oQ,AI:()=>O1,ABTestManager:()=>s6});import{createRequire as fG}from"node:module";import{existsSync as Q$,readdirSync as j4}from"node:fs";import{join as e1}from"node:path";import{createHash as L4}from"node:crypto";import{readFileSync as _9,readdirSync as M4,statSync as T4,existsSync as U6,writeFileSync as q9,copyFileSync as R4}from"node:fs";import{join as Z$,basename as D4,dirname as WQ,extname as zQ}from"node:path";import{readFileSync as M6,existsSync as gQ}from"node:fs";import{homedir as uQ}from"node:os";import{join as dQ}from"node:path";import{createHash as YZ}from"node:crypto";import{existsSync as AQ,mkdirSync as eH,readFileSync as KQ,readdirSync as BQ,unlinkSync as U$,writeFileSync as $F}from"node:fs";import{join as z6}from"node:path";import{createHash as S6}from"node:crypto";import{createReadStream as YF,readdirSync as QF,statSync as M9}from"node:fs";import{join as ZF,relative as UF}from"node:path";function dG($,J){this[$]=uG.bind(null,J)}function R9($){let J=typeof $==="string"?new URL($):$,{hostname:Y,pathname:Q}=J;if(Y.endsWith(".on.aws")){let z=Y.match(/^[^.]+\.lambda-url\.([^.]+)\.on\.aws$/);if(z)return{service:"lambda",region:z[1]};return{service:"",region:""}}if(Y.endsWith(".r2.cloudflarestorage.com"))return{service:"s3",region:"auto"};if(Y.endsWith(".backblazeb2.com")){let z=Y.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);if(z)return{service:"s3",region:z[1]};return{service:"",region:""}}let Z=Y.replace("dualstack.","").match(/([^.]+)\.(?:([^.]+)\.)?amazonaws\.com(?:\.cn)?$/);if(!Z)return{service:"",region:""};let U=Z[1],W=Z[2]||"";if(W==="us-gov")W="us-gov-west-1";else if(W==="s3"||W==="s3-accelerate")W="us-east-1",U="s3";else if(U==="iot")if(Y.startsWith("iot."))U="execute-api";else if(Y.startsWith("data.jobs.iot."))U="iot-jobs-data";else U=Q==="/mqtt"?"iotdevicegateway":"iotdata";else if(U==="autoscaling");else if(!W&&U.startsWith("s3-"))W=U.slice(3).replace(/^fips-|^external-1/,""),U="s3";else if(U.endsWith("-fips"))U=U.slice(0,-5);else if(W&&/-\d$/.test(U)&&!/-\d$/.test(W))[U,W]=[W,U];return U=CQ[U]||U,{service:U,region:W||"us-east-1"}}function v0($){let{method:J,url:Y,body:Q="",accessKeyId:Z,secretAccessKey:U,sessionToken:W,signQuery:z=!1,expiresIn:G=86400,datetime:H}=$,A=new URL(Y),K=A.hostname,B=R9(A),j=$.service||B.service,X=$.region||B.region;if(!j)throw Error("Could not detect service from URL. Please provide service explicitly.");if(!X)throw Error("Could not detect region from URL. Please provide region explicitly.");let O=H||new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),_=O.substring(0,8),w=[_,X,j,"aws4_request"].join("/"),E="AWS4-HMAC-SHA256";if(z)return lG({urlObj:A,method:J,body:Q,accessKeyId:Z,secretAccessKey:U,sessionToken:W,service:j,region:X,timestamp:O,date:_,credentialScope:w,algorithm:E,expiresIn:G,cache:$.cache});let M=A.pathname||"/",T=N9(A.searchParams),D={host:K,"x-amz-date":O,...$.headers};if(W)D["x-amz-security-token"]=W;let N=Object.keys(D).some((r)=>r.toLowerCase()==="content-type");if(Q&&!N)D["content-type"]="application/x-amz-json-1.0";if(j==="s3"&&!D["x-amz-content-sha256"])D["x-amz-content-sha256"]=z$(Q);let x=_Q(D),h=qQ(D),I=D["x-amz-content-sha256"]||z$(Q),b=[J,S9(M),T,x,h,I].join(`
56
+ `),k=z$(b),y=[E,O,w,k].join(`
57
+ `),m=$.cache??E2,l=wQ(U,_,X,j,y,m),p=[`${E} Credential=${Z}/${w}`,`SignedHeaders=${h}`,`Signature=${l}`].join(", ");return D.authorization=p,{url:Y,method:J,headers:D,body:Q||void 0}}async function D9($){let{method:J,url:Y,body:Q="",accessKeyId:Z,secretAccessKey:U,sessionToken:W,signQuery:z=!1,expiresIn:G=86400,datetime:H}=$,A=new URL(Y),K=A.hostname,B=R9(A),j=$.service||B.service,X=$.region||B.region;if(!j)throw Error("Could not detect service from URL. Please provide service explicitly.");if(!X)throw Error("Could not detect region from URL. Please provide region explicitly.");let O=H||new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),_=O.substring(0,8),w=[_,X,j,"aws4_request"].join("/"),E="AWS4-HMAC-SHA256";if(z)return pG({urlObj:A,method:J,body:Q,accessKeyId:Z,secretAccessKey:U,sessionToken:W,service:j,region:X,timestamp:O,date:_,credentialScope:w,algorithm:E,expiresIn:G,cache:$.cache});let M=A.pathname||"/",T=N9(A.searchParams),D={host:K,"x-amz-date":O,...$.headers};if(W)D["x-amz-security-token"]=W;let N=Object.keys(D).some((s)=>s.toLowerCase()==="content-type");if(Q&&!N)D["content-type"]="application/x-amz-json-1.0";let x=await w9(Q);if(j==="s3"&&!D["x-amz-content-sha256"])D["x-amz-content-sha256"]=x;let h=_Q(D),I=qQ(D),b=D["x-amz-content-sha256"]||x,k=[J,S9(M),T,h,I,b].join(`
58
+ `),y=await w9(k),m=[E,O,w,y].join(`
59
+ `),l=$.cache??E2,p=await VQ(U,_,X,j,m,l),r=[`${E} Credential=${Z}/${w}`,`SignedHeaders=${I}`,`Signature=${p}`].join(", ");return D.authorization=r,{url:Y,method:J,headers:D,body:Q||void 0}}function lG($){let{urlObj:J,method:Y,body:Q,accessKeyId:Z,secretAccessKey:U,sessionToken:W,service:z,region:G,timestamp:H,date:A,credentialScope:K,algorithm:B,expiresIn:j,cache:X}=$,O=new URL(J.toString());O.searchParams.set("X-Amz-Algorithm",B),O.searchParams.set("X-Amz-Credential",`${Z}/${K}`),O.searchParams.set("X-Amz-Date",H),O.searchParams.set("X-Amz-Expires",String(j));let _=z==="s3"?"UNSIGNED-PAYLOAD":z$(Q);if(z==="s3")O.searchParams.set("X-Amz-Content-Sha256",_);let w="host";if(O.searchParams.set("X-Amz-SignedHeaders",w),W)O.searchParams.set("X-Amz-Security-Token",W);let E=S9(O.pathname||"/"),M=`host:${O.hostname}
60
60
  `,T=N9(O.searchParams),D=[Y,E,T,M,w,_].join(`
61
61
  `),N=[B,H,K,z$(D)].join(`
62
62
  `),h=wQ(U,A,G,z,N,X??E2);return O.searchParams.set("X-Amz-Signature",h),{url:O.toString(),method:Y,headers:{},body:Q||void 0}}async function pG($){let{urlObj:J,method:Y,body:Q,accessKeyId:Z,secretAccessKey:U,sessionToken:W,service:z,region:G,timestamp:H,date:A,credentialScope:K,algorithm:B,expiresIn:j,cache:X}=$,O=new URL(J.toString());O.searchParams.set("X-Amz-Algorithm",B),O.searchParams.set("X-Amz-Credential",`${Z}/${K}`),O.searchParams.set("X-Amz-Date",H),O.searchParams.set("X-Amz-Expires",String(j));let _=z==="s3"?"UNSIGNED-PAYLOAD":await w9(Q);if(z==="s3")O.searchParams.set("X-Amz-Content-Sha256",_);let w="host";if(O.searchParams.set("X-Amz-SignedHeaders",w),W)O.searchParams.set("X-Amz-Security-Token",W);let E=S9(O.pathname||"/"),M=`host:${O.hostname}
@@ -69,12 +69,12 @@ ${this.convertToYAML(U,J+1)}`;else if(Array.isArray(U)){Q+=`${Y}${Z}:
69
69
  `;for(let W of U)if(typeof W==="object")Q+=`${Y} -
70
70
  ${this.convertToYAML(W,J+2)}`;else Q+=`${Y} - ${W}
71
71
  `}else Q+=`${Y}${Z}: ${U}
72
- `}return Q}}function aG($){let J=[],Y=[],Q=[];if(iG($,J),$.Resources)tG($.Resources,J,Y);else J.push({path:"Resources",message:"Template must contain at least one resource",severity:"error"});if($.Parameters)sG($.Parameters,J,Y);if($.Outputs)oG($.Outputs,J);eG($,J);let Z=$4($);if(Z.length>0)for(let U of Z)J.push({path:"Resources",message:`Circular dependency detected: ${U.join(" → ")}`,severity:"error"});return Y4($,Y,Q),{valid:J.length===0,errors:J,warnings:Y,info:Q}}function iG($,J){if(!$.AWSTemplateFormatVersion)J.push({path:"AWSTemplateFormatVersion",message:"Template should specify AWSTemplateFormatVersion",severity:"error"});else if($.AWSTemplateFormatVersion!=="2010-09-09")J.push({path:"AWSTemplateFormatVersion",message:'AWSTemplateFormatVersion must be "2010-09-09"',severity:"error"})}function tG($,J,Y){let Q=Object.keys($);if(Q.length===0){J.push({path:"Resources",message:"Template must contain at least one resource",severity:"error"});return}if(Q.length>500)Y.push({path:"Resources",message:`Template contains ${Q.length} resources (limit is 500)`,severity:"warning"});for(let Z of Q){let U=$[Z];if(!/^[a-zA-Z0-9]+$/.test(Z))J.push({path:`Resources.${Z}`,message:"Logical ID must contain only alphanumeric characters",severity:"error"});if(!U.Type)J.push({path:`Resources.${Z}.Type`,message:"Resource Type is required",severity:"error"});else if(!U.Type.startsWith("AWS::")&&!U.Type.startsWith("Custom::"))J.push({path:`Resources.${Z}.Type`,message:'Resource Type must start with "AWS::" or "Custom::"',severity:"error"});if(U.DeletionPolicy&&!["Delete","Retain","Snapshot"].includes(U.DeletionPolicy))J.push({path:`Resources.${Z}.DeletionPolicy`,message:'DeletionPolicy must be "Delete", "Retain", or "Snapshot"',severity:"error"});if(!U.DeletionPolicy&&IQ(U.Type))Y.push({path:`Resources.${Z}.DeletionPolicy`,message:`${U.Type} should specify DeletionPolicy to prevent accidental data loss`,severity:"warning"})}}function sG($,J,Y){let Q=Object.keys($);if(Q.length>200)Y.push({path:"Parameters",message:`Template contains ${Q.length} parameters (limit is 200)`,severity:"warning"});for(let Z of Q){let U=$[Z];if(!U.Type)J.push({path:`Parameters.${Z}.Type`,message:"Parameter Type is required",severity:"error"});let W=["String","Number","List<Number>","CommaDelimitedList","AWS::EC2::AvailabilityZone::Name","AWS::EC2::Image::Id","AWS::EC2::Instance::Id","AWS::EC2::KeyPair::KeyName","AWS::EC2::SecurityGroup::GroupName","AWS::EC2::SecurityGroup::Id","AWS::EC2::Subnet::Id","AWS::EC2::Volume::Id","AWS::EC2::VPC::Id","AWS::Route53::HostedZone::Id","List<AWS::EC2::AvailabilityZone::Name>","List<AWS::EC2::Image::Id>","List<AWS::EC2::Instance::Id>","List<AWS::EC2::SecurityGroup::GroupName>","List<AWS::EC2::SecurityGroup::Id>","List<AWS::EC2::Subnet::Id>","List<AWS::EC2::Volume::Id>","List<AWS::EC2::VPC::Id>","List<AWS::Route53::HostedZone::Id>","AWS::SSM::Parameter::Name","AWS::SSM::Parameter::Value<String>","AWS::SSM::Parameter::Value<List<String>>","AWS::SSM::Parameter::Value<CommaDelimitedList>"];if(U.Type&&!W.includes(U.Type))J.push({path:`Parameters.${Z}.Type`,message:`Invalid parameter type: ${U.Type}`,severity:"error"})}}function oG($,J){let Y=Object.keys($);for(let Q of Y)if(!$[Q].Value)J.push({path:`Outputs.${Q}.Value`,message:"Output Value is required",severity:"error"})}function eG($,J){let Y=$.Resources||{},Q=$.Parameters||{},Z=new Set(Object.keys(Y)),U=new Set(Object.keys(Q));function W(z,G){if(typeof z!=="object"||z===null)return;if(z.Ref){let H=z.Ref;if(!Z.has(H)&&!U.has(H)&&H!=="AWS::Region"&&H!=="AWS::AccountId"&&H!=="AWS::StackName"&&H!=="AWS::StackId"&&H!=="AWS::URLSuffix"&&H!=="AWS::Partition"&&H!=="AWS::NoValue")J.push({path:G,message:`Reference to non-existent resource or parameter: ${H}`,severity:"error"})}if(z["Fn::GetAtt"]){let H=z["Fn::GetAtt"];if(Array.isArray(H)&&H.length>=1){let A=H[0];if(!Z.has(A))J.push({path:G,message:`GetAtt references non-existent resource: ${A}`,severity:"error"})}}for(let H in z)W(z[H],`${G}.${H}`)}for(let z in Y)W(Y[z],`Resources.${z}`);if($.Outputs)for(let z in $.Outputs)W($.Outputs[z],`Outputs.${z}`)}function $4($){let J=$.Resources||{},Y=new Map;for(let z in J){let G=new Set,H=J[z];if(H.DependsOn)if(Array.isArray(H.DependsOn))H.DependsOn.forEach((K)=>G.add(K));else G.add(H.DependsOn);J4(H).forEach((K)=>G.add(K)),Y.set(z,G)}let Q=[],Z=new Set,U=new Set;function W(z,G){Z.add(z),U.add(z),G.push(z);let H=Y.get(z)||new Set;for(let A of H)if(!Z.has(A))W(A,[...G]);else if(U.has(A)){let K=G.indexOf(A),B=[...G.slice(K),A];Q.push(B)}U.delete(z)}for(let z of Y.keys())if(!Z.has(z))W(z,[]);return Q}function J4($){let J=new Set;function Y(Q){if(typeof Q!=="object"||Q===null)return;if(Q.Ref&&typeof Q.Ref==="string"){if(!Q.Ref.startsWith("AWS::"))J.add(Q.Ref)}if(Q["Fn::GetAtt"]&&Array.isArray(Q["Fn::GetAtt"]))J.add(Q["Fn::GetAtt"][0]);for(let Z in Q)Y(Q[Z])}return Y($),J}function IQ($){return["AWS::S3::Bucket","AWS::DynamoDB::Table","AWS::RDS::DBInstance","AWS::RDS::DBCluster","AWS::ElastiCache::CacheCluster","AWS::ElastiCache::ReplicationGroup","AWS::EFS::FileSystem","AWS::OpenSearchService::Domain"].includes($)}function Y4($,J,Y){let Q=$.Resources||{};if(!$.Description)Y.push({path:"Description",message:"Consider adding a Description to the template",severity:"info"});for(let Z in Q){let U=Q[Z],W=U.Properties;if(W&&!W.Tags&&Q4(U.Type))Y.push({path:`Resources.${Z}`,message:`Consider adding Tags to ${U.Type}`,severity:"info"});if(IQ(U.Type)){if(U.Type==="AWS::S3::Bucket"&&!W?.BucketEncryption)J.push({path:`Resources.${Z}`,message:"S3 bucket should enable encryption",severity:"warning"});if(U.Type==="AWS::RDS::DBInstance"&&!W?.StorageEncrypted)J.push({path:`Resources.${Z}`,message:"RDS instance should enable storage encryption",severity:"warning"})}}}function Q4($){return!["AWS::CloudFormation::Stack","AWS::CloudFormation::WaitCondition","AWS::CloudFormation::WaitConditionHandle"].includes($)}function Z4($){let J=[],Y=[],Q=[],Z=Buffer.byteLength($,"utf8"),U=Z/1024,W=51200,z=460800;if(Z>460800)J.push({path:"Template",message:`Template size (${U.toFixed(2)} KB) exceeds maximum size of 450 KB`,severity:"error"});else if(Z>51200)Y.push({path:"Template",message:`Template size (${U.toFixed(2)} KB) exceeds 50 KB. Must use S3 for deployment.`,severity:"warning"});return{valid:J.length===0,errors:J,warnings:Y,info:Q}}function U4($){let J=[],Y=[],Q=[],Z=$.Resources||{},U=$.Parameters||{},W=$.Outputs||{};if(Object.keys(Z).length>500)J.push({path:"Resources",message:`Template has ${Object.keys(Z).length} resources (limit is 500)`,severity:"error"});if(Object.keys(U).length>200)J.push({path:"Parameters",message:`Template has ${Object.keys(U).length} parameters (limit is 200)`,severity:"error"});if(Object.keys(W).length>200)J.push({path:"Outputs",message:`Template has ${Object.keys(W).length} outputs (limit is 200)`,severity:"error"});return{valid:J.length===0,errors:J,warnings:Y,info:Q}}function v($){let{slug:J,environment:Y,resourceType:Q,timestamp:Z,suffix:U}=$,W=[J,Y,Q];if(Z)W.push(Z);if(U)W.push(U);return W.join("-")}function S($){return $.split("-").map((J)=>J.charAt(0).toUpperCase()+J.slice(1)).join("")}function z4(){return Date.now().toString()}function G4($){return $.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-+|-+$/g,"").replace(/-+/g,"-")}function A1($,J){return $.project.stackName??`${$.project.slug}-${J}`}function X6($,J,Y,Q){return Y.stackName??`${$.project.slug}-${Q}-${J}-site`}function O6($,J){return`${$.project.slug}-${J}`}function _6($,J,Y,Q){if(Q)return Q;if(Y==="main")return`${$}-${J}-site`;return`${$}-${J}-${Y}`}function H4($,J,Y,Q){return Q??`${$}-${J}-${Y}`}function kQ($,J){return`${$}-${J}-deploy`}class hQ{nodes=new Map;addResource($,J){let Y=this.extractDependencies(J);this.nodes.set($,{logicalId:$,resource:J,dependencies:Y})}extractDependencies($){let J=new Set;if($.DependsOn)if(Array.isArray($.DependsOn))$.DependsOn.forEach((Y)=>J.add(Y));else J.add($.DependsOn);return this.findReferences($.Properties||{},J),J}findReferences($,J){if(!$||typeof $!=="object")return;if("Ref"in $&&typeof $.Ref==="string"){if(!$.Ref.startsWith("AWS::"))J.add($.Ref)}if("Fn::GetAtt"in $&&Array.isArray($["Fn::GetAtt"]))J.add($["Fn::GetAtt"][0]);for(let Y of Object.values($))if(typeof Y==="object")this.findReferences(Y,J)}topologicalSort(){let $=[],J=new Set,Y=new Set,Q=(Z)=>{if(J.has(Z))return;if(Y.has(Z))throw Error(`Circular dependency detected: ${Z}`);Y.add(Z);let U=this.nodes.get(Z);if(U)for(let W of U.dependencies)Q(W);Y.delete(Z),J.add(Z),$.push(Z)};for(let Z of this.nodes.keys())Q(Z);return $}validate(){for(let[$,J]of this.nodes.entries())for(let Y of J.dependencies)if(!this.nodes.has(Y))throw Error(`Resource "${$}" depends on "${Y}" which does not exist`)}getDependents($){let J=[];for(let[Y,Q]of this.nodes.entries())if(Q.dependencies.has($))J.push(Y);return J}}function F4($,J){let Y=[],Q=[],Z=[],U=[],W=[],z=$.Resources||{},G=J.Resources||{},H=new Set([...Object.keys(z),...Object.keys(G)]);for(let K of H){let B=z[K],j=G[K];if(!B&&j)Y.push({logicalId:K,action:"add",resourceType:j.Type});else if(B&&!j)Q.push({logicalId:K,action:"remove",resourceType:B.Type});else if(B&&j)if(B.Type!==j.Type)U.push({logicalId:K,action:"replace",resourceType:j.Type,reason:`Type changed from ${B.Type} to ${j.Type}`});else{let X=bQ(B.Properties||{},j.Properties||{});if(X.length>0)if(A4(B.Type,X))U.push({logicalId:K,action:"replace",resourceType:j.Type,changes:X,reason:"Property changes require replacement"});else Z.push({logicalId:K,action:"update",resourceType:j.Type,changes:X});else W.push(K)}}let A=K4([...Q,...U,...Z]);return{added:Y,removed:Q,updated:Z,replaced:U,unchanged:W,summary:{totalChanges:Y.length+Q.length+Z.length+U.length,requiresReplacement:U.length>0,dangerousChanges:A}}}function bQ($,J,Y=""){let Q=[],Z=new Set([...Object.keys($),...Object.keys(J)]);for(let U of Z){let W=Y?`${Y}.${U}`:U,z=$[U],G=J[U];if(z===void 0&&G!==void 0)Q.push({path:W,oldValue:void 0,newValue:G});else if(z!==void 0&&G===void 0)Q.push({path:W,oldValue:z,newValue:void 0});else if(typeof z!==typeof G)Q.push({path:W,oldValue:z,newValue:G});else if(typeof z==="object"&&z!==null)if(Array.isArray(z)&&Array.isArray(G)){if(JSON.stringify(z)!==JSON.stringify(G))Q.push({path:W,oldValue:z,newValue:G})}else if(!Array.isArray(z)&&!Array.isArray(G)){let H=bQ(z,G,W);Q.push(...H)}else Q.push({path:W,oldValue:z,newValue:G});else if(z!==G)Q.push({path:W,oldValue:z,newValue:G})}return Q}function A4($,J){let Q={"AWS::S3::Bucket":new Set(["BucketName"]),"AWS::DynamoDB::Table":new Set(["TableName","KeySchema"]),"AWS::RDS::DBInstance":new Set(["DBInstanceIdentifier","DBName","Engine"]),"AWS::Lambda::Function":new Set(["FunctionName"]),"AWS::EC2::Instance":new Set(["ImageId","InstanceType","KeyName"]),"AWS::ECS::TaskDefinition":new Set(["Family","ContainerDefinitions"]),"AWS::ElastiCache::CacheCluster":new Set(["CacheNodeType","Engine"]),"AWS::CloudFront::Distribution":new Set([]),"AWS::Route53::HostedZone":new Set(["Name"]),"AWS::IAM::Role":new Set(["RoleName","Path"]),"AWS::KMS::Key":new Set(["KeyPolicy"]),"AWS::Cognito::UserPool":new Set(["UserPoolName"]),"AWS::OpenSearchService::Domain":new Set(["DomainName"])}[$];if(!Q)return!1;for(let Z of J){let U=Z.path.split(".")[0];if(Q.has(U))return!0}return!1}function K4($){let J=[];for(let Y of $){if(Y.action==="remove"&&(Y.resourceType==="AWS::RDS::DBInstance"||Y.resourceType==="AWS::DynamoDB::Table"||Y.resourceType==="AWS::ElastiCache::CacheCluster"))J.push(`Removing ${Y.resourceType} ${Y.logicalId} - data loss risk!`);if(Y.action==="replace"&&(Y.resourceType==="AWS::RDS::DBInstance"||Y.resourceType==="AWS::DynamoDB::Table"))J.push(`Replacing ${Y.resourceType} ${Y.logicalId} - data loss risk!`);if((Y.action==="remove"||Y.action==="replace")&&Y.resourceType==="AWS::S3::Bucket")J.push(`${Y.action==="remove"?"Removing":"Replacing"} S3 bucket ${Y.logicalId} - data loss risk!`);if(Y.action==="replace"&&Y.resourceType==="AWS::EC2::Instance")J.push(`Replacing EC2 instance ${Y.logicalId} - downtime expected`);if(Y.action==="update"&&Y.resourceType==="AWS::EC2::SecurityGroup")J.push(`Updating security group ${Y.logicalId} - may affect connectivity`);if((Y.action==="update"||Y.action==="replace")&&(Y.resourceType==="AWS::IAM::Role"||Y.resourceType==="AWS::IAM::Policy"))J.push(`Modifying IAM ${Y.resourceType.split("::")[2]} ${Y.logicalId} - may affect permissions`)}return J}function B4($){let J=[];if(J.push(`=== Stack Update Analysis ===
72
+ `}return Q}}function aG($){let J=[],Y=[],Q=[];if(iG($,J),$.Resources)tG($.Resources,J,Y);else J.push({path:"Resources",message:"Template must contain at least one resource",severity:"error"});if($.Parameters)sG($.Parameters,J,Y);if($.Outputs)oG($.Outputs,J);eG($,J);let Z=$4($);if(Z.length>0)for(let U of Z)J.push({path:"Resources",message:`Circular dependency detected: ${U.join(" → ")}`,severity:"error"});return Y4($,Y,Q),{valid:J.length===0,errors:J,warnings:Y,info:Q}}function iG($,J){if(!$.AWSTemplateFormatVersion)J.push({path:"AWSTemplateFormatVersion",message:"Template should specify AWSTemplateFormatVersion",severity:"error"});else if($.AWSTemplateFormatVersion!=="2010-09-09")J.push({path:"AWSTemplateFormatVersion",message:'AWSTemplateFormatVersion must be "2010-09-09"',severity:"error"})}function tG($,J,Y){let Q=Object.keys($);if(Q.length===0){J.push({path:"Resources",message:"Template must contain at least one resource",severity:"error"});return}if(Q.length>500)Y.push({path:"Resources",message:`Template contains ${Q.length} resources (limit is 500)`,severity:"warning"});for(let Z of Q){let U=$[Z];if(!/^[a-zA-Z0-9]+$/.test(Z))J.push({path:`Resources.${Z}`,message:"Logical ID must contain only alphanumeric characters",severity:"error"});if(!U.Type)J.push({path:`Resources.${Z}.Type`,message:"Resource Type is required",severity:"error"});else if(!U.Type.startsWith("AWS::")&&!U.Type.startsWith("Custom::"))J.push({path:`Resources.${Z}.Type`,message:'Resource Type must start with "AWS::" or "Custom::"',severity:"error"});if(U.DeletionPolicy&&!["Delete","Retain","Snapshot"].includes(U.DeletionPolicy))J.push({path:`Resources.${Z}.DeletionPolicy`,message:'DeletionPolicy must be "Delete", "Retain", or "Snapshot"',severity:"error"});if(!U.DeletionPolicy&&IQ(U.Type))Y.push({path:`Resources.${Z}.DeletionPolicy`,message:`${U.Type} should specify DeletionPolicy to prevent accidental data loss`,severity:"warning"})}}function sG($,J,Y){let Q=Object.keys($);if(Q.length>200)Y.push({path:"Parameters",message:`Template contains ${Q.length} parameters (limit is 200)`,severity:"warning"});for(let Z of Q){let U=$[Z];if(!U.Type)J.push({path:`Parameters.${Z}.Type`,message:"Parameter Type is required",severity:"error"});let W=["String","Number","List<Number>","CommaDelimitedList","AWS::EC2::AvailabilityZone::Name","AWS::EC2::Image::Id","AWS::EC2::Instance::Id","AWS::EC2::KeyPair::KeyName","AWS::EC2::SecurityGroup::GroupName","AWS::EC2::SecurityGroup::Id","AWS::EC2::Subnet::Id","AWS::EC2::Volume::Id","AWS::EC2::VPC::Id","AWS::Route53::HostedZone::Id","List<AWS::EC2::AvailabilityZone::Name>","List<AWS::EC2::Image::Id>","List<AWS::EC2::Instance::Id>","List<AWS::EC2::SecurityGroup::GroupName>","List<AWS::EC2::SecurityGroup::Id>","List<AWS::EC2::Subnet::Id>","List<AWS::EC2::Volume::Id>","List<AWS::EC2::VPC::Id>","List<AWS::Route53::HostedZone::Id>","AWS::SSM::Parameter::Name","AWS::SSM::Parameter::Value<String>","AWS::SSM::Parameter::Value<List<String>>","AWS::SSM::Parameter::Value<CommaDelimitedList>"];if(U.Type&&!W.includes(U.Type))J.push({path:`Parameters.${Z}.Type`,message:`Invalid parameter type: ${U.Type}`,severity:"error"})}}function oG($,J){let Y=Object.keys($);for(let Q of Y)if(!$[Q].Value)J.push({path:`Outputs.${Q}.Value`,message:"Output Value is required",severity:"error"})}function eG($,J){let Y=$.Resources||{},Q=$.Parameters||{},Z=new Set(Object.keys(Y)),U=new Set(Object.keys(Q));function W(z,G){if(typeof z!=="object"||z===null)return;if(z.Ref){let H=z.Ref;if(!Z.has(H)&&!U.has(H)&&H!=="AWS::Region"&&H!=="AWS::AccountId"&&H!=="AWS::StackName"&&H!=="AWS::StackId"&&H!=="AWS::URLSuffix"&&H!=="AWS::Partition"&&H!=="AWS::NoValue")J.push({path:G,message:`Reference to non-existent resource or parameter: ${H}`,severity:"error"})}if(z["Fn::GetAtt"]){let H=z["Fn::GetAtt"];if(Array.isArray(H)&&H.length>=1){let A=H[0];if(!Z.has(A))J.push({path:G,message:`GetAtt references non-existent resource: ${A}`,severity:"error"})}}for(let H in z)W(z[H],`${G}.${H}`)}for(let z in Y)W(Y[z],`Resources.${z}`);if($.Outputs)for(let z in $.Outputs)W($.Outputs[z],`Outputs.${z}`)}function $4($){let J=$.Resources||{},Y=new Map;for(let z in J){let G=new Set,H=J[z];if(H.DependsOn)if(Array.isArray(H.DependsOn))H.DependsOn.forEach((K)=>G.add(K));else G.add(H.DependsOn);J4(H).forEach((K)=>G.add(K)),Y.set(z,G)}let Q=[],Z=new Set,U=new Set;function W(z,G){Z.add(z),U.add(z),G.push(z);let H=Y.get(z)||new Set;for(let A of H)if(!Z.has(A))W(A,[...G]);else if(U.has(A)){let K=G.indexOf(A),B=[...G.slice(K),A];Q.push(B)}U.delete(z)}for(let z of Y.keys())if(!Z.has(z))W(z,[]);return Q}function J4($){let J=new Set;function Y(Q){if(typeof Q!=="object"||Q===null)return;if(Q.Ref&&typeof Q.Ref==="string"){if(!Q.Ref.startsWith("AWS::"))J.add(Q.Ref)}if(Q["Fn::GetAtt"]&&Array.isArray(Q["Fn::GetAtt"]))J.add(Q["Fn::GetAtt"][0]);for(let Z in Q)Y(Q[Z])}return Y($),J}function IQ($){return["AWS::S3::Bucket","AWS::DynamoDB::Table","AWS::RDS::DBInstance","AWS::RDS::DBCluster","AWS::ElastiCache::CacheCluster","AWS::ElastiCache::ReplicationGroup","AWS::EFS::FileSystem","AWS::OpenSearchService::Domain"].includes($)}function Y4($,J,Y){let Q=$.Resources||{};if(!$.Description)Y.push({path:"Description",message:"Consider adding a Description to the template",severity:"info"});for(let Z in Q){let U=Q[Z],W=U.Properties;if(W&&!W.Tags&&Q4(U.Type))Y.push({path:`Resources.${Z}`,message:`Consider adding Tags to ${U.Type}`,severity:"info"});if(IQ(U.Type)){if(U.Type==="AWS::S3::Bucket"&&!W?.BucketEncryption)J.push({path:`Resources.${Z}`,message:"S3 bucket should enable encryption",severity:"warning"});if(U.Type==="AWS::RDS::DBInstance"&&!W?.StorageEncrypted)J.push({path:`Resources.${Z}`,message:"RDS instance should enable storage encryption",severity:"warning"})}}}function Q4($){return!["AWS::CloudFormation::Stack","AWS::CloudFormation::WaitCondition","AWS::CloudFormation::WaitConditionHandle"].includes($)}function Z4($){let J=[],Y=[],Q=[],Z=Buffer.byteLength($,"utf8"),U=Z/1024,W=51200,z=460800;if(Z>460800)J.push({path:"Template",message:`Template size (${U.toFixed(2)} KB) exceeds maximum size of 450 KB`,severity:"error"});else if(Z>51200)Y.push({path:"Template",message:`Template size (${U.toFixed(2)} KB) exceeds 50 KB. Must use S3 for deployment.`,severity:"warning"});return{valid:J.length===0,errors:J,warnings:Y,info:Q}}function U4($){let J=[],Y=[],Q=[],Z=$.Resources||{},U=$.Parameters||{},W=$.Outputs||{};if(Object.keys(Z).length>500)J.push({path:"Resources",message:`Template has ${Object.keys(Z).length} resources (limit is 500)`,severity:"error"});if(Object.keys(U).length>200)J.push({path:"Parameters",message:`Template has ${Object.keys(U).length} parameters (limit is 200)`,severity:"error"});if(Object.keys(W).length>200)J.push({path:"Outputs",message:`Template has ${Object.keys(W).length} outputs (limit is 200)`,severity:"error"});return{valid:J.length===0,errors:J,warnings:Y,info:Q}}function f($){let{slug:J,environment:Y,resourceType:Q,timestamp:Z,suffix:U}=$,W=[J,Y,Q];if(Z)W.push(Z);if(U)W.push(U);return W.join("-")}function S($){return $.split("-").map((J)=>J.charAt(0).toUpperCase()+J.slice(1)).join("")}function z4(){return Date.now().toString()}function G4($){return $.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-+|-+$/g,"").replace(/-+/g,"-")}function A1($,J){return $.project.stackName??`${$.project.slug}-${J}`}function X6($,J,Y,Q){return Y.stackName??`${$.project.slug}-${Q}-${J}-site`}function O6($,J){return`${$.project.slug}-${J}`}function _6($,J,Y,Q){if(Q)return Q;if(Y==="main")return`${$}-${J}-site`;return`${$}-${J}-${Y}`}function H4($,J,Y,Q){return Q??`${$}-${J}-${Y}`}function kQ($,J){return`${$}-${J}-deploy`}class hQ{nodes=new Map;addResource($,J){let Y=this.extractDependencies(J);this.nodes.set($,{logicalId:$,resource:J,dependencies:Y})}extractDependencies($){let J=new Set;if($.DependsOn)if(Array.isArray($.DependsOn))$.DependsOn.forEach((Y)=>J.add(Y));else J.add($.DependsOn);return this.findReferences($.Properties||{},J),J}findReferences($,J){if(!$||typeof $!=="object")return;if("Ref"in $&&typeof $.Ref==="string"){if(!$.Ref.startsWith("AWS::"))J.add($.Ref)}if("Fn::GetAtt"in $&&Array.isArray($["Fn::GetAtt"]))J.add($["Fn::GetAtt"][0]);for(let Y of Object.values($))if(typeof Y==="object")this.findReferences(Y,J)}topologicalSort(){let $=[],J=new Set,Y=new Set,Q=(Z)=>{if(J.has(Z))return;if(Y.has(Z))throw Error(`Circular dependency detected: ${Z}`);Y.add(Z);let U=this.nodes.get(Z);if(U)for(let W of U.dependencies)Q(W);Y.delete(Z),J.add(Z),$.push(Z)};for(let Z of this.nodes.keys())Q(Z);return $}validate(){for(let[$,J]of this.nodes.entries())for(let Y of J.dependencies)if(!this.nodes.has(Y))throw Error(`Resource "${$}" depends on "${Y}" which does not exist`)}getDependents($){let J=[];for(let[Y,Q]of this.nodes.entries())if(Q.dependencies.has($))J.push(Y);return J}}function F4($,J){let Y=[],Q=[],Z=[],U=[],W=[],z=$.Resources||{},G=J.Resources||{},H=new Set([...Object.keys(z),...Object.keys(G)]);for(let K of H){let B=z[K],j=G[K];if(!B&&j)Y.push({logicalId:K,action:"add",resourceType:j.Type});else if(B&&!j)Q.push({logicalId:K,action:"remove",resourceType:B.Type});else if(B&&j)if(B.Type!==j.Type)U.push({logicalId:K,action:"replace",resourceType:j.Type,reason:`Type changed from ${B.Type} to ${j.Type}`});else{let X=bQ(B.Properties||{},j.Properties||{});if(X.length>0)if(A4(B.Type,X))U.push({logicalId:K,action:"replace",resourceType:j.Type,changes:X,reason:"Property changes require replacement"});else Z.push({logicalId:K,action:"update",resourceType:j.Type,changes:X});else W.push(K)}}let A=K4([...Q,...U,...Z]);return{added:Y,removed:Q,updated:Z,replaced:U,unchanged:W,summary:{totalChanges:Y.length+Q.length+Z.length+U.length,requiresReplacement:U.length>0,dangerousChanges:A}}}function bQ($,J,Y=""){let Q=[],Z=new Set([...Object.keys($),...Object.keys(J)]);for(let U of Z){let W=Y?`${Y}.${U}`:U,z=$[U],G=J[U];if(z===void 0&&G!==void 0)Q.push({path:W,oldValue:void 0,newValue:G});else if(z!==void 0&&G===void 0)Q.push({path:W,oldValue:z,newValue:void 0});else if(typeof z!==typeof G)Q.push({path:W,oldValue:z,newValue:G});else if(typeof z==="object"&&z!==null)if(Array.isArray(z)&&Array.isArray(G)){if(JSON.stringify(z)!==JSON.stringify(G))Q.push({path:W,oldValue:z,newValue:G})}else if(!Array.isArray(z)&&!Array.isArray(G)){let H=bQ(z,G,W);Q.push(...H)}else Q.push({path:W,oldValue:z,newValue:G});else if(z!==G)Q.push({path:W,oldValue:z,newValue:G})}return Q}function A4($,J){let Q={"AWS::S3::Bucket":new Set(["BucketName"]),"AWS::DynamoDB::Table":new Set(["TableName","KeySchema"]),"AWS::RDS::DBInstance":new Set(["DBInstanceIdentifier","DBName","Engine"]),"AWS::Lambda::Function":new Set(["FunctionName"]),"AWS::EC2::Instance":new Set(["ImageId","InstanceType","KeyName"]),"AWS::ECS::TaskDefinition":new Set(["Family","ContainerDefinitions"]),"AWS::ElastiCache::CacheCluster":new Set(["CacheNodeType","Engine"]),"AWS::CloudFront::Distribution":new Set([]),"AWS::Route53::HostedZone":new Set(["Name"]),"AWS::IAM::Role":new Set(["RoleName","Path"]),"AWS::KMS::Key":new Set(["KeyPolicy"]),"AWS::Cognito::UserPool":new Set(["UserPoolName"]),"AWS::OpenSearchService::Domain":new Set(["DomainName"])}[$];if(!Q)return!1;for(let Z of J){let U=Z.path.split(".")[0];if(Q.has(U))return!0}return!1}function K4($){let J=[];for(let Y of $){if(Y.action==="remove"&&(Y.resourceType==="AWS::RDS::DBInstance"||Y.resourceType==="AWS::DynamoDB::Table"||Y.resourceType==="AWS::ElastiCache::CacheCluster"))J.push(`Removing ${Y.resourceType} ${Y.logicalId} - data loss risk!`);if(Y.action==="replace"&&(Y.resourceType==="AWS::RDS::DBInstance"||Y.resourceType==="AWS::DynamoDB::Table"))J.push(`Replacing ${Y.resourceType} ${Y.logicalId} - data loss risk!`);if((Y.action==="remove"||Y.action==="replace")&&Y.resourceType==="AWS::S3::Bucket")J.push(`${Y.action==="remove"?"Removing":"Replacing"} S3 bucket ${Y.logicalId} - data loss risk!`);if(Y.action==="replace"&&Y.resourceType==="AWS::EC2::Instance")J.push(`Replacing EC2 instance ${Y.logicalId} - downtime expected`);if(Y.action==="update"&&Y.resourceType==="AWS::EC2::SecurityGroup")J.push(`Updating security group ${Y.logicalId} - may affect connectivity`);if((Y.action==="update"||Y.action==="replace")&&(Y.resourceType==="AWS::IAM::Role"||Y.resourceType==="AWS::IAM::Policy"))J.push(`Modifying IAM ${Y.resourceType.split("::")[2]} ${Y.logicalId} - may affect permissions`)}return J}function B4($){let J=[];if(J.push(`=== Stack Update Analysis ===
73
73
  `),$.summary.totalChanges===0)return J.push(`No changes detected.
74
74
  `),J.join(`
75
75
  `);if(J.push(`Total changes: ${$.summary.totalChanges}`),J.push(`Requires replacement: ${$.summary.requiresReplacement?"Yes":"No"}
76
76
  `),$.summary.dangerousChanges.length>0){J.push("⚠️ DANGEROUS CHANGES DETECTED:");for(let Y of $.summary.dangerousChanges)J.push(` • ${Y}`);J.push("")}if($.added.length>0){J.push(`✅ Resources to Add (${$.added.length}):`);for(let Y of $.added)J.push(` + ${Y.logicalId} (${Y.resourceType})`);J.push("")}if($.removed.length>0){J.push(`❌ Resources to Remove (${$.removed.length}):`);for(let Y of $.removed)J.push(` - ${Y.logicalId} (${Y.resourceType})`);J.push("")}if($.replaced.length>0){J.push(`\uD83D\uDD04 Resources to Replace (${$.replaced.length}):`);for(let Y of $.replaced){if(J.push(` ~ ${Y.logicalId} (${Y.resourceType})`),Y.reason)J.push(` Reason: ${Y.reason}`);if(Y.changes){for(let Q of Y.changes.slice(0,3))J.push(` • ${Q.path}: ${JSON.stringify(Q.oldValue)} → ${JSON.stringify(Q.newValue)}`);if(Y.changes.length>3)J.push(` ... and ${Y.changes.length-3} more changes`)}}J.push("")}if($.updated.length>0){J.push(`\uD83D\uDCDD Resources to Update (${$.updated.length}):`);for(let Y of $.updated)if(J.push(` ~ ${Y.logicalId} (${Y.resourceType})`),Y.changes){for(let Q of Y.changes.slice(0,3))J.push(` • ${Q.path}: ${JSON.stringify(Q.oldValue)} → ${JSON.stringify(Q.newValue)}`);if(Y.changes.length>3)J.push(` ... and ${Y.changes.length-3} more changes`)}J.push("")}if($.unchanged.length>0)J.push(`⚪ Unchanged Resources (${$.unchanged.length})`);return J.join(`
77
- `)}class E0{static createVpc($){let{slug:J,environment:Y,cidr:Q="10.0.0.0/16",enableDnsHostnames:Z=!0,enableDnsSupport:U=!0}=$,W=v({slug:J,environment:Y,resourceType:"vpc"}),z=S(W);return{vpc:{Type:"AWS::EC2::VPC",Properties:{CidrBlock:Q,EnableDnsHostnames:Z,EnableDnsSupport:U,Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Y}]}},logicalId:z}}static createSubnet($){let{slug:J,environment:Y,vpcId:Q,type:Z,cidr:U,availabilityZone:W,mapPublicIp:z=Z==="public"}=$,G=v({slug:J,environment:Y,resourceType:`subnet-${Z}`}),H=S(`${G}-${W}`);return{subnet:{Type:"AWS::EC2::Subnet",Properties:{VpcId:Q,CidrBlock:U,AvailabilityZone:W,MapPublicIpOnLaunch:z,Tags:[{Key:"Name",Value:`${G}-${W}`},{Key:"Environment",Value:Y},{Key:"Type",Value:Z}]}},logicalId:H}}static createInternetGateway($,J){let Y=v({slug:$,environment:J,resourceType:"igw"}),Q=S(Y);return{internetGateway:{Type:"AWS::EC2::InternetGateway",Properties:{Tags:[{Key:"Name",Value:Y},{Key:"Environment",Value:J}]}},logicalId:Q}}static attachInternetGateway($,J){let Y=S(`${$}-igw-attachment`);return{attachment:{Type:"AWS::EC2::VPCGatewayAttachment",Properties:{VpcId:u.Ref($),InternetGatewayId:u.Ref(J)}},logicalId:Y}}static createEip($,J){let Y=v({slug:$,environment:J,resourceType:"eip"}),Q=S(Y);return{eip:{Type:"AWS::EC2::EIP",Properties:{Domain:"vpc",Tags:[{Key:"Name",Value:Y},{Key:"Environment",Value:J}]}},logicalId:Q}}static createNatGateway($,J){let{slug:Y,environment:Q,subnetId:Z}=$,U=v({slug:Y,environment:Q,resourceType:"nat"}),W=S(U);return{natGateway:{Type:"AWS::EC2::NatGateway",Properties:{AllocationId:u.GetAtt(J,"AllocationId"),SubnetId:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q},{Key:"Warning",Value:"NAT Gateway incurs hourly charges"}]}},logicalId:W}}static createRouteTable($,J,Y,Q){let Z=v({slug:$,environment:J,resourceType:`rt-${Q}`}),U=S(Z);return{routeTable:{Type:"AWS::EC2::RouteTable",Properties:{VpcId:u.Ref(Y),Tags:[{Key:"Name",Value:Z},{Key:"Environment",Value:J},{Key:"Type",Value:Q}]}},logicalId:U}}static createRoute($,J,Y){let Q=S(`${$}-route-${Y.type}`),Z={Type:"AWS::EC2::Route",Properties:{RouteTableId:u.Ref($),DestinationCidrBlock:J}};if(Y.type==="igw")Z.Properties.GatewayId=u.Ref(Y.logicalId);else if(Y.type==="nat")Z.Properties.NatGatewayId=u.Ref(Y.logicalId);else if(Y.type==="instance")Z.Properties.InstanceId=u.Ref(Y.logicalId);return{route:Z,logicalId:Q}}static associateSubnetWithRouteTable($,J){let Y=S(`${$}-rt-assoc`);return{association:{Type:"AWS::EC2::SubnetRouteTableAssociation",Properties:{SubnetId:u.Ref($),RouteTableId:u.Ref(J)}},logicalId:Y}}static enableFlowLogs($){let{slug:J,environment:Y,resourceId:Q,resourceType:Z,trafficType:U="ALL",logGroupName:W}=$,z=v({slug:J,environment:Y,resourceType:"flowlog"}),G=S(z);return{flowLog:{Type:"AWS::EC2::FlowLog",Properties:{ResourceType:Z,ResourceIds:[Q],TrafficType:U,LogDestinationType:"cloud-watch-logs",LogGroupName:W||`/aws/vpc/${J}-${Y}`,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}},logicalId:G}}static calculateSubnetCidrs($,J,Y=3){let[Q,Z]=$.split("/"),U=Number.parseInt(Z,10),W=Math.ceil(Math.log2(J*Y)),z=U+W;if(z>28)throw Error("VPC CIDR is too small to accommodate requested subnets");let[G,H,A,K]=Q.split(".").map(Number),B=(G<<24)+(H<<16)+(A<<8)+K,j=2**(32-z),X=[];for(let O=0;O<J*Y;O++){let _=B+O*j,w=[_>>>24&255,_>>>16&255,_>>>8&255,_&255].join(".");X.push(`${w}/${z}`)}return X}static getAvailabilityZones($,J){return["a","b","c","d","e","f"].slice(0,J).map((Q)=>`${$}${Q}`)}static createMultiAzNetwork($){let{slug:J,environment:Y,region:Q,cidr:Z="10.0.0.0/16",zones:U=3,enableNatGateway:W=!1,singleNatGateway:z=!1,enableFlowLogs:G=!1}=$,H={},A=[],K=[],B=[],{vpc:j,logicalId:X}=E0.createVpc({slug:J,environment:Y,cidr:Z});H[X]=j;let{internetGateway:O,logicalId:_}=E0.createInternetGateway(J,Y);H[_]=O;let{attachment:w,logicalId:E}=E0.attachInternetGateway(X,_);H[E]=w;let{routeTable:M,logicalId:T}=E0.createRouteTable(J,Y,X,"public");H[T]=M;let{route:D,logicalId:N}=E0.createRoute(T,"0.0.0.0/0",{type:"igw",logicalId:_});D.DependsOn=E,H[N]=D;let x=E0.calculateSubnetCidrs(Z,U,2),h=E0.getAvailabilityZones(Q,U),k=[];for(let b=0;b<U;b++){let I=h[b],f=x[b*2],m=x[b*2+1],{subnet:l,logicalId:p}=E0.createSubnet({slug:J,environment:Y,vpcId:u.Ref(X),type:"public",cidr:f,availabilityZone:I});H[p]=l,A.push(p);let{association:r,logicalId:s}=E0.associateSubnetWithRouteTable(p,T);H[s]=r;let{subnet:o,logicalId:B0}=E0.createSubnet({slug:J,environment:Y,vpcId:u.Ref(X),type:"private",cidr:m,availabilityZone:I});if(H[B0]=o,K.push(B0),W&&(!z||b===0)){let{eip:c0,logicalId:x0}=E0.createEip(`${J}-${I}`,Y);H[x0]=c0;let{natGateway:z2,logicalId:G2}=E0.createNatGateway({slug:`${J}-${I}`,environment:Y,subnetId:u.Ref(p)},x0);z2.DependsOn=E,H[G2]=z2,B.push(G2);let{routeTable:N0,logicalId:k1}=E0.createRouteTable(`${J}-${I}`,Y,X,"private");H[k1]=N0,k.push(k1);let{route:p2,logicalId:a9}=E0.createRoute(k1,"0.0.0.0/0",{type:"nat",logicalId:G2});H[a9]=p2;let{association:GU,logicalId:HU}=E0.associateSubnetWithRouteTable(B0,k1);H[HU]=GU}else if(W&&z&&b>0){let{association:c0,logicalId:x0}=E0.associateSubnetWithRouteTable(B0,k[0]);H[x0]=c0}else{let{routeTable:c0,logicalId:x0}=E0.createRouteTable(`${J}-${I}-isolated`,Y,X,"private");H[x0]=c0;let{association:z2,logicalId:G2}=E0.associateSubnetWithRouteTable(B0,x0);H[G2]=z2}}if(G){let{flowLog:b,logicalId:I}=E0.enableFlowLogs({slug:J,environment:Y,resourceId:u.Ref(X),resourceType:"VPC"});H[I]=b}return{resources:H,outputs:{vpcId:X,publicSubnetIds:A,privateSubnetIds:K,natGatewayIds:B.length>0?B:void 0}}}static NatGatewayCostWarning=`
77
+ `)}class E0{static createVpc($){let{slug:J,environment:Y,cidr:Q="10.0.0.0/16",enableDnsHostnames:Z=!0,enableDnsSupport:U=!0}=$,W=f({slug:J,environment:Y,resourceType:"vpc"}),z=S(W);return{vpc:{Type:"AWS::EC2::VPC",Properties:{CidrBlock:Q,EnableDnsHostnames:Z,EnableDnsSupport:U,Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Y}]}},logicalId:z}}static createSubnet($){let{slug:J,environment:Y,vpcId:Q,type:Z,cidr:U,availabilityZone:W,mapPublicIp:z=Z==="public"}=$,G=f({slug:J,environment:Y,resourceType:`subnet-${Z}`}),H=S(`${G}-${W}`);return{subnet:{Type:"AWS::EC2::Subnet",Properties:{VpcId:Q,CidrBlock:U,AvailabilityZone:W,MapPublicIpOnLaunch:z,Tags:[{Key:"Name",Value:`${G}-${W}`},{Key:"Environment",Value:Y},{Key:"Type",Value:Z}]}},logicalId:H}}static createInternetGateway($,J){let Y=f({slug:$,environment:J,resourceType:"igw"}),Q=S(Y);return{internetGateway:{Type:"AWS::EC2::InternetGateway",Properties:{Tags:[{Key:"Name",Value:Y},{Key:"Environment",Value:J}]}},logicalId:Q}}static attachInternetGateway($,J){let Y=S(`${$}-igw-attachment`);return{attachment:{Type:"AWS::EC2::VPCGatewayAttachment",Properties:{VpcId:u.Ref($),InternetGatewayId:u.Ref(J)}},logicalId:Y}}static createEip($,J){let Y=f({slug:$,environment:J,resourceType:"eip"}),Q=S(Y);return{eip:{Type:"AWS::EC2::EIP",Properties:{Domain:"vpc",Tags:[{Key:"Name",Value:Y},{Key:"Environment",Value:J}]}},logicalId:Q}}static createNatGateway($,J){let{slug:Y,environment:Q,subnetId:Z}=$,U=f({slug:Y,environment:Q,resourceType:"nat"}),W=S(U);return{natGateway:{Type:"AWS::EC2::NatGateway",Properties:{AllocationId:u.GetAtt(J,"AllocationId"),SubnetId:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q},{Key:"Warning",Value:"NAT Gateway incurs hourly charges"}]}},logicalId:W}}static createRouteTable($,J,Y,Q){let Z=f({slug:$,environment:J,resourceType:`rt-${Q}`}),U=S(Z);return{routeTable:{Type:"AWS::EC2::RouteTable",Properties:{VpcId:u.Ref(Y),Tags:[{Key:"Name",Value:Z},{Key:"Environment",Value:J},{Key:"Type",Value:Q}]}},logicalId:U}}static createRoute($,J,Y){let Q=S(`${$}-route-${Y.type}`),Z={Type:"AWS::EC2::Route",Properties:{RouteTableId:u.Ref($),DestinationCidrBlock:J}};if(Y.type==="igw")Z.Properties.GatewayId=u.Ref(Y.logicalId);else if(Y.type==="nat")Z.Properties.NatGatewayId=u.Ref(Y.logicalId);else if(Y.type==="instance")Z.Properties.InstanceId=u.Ref(Y.logicalId);return{route:Z,logicalId:Q}}static associateSubnetWithRouteTable($,J){let Y=S(`${$}-rt-assoc`);return{association:{Type:"AWS::EC2::SubnetRouteTableAssociation",Properties:{SubnetId:u.Ref($),RouteTableId:u.Ref(J)}},logicalId:Y}}static enableFlowLogs($){let{slug:J,environment:Y,resourceId:Q,resourceType:Z,trafficType:U="ALL",logGroupName:W}=$,z=f({slug:J,environment:Y,resourceType:"flowlog"}),G=S(z);return{flowLog:{Type:"AWS::EC2::FlowLog",Properties:{ResourceType:Z,ResourceIds:[Q],TrafficType:U,LogDestinationType:"cloud-watch-logs",LogGroupName:W||`/aws/vpc/${J}-${Y}`,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}},logicalId:G}}static calculateSubnetCidrs($,J,Y=3){let[Q,Z]=$.split("/"),U=Number.parseInt(Z,10),W=Math.ceil(Math.log2(J*Y)),z=U+W;if(z>28)throw Error("VPC CIDR is too small to accommodate requested subnets");let[G,H,A,K]=Q.split(".").map(Number),B=(G<<24)+(H<<16)+(A<<8)+K,j=2**(32-z),X=[];for(let O=0;O<J*Y;O++){let _=B+O*j,w=[_>>>24&255,_>>>16&255,_>>>8&255,_&255].join(".");X.push(`${w}/${z}`)}return X}static getAvailabilityZones($,J){return["a","b","c","d","e","f"].slice(0,J).map((Q)=>`${$}${Q}`)}static createMultiAzNetwork($){let{slug:J,environment:Y,region:Q,cidr:Z="10.0.0.0/16",zones:U=3,enableNatGateway:W=!1,singleNatGateway:z=!1,enableFlowLogs:G=!1}=$,H={},A=[],K=[],B=[],{vpc:j,logicalId:X}=E0.createVpc({slug:J,environment:Y,cidr:Z});H[X]=j;let{internetGateway:O,logicalId:_}=E0.createInternetGateway(J,Y);H[_]=O;let{attachment:w,logicalId:E}=E0.attachInternetGateway(X,_);H[E]=w;let{routeTable:M,logicalId:T}=E0.createRouteTable(J,Y,X,"public");H[T]=M;let{route:D,logicalId:N}=E0.createRoute(T,"0.0.0.0/0",{type:"igw",logicalId:_});D.DependsOn=E,H[N]=D;let x=E0.calculateSubnetCidrs(Z,U,2),h=E0.getAvailabilityZones(Q,U),I=[];for(let b=0;b<U;b++){let k=h[b],y=x[b*2],m=x[b*2+1],{subnet:l,logicalId:p}=E0.createSubnet({slug:J,environment:Y,vpcId:u.Ref(X),type:"public",cidr:y,availabilityZone:k});H[p]=l,A.push(p);let{association:r,logicalId:s}=E0.associateSubnetWithRouteTable(p,T);H[s]=r;let{subnet:o,logicalId:B0}=E0.createSubnet({slug:J,environment:Y,vpcId:u.Ref(X),type:"private",cidr:m,availabilityZone:k});if(H[B0]=o,K.push(B0),W&&(!z||b===0)){let{eip:c0,logicalId:x0}=E0.createEip(`${J}-${k}`,Y);H[x0]=c0;let{natGateway:z2,logicalId:G2}=E0.createNatGateway({slug:`${J}-${k}`,environment:Y,subnetId:u.Ref(p)},x0);z2.DependsOn=E,H[G2]=z2,B.push(G2);let{routeTable:N0,logicalId:k1}=E0.createRouteTable(`${J}-${k}`,Y,X,"private");H[k1]=N0,I.push(k1);let{route:p2,logicalId:a9}=E0.createRoute(k1,"0.0.0.0/0",{type:"nat",logicalId:G2});H[a9]=p2;let{association:GU,logicalId:HU}=E0.associateSubnetWithRouteTable(B0,k1);H[HU]=GU}else if(W&&z&&b>0){let{association:c0,logicalId:x0}=E0.associateSubnetWithRouteTable(B0,I[0]);H[x0]=c0}else{let{routeTable:c0,logicalId:x0}=E0.createRouteTable(`${J}-${k}-isolated`,Y,X,"private");H[x0]=c0;let{association:z2,logicalId:G2}=E0.associateSubnetWithRouteTable(B0,x0);H[G2]=z2}}if(G){let{flowLog:b,logicalId:k}=E0.enableFlowLogs({slug:J,environment:Y,resourceId:u.Ref(X),resourceType:"VPC"});H[k]=b}return{resources:H,outputs:{vpcId:X,publicSubnetIds:A,privateSubnetIds:K,natGatewayIds:B.length>0?B:void 0}}}static NatGatewayCostWarning=`
78
78
  ⚠️ NAT Gateway Cost Warning:
79
79
  - Each NAT Gateway costs approximately $32-45/month (hourly charges)
80
80
  - Data processing charges: $0.045/GB processed
@@ -82,7 +82,7 @@ ${this.convertToYAML(W,J+2)}`;else Q+=`${Y} - ${W}
82
82
  - Using a single NAT Gateway (singleNatGateway: true)
83
83
  - Using NAT Instances instead (cheaper but requires management)
84
84
  - Disabling NAT entirely for isolated private subnets
85
- `}class D1{static createFileSystem($){let{slug:J,environment:Y,encrypted:Q=!0,kmsKeyId:Z,performanceMode:U="generalPurpose",throughputMode:W="bursting",provisionedThroughput:z,enableBackup:G=!0}=$,H=v({slug:J,environment:Y,resourceType:"efs"}),A=S(H),K={Type:"AWS::EFS::FileSystem",Properties:{Encrypted:Q,PerformanceMode:U,ThroughputMode:W,FileSystemTags:[{Key:"Name",Value:H},{Key:"Environment",Value:Y}]}};if(Z)K.Properties.KmsKeyId=Z;if(W==="provisioned"&&z)K.Properties.ProvisionedThroughputInMibps=z;if(G)K.Properties.BackupPolicy={Status:"ENABLED"};return{fileSystem:K,logicalId:A}}static createMountTarget($,J){let{slug:Y,environment:Q,subnetId:Z,securityGroups:U,ipAddress:W}=J,z=v({slug:Y,environment:Q,resourceType:"efs-mt"}),G=S(`${z}-${Z}`),H={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:u.Ref($),SubnetId:Z,SecurityGroups:U}};if(W)H.Properties.IpAddress=W;return{mountTarget:H,logicalId:G}}static createAccessPoint($,J){let{slug:Y,environment:Q,path:Z="/",uid:U="1000",gid:W="1000",permissions:z="755"}=J,G=v({slug:Y,environment:Q,resourceType:"efs-ap"}),H=S(`${G}-${Z.replace(/\//g,"-")}`);return{accessPoint:{Type:"AWS::EFS::AccessPoint",Properties:{FileSystemId:u.Ref($),PosixUser:{Uid:U,Gid:W},RootDirectory:{Path:Z,CreationInfo:{OwnerUid:U,OwnerGid:W,Permissions:z}},AccessPointTags:[{Key:"Name",Value:`${G}-${Z}`},{Key:"Environment",Value:Q}]}},logicalId:H}}static setLifecyclePolicy($,J){let{transitionToIA:Y,transitionToPrimary:Q=!1}=J;if(!$.Properties)$.Properties={};if($.Properties.LifecyclePolicies=[],Y){let Z=`AFTER_${Y}_DAYS`;$.Properties.LifecyclePolicies.push({TransitionToIA:Z})}if(Q)$.Properties.LifecyclePolicies.push({TransitionToPrimaryStorageClass:"AFTER_1_ACCESS"});return $}static enableBackup($){if(!$.Properties)$.Properties={};return $.Properties.BackupPolicy={Status:"ENABLED"},$}static disableBackup($){if(!$.Properties)$.Properties={};return $.Properties.BackupPolicy={Status:"DISABLED"},$}static setProvisionedThroughput($,J){if(!$.Properties)$.Properties={};return $.Properties.ThroughputMode="provisioned",$.Properties.ProvisionedThroughputInMibps=J,$}static setElasticThroughput($){if(!$.Properties)$.Properties={};return $.Properties.ThroughputMode="elastic",$}static enableMaxIO($){if(!$.Properties)$.Properties={};return $.Properties.PerformanceMode="maxIO",$}static createEfsSecurityGroup($){let{slug:J,environment:Y,vpcId:Q,sourceSecurityGroupIds:Z=[],sourceCidrBlocks:U=[],description:W}=$,z=v({slug:J,environment:Y,resourceType:"efs-sg"}),G=S(z),H=[];for(let K of Z)H.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,SourceSecurityGroupId:K,Description:"NFS from security group"});for(let K of U)H.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,CidrIp:K,Description:"NFS from CIDR block"});return{securityGroup:{Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:z,GroupDescription:W||`Security group for EFS mount targets - ${J} ${Y}`,VpcId:Q,SecurityGroupIngress:H,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}},logicalId:G}}static createMultiAzMountTargets($,J){let{slug:Y,environment:Q,subnetIds:Z,securityGroupId:U}=J,W=[],z=[];for(let G=0;G<Z.length;G++){let H=Z[G],A=v({slug:Y,environment:Q,resourceType:"efs-mt"}),K=S(`${A}-az${G+1}`),B={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:u.Ref($),SubnetId:H,SecurityGroups:[U]}};W.push(B),z.push(K)}return{mountTargets:W,logicalIds:z}}static createCompleteFileSystem($){let{slug:J,environment:Y,vpcId:Q,subnetIds:Z,sourceSecurityGroupIds:U=[],encrypted:W=!0,performanceMode:z="generalPurpose",throughputMode:G="elastic",enableBackup:H=!0,transitionToIA:A}=$,K={},{fileSystem:B,logicalId:j}=D1.createFileSystem({slug:J,environment:Y,encrypted:W,performanceMode:z,throughputMode:G,enableBackup:H});if(A)D1.setLifecyclePolicy(B,{transitionToIA:A,transitionToPrimary:!0});K[j]=B;let{securityGroup:X,logicalId:O}=D1.createEfsSecurityGroup({slug:J,environment:Y,vpcId:Q,sourceSecurityGroupIds:U});K[O]=X;let{mountTargets:_,logicalIds:w}=D1.createMultiAzMountTargets(j,{slug:J,environment:Y,subnetIds:Z,securityGroupId:u.Ref(O)});for(let E=0;E<_.length;E++)K[w[E]]=_[E];return{resources:K,outputs:{fileSystemId:j,securityGroupId:O,mountTargetIds:w}}}}class m1{static async discoverJobs($){let{projectRoot:J,jobsPath:Y="app/Jobs"}=$,Q=`${J}/${Y}`,Z=[];try{let U=await import("node:fs"),W=await import("node:path");if(!U.existsSync(Q))return[];let z=U.readdirSync(Q).filter((G)=>G.endsWith(".ts")&&!G.startsWith("_")&&G!=="runner.ts");for(let G of z){let H=W.join(Q,G),A=G.replace(".ts",""),K=U.readFileSync(H,"utf-8"),B=m1.parseJobMetadata(K,A,H);if(B)Z.push(B)}}catch{return[]}return Z}static parseJobMetadata($,J,Y){let Q=$.match(/export\s+const\s+schedule\s*=\s*['"`]([^'"`]+)['"`]/)||$.match(/schedule:\s*['"`]([^'"`]+)['"`]/),Z=$.match(/export\s+const\s+enabled\s*=\s*(true|false)/)||$.match(/enabled:\s*(true|false)/),U=$.match(/export\s+const\s+retries\s*=\s*(\d+)/)||$.match(/retries:\s*(\d+)/),W=$.match(/export\s+const\s+timeout\s*=\s*(\d+)/)||$.match(/timeout:\s*(\d+)/),z=$.match(/export\s+const\s+backoff\s*=\s*['"`](linear|exponential|fixed)['"`]/)||$.match(/backoff:\s*['"`](linear|exponential|fixed)['"`]/),G=$.match(/export\s+const\s+description\s*=\s*['"`]([^'"`]+)['"`]/)||$.match(/description:\s*['"`]([^'"`]+)['"`]/);if(!($.includes("export async function handle")||$.includes("export function handle")||$.includes("export default")))return null;return{name:J,path:Y,schedule:Q?.[1],handler:`${J}.handle`,enabled:Z?.[1]!=="false",retries:U?parseInt(U[1],10):void 0,backoff:z?.[1],timeout:W?parseInt(W[1],10):void 0,description:G?.[1]}}static async discoverActions($){let{projectRoot:J,actionsPath:Y="app/Actions"}=$,Q=`${J}/${Y}`,Z=[];try{let U=await import("node:fs"),W=await import("node:path");if(!U.existsSync(Q))return[];let z=U.readdirSync(Q).filter((G)=>G.endsWith(".ts")&&!G.startsWith("_"));for(let G of z){let H=W.join(Q,G),A=G.replace(".ts",""),K=U.readFileSync(H,"utf-8"),B=m1.parseActionMetadata(K,A,H);if(B)Z.push(B)}}catch{return[]}return Z}static parseActionMetadata($,J,Y){if(!($.includes("export async function handle")||$.includes("export function handle")||$.includes("export default")))return null;let Z=$.match(/export\s+const\s+description\s*=\s*['"`]([^'"`]+)['"`]/)||$.match(/description:\s*['"`]([^'"`]+)['"`]/);return{name:J,path:Y,handler:`${J}.handle`,description:Z?.[1]}}static generateScheduledJobResources($){let{slug:J,environment:Y,jobs:Q,taskDefinitionArn:Z,clusterArn:U,subnets:W,securityGroups:z=[],roleArn:G,containerName:H="app"}=$,A={},K=0;for(let B of Q){if(!B.schedule||!B.enabled)continue;let{rule:j,logicalId:X}=t0.createScheduledJob({slug:J,environment:Y,schedule:B.schedule,jobClass:B.name,taskDefinitionArn:Z,clusterArn:U,subnets:W,securityGroups:z,roleArn:G,containerName:H});A[X]=j,K++}return{rules:A,count:K}}static generateJobRunnerScript(){return`#!/usr/bin/env bun
85
+ `}class D1{static createFileSystem($){let{slug:J,environment:Y,encrypted:Q=!0,kmsKeyId:Z,performanceMode:U="generalPurpose",throughputMode:W="bursting",provisionedThroughput:z,enableBackup:G=!0}=$,H=f({slug:J,environment:Y,resourceType:"efs"}),A=S(H),K={Type:"AWS::EFS::FileSystem",Properties:{Encrypted:Q,PerformanceMode:U,ThroughputMode:W,FileSystemTags:[{Key:"Name",Value:H},{Key:"Environment",Value:Y}]}};if(Z)K.Properties.KmsKeyId=Z;if(W==="provisioned"&&z)K.Properties.ProvisionedThroughputInMibps=z;if(G)K.Properties.BackupPolicy={Status:"ENABLED"};return{fileSystem:K,logicalId:A}}static createMountTarget($,J){let{slug:Y,environment:Q,subnetId:Z,securityGroups:U,ipAddress:W}=J,z=f({slug:Y,environment:Q,resourceType:"efs-mt"}),G=S(`${z}-${Z}`),H={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:u.Ref($),SubnetId:Z,SecurityGroups:U}};if(W)H.Properties.IpAddress=W;return{mountTarget:H,logicalId:G}}static createAccessPoint($,J){let{slug:Y,environment:Q,path:Z="/",uid:U="1000",gid:W="1000",permissions:z="755"}=J,G=f({slug:Y,environment:Q,resourceType:"efs-ap"}),H=S(`${G}-${Z.replace(/\//g,"-")}`);return{accessPoint:{Type:"AWS::EFS::AccessPoint",Properties:{FileSystemId:u.Ref($),PosixUser:{Uid:U,Gid:W},RootDirectory:{Path:Z,CreationInfo:{OwnerUid:U,OwnerGid:W,Permissions:z}},AccessPointTags:[{Key:"Name",Value:`${G}-${Z}`},{Key:"Environment",Value:Q}]}},logicalId:H}}static setLifecyclePolicy($,J){let{transitionToIA:Y,transitionToPrimary:Q=!1}=J;if(!$.Properties)$.Properties={};if($.Properties.LifecyclePolicies=[],Y){let Z=`AFTER_${Y}_DAYS`;$.Properties.LifecyclePolicies.push({TransitionToIA:Z})}if(Q)$.Properties.LifecyclePolicies.push({TransitionToPrimaryStorageClass:"AFTER_1_ACCESS"});return $}static enableBackup($){if(!$.Properties)$.Properties={};return $.Properties.BackupPolicy={Status:"ENABLED"},$}static disableBackup($){if(!$.Properties)$.Properties={};return $.Properties.BackupPolicy={Status:"DISABLED"},$}static setProvisionedThroughput($,J){if(!$.Properties)$.Properties={};return $.Properties.ThroughputMode="provisioned",$.Properties.ProvisionedThroughputInMibps=J,$}static setElasticThroughput($){if(!$.Properties)$.Properties={};return $.Properties.ThroughputMode="elastic",$}static enableMaxIO($){if(!$.Properties)$.Properties={};return $.Properties.PerformanceMode="maxIO",$}static createEfsSecurityGroup($){let{slug:J,environment:Y,vpcId:Q,sourceSecurityGroupIds:Z=[],sourceCidrBlocks:U=[],description:W}=$,z=f({slug:J,environment:Y,resourceType:"efs-sg"}),G=S(z),H=[];for(let K of Z)H.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,SourceSecurityGroupId:K,Description:"NFS from security group"});for(let K of U)H.push({IpProtocol:"tcp",FromPort:2049,ToPort:2049,CidrIp:K,Description:"NFS from CIDR block"});return{securityGroup:{Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:z,GroupDescription:W||`Security group for EFS mount targets - ${J} ${Y}`,VpcId:Q,SecurityGroupIngress:H,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}},logicalId:G}}static createMultiAzMountTargets($,J){let{slug:Y,environment:Q,subnetIds:Z,securityGroupId:U}=J,W=[],z=[];for(let G=0;G<Z.length;G++){let H=Z[G],A=f({slug:Y,environment:Q,resourceType:"efs-mt"}),K=S(`${A}-az${G+1}`),B={Type:"AWS::EFS::MountTarget",Properties:{FileSystemId:u.Ref($),SubnetId:H,SecurityGroups:[U]}};W.push(B),z.push(K)}return{mountTargets:W,logicalIds:z}}static createCompleteFileSystem($){let{slug:J,environment:Y,vpcId:Q,subnetIds:Z,sourceSecurityGroupIds:U=[],encrypted:W=!0,performanceMode:z="generalPurpose",throughputMode:G="elastic",enableBackup:H=!0,transitionToIA:A}=$,K={},{fileSystem:B,logicalId:j}=D1.createFileSystem({slug:J,environment:Y,encrypted:W,performanceMode:z,throughputMode:G,enableBackup:H});if(A)D1.setLifecyclePolicy(B,{transitionToIA:A,transitionToPrimary:!0});K[j]=B;let{securityGroup:X,logicalId:O}=D1.createEfsSecurityGroup({slug:J,environment:Y,vpcId:Q,sourceSecurityGroupIds:U});K[O]=X;let{mountTargets:_,logicalIds:w}=D1.createMultiAzMountTargets(j,{slug:J,environment:Y,subnetIds:Z,securityGroupId:u.Ref(O)});for(let E=0;E<_.length;E++)K[w[E]]=_[E];return{resources:K,outputs:{fileSystemId:j,securityGroupId:O,mountTargetIds:w}}}}class m1{static async discoverJobs($){let{projectRoot:J,jobsPath:Y="app/Jobs"}=$,Q=`${J}/${Y}`,Z=[];try{let U=await import("node:fs"),W=await import("node:path");if(!U.existsSync(Q))return[];let z=U.readdirSync(Q).filter((G)=>G.endsWith(".ts")&&!G.startsWith("_")&&G!=="runner.ts");for(let G of z){let H=W.join(Q,G),A=G.replace(".ts",""),K=U.readFileSync(H,"utf-8"),B=m1.parseJobMetadata(K,A,H);if(B)Z.push(B)}}catch{return[]}return Z}static parseJobMetadata($,J,Y){let Q=$.match(/export\s+const\s+schedule\s*=\s*['"`]([^'"`]+)['"`]/)||$.match(/schedule:\s*['"`]([^'"`]+)['"`]/),Z=$.match(/export\s+const\s+enabled\s*=\s*(true|false)/)||$.match(/enabled:\s*(true|false)/),U=$.match(/export\s+const\s+retries\s*=\s*(\d+)/)||$.match(/retries:\s*(\d+)/),W=$.match(/export\s+const\s+timeout\s*=\s*(\d+)/)||$.match(/timeout:\s*(\d+)/),z=$.match(/export\s+const\s+backoff\s*=\s*['"`](linear|exponential|fixed)['"`]/)||$.match(/backoff:\s*['"`](linear|exponential|fixed)['"`]/),G=$.match(/export\s+const\s+description\s*=\s*['"`]([^'"`]+)['"`]/)||$.match(/description:\s*['"`]([^'"`]+)['"`]/);if(!($.includes("export async function handle")||$.includes("export function handle")||$.includes("export default")))return null;return{name:J,path:Y,schedule:Q?.[1],handler:`${J}.handle`,enabled:Z?.[1]!=="false",retries:U?parseInt(U[1],10):void 0,backoff:z?.[1],timeout:W?parseInt(W[1],10):void 0,description:G?.[1]}}static async discoverActions($){let{projectRoot:J,actionsPath:Y="app/Actions"}=$,Q=`${J}/${Y}`,Z=[];try{let U=await import("node:fs"),W=await import("node:path");if(!U.existsSync(Q))return[];let z=U.readdirSync(Q).filter((G)=>G.endsWith(".ts")&&!G.startsWith("_"));for(let G of z){let H=W.join(Q,G),A=G.replace(".ts",""),K=U.readFileSync(H,"utf-8"),B=m1.parseActionMetadata(K,A,H);if(B)Z.push(B)}}catch{return[]}return Z}static parseActionMetadata($,J,Y){if(!($.includes("export async function handle")||$.includes("export function handle")||$.includes("export default")))return null;let Z=$.match(/export\s+const\s+description\s*=\s*['"`]([^'"`]+)['"`]/)||$.match(/description:\s*['"`]([^'"`]+)['"`]/);return{name:J,path:Y,handler:`${J}.handle`,description:Z?.[1]}}static generateScheduledJobResources($){let{slug:J,environment:Y,jobs:Q,taskDefinitionArn:Z,clusterArn:U,subnets:W,securityGroups:z=[],roleArn:G,containerName:H="app"}=$,A={},K=0;for(let B of Q){if(!B.schedule||!B.enabled)continue;let{rule:j,logicalId:X}=t0.createScheduledJob({slug:J,environment:Y,schedule:B.schedule,jobClass:B.name,taskDefinitionArn:Z,clusterArn:U,subnets:W,securityGroups:z,roleArn:G,containerName:H});A[X]=j,K++}return{rules:A,count:K}}static generateJobRunnerScript(){return`#!/usr/bin/env bun
86
86
  /**
87
87
  * Job Runner Script
88
88
  * This script is invoked by ECS scheduled tasks to run jobs
@@ -253,7 +253,7 @@ rpm -U ./amazon-cloudwatch-agent.rpm || true
253
253
  `}},storage:{uploads:{type:"efs",performanceMode:"generalPurpose",throughputMode:"bursting",encrypted:!0,lifecyclePolicy:{transitionToIA:30}},backups:{public:!1,versioning:!0,encryption:!0,lifecycleRules:[{id:"ArchiveOldBackups",enabled:!0,transitions:[{days:90,storageClass:"GLACIER"}]}]},static:{public:!0,versioning:!1,encryption:!1,cors:[{allowedOrigins:[Q||"*"],allowedMethods:["GET","HEAD"]}]}},cdn:{enabled:!0,origins:[{originId:"static-assets",domainName:`${Y}-static.s3.amazonaws.com`,pathPattern:"/static/*"}],customDomain:Q?{domain:Q,certificateArn:"TO_BE_GENERATED"}:void 0,cachePolicy:{minTTL:0,defaultTTL:86400,maxTTL:31536000},compress:!0,http3:!0},databases:z==="mysql"?{mysql:{engine:"mysql",version:"8.0",instanceClass:"db.t3.medium",allocatedStorage:100,maxAllocatedStorage:500,multiAZ:!0,backupRetentionDays:14,preferredBackupWindow:"03:00-04:00",preferredMaintenanceWindow:"sun:04:00-sun:05:00",enablePerformanceInsights:!0,performanceInsightsRetention:7,deletionProtection:!0,parameters:{max_connections:"500",innodb_buffer_pool_size:"{DBInstanceClassMemory*3/4}",slow_query_log:"1",long_query_time:"2"}}}:{postgres:{engine:"postgres",version:"15",instanceClass:"db.t3.medium",allocatedStorage:100,maxAllocatedStorage:500,multiAZ:!0,backupRetentionDays:14,preferredBackupWindow:"03:00-04:00",preferredMaintenanceWindow:"sun:04:00-sun:05:00",enablePerformanceInsights:!0,performanceInsightsRetention:7,deletionProtection:!0,parameters:{max_connections:"500",shared_buffers:"{DBInstanceClassMemory/4}",log_min_duration_statement:"2000"}}},cache:G==="redis"?{redis:{nodeType:"cache.t3.medium",numCacheNodes:2,engine:"redis",engineVersion:"7.0",port:6379,parameterGroup:{maxmemoryPolicy:"allkeys-lru",timeout:"300"},snapshotRetentionLimit:5,snapshotWindow:"03:00-05:00",automaticFailoverEnabled:!0}}:void 0,queues:{jobs:{fifo:!1,visibilityTimeout:900,messageRetentionPeriod:345600,receiveMessageWaitTime:20,deadLetterQueue:!0,maxReceiveCount:3},emails:{fifo:!1,visibilityTimeout:300,messageRetentionPeriod:86400,deadLetterQueue:!0}},functions:{"job-worker":{runtime:"nodejs20.x",handler:"dist/workers/jobs.handler",memory:2048,timeout:900,events:[{type:"sqs",queueName:`${Y}-jobs`,batchSize:10}]},"email-sender":{runtime:"nodejs20.x",handler:"dist/workers/email.handler",memory:512,timeout:60,events:[{type:"sqs",queueName:`${Y}-emails`,batchSize:10}]},cleanup:{runtime:"nodejs20.x",handler:"dist/tasks/cleanup.handler",memory:512,timeout:300,events:[{type:"schedule",expression:"cron(0 2 * * ? *)"}]}},monitoring:{dashboard:{name:`${Y}-web-app`,widgets:[{type:"metric",metrics:["EC2CPUUtilization","ALBRequestCount","ALBTargetResponseTime","RDSCPUUtilization","RDSDatabaseConnections","RDSReadLatency","RDSWriteLatency"]}]},alarms:[{metric:"EC2CPUUtilization",threshold:80,evaluationPeriods:2},{metric:"RDSCPUUtilization",threshold:80,evaluationPeriods:2},{metric:"RDSDatabaseConnections",threshold:400,evaluationPeriods:1},{metric:"ALBTargetResponseTime",threshold:2000,evaluationPeriods:2},{metric:"ALBUnhealthyHostCount",threshold:1,evaluationPeriods:1}],logs:{retention:14,groups:[`${Y}-app`,`${Y}-nginx`,`${Y}-workers`]}},security:{certificate:Q?{domain:Q,validationMethod:"DNS"}:void 0,waf:{enabled:!0,rules:["rateLimit","sqlInjection","xss","knownBadInputs"]},securityGroups:{alb:{ingress:[{port:80,protocol:"tcp",cidr:"0.0.0.0/0"},{port:443,protocol:"tcp",cidr:"0.0.0.0/0"}]},app:{ingress:[{port:3000,protocol:"tcp",source:"alb-sg"}]},database:{ingress:[{port:z==="mysql"?3306:5432,protocol:"tcp",source:"app-sg"}]},...G==="redis"&&{cache:{ingress:[{port:6379,protocol:"tcp",source:"app-sg"}]}}}}}}}function L6($,J){let Y={...$};for(let Q in J){let Z=J[Q],U=Y[Q];if(Z===void 0)continue;if(Array.isArray(Z)&&Array.isArray(U))Y[Q]=[...U,...Z];else if(typeof Z==="object"&&Z!==null&&!Array.isArray(Z)&&typeof U==="object"&&U!==null&&!Array.isArray(U))Y[Q]=L6(U,Z);else Y[Q]=Z}return Y}function A6($,J){return L6($,J)}function RH(...$){return $.reduce((J,Y)=>L6(J,Y),{})}function DH($,J){return(Y)=>{let Q=$(Y);if(typeof J==="function")return A6(Q,J(Q,Y));return A6(Q,J)}}function V2($){return{infrastructure:$}}function NH($){return V2({monitoring:$})}function SH($){return V2({security:$})}function PH($){return V2({databases:$})}function xH($){return V2({cache:$})}function CH($){return V2({cdn:$})}function IH($){return V2({queues:$})}function mQ(){let $=process.env.AWS_ACCESS_KEY_ID,J=process.env.AWS_SECRET_ACCESS_KEY;if(!$||!J)return null;return{accessKeyId:$,secretAccessKey:J,sessionToken:process.env.AWS_SESSION_TOKEN}}function cQ($){let J=$?.profile||process.env.AWS_PROFILE||"default",Y=$?.credentialsFile||dQ(uQ(),".aws","credentials");if(!gQ(Y))return null;try{let Q=M6(Y,"utf-8");return kH(Q,J)}catch{return null}}function kH($,J){let Y=$.split(`
254
254
  `),Q=null,Z,U,W;for(let z of Y){let G=z.trim();if(!G||G.startsWith("#")||G.startsWith(";"))continue;let H=G.match(/^\[([^\]]+)\]$/);if(H){if(Q===J&&Z&&U)return{accessKeyId:Z,secretAccessKey:U,sessionToken:W};Q=H[1],Z=void 0,U=void 0,W=void 0;continue}if(Q===J){let[A,...K]=G.split("="),B=K.join("=").trim();switch(A.trim().toLowerCase()){case"aws_access_key_id":Z=B;break;case"aws_secret_access_key":U=B;break;case"aws_session_token":W=B;break}}}if(Q===J&&Z&&U)return{accessKeyId:Z,secretAccessKey:U,sessionToken:W};return null}async function lQ($){let J=$?.timeout??1000,Y="http://169.254.169.254";try{let Q=await H$("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}},J);if(!Q.ok)return null;let Z=await Q.text(),U=await H$("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":Z}},J);if(!U.ok)return null;let W=(await U.text()).trim(),z=await H$(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${W}`,{headers:{"X-aws-ec2-metadata-token":Z}},J);if(!z.ok)return null;let G=await z.json();return{accessKeyId:G.AccessKeyId,secretAccessKey:G.SecretAccessKey,sessionToken:G.Token,expiration:new Date(G.Expiration)}}catch{return null}}async function pQ($){let J=$?.timeout??1000,Y=process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,Q=process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI,Z=null;if(Y)Z=`http://169.254.170.2${Y}`;else if(Q)Z=Q;if(!Z)return null;try{let U={},W=process.env.AWS_CONTAINER_AUTHORIZATION_TOKEN;if(W)U.Authorization=W;let z=await H$(Z,{headers:U},J);if(!z.ok)return null;let G=await z.json();return{accessKeyId:G.AccessKeyId,secretAccessKey:G.SecretAccessKey,sessionToken:G.Token,expiration:new Date(G.Expiration)}}catch{return null}}async function rQ($){let J=$?.timeout??5000,Y=process.env.AWS_WEB_IDENTITY_TOKEN_FILE,Q=process.env.AWS_ROLE_ARN,Z=process.env.AWS_ROLE_SESSION_NAME||"ts-cloud-session";if(!Y||!Q)return null;try{let U=M6(Y,"utf-8").trim(),W=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"us-east-1",z=W.startsWith("us-gov")?`https://sts.${W}.amazonaws.com`:W==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${W}.amazonaws.com`,G=new URLSearchParams({Action:"AssumeRoleWithWebIdentity",Version:"2011-06-15",RoleArn:Q,RoleSessionName:Z,WebIdentityToken:U}),H=await H$(`${z}/?${G.toString()}`,{method:"POST"},J);if(!H.ok)return null;let A=await H.text(),K=W$(A,"AccessKeyId"),B=W$(A,"SecretAccessKey"),j=W$(A,"SessionToken"),X=W$(A,"Expiration");if(!K||!B)return null;return{accessKeyId:K,secretAccessKey:B,sessionToken:j??void 0,expiration:X?new Date(X):void 0}}catch{return null}}async function q$($){let J=mQ();if(J)return J;let Y=cQ($);if(Y)return Y;let Q=await rQ($);if(Q)return Q;let Z=await pQ($);if(Z)return Z;let U=await lQ($);if(U)return U;throw Error("Could not find AWS credentials. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or configure ~/.aws/credentials, or run on an EC2 instance with an IAM role.")}function hH($){let J=null,Y=null;return async()=>{if(J){if(!J.expiration)return J;let Q=300000;if(J.expiration.getTime()-Date.now()>Q)return J}if(Y)return Y;return Y=q$($).then((Q)=>{return J=Q,Y=null,Q}).catch((Q)=>{throw Y=null,Q}),Y}}async function H$($,J,Y){let Q=new AbortController,Z=setTimeout(()=>Q.abort(),Y);try{let U=await fetch($,{...J,signal:Q.signal});return clearTimeout(Z),U}catch(U){throw clearTimeout(Z),U}}function W$($,J){let Y=new RegExp(`<${J}>([^<]+)</${J}>`),Q=$.match(Y);return Q?Q[1]:null}async function C9($){return q$({profile:$})}function nQ($){let J=process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION;if(J)return J;let Y=dQ(uQ(),".aws","config");if(gQ(Y))try{let Q=M6(Y,"utf-8"),Z=$||process.env.AWS_PROFILE||"default",U=Z==="default"?"[default]":`[profile ${Z}]`,W=Q.split(`
255
255
  `),z=!1;for(let G of W){let H=G.trim();if(H.startsWith("[")){z=H===U;continue}if(z&&H.startsWith("region")){let[,A]=H.split("=");if(A)return A.trim()}}}catch{}return"us-east-1"}async function aQ($){let J=$||await q$(),Y=nQ(),{signRequest:Q}=await X$().then(()=>XQ),Z=Y.startsWith("us-gov")?`https://sts.${Y}.amazonaws.com`:Y==="us-east-1"?"https://sts.amazonaws.com":`https://sts.${Y}.amazonaws.com`,U="Action=GetCallerIdentity&Version=2011-06-15",W=Q({method:"POST",url:Z,body:"Action=GetCallerIdentity&Version=2011-06-15",headers:{"Content-Type":"application/x-www-form-urlencoded"},...J,service:"sts",region:Y}),z=await fetch(W.url,{method:W.method,headers:W.headers,body:W.body});if(!z.ok)throw Error(`Failed to get account ID: ${await z.text()}`);let G=await z.text(),H=W$(G,"Account");if(!H)throw Error("Failed to parse account ID from response");return H}class iQ{profile;credentials=null;region;constructor($="us-east-1",J="default"){this.profile=J,this.region=$}async init(){if(this.credentials=await C9(this.profile),this.credentials.region)this.region=this.credentials.region}async ensureCredentials(){if(!this.credentials)await this.init();return this.credentials}async request($,J){let Y=await this.ensureCredentials(),Q={Action:$,Version:"2010-05-15",...K6(J)},Z=new URLSearchParams(Q).toString(),W=await(await _2({method:"POST",url:`https://cloudformation.${this.region}.amazonaws.com/`,service:"cloudformation",region:this.region,headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Z,accessKeyId:Y.accessKeyId,secretAccessKey:Y.secretAccessKey,sessionToken:Y.sessionToken})).text();return bH(W)}async createStack($){let J={StackName:$.stackName};if($.templateBody)J.TemplateBody=$.templateBody;else if($.templateURL)J.TemplateURL=$.templateURL;else throw Error("Either templateBody or templateURL must be provided");if($.parameters)for(let[Z,[U,W]]of Object.entries($.parameters).entries())J[`Parameters.member.${Z+1}.ParameterKey`]=U,J[`Parameters.member.${Z+1}.ParameterValue`]=W;if($.capabilities)for(let[Z,U]of $.capabilities.entries())J[`Capabilities.member.${Z+1}`]=U;if($.tags)for(let[Z,[U,W]]of Object.entries($.tags).entries())J[`Tags.member.${Z+1}.Key`]=U,J[`Tags.member.${Z+1}.Value`]=W;if($.timeoutInMinutes)J.TimeoutInMinutes=$.timeoutInMinutes;if($.onFailure)J.OnFailure=$.onFailure;let Y=await this.request("CreateStack",J);return(Y?.CreateStackResult||Y?.CreateStackResponse?.CreateStackResult||Y)?.StackId}async updateStack($){let J={StackName:$.stackName};if($.templateBody)J.TemplateBody=$.templateBody;else if($.templateURL)J.TemplateURL=$.templateURL;if($.parameters)for(let[Z,[U,W]]of Object.entries($.parameters).entries())J[`Parameters.member.${Z+1}.ParameterKey`]=U,J[`Parameters.member.${Z+1}.ParameterValue`]=W;if($.capabilities)for(let[Z,U]of $.capabilities.entries())J[`Capabilities.member.${Z+1}`]=U;if($.tags)for(let[Z,[U,W]]of Object.entries($.tags).entries())J[`Tags.member.${Z+1}.Key`]=U,J[`Tags.member.${Z+1}.Value`]=W;let Y=await this.request("UpdateStack",J);return(Y?.UpdateStackResult||Y?.UpdateStackResponse?.UpdateStackResult||Y)?.StackId}async deleteStack($){await this.request("DeleteStack",{StackName:$})}async describeStack($){let J=await this.request("DescribeStacks",{StackName:$}),Q=(J?.DescribeStacksResult||J?.DescribeStacksResponse?.DescribeStacksResult||J)?.Stacks?.member,Z=Array.isArray(Q)?Q[0]:Q;if(!Z)throw Error(`Stack ${$} not found`);return yH(Z)}async listStacks($){let J={};if($)for(let[Q,Z]of $.entries())J[`StackStatusFilter.member.${Q+1}`]=Z;let Y=await this.request("ListStacks",J);return vH(Y)}async describeStackEvents($){let J=await this.request("DescribeStackEvents",{StackName:$});return fH(J)}async waitForStack($,J,Y){let U=0,W=null;while(U<360){U++;let z=await this.describeStack($);if(Y)try{let G=await this.describeStackEvents($),H=[];if(W){for(let A of G){if(A.EventId===W)break;H.push(A)}H.reverse()}else if(G.length>0)H=[G[0]];for(let A of H)Y(A);if(G.length>0)W=G[0].EventId}catch{}if(z.StackStatus&&J.includes(z.StackStatus))return z;if(z.StackStatus?.includes("FAILED")||z.StackStatus?.includes("ROLLBACK"))throw Error(`Stack reached failed state: ${z.StackStatus}
256
- Reason: ${z.StackStatusReason||"Unknown"}`);await new Promise((G)=>setTimeout(G,5000))}throw Error(`Timeout waiting for stack ${$} to complete`)}async waitForStackWithProgress($,J,Y){let Z={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]}[J];if(!Z)throw Error(`Unknown waiter: ${J}`);return this.waitForStack($,Z,Y)}async createChangeSet($){let J={StackName:$.stackName,ChangeSetName:$.changeSetName,ChangeSetType:"UPDATE"};if($.templateBody)J.TemplateBody=$.templateBody;else if($.templateURL)J.TemplateURL=$.templateURL;if($.parameters)for(let[Q,[Z,U]]of Object.entries($.parameters).entries())J[`Parameters.member.${Q+1}.ParameterKey`]=Z,J[`Parameters.member.${Q+1}.ParameterValue`]=U;if($.capabilities)for(let[Q,Z]of $.capabilities.entries())J[`Capabilities.member.${Q+1}`]=Z;return(await this.request("CreateChangeSet",J)).ChangeSetId}async executeChangeSet($,J){await this.request("ExecuteChangeSet",{ChangeSetName:$,StackName:J})}async describeStacks($){let J=typeof $==="string"?$:$.stackName;try{return{Stacks:[await this.describeStack(J)]}}catch{return{Stacks:[]}}}async getStackOutputs($){let J=await this.request("DescribeStacks",{StackName:$}),Q=(J?.DescribeStacksResult||J?.DescribeStacksResponse?.DescribeStacksResult||J)?.Stacks?.member,Z=Array.isArray(Q)?Q[0]:Q;if(!Z)return{};let U={},W=Z.Outputs?.member;if(W){let z=Array.isArray(W)?W:[W];for(let G of z)if(G.OutputKey&&G.OutputValue)U[G.OutputKey]=G.OutputValue}return U}}function K6($,J=""){let Y={};for(let[Q,Z]of Object.entries($)){let U=J?`${J}.${Q}`:Q;if(Array.isArray(Z))Z.forEach((W,z)=>{if(typeof W==="object")Object.assign(Y,K6(W,`${U}.${z+1}`));else Y[`${U}.${z+1}`]=String(W)});else if(typeof Z==="object"&&Z!==null)Object.assign(Y,K6(Z,U));else if(Z!==void 0&&Z!==null)Y[U]=String(Z)}return Y}function bH($){$=$.replace(/<\?xml[^?]*\?>\s*/,"").trim();function J(Z,U,W){let z=1,G=W,H=`<${U}`,A=`</${U}>`;while(G<Z.length&&z>0){let K=Z.indexOf(H,G),B=Z.indexOf(A,G);if(B===-1)return-1;if(K!==-1&&K<B){let j=Z[K+H.length];if(j===">"||j===" "||j==="/"){let X=Z.indexOf(">",K);if(X!==-1&&Z[X-1]==="/")G=X+1;else z++,G=X+1}else G=K+H.length}else{if(z--,z===0)return B;G=B+A.length}}return-1}function Y(Z,U){while(U<Z.length&&/\s/.test(Z[U]))U++;if(U>=Z.length||Z[U]!=="<"){let O=Z.indexOf("<",U);if(O===-1)return{value:Z.slice(U).trim(),end:Z.length};return{value:Z.slice(U,O).trim(),end:O}}if(Z[U+1]==="/")return{value:void 0,end:U};let W=Z.slice(U).match(/^<(\w+)([^>]*?)\/?>/);if(!W)return{value:void 0,end:U+1};let z=W[1];if(W[0].endsWith("/>"))return{value:"",end:U+W[0].length};let H=U+W[0].length,A=`</${z}>`,K=J(Z,z,H);if(K===-1)return{value:void 0,end:U+W[0].length};let B=Z.slice(H,K).trim();if(!B.includes("<"))return{value:B,end:K+A.length};let j={},X=H;while(X<K){while(X<K&&/\s/.test(Z[X]))X++;if(X>=K)break;if(Z[X]!=="<"||Z[X+1]==="/")break;let O=Z.slice(X).match(/^<(\w+)/);if(!O)break;let _=O[1],w=Y(Z,X);if(w.value===void 0){X++;continue}if(_==="member"||j[_]!==void 0){if(!Array.isArray(j[_]))j[_]=j[_]!==void 0?[j[_]]:[];j[_].push(w.value)}else j[_]=w.value;X=w.end}return{value:j,end:K+A.length}}return Y($,0).value||{}}function yH($){return{StackName:$.StackName||"",StackId:$.StackId,StackStatus:$.StackStatus,CreationTime:$.CreationTime,LastUpdatedTime:$.LastUpdatedTime,StackStatusReason:$.StackStatusReason,Description:$.Description}}function vH($){let Y=($?.ListStacksResult||$?.ListStacksResponse?.ListStacksResult||$)?.StackSummaries?.member;if(!Y)return[];return(Array.isArray(Y)?Y:[Y]).map((Z)=>({StackName:Z.StackName||"",StackId:Z.StackId,StackStatus:Z.StackStatus,CreationTime:Z.CreationTime,LastUpdatedTime:Z.LastUpdatedTime,StackStatusReason:Z.StackStatusReason,Description:Z.Description}))}function fH($){let Y=($?.DescribeStackEventsResult||$?.DescribeStackEventsResponse?.DescribeStackEventsResult||$)?.StackEvents?.member;if(!Y)return[];return(Array.isArray(Y)?Y:[Y]).map((Z)=>({StackId:Z.StackId||"",EventId:Z.EventId||"",StackName:Z.StackName||"",LogicalResourceId:Z.LogicalResourceId||"",PhysicalResourceId:Z.PhysicalResourceId,ResourceType:Z.ResourceType||"",Timestamp:Z.Timestamp||"",ResourceStatus:Z.ResourceStatus||"",ResourceStatusReason:Z.ResourceStatusReason}))}class T6{region;endpoint;forcePathStyle;credentials;credentialOptions;retryOptions;constructor($={}){this.region=$.region||process.env.AWS_REGION||"us-east-1",this.endpoint=$.endpoint||`https://s3.${this.region}.amazonaws.com`,this.forcePathStyle=$.forcePathStyle||!1,this.credentials=$.credentials,this.credentialOptions=$.credentialOptions,this.retryOptions=$.retryOptions||{}}async getCredentials(){if(this.credentials)return this.credentials;return q$(this.credentialOptions)}buildUrl($,J){let Y=J?encodeURIComponent(J).replace(/%2F/g,"/"):"";if(this.forcePathStyle)return J?`${this.endpoint}/${$}/${Y}`:`${this.endpoint}/${$}`;let Q=new URL(this.endpoint);return Q.hostname=`${$}.${Q.hostname}`,J?`${Q.origin}/${Y}`:Q.origin}async get($,J,Y={}){let Q=await this.getCredentials(),Z=this.buildUrl($,J),U={};if(Y.range)U.Range=Y.range;if(Y.ifModifiedSince)U["If-Modified-Since"]=Y.ifModifiedSince.toUTCString();if(Y.ifMatch)U["If-Match"]=Y.ifMatch;if(Y.ifNoneMatch)U["If-None-Match"]=Y.ifNoneMatch;let W=new URL(Z);if(Y.responseContentType)W.searchParams.set("response-content-type",Y.responseContentType);if(Y.responseContentDisposition)W.searchParams.set("response-content-disposition",Y.responseContentDisposition);let z=v0({method:"GET",url:W.toString(),headers:U,...Q,service:"s3",region:this.region}),G=await fetch(z.url,{method:z.method,headers:z.headers});if(!G.ok&&G.status!==304){let H=await G.text();throw new J1(`Failed to get object: ${H}`,G.status,$,J)}return G}async getText($,J,Y={}){return(await this.get($,J,Y)).text()}async getJSON($,J,Y={}){return(await this.get($,J,Y)).json()}async getBuffer($,J,Y={}){return(await this.get($,J,Y)).arrayBuffer()}async put($,J,Y,Q={}){let Z,U;if(typeof Y==="string")Z=new TextEncoder().encode(Y).length,U=Y;else if(Y instanceof ArrayBuffer)Z=Y.byteLength,U=Y;else if(Y instanceof Uint8Array)Z=Y.byteLength,U=Y;else if(Y instanceof Blob)Z=Y.size,U=Y;else return this.uploadMultipart($,J,Y,{...Q,partSize:W6});if(Z>uH){let W=cH(U).stream();return this.uploadMultipart($,J,W,{...Q,partSize:W6})}return this.putSimple($,J,U,Z,Q)}async putSimple($,J,Y,Q,Z){let U=await this.getCredentials(),W=this.buildUrl($,J),z={"Content-Length":String(Q),"Content-Type":Z.contentType||FQ(J)};if(Z.contentEncoding)z["Content-Encoding"]=Z.contentEncoding;if(Z.cacheControl)z["Cache-Control"]=Z.cacheControl;if(Z.contentDisposition)z["Content-Disposition"]=Z.contentDisposition;if(Z.storageClass)z["x-amz-storage-class"]=Z.storageClass;if(Z.serverSideEncryption)z["x-amz-server-side-encryption"]=Z.serverSideEncryption;if(Z.acl)z["x-amz-acl"]=Z.acl;if(Z.tagging)z["x-amz-tagging"]=Z.tagging;if(Z.metadata)for(let[B,j]of Object.entries(Z.metadata))z[`x-amz-meta-${B.toLowerCase()}`]=j;let G;if(typeof Y==="string")G=Y;else if(Y instanceof Blob)G=await Y.text();else G=new TextDecoder().decode(Y instanceof ArrayBuffer?new Uint8Array(Y):Y);let H=v0({method:"PUT",url:W,headers:z,body:G,...U,service:"s3",region:this.region}),A=await fetch(H.url,{method:H.method,headers:H.headers,body:Y});if(!A.ok){let B=await A.text();throw new J1(`Failed to put object: ${B}`,A.status,$,J)}return{etag:(A.headers.get("ETag")||"").replace(/"/g,"")}}async delete($,J){let Y=await this.getCredentials(),Q=this.buildUrl($,J),Z=v0({method:"DELETE",url:Q,...Y,service:"s3",region:this.region}),U=await fetch(Z.url,{method:Z.method,headers:Z.headers});if(!U.ok&&U.status!==204){let W=await U.text();throw new J1(`Failed to delete object: ${W}`,U.status,$,J)}}async deleteMany($,J){let Y=await this.getCredentials(),Q=`${this.buildUrl($)}?delete`,U=`<?xml version="1.0" encoding="UTF-8"?><Delete><Quiet>false</Quiet>${J.map((X)=>`<Object><Key>${mH(X)}</Key></Object>`).join("")}</Delete>`,W=v0({method:"POST",url:Q,headers:{"Content-Type":"application/xml"},body:U,...Y,service:"s3",region:this.region}),z=await fetch(W.url,{method:W.method,headers:W.headers,body:U});if(!z.ok){let X=await z.text();throw new J1(`Failed to delete objects: ${X}`,z.status,$)}let G=await z.text(),H=[],A=[],K=/<Deleted><Key>([^<]+)<\/Key>/g,B;while((B=K.exec(G))!==null)H.push(B[1]);let j=/<Error><Key>([^<]+)<\/Key><Code>([^<]+)<\/Code><Message>([^<]+)<\/Message>/g;while((B=j.exec(G))!==null)A.push({key:B[1],error:`${B[2]}: ${B[3]}`});return{deleted:H,errors:A}}async list($,J={}){let Y=await this.getCredentials(),Q=new URL(this.buildUrl($));if(Q.searchParams.set("list-type","2"),J.prefix)Q.searchParams.set("prefix",J.prefix);if(J.delimiter)Q.searchParams.set("delimiter",J.delimiter);if(J.maxKeys)Q.searchParams.set("max-keys",String(J.maxKeys));if(J.continuationToken)Q.searchParams.set("continuation-token",J.continuationToken);if(J.startAfter)Q.searchParams.set("start-after",J.startAfter);let Z=v0({method:"GET",url:Q.toString(),...Y,service:"s3",region:this.region}),U=await fetch(Z.url,{method:Z.method,headers:Z.headers});if(!U.ok){let z=await U.text();throw new J1(`Failed to list objects: ${z}`,U.status,$)}let W=await U.text();return dH(W)}async*listAll($,J={}){let Y;do{let Q=await this.list($,{...J,continuationToken:Y});for(let Z of Q.contents)yield Z;Y=Q.nextContinuationToken}while(Y)}async head($,J){let Y=await this.getCredentials(),Q=this.buildUrl($,J),Z=v0({method:"HEAD",url:Q,...Y,service:"s3",region:this.region}),U=await fetch(Z.url,{method:Z.method,headers:Z.headers});if(U.status===404)return null;if(!U.ok){let z=await U.text();throw new J1(`Failed to head object: ${z}`,U.status,$,J)}let W={};return U.headers.forEach((z,G)=>{if(G.toLowerCase().startsWith("x-amz-meta-"))W[G.slice(11)]=z}),{contentLength:Number(U.headers.get("Content-Length")||0),contentType:U.headers.get("Content-Type")||"application/octet-stream",etag:(U.headers.get("ETag")||"").replace(/"/g,""),lastModified:new Date(U.headers.get("Last-Modified")||0),metadata:W,storageClass:U.headers.get("x-amz-storage-class")||void 0,serverSideEncryption:U.headers.get("x-amz-server-side-encryption")||void 0}}async exists($,J){return await this.head($,J)!==null}async copy($,J,Y,Q,Z={}){let U=await this.getCredentials(),W=this.buildUrl(Y,Q),z={"x-amz-copy-source":`/${$}/${encodeURIComponent(J)}`};if(Z.metadataDirective)z["x-amz-metadata-directive"]=Z.metadataDirective;if(Z.contentType)z["Content-Type"]=Z.contentType;if(Z.storageClass)z["x-amz-storage-class"]=Z.storageClass;if(Z.acl)z["x-amz-acl"]=Z.acl;if(Z.metadata)for(let[j,X]of Object.entries(Z.metadata))z[`x-amz-meta-${j.toLowerCase()}`]=X;let G=v0({method:"PUT",url:W,headers:z,...U,service:"s3",region:this.region}),H=await fetch(G.url,{method:G.method,headers:G.headers});if(!H.ok){let j=await H.text();throw new J1(`Failed to copy object: ${j}`,H.status,Y,Q)}let K=(await H.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:K?K[1]:""}}async getPresignedUrl($,J,Y={}){let Q=await this.getCredentials(),Z=this.buildUrl($,J);return j6({url:Z,method:Y.method||"GET",expiresIn:Y.expiresIn||3600,...Q,service:"s3",region:this.region})}async uploadMultipart($,J,Y,Q={}){let Z=await this.getCredentials(),U=Math.max(Q.partSize||W6,gH),W,z;if(Y instanceof ReadableStream)W=Y;else if(Y instanceof Blob)W=Y.stream(),z=Y.size;else{let H=new Blob([Y]);W=H.stream(),z=H.size}let G=await this.initiateMultipartUpload($,J,Q);try{let H=await this.uploadParts($,J,G,W,U,Z,z,Q.concurrency||4,Q.onProgress);return await this.completeMultipartUpload($,J,G,H)}catch(H){throw await this.abortMultipartUpload($,J,G).catch(()=>{}),H}}async initiateMultipartUpload($,J,Y){let Q=await this.getCredentials(),Z=`${this.buildUrl($,J)}?uploads`,U={"Content-Type":Y.contentType||FQ(J)};if(Y.storageClass)U["x-amz-storage-class"]=Y.storageClass;if(Y.serverSideEncryption)U["x-amz-server-side-encryption"]=Y.serverSideEncryption;if(Y.acl)U["x-amz-acl"]=Y.acl;if(Y.metadata)for(let[A,K]of Object.entries(Y.metadata))U[`x-amz-meta-${A.toLowerCase()}`]=K;let W=v0({method:"POST",url:Z,headers:U,...Q,service:"s3",region:this.region}),z=await fetch(W.url,{method:W.method,headers:W.headers});if(!z.ok){let A=await z.text();throw new J1(`Failed to initiate multipart upload: ${A}`,z.status,$,J)}let H=(await z.text()).match(/<UploadId>([^<]+)<\/UploadId>/);if(!H)throw new J1("Failed to parse upload ID from response",0,$,J);return H[1]}async uploadParts($,J,Y,Q,Z,U,W,z,G){let H=[],A=Q.getReader(),K=1,B=new Uint8Array(0),j=0,X=W?Math.ceil(W/Z):void 0,O=[],_=async(E,M)=>{let T=`${this.buildUrl($,J)}?partNumber=${M}&uploadId=${encodeURIComponent(Y)}`,D={"Content-Length":String(E.byteLength),"x-amz-content-sha256":"UNSIGNED-PAYLOAD"},N=v0({method:"PUT",url:T,headers:D,...U,service:"s3",region:this.region}),x=await fetch(N.url,{method:N.method,headers:N.headers,body:E});if(!x.ok){let k=await x.text();throw new J1(`Failed to upload part ${M}: ${k}`,x.status,$,J)}let h=(x.headers.get("ETag")||"").replace(/"/g,"");return{partNumber:M,etag:h}};while(!0){let{done:E,value:M}=await A.read();if(M){let T=new Uint8Array(B.length+M.length);T.set(B),T.set(M,B.length),B=T}while(B.length>=Z||E&&B.length>0){let T=B.slice(0,Z);B=B.slice(Z);let D=K++;if(O.length>=z){let x=await Promise.race(O);H.push(x),O.splice(O.indexOf(Promise.resolve(x)),1)}let N=_(T,D);if(O.push(N),j+=T.byteLength,G)G({loaded:j,total:W||j,part:D,totalParts:X||D})}if(E)break}let w=await Promise.all(O);return H.push(...w),H.sort((E,M)=>E.partNumber-M.partNumber),H}async completeMultipartUpload($,J,Y,Q){let Z=await this.getCredentials(),U=`${this.buildUrl($,J)}?uploadId=${encodeURIComponent(Y)}`,z=`<?xml version="1.0" encoding="UTF-8"?><CompleteMultipartUpload>${Q.map((j)=>`<Part><PartNumber>${j.partNumber}</PartNumber><ETag>"${j.etag}"</ETag></Part>`).join("")}</CompleteMultipartUpload>`,G=v0({method:"POST",url:U,headers:{"Content-Type":"application/xml"},body:z,...Z,service:"s3",region:this.region}),H=await fetch(G.url,{method:G.method,headers:G.headers,body:z});if(!H.ok){let j=await H.text();throw new J1(`Failed to complete multipart upload: ${j}`,H.status,$,J)}let K=(await H.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:K?K[1]:""}}async abortMultipartUpload($,J,Y){let Q=await this.getCredentials(),Z=`${this.buildUrl($,J)}?uploadId=${encodeURIComponent(Y)}`,U=v0({method:"DELETE",url:Z,...Q,service:"s3",region:this.region});await fetch(U.url,{method:U.method,headers:U.headers})}async emptyAndDeleteBucket($){let Y=[];for await(let W of this.listAll($,{}))if(Y.push(W.key),Y.length>=1000)await this.deleteMany($,Y),Y=[];if(Y.length>0)await this.deleteMany($,Y);let Q=await this.getCredentials(),Z=this.buildUrl($),U=v0({method:"DELETE",url:Z,...Q,service:"s3",region:this.region});await fetch(U.url,{method:U.method,headers:U.headers})}}function dH($){let J=[],Y=[],Q=/<Contents>([\s\S]*?)<\/Contents>/g,Z;while((Z=Q.exec($))!==null){let W=Z[1];J.push({key:F1(W,"Key")||"",lastModified:new Date(F1(W,"LastModified")||0),etag:(F1(W,"ETag")||"").replace(/"/g,""),size:Number(F1(W,"Size")||0),storageClass:F1(W,"StorageClass")||"STANDARD"})}let U=/<CommonPrefixes><Prefix>([^<]+)<\/Prefix><\/CommonPrefixes>/g;while((Z=U.exec($))!==null)Y.push(Z[1]);return{contents:J,commonPrefixes:Y,isTruncated:F1($,"IsTruncated")==="true",continuationToken:F1($,"ContinuationToken")||void 0,nextContinuationToken:F1($,"NextContinuationToken")||void 0,keyCount:Number(F1($,"KeyCount")||0),maxKeys:Number(F1($,"MaxKeys")||1000),prefix:F1($,"Prefix")||void 0,delimiter:F1($,"Delimiter")||void 0}}function F1($,J){let Y=new RegExp(`<${J}>([^<]*)</${J}>`),Q=$.match(Y);return Q?Q[1]:null}function mH($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function FQ($){let J=$.split(".").pop()?.toLowerCase();return{html:"text/html",htm:"text/html",css:"text/css",js:"application/javascript",mjs:"application/javascript",json:"application/json",xml:"application/xml",txt:"text/plain",md:"text/markdown",csv:"text/csv",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mp3:"audio/mpeg",wav:"audio/wav",ogg:"audio/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",zip:"application/zip",gz:"application/gzip",tar:"application/x-tar",rar:"application/vnd.rar","7z":"application/x-7z-compressed",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject",wasm:"application/wasm"}[J||""]||"application/octet-stream"}function cH($){if($ instanceof Blob)return $;if(typeof $==="string")return new Blob([$],{type:"text/plain"});return new Blob([$])}function lH($){return new T6($)}class tQ{profile;credentials=null;constructor($="default"){this.profile=$}async init(){this.credentials=await C9(this.profile)}async ensureCredentials(){if(!this.credentials)await this.init();return this.credentials}async createInvalidation($){let J=await this.ensureCredentials(),Y=$.callerReference||`invalidation-${Date.now()}`,Q=`<?xml version="1.0" encoding="UTF-8"?>
256
+ Reason: ${z.StackStatusReason||"Unknown"}`);await new Promise((G)=>setTimeout(G,5000))}throw Error(`Timeout waiting for stack ${$} to complete`)}async waitForStackWithProgress($,J,Y){let Z={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]}[J];if(!Z)throw Error(`Unknown waiter: ${J}`);return this.waitForStack($,Z,Y)}async createChangeSet($){let J={StackName:$.stackName,ChangeSetName:$.changeSetName,ChangeSetType:"UPDATE"};if($.templateBody)J.TemplateBody=$.templateBody;else if($.templateURL)J.TemplateURL=$.templateURL;if($.parameters)for(let[Q,[Z,U]]of Object.entries($.parameters).entries())J[`Parameters.member.${Q+1}.ParameterKey`]=Z,J[`Parameters.member.${Q+1}.ParameterValue`]=U;if($.capabilities)for(let[Q,Z]of $.capabilities.entries())J[`Capabilities.member.${Q+1}`]=Z;return(await this.request("CreateChangeSet",J)).ChangeSetId}async executeChangeSet($,J){await this.request("ExecuteChangeSet",{ChangeSetName:$,StackName:J})}async describeStacks($){let J=typeof $==="string"?$:$.stackName;try{return{Stacks:[await this.describeStack(J)]}}catch{return{Stacks:[]}}}async getStackOutputs($){let J=await this.request("DescribeStacks",{StackName:$}),Q=(J?.DescribeStacksResult||J?.DescribeStacksResponse?.DescribeStacksResult||J)?.Stacks?.member,Z=Array.isArray(Q)?Q[0]:Q;if(!Z)return{};let U={},W=Z.Outputs?.member;if(W){let z=Array.isArray(W)?W:[W];for(let G of z)if(G.OutputKey&&G.OutputValue)U[G.OutputKey]=G.OutputValue}return U}}function K6($,J=""){let Y={};for(let[Q,Z]of Object.entries($)){let U=J?`${J}.${Q}`:Q;if(Array.isArray(Z))Z.forEach((W,z)=>{if(typeof W==="object")Object.assign(Y,K6(W,`${U}.${z+1}`));else Y[`${U}.${z+1}`]=String(W)});else if(typeof Z==="object"&&Z!==null)Object.assign(Y,K6(Z,U));else if(Z!==void 0&&Z!==null)Y[U]=String(Z)}return Y}function bH($){$=$.replace(/<\?xml[^?]*\?>\s*/,"").trim();function J(Z,U,W){let z=1,G=W,H=`<${U}`,A=`</${U}>`;while(G<Z.length&&z>0){let K=Z.indexOf(H,G),B=Z.indexOf(A,G);if(B===-1)return-1;if(K!==-1&&K<B){let j=Z[K+H.length];if(j===">"||j===" "||j==="/"){let X=Z.indexOf(">",K);if(X!==-1&&Z[X-1]==="/")G=X+1;else z++,G=X+1}else G=K+H.length}else{if(z--,z===0)return B;G=B+A.length}}return-1}function Y(Z,U){while(U<Z.length&&/\s/.test(Z[U]))U++;if(U>=Z.length||Z[U]!=="<"){let O=Z.indexOf("<",U);if(O===-1)return{value:Z.slice(U).trim(),end:Z.length};return{value:Z.slice(U,O).trim(),end:O}}if(Z[U+1]==="/")return{value:void 0,end:U};let W=Z.slice(U).match(/^<(\w+)([^>]*?)\/?>/);if(!W)return{value:void 0,end:U+1};let z=W[1];if(W[0].endsWith("/>"))return{value:"",end:U+W[0].length};let H=U+W[0].length,A=`</${z}>`,K=J(Z,z,H);if(K===-1)return{value:void 0,end:U+W[0].length};let B=Z.slice(H,K).trim();if(!B.includes("<"))return{value:B,end:K+A.length};let j={},X=H;while(X<K){while(X<K&&/\s/.test(Z[X]))X++;if(X>=K)break;if(Z[X]!=="<"||Z[X+1]==="/")break;let O=Z.slice(X).match(/^<(\w+)/);if(!O)break;let _=O[1],w=Y(Z,X);if(w.value===void 0){X++;continue}if(_==="member"||j[_]!==void 0){if(!Array.isArray(j[_]))j[_]=j[_]!==void 0?[j[_]]:[];j[_].push(w.value)}else j[_]=w.value;X=w.end}return{value:j,end:K+A.length}}return Y($,0).value||{}}function yH($){return{StackName:$.StackName||"",StackId:$.StackId,StackStatus:$.StackStatus,CreationTime:$.CreationTime,LastUpdatedTime:$.LastUpdatedTime,StackStatusReason:$.StackStatusReason,Description:$.Description}}function vH($){let Y=($?.ListStacksResult||$?.ListStacksResponse?.ListStacksResult||$)?.StackSummaries?.member;if(!Y)return[];return(Array.isArray(Y)?Y:[Y]).map((Z)=>({StackName:Z.StackName||"",StackId:Z.StackId,StackStatus:Z.StackStatus,CreationTime:Z.CreationTime,LastUpdatedTime:Z.LastUpdatedTime,StackStatusReason:Z.StackStatusReason,Description:Z.Description}))}function fH($){let Y=($?.DescribeStackEventsResult||$?.DescribeStackEventsResponse?.DescribeStackEventsResult||$)?.StackEvents?.member;if(!Y)return[];return(Array.isArray(Y)?Y:[Y]).map((Z)=>({StackId:Z.StackId||"",EventId:Z.EventId||"",StackName:Z.StackName||"",LogicalResourceId:Z.LogicalResourceId||"",PhysicalResourceId:Z.PhysicalResourceId,ResourceType:Z.ResourceType||"",Timestamp:Z.Timestamp||"",ResourceStatus:Z.ResourceStatus||"",ResourceStatusReason:Z.ResourceStatusReason}))}class T6{region;endpoint;forcePathStyle;credentials;credentialOptions;retryOptions;constructor($={}){this.region=$.region||process.env.AWS_REGION||"us-east-1",this.endpoint=$.endpoint||`https://s3.${this.region}.amazonaws.com`,this.forcePathStyle=$.forcePathStyle||!1,this.credentials=$.credentials,this.credentialOptions=$.credentialOptions,this.retryOptions=$.retryOptions||{}}async getCredentials(){if(this.credentials)return this.credentials;return q$(this.credentialOptions)}buildUrl($,J){let Y=J?encodeURIComponent(J).replace(/%2F/g,"/"):"";if(this.forcePathStyle)return J?`${this.endpoint}/${$}/${Y}`:`${this.endpoint}/${$}`;let Q=new URL(this.endpoint);return Q.hostname=`${$}.${Q.hostname}`,J?`${Q.origin}/${Y}`:Q.origin}async get($,J,Y={}){let Q=await this.getCredentials(),Z=this.buildUrl($,J),U={};if(Y.range)U.Range=Y.range;if(Y.ifModifiedSince)U["If-Modified-Since"]=Y.ifModifiedSince.toUTCString();if(Y.ifMatch)U["If-Match"]=Y.ifMatch;if(Y.ifNoneMatch)U["If-None-Match"]=Y.ifNoneMatch;let W=new URL(Z);if(Y.responseContentType)W.searchParams.set("response-content-type",Y.responseContentType);if(Y.responseContentDisposition)W.searchParams.set("response-content-disposition",Y.responseContentDisposition);let z=v0({method:"GET",url:W.toString(),headers:U,...Q,service:"s3",region:this.region}),G=await fetch(z.url,{method:z.method,headers:z.headers});if(!G.ok&&G.status!==304){let H=await G.text();throw new J1(`Failed to get object: ${H}`,G.status,$,J)}return G}async getText($,J,Y={}){return(await this.get($,J,Y)).text()}async getJSON($,J,Y={}){return(await this.get($,J,Y)).json()}async getBuffer($,J,Y={}){return(await this.get($,J,Y)).arrayBuffer()}async put($,J,Y,Q={}){let Z,U;if(typeof Y==="string")Z=new TextEncoder().encode(Y).length,U=Y;else if(Y instanceof ArrayBuffer)Z=Y.byteLength,U=Y;else if(Y instanceof Uint8Array)Z=Y.byteLength,U=Y;else if(Y instanceof Blob)Z=Y.size,U=Y;else return this.uploadMultipart($,J,Y,{...Q,partSize:W6});if(Z>uH){let W=cH(U).stream();return this.uploadMultipart($,J,W,{...Q,partSize:W6})}return this.putSimple($,J,U,Z,Q)}async putSimple($,J,Y,Q,Z){let U=await this.getCredentials(),W=this.buildUrl($,J),z={"Content-Length":String(Q),"Content-Type":Z.contentType||FQ(J)};if(Z.contentEncoding)z["Content-Encoding"]=Z.contentEncoding;if(Z.cacheControl)z["Cache-Control"]=Z.cacheControl;if(Z.contentDisposition)z["Content-Disposition"]=Z.contentDisposition;if(Z.storageClass)z["x-amz-storage-class"]=Z.storageClass;if(Z.serverSideEncryption)z["x-amz-server-side-encryption"]=Z.serverSideEncryption;if(Z.acl)z["x-amz-acl"]=Z.acl;if(Z.tagging)z["x-amz-tagging"]=Z.tagging;if(Z.metadata)for(let[B,j]of Object.entries(Z.metadata))z[`x-amz-meta-${B.toLowerCase()}`]=j;let G;if(typeof Y==="string")G=Y;else if(Y instanceof Blob)G=await Y.text();else G=new TextDecoder().decode(Y instanceof ArrayBuffer?new Uint8Array(Y):Y);let H=v0({method:"PUT",url:W,headers:z,body:G,...U,service:"s3",region:this.region}),A=await fetch(H.url,{method:H.method,headers:H.headers,body:Y});if(!A.ok){let B=await A.text();throw new J1(`Failed to put object: ${B}`,A.status,$,J)}return{etag:(A.headers.get("ETag")||"").replace(/"/g,"")}}async delete($,J){let Y=await this.getCredentials(),Q=this.buildUrl($,J),Z=v0({method:"DELETE",url:Q,...Y,service:"s3",region:this.region}),U=await fetch(Z.url,{method:Z.method,headers:Z.headers});if(!U.ok&&U.status!==204){let W=await U.text();throw new J1(`Failed to delete object: ${W}`,U.status,$,J)}}async deleteMany($,J){let Y=await this.getCredentials(),Q=`${this.buildUrl($)}?delete`,U=`<?xml version="1.0" encoding="UTF-8"?><Delete><Quiet>false</Quiet>${J.map((X)=>`<Object><Key>${mH(X)}</Key></Object>`).join("")}</Delete>`,W=v0({method:"POST",url:Q,headers:{"Content-Type":"application/xml"},body:U,...Y,service:"s3",region:this.region}),z=await fetch(W.url,{method:W.method,headers:W.headers,body:U});if(!z.ok){let X=await z.text();throw new J1(`Failed to delete objects: ${X}`,z.status,$)}let G=await z.text(),H=[],A=[],K=/<Deleted><Key>([^<]+)<\/Key>/g,B;while((B=K.exec(G))!==null)H.push(B[1]);let j=/<Error><Key>([^<]+)<\/Key><Code>([^<]+)<\/Code><Message>([^<]+)<\/Message>/g;while((B=j.exec(G))!==null)A.push({key:B[1],error:`${B[2]}: ${B[3]}`});return{deleted:H,errors:A}}async list($,J={}){let Y=await this.getCredentials(),Q=new URL(this.buildUrl($));if(Q.searchParams.set("list-type","2"),J.prefix)Q.searchParams.set("prefix",J.prefix);if(J.delimiter)Q.searchParams.set("delimiter",J.delimiter);if(J.maxKeys)Q.searchParams.set("max-keys",String(J.maxKeys));if(J.continuationToken)Q.searchParams.set("continuation-token",J.continuationToken);if(J.startAfter)Q.searchParams.set("start-after",J.startAfter);let Z=v0({method:"GET",url:Q.toString(),...Y,service:"s3",region:this.region}),U=await fetch(Z.url,{method:Z.method,headers:Z.headers});if(!U.ok){let z=await U.text();throw new J1(`Failed to list objects: ${z}`,U.status,$)}let W=await U.text();return dH(W)}async*listAll($,J={}){let Y;do{let Q=await this.list($,{...J,continuationToken:Y});for(let Z of Q.contents)yield Z;Y=Q.nextContinuationToken}while(Y)}async head($,J){let Y=await this.getCredentials(),Q=this.buildUrl($,J),Z=v0({method:"HEAD",url:Q,...Y,service:"s3",region:this.region}),U=await fetch(Z.url,{method:Z.method,headers:Z.headers});if(U.status===404)return null;if(!U.ok){let z=await U.text();throw new J1(`Failed to head object: ${z}`,U.status,$,J)}let W={};return U.headers.forEach((z,G)=>{if(G.toLowerCase().startsWith("x-amz-meta-"))W[G.slice(11)]=z}),{contentLength:Number(U.headers.get("Content-Length")||0),contentType:U.headers.get("Content-Type")||"application/octet-stream",etag:(U.headers.get("ETag")||"").replace(/"/g,""),lastModified:new Date(U.headers.get("Last-Modified")||0),metadata:W,storageClass:U.headers.get("x-amz-storage-class")||void 0,serverSideEncryption:U.headers.get("x-amz-server-side-encryption")||void 0}}async exists($,J){return await this.head($,J)!==null}async copy($,J,Y,Q,Z={}){let U=await this.getCredentials(),W=this.buildUrl(Y,Q),z={"x-amz-copy-source":`/${$}/${encodeURIComponent(J)}`};if(Z.metadataDirective)z["x-amz-metadata-directive"]=Z.metadataDirective;if(Z.contentType)z["Content-Type"]=Z.contentType;if(Z.storageClass)z["x-amz-storage-class"]=Z.storageClass;if(Z.acl)z["x-amz-acl"]=Z.acl;if(Z.metadata)for(let[j,X]of Object.entries(Z.metadata))z[`x-amz-meta-${j.toLowerCase()}`]=X;let G=v0({method:"PUT",url:W,headers:z,...U,service:"s3",region:this.region}),H=await fetch(G.url,{method:G.method,headers:G.headers});if(!H.ok){let j=await H.text();throw new J1(`Failed to copy object: ${j}`,H.status,Y,Q)}let K=(await H.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:K?K[1]:""}}async getPresignedUrl($,J,Y={}){let Q=await this.getCredentials(),Z=this.buildUrl($,J);return j6({url:Z,method:Y.method||"GET",expiresIn:Y.expiresIn||3600,...Q,service:"s3",region:this.region})}async uploadMultipart($,J,Y,Q={}){let Z=await this.getCredentials(),U=Math.max(Q.partSize||W6,gH),W,z;if(Y instanceof ReadableStream)W=Y;else if(Y instanceof Blob)W=Y.stream(),z=Y.size;else{let H=new Blob([Y]);W=H.stream(),z=H.size}let G=await this.initiateMultipartUpload($,J,Q);try{let H=await this.uploadParts($,J,G,W,U,Z,z,Q.concurrency||4,Q.onProgress);return await this.completeMultipartUpload($,J,G,H)}catch(H){throw await this.abortMultipartUpload($,J,G).catch(()=>{}),H}}async initiateMultipartUpload($,J,Y){let Q=await this.getCredentials(),Z=`${this.buildUrl($,J)}?uploads`,U={"Content-Type":Y.contentType||FQ(J)};if(Y.storageClass)U["x-amz-storage-class"]=Y.storageClass;if(Y.serverSideEncryption)U["x-amz-server-side-encryption"]=Y.serverSideEncryption;if(Y.acl)U["x-amz-acl"]=Y.acl;if(Y.metadata)for(let[A,K]of Object.entries(Y.metadata))U[`x-amz-meta-${A.toLowerCase()}`]=K;let W=v0({method:"POST",url:Z,headers:U,...Q,service:"s3",region:this.region}),z=await fetch(W.url,{method:W.method,headers:W.headers});if(!z.ok){let A=await z.text();throw new J1(`Failed to initiate multipart upload: ${A}`,z.status,$,J)}let H=(await z.text()).match(/<UploadId>([^<]+)<\/UploadId>/);if(!H)throw new J1("Failed to parse upload ID from response",0,$,J);return H[1]}async uploadParts($,J,Y,Q,Z,U,W,z,G){let H=[],A=Q.getReader(),K=1,B=new Uint8Array(0),j=0,X=W?Math.ceil(W/Z):void 0,O=[],_=async(E,M)=>{let T=`${this.buildUrl($,J)}?partNumber=${M}&uploadId=${encodeURIComponent(Y)}`,D={"Content-Length":String(E.byteLength),"x-amz-content-sha256":"UNSIGNED-PAYLOAD"},N=v0({method:"PUT",url:T,headers:D,...U,service:"s3",region:this.region}),x=await fetch(N.url,{method:N.method,headers:N.headers,body:E});if(!x.ok){let I=await x.text();throw new J1(`Failed to upload part ${M}: ${I}`,x.status,$,J)}let h=(x.headers.get("ETag")||"").replace(/"/g,"");return{partNumber:M,etag:h}};while(!0){let{done:E,value:M}=await A.read();if(M){let T=new Uint8Array(B.length+M.length);T.set(B),T.set(M,B.length),B=T}while(B.length>=Z||E&&B.length>0){let T=B.slice(0,Z);B=B.slice(Z);let D=K++;if(O.length>=z){let x=await Promise.race(O);H.push(x),O.splice(O.indexOf(Promise.resolve(x)),1)}let N=_(T,D);if(O.push(N),j+=T.byteLength,G)G({loaded:j,total:W||j,part:D,totalParts:X||D})}if(E)break}let w=await Promise.all(O);return H.push(...w),H.sort((E,M)=>E.partNumber-M.partNumber),H}async completeMultipartUpload($,J,Y,Q){let Z=await this.getCredentials(),U=`${this.buildUrl($,J)}?uploadId=${encodeURIComponent(Y)}`,z=`<?xml version="1.0" encoding="UTF-8"?><CompleteMultipartUpload>${Q.map((j)=>`<Part><PartNumber>${j.partNumber}</PartNumber><ETag>"${j.etag}"</ETag></Part>`).join("")}</CompleteMultipartUpload>`,G=v0({method:"POST",url:U,headers:{"Content-Type":"application/xml"},body:z,...Z,service:"s3",region:this.region}),H=await fetch(G.url,{method:G.method,headers:G.headers,body:z});if(!H.ok){let j=await H.text();throw new J1(`Failed to complete multipart upload: ${j}`,H.status,$,J)}let K=(await H.text()).match(/<ETag>"?([^"<]+)"?<\/ETag>/);return{etag:K?K[1]:""}}async abortMultipartUpload($,J,Y){let Q=await this.getCredentials(),Z=`${this.buildUrl($,J)}?uploadId=${encodeURIComponent(Y)}`,U=v0({method:"DELETE",url:Z,...Q,service:"s3",region:this.region});await fetch(U.url,{method:U.method,headers:U.headers})}async emptyAndDeleteBucket($){let Y=[];for await(let W of this.listAll($,{}))if(Y.push(W.key),Y.length>=1000)await this.deleteMany($,Y),Y=[];if(Y.length>0)await this.deleteMany($,Y);let Q=await this.getCredentials(),Z=this.buildUrl($),U=v0({method:"DELETE",url:Z,...Q,service:"s3",region:this.region});await fetch(U.url,{method:U.method,headers:U.headers})}}function dH($){let J=[],Y=[],Q=/<Contents>([\s\S]*?)<\/Contents>/g,Z;while((Z=Q.exec($))!==null){let W=Z[1];J.push({key:F1(W,"Key")||"",lastModified:new Date(F1(W,"LastModified")||0),etag:(F1(W,"ETag")||"").replace(/"/g,""),size:Number(F1(W,"Size")||0),storageClass:F1(W,"StorageClass")||"STANDARD"})}let U=/<CommonPrefixes><Prefix>([^<]+)<\/Prefix><\/CommonPrefixes>/g;while((Z=U.exec($))!==null)Y.push(Z[1]);return{contents:J,commonPrefixes:Y,isTruncated:F1($,"IsTruncated")==="true",continuationToken:F1($,"ContinuationToken")||void 0,nextContinuationToken:F1($,"NextContinuationToken")||void 0,keyCount:Number(F1($,"KeyCount")||0),maxKeys:Number(F1($,"MaxKeys")||1000),prefix:F1($,"Prefix")||void 0,delimiter:F1($,"Delimiter")||void 0}}function F1($,J){let Y=new RegExp(`<${J}>([^<]*)</${J}>`),Q=$.match(Y);return Q?Q[1]:null}function mH($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function FQ($){let J=$.split(".").pop()?.toLowerCase();return{html:"text/html",htm:"text/html",css:"text/css",js:"application/javascript",mjs:"application/javascript",json:"application/json",xml:"application/xml",txt:"text/plain",md:"text/markdown",csv:"text/csv",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mp3:"audio/mpeg",wav:"audio/wav",ogg:"audio/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",zip:"application/zip",gz:"application/gzip",tar:"application/x-tar",rar:"application/vnd.rar","7z":"application/x-7z-compressed",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject",wasm:"application/wasm"}[J||""]||"application/octet-stream"}function cH($){if($ instanceof Blob)return $;if(typeof $==="string")return new Blob([$],{type:"text/plain"});return new Blob([$])}function lH($){return new T6($)}class tQ{profile;credentials=null;constructor($="default"){this.profile=$}async init(){this.credentials=await C9(this.profile)}async ensureCredentials(){if(!this.credentials)await this.init();return this.credentials}async createInvalidation($){let J=await this.ensureCredentials(),Y=$.callerReference||`invalidation-${Date.now()}`,Q=`<?xml version="1.0" encoding="UTF-8"?>
257
257
  <InvalidationBatch>
258
258
  <Paths>
259
259
  <Quantity>${$.paths.length}</Quantity>
@@ -4605,7 +4605,7 @@ catch (error) {
4605
4605
 
4606
4606
  return { statusCode: 200, body: 'OK' };
4607
4607
  };
4608
- `,PK,VZ,d2,LZ,y7,v7,xK,CK,IK,kK,hK,bK,yK,vK,fK;var Z2=S0(async()=>{gG=Object.defineProperty;cG=fG(import.meta.url),XQ={};q2(XQ,{signRequestAsync:()=>D9,signRequest:()=>v0,parseXMLResponse:()=>G$,parseJSONResponse:()=>RQ,makeAWSRequestOnce:()=>MQ,makeAWSRequestAsync:()=>TQ,makeAWSRequest:()=>_2,isWebCryptoAvailable:()=>PQ,isNodeCryptoAvailable:()=>SQ,getSigningKeyCacheSize:()=>NQ,detectServiceRegion:()=>R9,createPresignedUrlAsync:()=>OQ,createPresignedUrl:()=>j6,clearSigningKeyCache:()=>DQ});X$=mG(async()=>{try{m2=await import("node:crypto")}catch{}E2=new Map,CQ={appstream2:"appstream",cloudhsmv2:"cloudhsm",email:"ses",marketplace:"aws-marketplace",mobile:"AWSMobileHubService",pinpoint:"mobiletargeting",queue:"sqs","git-codecommit":"codecommit","mturk-requester-sandbox":"mturk-requester","personalize-runtime":"personalize"}}),rG={backgroundJobs:{visibilityTimeout:120,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fifo:{fifo:!0,contentBasedDeduplication:!0,visibilityTimeout:30,encrypted:!0},highThroughput:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0},delayed:{delaySeconds:60,visibilityTimeout:60,encrypted:!0},longRunning:{visibilityTimeout:900,messageRetentionPeriod:1209600,deadLetterQueue:!0,maxReceiveCount:2,encrypted:!0},monitored:{visibilityTimeout:60,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0,alarms:{enabled:!0,queueDepthThreshold:1000,messageAgeThreshold:3600,dlqAlarm:!0}},lambdaOptimized:{visibilityTimeout:360,receiveMessageWaitTime:20,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fanOut:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0}},nG={serverless:{development:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:!0},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:1000,handlerMemory:128}},production:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:30,inactivityTimeout:60}},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST",pointInTimeRecovery:!0,connectionTTL:86400}},scaling:{maxConnections:50000,messagesPerSecond:5000,handlerMemory:256,handlerTimeout:30},monitoring:{enabled:!0,connectionThreshold:40000,errorThreshold:100,latencyThreshold:500},keepAlive:!0,keepAliveInterval:30,idleTimeout:600},notifications:{enabled:!0,mode:"serverless",channels:{public:!1,private:!0,presence:!1},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:50000,messagesPerSecond:2000,handlerMemory:128},keepAlive:!0,keepAliveInterval:60,idleTimeout:1800}},server:{development:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"ws",driver:"bun",idleTimeout:120,perMessageDeflate:!1,metrics:!1}},production:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,maxPayloadLength:16777216,backpressureLimit:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"broadcasting:"},rateLimit:{enabled:!0,max:100,window:60000,perChannel:!0,perUser:!0},loadManagement:{enabled:!0,maxConnections:1e4,maxSubscriptionsPerConnection:100,shedLoadThreshold:0.8},metrics:!0,autoScaling:{min:2,max:10,targetCPU:70}},monitoring:{enabled:!0,connectionThreshold:8000,errorThreshold:100}},highPerformance:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:60,maxPayloadLength:8388608,backpressureLimit:2097152,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!0,instances:4,redis:{enabled:!0,useElastiCache:!0,keyPrefix:"rt:"},rateLimit:{enabled:!0,max:200,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:25000,maxSubscriptionsPerConnection:50,shedLoadThreshold:0.7},metrics:{enabled:!0,path:"/metrics"},autoScaling:{min:4,max:20,targetCPU:60,targetConnections:20000}},monitoring:{enabled:!0,connectionThreshold:80000,errorThreshold:50,latencyThreshold:50}},chat:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:200,heartbeatInterval:20,inactivityTimeout:60}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:300,maxPayloadLength:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"chat:"},rateLimit:{enabled:!0,max:60,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:15000,maxSubscriptionsPerConnection:20},metrics:!0},keepAlive:!0,keepAliveInterval:25,idleTimeout:900},gaming:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:10,inactivityTimeout:30}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:30,maxPayloadLength:65536,backpressureLimit:524288,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!1,instances:4,redis:{enabled:!0,useElastiCache:!0},rateLimit:{enabled:!0,max:120,window:60000},loadManagement:{enabled:!0,maxConnections:5000,maxSubscriptionsPerConnection:10,shedLoadThreshold:0.6},metrics:!0,autoScaling:{min:4,max:16,targetCPU:50}},keepAlive:!0,keepAliveInterval:10,idleTimeout:60},single:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,sendPings:!0,perMessageDeflate:!0,instances:1,rateLimit:{enabled:!0,max:100,window:60000},loadManagement:{enabled:!0,maxConnections:1e4},metrics:!0}}}};u={Ref:($)=>({Ref:$}),GetAtt:($,J)=>({"Fn::GetAtt":[$,J]}),Sub:($,J)=>{if(J)return{"Fn::Sub":[$,J]};return{"Fn::Sub":$}},Join:($,J)=>({"Fn::Join":[$,J]}),Select:($,J)=>({"Fn::Select":[$,J]}),Split:($,J)=>({"Fn::Split":[$,J]}),GetAZs:($="")=>({"Fn::GetAZs":$}),ImportValue:($)=>({"Fn::ImportValue":$}),If:($,J,Y)=>({"Fn::If":[$,J,Y]}),Equals:($,J)=>({"Fn::Equals":[$,J]}),And:(...$)=>({"Fn::And":$}),Or:(...$)=>({"Fn::Or":$}),Not:($)=>({"Fn::Not":[$]}),Base64:($)=>({"Fn::Base64":$})},W4={AccountId:{Ref:"AWS::AccountId"},Region:{Ref:"AWS::Region"},StackId:{Ref:"AWS::StackId"},StackName:{Ref:"AWS::StackName"},NotificationARNs:{Ref:"AWS::NotificationARNs"},Partition:{Ref:"AWS::Partition"},URLSuffix:{Ref:"AWS::URLSuffix"},NoValue:{Ref:"AWS::NoValue"}};X1=class X1{static createBucket($){let{name:J,bucketName:Y,slug:Q,environment:Z,public:U=!1,versioning:W=!1,website:z=!1,encryption:G=!0,intelligentTiering:H=!1,cors:A,lifecycleRules:K}=$,B=Y??v({slug:Q,environment:Z,resourceType:"s3",suffix:J}),j=S(B),X={Type:"AWS::S3::Bucket",Properties:{BucketName:B}};if(G)X.Properties.BucketEncryption={ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]};if(W)X.Properties.VersioningConfiguration={Status:"Enabled"};if(z)X.Properties.WebsiteConfiguration={IndexDocument:"index.html",ErrorDocument:"error.html"};if(!U)X.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0};if(A&&A.length>0)X.Properties.CorsConfiguration={CorsRules:A.map((_)=>({AllowedOrigins:_.allowedOrigins,AllowedMethods:_.allowedMethods,AllowedHeaders:_.allowedHeaders,MaxAge:_.maxAge}))};if(K&&K.length>0)X.Properties.LifecycleConfiguration={Rules:K.map((_)=>({Id:_.id,Status:_.enabled?"Enabled":"Disabled",ExpirationInDays:_.expirationDays,Transitions:_.transitions?.map((w)=>({TransitionInDays:w.days,StorageClass:w.storageClass}))}))};if(H&&K){let _={id:"IntelligentTieringRule",enabled:!0,transitions:[{days:0,storageClass:"INTELLIGENT_TIERING"}]};if(!X.Properties.LifecycleConfiguration)X.Properties.LifecycleConfiguration={Rules:[]};X.Properties.LifecycleConfiguration.Rules.push({Id:_.id,Status:"Enabled",Transitions:_.transitions?.map((w)=>({TransitionInDays:w.days,StorageClass:w.storageClass}))})}let O;if(U)O={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(j),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadGetObject",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[u.Join("",[u.GetAtt(j,"Arn"),"/*"])]}]}}};return{bucket:X,bucketPolicy:O,logicalId:j}}static enableVersioning($){if(!$.Properties)$.Properties={};return $.Properties.VersioningConfiguration={Status:"Enabled"},$}static enableWebsiteHosting($,J="index.html",Y="error.html"){if(!$.Properties)$.Properties={};return $.Properties.WebsiteConfiguration={IndexDocument:J,ErrorDocument:Y},$}static setLifecycleRules($,J){if(!$.Properties)$.Properties={};return $.Properties.LifecycleConfiguration={Rules:J.map((Y)=>({Id:Y.id,Status:Y.enabled?"Enabled":"Disabled",ExpirationInDays:Y.expirationDays,Transitions:Y.transitions?.map((Q)=>({TransitionInDays:Q.days,StorageClass:Q.storageClass}))}))},$}static enableIntelligentTiering($){if(!$.Properties)$.Properties={};if(!$.Properties.LifecycleConfiguration)$.Properties.LifecycleConfiguration={Rules:[]};return $.Properties.LifecycleConfiguration.Rules.push({Id:"IntelligentTieringRule",Status:"Enabled",Transitions:[{TransitionInDays:0,StorageClass:"INTELLIGENT_TIERING"}]}),$}static addLambdaNotification($,J){if(!$.Properties)$.Properties={};if(!$.Properties.NotificationConfiguration)$.Properties.NotificationConfiguration={};if(!$.Properties.NotificationConfiguration.LambdaConfigurations)$.Properties.NotificationConfiguration.LambdaConfigurations=[];let Y={Event:J.events[0],Function:J.functionArn};if(J.filter)Y.Filter={S3Key:{Rules:[...J.filter.prefix?[{Name:"prefix",Value:J.filter.prefix}]:[],...J.filter.suffix?[{Name:"suffix",Value:J.filter.suffix}]:[]]}};for(let Q of J.events){let Z={...Y,Event:Q};$.Properties.NotificationConfiguration.LambdaConfigurations.push(Z)}return $}static Notifications={onObjectCreated:($)=>({functionArn:$,events:["s3:ObjectCreated:*"]}),onObjectRemoved:($)=>({functionArn:$,events:["s3:ObjectRemoved:*"]}),onImageUpload:($,J)=>({functionArn:$,events:["s3:ObjectCreated:*"],filter:{prefix:J,suffix:".jpg"}}),onFileType:($,J,Y)=>({functionArn:$,events:["s3:ObjectCreated:*"],filter:{prefix:Y,suffix:J}}),onFolderUpload:($,J)=>({functionArn:$,events:["s3:ObjectCreated:*"],filter:{prefix:J.endsWith("/")?J:`${J}/`}})};static createBackupPlan($){let{name:J,slug:Y,environment:Q,bucketLogicalIds:Z,retentionDays:U,schedule:W="cron(0 5 * * ? *)",vaultName:z,enableContinuousBackup:G=!1,moveToColdStorageAfterDays:H}=$,A=z||v({slug:Y,environment:Q,resourceType:"backup-vault",suffix:J}),K=S(A),B={Type:"AWS::Backup::BackupVault",Properties:{BackupVaultName:A}},j=v({slug:Y,environment:Q,resourceType:"backup-role",suffix:J}),X=S(j),O={Type:"AWS::IAM::Role",Properties:{RoleName:j,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"backup.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup","arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"]}},_=v({slug:Y,environment:Q,resourceType:"backup-plan",suffix:J}),w=S(_),E={DeleteAfterDays:U};if(H&&H<U)E.MoveToColdStorageAfterDays=H;let M={Type:"AWS::Backup::BackupPlan",Properties:{BackupPlan:{BackupPlanName:_,BackupPlanRule:[{RuleName:`${J}-daily-backup`,TargetBackupVault:u.Ref(K),ScheduleExpression:W,StartWindowMinutes:60,CompletionWindowMinutes:120,Lifecycle:E,EnableContinuousBackup:G}]}}},T=v({slug:Y,environment:Q,resourceType:"backup-selection",suffix:J}),D=S(T),N=Z.map((h)=>u.GetAtt(h,"Arn")),x={Type:"AWS::Backup::BackupSelection",Properties:{BackupPlanId:u.Ref(w),BackupSelection:{SelectionName:T,IamRoleArn:u.GetAtt(X,"Arn"),Resources:N}}};return{vault:B,plan:M,selection:x,role:O,vaultLogicalId:K,planLogicalId:w,selectionLogicalId:D,roleLogicalId:X}}static BackupSchedules={HOURLY:"cron(0 * * * ? *)",DAILY_5AM:"cron(0 5 * * ? *)",DAILY_MIDNIGHT:"cron(0 0 * * ? *)",WEEKLY_SUNDAY:"cron(0 5 ? * SUN *)",WEEKLY_SATURDAY:"cron(0 5 ? * SAT *)",MONTHLY_FIRST:"cron(0 5 1 * ? *)",EVERY_12_HOURS:"cron(0 */12 * * ? *)",EVERY_6_HOURS:"cron(0 */6 * * ? *)"};static BackupRetention={ONE_DAY:1,ONE_WEEK:7,TWO_WEEKS:14,ONE_MONTH:30,THREE_MONTHS:90,SIX_MONTHS:180,ONE_YEAR:365,TWO_YEARS:730,FIVE_YEARS:1825,SEVEN_YEARS:2555};static createWwwRedirectBucket($){let{slug:J,environment:Y,sourceDomain:Q,targetDomain:Z,protocol:U="https"}=$,W=v({slug:J,environment:Y,resourceType:"s3",suffix:"www-redirect"}),z=S(W),G={Type:"AWS::S3::Bucket",Properties:{BucketName:Q,WebsiteConfiguration:{RedirectAllRequestsTo:{HostName:Z,Protocol:U}},PublicAccessBlockConfiguration:{BlockPublicAcls:!1,BlockPublicPolicy:!1,IgnorePublicAcls:!1,RestrictPublicBuckets:!1}}},H={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(z),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadForRedirect",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[u.Join("",[u.GetAtt(z,"Arn"),"/*"])]}]}}};return{bucket:G,bucketPolicy:H,logicalId:z}}static createDocsBucket($){let{slug:J,environment:Y,domain:Q}=$,Z=Q||v({slug:J,environment:Y,resourceType:"s3",suffix:"docs"}),U=S(Z);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:Z,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},Tags:[{Key:"backup",Value:"weekly"}]}},logicalId:U}}static createEmailBucket($){let{slug:J,environment:Y}=$,Q=v({slug:J,environment:Y,resourceType:"s3",suffix:"email"}),Z=S(Q),U={Type:"AWS::S3::Bucket",Properties:{BucketName:Q,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"EmailRetention",Status:"Enabled",ExpirationInDays:90,Transitions:[{TransitionInDays:30,StorageClass:"STANDARD_IA"}]}]}}},W={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(Z),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowSESPuts",Effect:"Allow",Principal:{Service:"ses.amazonaws.com"},Action:"s3:PutObject",Resource:u.Join("",[u.GetAtt(Z,"Arn"),"/*"]),Condition:{StringEquals:{"AWS:SourceAccount":u.Ref("AWS::AccountId")}}}]}}};return{bucket:U,bucketPolicy:W,logicalId:Z}}static docsExist($={}){let{projectRoot:J=process.cwd(),docsPaths:Y=["docs","documentation","doc"]}=$;for(let Q of Y){let Z=e1(J,Q);if(Q$(Z)){let U=["dist","build",".vitepress/dist","_site","out","public"];for(let W of U){let z=e1(Z,W);if(Q$(z))try{if(j4(z).length>0)return{exists:!0,path:Z,hasDistFolder:!0,distPath:z}}catch{}}return{exists:!0,path:Z,hasDistFolder:!1,distPath:null}}}return{exists:!1,path:null,hasDistFolder:!1,distPath:null}}static createDocsBucketIfExists($){let J=X1.docsExist({projectRoot:$.projectRoot,docsPaths:$.docsPaths});if(!J.exists)return{bucket:null,logicalId:null,docsInfo:J};let Y=X1.createDocsBucket({slug:$.slug,environment:$.environment,domain:$.domain});return{bucket:Y.bucket,bucketPolicy:Y.bucketPolicy,logicalId:Y.logicalId,docsInfo:J}}static createPrivateBucket($){let{slug:J,environment:Y,enableVersioning:Q=!0,retentionDays:Z,encryptionKeyArn:U}=$,W=v({slug:J,environment:Y,resourceType:"s3",suffix:"private"}),z=S(W);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:W,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:U?{SSEAlgorithm:"aws:kms",KMSMasterKeyID:U}:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},VersioningConfiguration:Q?{Status:"Enabled"}:void 0,LifecycleConfiguration:Z?{Rules:[{Id:"RetentionPolicy",Status:"Enabled",ExpirationInDays:Z}]}:void 0,Tags:[{Key:"backup",Value:"daily"}]}},logicalId:z}}static checkSourcePaths($={}){let{projectRoot:J=process.cwd(),paths:Y={}}=$,Q=Y.web||"views/web/dist",Z=Y.docs||"docs/dist",U=Y.private||"private";return{web:{exists:Q$(e1(J,Q)),path:e1(J,Q)},docs:{exists:Q$(e1(J,Z)),path:e1(J,Z)},private:{exists:Q$(e1(J,U)),path:e1(J,U)}}}static createDeploymentBuckets($){let{slug:J,environment:Y,domain:Q,projectRoot:Z,paths:U}=$,W=X1.checkSourcePaths({projectRoot:Z,paths:U}),z={},G={web:!1,docs:!1,private:!1},H=X1.createBucket({name:"web",slug:J,environment:Y,public:!1,versioning:!1,encryption:!0});if(z[H.logicalId]=H.bucket,G.web=!0,W.docs.exists){let A=X1.createDocsBucket({slug:J,environment:Y,domain:Q?`docs.${Q}`:void 0});if(z[A.logicalId]=A.bucket,A.bucketPolicy)z[`${A.logicalId}Policy`]=A.bucketPolicy;G.docs=!0}if(W.private.exists){let A=X1.createPrivateBucket({slug:J,environment:Y,enableVersioning:!0});z[A.logicalId]=A.bucket,G.private=!0}return{resources:z,created:G,sourcePaths:W}}};T1=class T1{static createRepository($){let{name:J,slug:Y,environment:Q,scanOnPush:Z=!0,imageMutability:U="MUTABLE",encryption:W="AES256",kmsKey:z,lifecyclePolicy:G,tags:H}=$,A=v({slug:Y,environment:Q,resourceType:"ecr",suffix:J}),K=S(A),B={Type:"AWS::ECR::Repository",Properties:{RepositoryName:A,ImageTagMutability:U,ImageScanningConfiguration:{ScanOnPush:Z},EncryptionConfiguration:{EncryptionType:W,...z&&W==="KMS"?{KmsKey:z}:{}}}};if(G)B.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(T1.generateLifecyclePolicy(G))};if(H)B.Properties.Tags=Object.entries(H).map(([j,X])=>({Key:j,Value:X}));return{repository:B,logicalId:K}}static generateLifecyclePolicy($){let J=[];if($.untaggedImageExpireDays!==void 0)J.push({rulePriority:1,description:"Delete untagged images",selection:{tagStatus:"untagged",countType:"sinceImagePushed",countNumber:$.untaggedImageExpireDays,countUnit:"days"},action:{type:"expire"}});if($.maxImageCount!==void 0)J.push({rulePriority:J.length+1,description:"Keep only most recent images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:$.maxImageCount},action:{type:"expire"}});if($.maxImageAgeDays!==void 0)J.push({rulePriority:J.length+1,description:"Delete images older than specified days",selection:{tagStatus:"any",countType:"sinceImagePushed",countNumber:$.maxImageAgeDays,countUnit:"days"},action:{type:"expire"}});return{rules:J}}static LifecyclePolicies={production:{maxImageCount:10,untaggedImageExpireDays:7},development:{maxImageCount:5,untaggedImageExpireDays:3},minimal:{maxImageCount:3,untaggedImageExpireDays:1},archive:{maxImageCount:50,untaggedImageExpireDays:30}};static enableImmutableTags($){if(!$.Properties)$.Properties={};return $.Properties.ImageTagMutability="IMMUTABLE",$}static enableScanOnPush($){if(!$.Properties)$.Properties={};return $.Properties.ImageScanningConfiguration={ScanOnPush:!0},$}static setLifecyclePolicy($,J){if(!$.Properties)$.Properties={};return $.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(T1.generateLifecyclePolicy(J))},$}static addCrossAccountAccess($,J){if(!$.Properties)$.Properties={};return $.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"CrossAccountPull",Effect:"Allow",Principal:{AWS:J.map((Y)=>`arn:aws:iam::${Y}:root`)},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:BatchCheckLayerAvailability"]}]},$}static addLambdaAccess($){if(!$.Properties)$.Properties={};return $.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"LambdaECRImageRetrievalPolicy",Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage"]}]},$}static generateBunDockerfile($){let{baseImage:J="oven/bun:1-debian",serverPath:Y,port:Q=3000,additionalDirs:Z=[],healthCheckEndpoint:U="/health",nodeCompatible:W=!1,envVars:z={},buildCommands:G=[],runCommand:H}=$,A=["app","config",...Z],K=H||`bun run ${Y}`,B=`# Multi-stage build for Bun application
4608
+ `,PK,VZ,d2,LZ,y7,v7,xK,CK,IK,kK,hK,bK,yK,vK,fK;var Z2=S0(async()=>{gG=Object.defineProperty;cG=fG(import.meta.url),XQ={};q2(XQ,{signRequestAsync:()=>D9,signRequest:()=>v0,parseXMLResponse:()=>G$,parseJSONResponse:()=>RQ,makeAWSRequestOnce:()=>MQ,makeAWSRequestAsync:()=>TQ,makeAWSRequest:()=>_2,isWebCryptoAvailable:()=>PQ,isNodeCryptoAvailable:()=>SQ,getSigningKeyCacheSize:()=>NQ,detectServiceRegion:()=>R9,createPresignedUrlAsync:()=>OQ,createPresignedUrl:()=>j6,clearSigningKeyCache:()=>DQ});X$=mG(async()=>{try{m2=await import("node:crypto")}catch{}E2=new Map,CQ={appstream2:"appstream",cloudhsmv2:"cloudhsm",email:"ses",marketplace:"aws-marketplace",mobile:"AWSMobileHubService",pinpoint:"mobiletargeting",queue:"sqs","git-codecommit":"codecommit","mturk-requester-sandbox":"mturk-requester","personalize-runtime":"personalize"}}),rG={backgroundJobs:{visibilityTimeout:120,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fifo:{fifo:!0,contentBasedDeduplication:!0,visibilityTimeout:30,encrypted:!0},highThroughput:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0},delayed:{delaySeconds:60,visibilityTimeout:60,encrypted:!0},longRunning:{visibilityTimeout:900,messageRetentionPeriod:1209600,deadLetterQueue:!0,maxReceiveCount:2,encrypted:!0},monitored:{visibilityTimeout:60,messageRetentionPeriod:604800,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0,alarms:{enabled:!0,queueDepthThreshold:1000,messageAgeThreshold:3600,dlqAlarm:!0}},lambdaOptimized:{visibilityTimeout:360,receiveMessageWaitTime:20,deadLetterQueue:!0,maxReceiveCount:3,encrypted:!0},fanOut:{visibilityTimeout:30,receiveMessageWaitTime:20,encrypted:!0}},nG={serverless:{development:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:!0},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:1000,handlerMemory:128}},production:{enabled:!0,mode:"serverless",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:30,inactivityTimeout:60}},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST",pointInTimeRecovery:!0,connectionTTL:86400}},scaling:{maxConnections:50000,messagesPerSecond:5000,handlerMemory:256,handlerTimeout:30},monitoring:{enabled:!0,connectionThreshold:40000,errorThreshold:100,latencyThreshold:500},keepAlive:!0,keepAliveInterval:30,idleTimeout:600},notifications:{enabled:!0,mode:"serverless",channels:{public:!1,private:!0,presence:!1},storage:{type:"dynamodb",dynamodb:{billingMode:"PAY_PER_REQUEST"}},scaling:{maxConnections:50000,messagesPerSecond:2000,handlerMemory:128},keepAlive:!0,keepAliveInterval:60,idleTimeout:1800}},server:{development:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"ws",driver:"bun",idleTimeout:120,perMessageDeflate:!1,metrics:!1}},production:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,maxPayloadLength:16777216,backpressureLimit:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"broadcasting:"},rateLimit:{enabled:!0,max:100,window:60000,perChannel:!0,perUser:!0},loadManagement:{enabled:!0,maxConnections:1e4,maxSubscriptionsPerConnection:100,shedLoadThreshold:0.8},metrics:!0,autoScaling:{min:2,max:10,targetCPU:70}},monitoring:{enabled:!0,connectionThreshold:8000,errorThreshold:100}},highPerformance:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:60,maxPayloadLength:8388608,backpressureLimit:2097152,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!0,instances:4,redis:{enabled:!0,useElastiCache:!0,keyPrefix:"rt:"},rateLimit:{enabled:!0,max:200,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:25000,maxSubscriptionsPerConnection:50,shedLoadThreshold:0.7},metrics:{enabled:!0,path:"/metrics"},autoScaling:{min:4,max:20,targetCPU:60,targetConnections:20000}},monitoring:{enabled:!0,connectionThreshold:80000,errorThreshold:50,latencyThreshold:50}},chat:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:200,heartbeatInterval:20,inactivityTimeout:60}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:300,maxPayloadLength:1048576,sendPings:!0,perMessageDeflate:!0,instances:2,redis:{enabled:!0,keyPrefix:"chat:"},rateLimit:{enabled:!0,max:60,window:60000,perChannel:!0},loadManagement:{enabled:!0,maxConnections:15000,maxSubscriptionsPerConnection:20},metrics:!0},keepAlive:!0,keepAliveInterval:25,idleTimeout:900},gaming:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:{enabled:!0,maxMembers:100,heartbeatInterval:10,inactivityTimeout:30}},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:30,maxPayloadLength:65536,backpressureLimit:524288,closeOnBackpressureLimit:!0,sendPings:!0,perMessageDeflate:!1,instances:4,redis:{enabled:!0,useElastiCache:!0},rateLimit:{enabled:!0,max:120,window:60000},loadManagement:{enabled:!0,maxConnections:5000,maxSubscriptionsPerConnection:10,shedLoadThreshold:0.6},metrics:!0,autoScaling:{min:4,max:16,targetCPU:50}},keepAlive:!0,keepAliveInterval:10,idleTimeout:60},single:{enabled:!0,mode:"server",channels:{public:!0,private:!0,presence:!0},server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",idleTimeout:120,sendPings:!0,perMessageDeflate:!0,instances:1,rateLimit:{enabled:!0,max:100,window:60000},loadManagement:{enabled:!0,maxConnections:1e4},metrics:!0}}}};u={Ref:($)=>({Ref:$}),GetAtt:($,J)=>({"Fn::GetAtt":[$,J]}),Sub:($,J)=>{if(J)return{"Fn::Sub":[$,J]};return{"Fn::Sub":$}},Join:($,J)=>({"Fn::Join":[$,J]}),Select:($,J)=>({"Fn::Select":[$,J]}),Split:($,J)=>({"Fn::Split":[$,J]}),GetAZs:($="")=>({"Fn::GetAZs":$}),ImportValue:($)=>({"Fn::ImportValue":$}),If:($,J,Y)=>({"Fn::If":[$,J,Y]}),Equals:($,J)=>({"Fn::Equals":[$,J]}),And:(...$)=>({"Fn::And":$}),Or:(...$)=>({"Fn::Or":$}),Not:($)=>({"Fn::Not":[$]}),Base64:($)=>({"Fn::Base64":$})},W4={AccountId:{Ref:"AWS::AccountId"},Region:{Ref:"AWS::Region"},StackId:{Ref:"AWS::StackId"},StackName:{Ref:"AWS::StackName"},NotificationARNs:{Ref:"AWS::NotificationARNs"},Partition:{Ref:"AWS::Partition"},URLSuffix:{Ref:"AWS::URLSuffix"},NoValue:{Ref:"AWS::NoValue"}};X1=class X1{static createBucket($){let{name:J,bucketName:Y,slug:Q,environment:Z,public:U=!1,versioning:W=!1,website:z=!1,encryption:G=!0,intelligentTiering:H=!1,cors:A,lifecycleRules:K}=$,B=Y??f({slug:Q,environment:Z,resourceType:"s3",suffix:J}),j=S(B),X={Type:"AWS::S3::Bucket",Properties:{BucketName:B}};if(G)X.Properties.BucketEncryption={ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]};if(W)X.Properties.VersioningConfiguration={Status:"Enabled"};if(z)X.Properties.WebsiteConfiguration={IndexDocument:"index.html",ErrorDocument:"error.html"};if(!U)X.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0};if(A&&A.length>0)X.Properties.CorsConfiguration={CorsRules:A.map((_)=>({AllowedOrigins:_.allowedOrigins,AllowedMethods:_.allowedMethods,AllowedHeaders:_.allowedHeaders,MaxAge:_.maxAge}))};if(K&&K.length>0)X.Properties.LifecycleConfiguration={Rules:K.map((_)=>({Id:_.id,Status:_.enabled?"Enabled":"Disabled",ExpirationInDays:_.expirationDays,Transitions:_.transitions?.map((w)=>({TransitionInDays:w.days,StorageClass:w.storageClass}))}))};if(H&&K){let _={id:"IntelligentTieringRule",enabled:!0,transitions:[{days:0,storageClass:"INTELLIGENT_TIERING"}]};if(!X.Properties.LifecycleConfiguration)X.Properties.LifecycleConfiguration={Rules:[]};X.Properties.LifecycleConfiguration.Rules.push({Id:_.id,Status:"Enabled",Transitions:_.transitions?.map((w)=>({TransitionInDays:w.days,StorageClass:w.storageClass}))})}let O;if(U)O={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(j),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadGetObject",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[u.Join("",[u.GetAtt(j,"Arn"),"/*"])]}]}}};return{bucket:X,bucketPolicy:O,logicalId:j}}static enableVersioning($){if(!$.Properties)$.Properties={};return $.Properties.VersioningConfiguration={Status:"Enabled"},$}static enableWebsiteHosting($,J="index.html",Y="error.html"){if(!$.Properties)$.Properties={};return $.Properties.WebsiteConfiguration={IndexDocument:J,ErrorDocument:Y},$}static setLifecycleRules($,J){if(!$.Properties)$.Properties={};return $.Properties.LifecycleConfiguration={Rules:J.map((Y)=>({Id:Y.id,Status:Y.enabled?"Enabled":"Disabled",ExpirationInDays:Y.expirationDays,Transitions:Y.transitions?.map((Q)=>({TransitionInDays:Q.days,StorageClass:Q.storageClass}))}))},$}static enableIntelligentTiering($){if(!$.Properties)$.Properties={};if(!$.Properties.LifecycleConfiguration)$.Properties.LifecycleConfiguration={Rules:[]};return $.Properties.LifecycleConfiguration.Rules.push({Id:"IntelligentTieringRule",Status:"Enabled",Transitions:[{TransitionInDays:0,StorageClass:"INTELLIGENT_TIERING"}]}),$}static addLambdaNotification($,J){if(!$.Properties)$.Properties={};if(!$.Properties.NotificationConfiguration)$.Properties.NotificationConfiguration={};if(!$.Properties.NotificationConfiguration.LambdaConfigurations)$.Properties.NotificationConfiguration.LambdaConfigurations=[];let Y={Event:J.events[0],Function:J.functionArn};if(J.filter)Y.Filter={S3Key:{Rules:[...J.filter.prefix?[{Name:"prefix",Value:J.filter.prefix}]:[],...J.filter.suffix?[{Name:"suffix",Value:J.filter.suffix}]:[]]}};for(let Q of J.events){let Z={...Y,Event:Q};$.Properties.NotificationConfiguration.LambdaConfigurations.push(Z)}return $}static Notifications={onObjectCreated:($)=>({functionArn:$,events:["s3:ObjectCreated:*"]}),onObjectRemoved:($)=>({functionArn:$,events:["s3:ObjectRemoved:*"]}),onImageUpload:($,J)=>({functionArn:$,events:["s3:ObjectCreated:*"],filter:{prefix:J,suffix:".jpg"}}),onFileType:($,J,Y)=>({functionArn:$,events:["s3:ObjectCreated:*"],filter:{prefix:Y,suffix:J}}),onFolderUpload:($,J)=>({functionArn:$,events:["s3:ObjectCreated:*"],filter:{prefix:J.endsWith("/")?J:`${J}/`}})};static createBackupPlan($){let{name:J,slug:Y,environment:Q,bucketLogicalIds:Z,retentionDays:U,schedule:W="cron(0 5 * * ? *)",vaultName:z,enableContinuousBackup:G=!1,moveToColdStorageAfterDays:H}=$,A=z||f({slug:Y,environment:Q,resourceType:"backup-vault",suffix:J}),K=S(A),B={Type:"AWS::Backup::BackupVault",Properties:{BackupVaultName:A}},j=f({slug:Y,environment:Q,resourceType:"backup-role",suffix:J}),X=S(j),O={Type:"AWS::IAM::Role",Properties:{RoleName:j,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"backup.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup","arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"]}},_=f({slug:Y,environment:Q,resourceType:"backup-plan",suffix:J}),w=S(_),E={DeleteAfterDays:U};if(H&&H<U)E.MoveToColdStorageAfterDays=H;let M={Type:"AWS::Backup::BackupPlan",Properties:{BackupPlan:{BackupPlanName:_,BackupPlanRule:[{RuleName:`${J}-daily-backup`,TargetBackupVault:u.Ref(K),ScheduleExpression:W,StartWindowMinutes:60,CompletionWindowMinutes:120,Lifecycle:E,EnableContinuousBackup:G}]}}},T=f({slug:Y,environment:Q,resourceType:"backup-selection",suffix:J}),D=S(T),N=Z.map((h)=>u.GetAtt(h,"Arn")),x={Type:"AWS::Backup::BackupSelection",Properties:{BackupPlanId:u.Ref(w),BackupSelection:{SelectionName:T,IamRoleArn:u.GetAtt(X,"Arn"),Resources:N}}};return{vault:B,plan:M,selection:x,role:O,vaultLogicalId:K,planLogicalId:w,selectionLogicalId:D,roleLogicalId:X}}static BackupSchedules={HOURLY:"cron(0 * * * ? *)",DAILY_5AM:"cron(0 5 * * ? *)",DAILY_MIDNIGHT:"cron(0 0 * * ? *)",WEEKLY_SUNDAY:"cron(0 5 ? * SUN *)",WEEKLY_SATURDAY:"cron(0 5 ? * SAT *)",MONTHLY_FIRST:"cron(0 5 1 * ? *)",EVERY_12_HOURS:"cron(0 */12 * * ? *)",EVERY_6_HOURS:"cron(0 */6 * * ? *)"};static BackupRetention={ONE_DAY:1,ONE_WEEK:7,TWO_WEEKS:14,ONE_MONTH:30,THREE_MONTHS:90,SIX_MONTHS:180,ONE_YEAR:365,TWO_YEARS:730,FIVE_YEARS:1825,SEVEN_YEARS:2555};static createWwwRedirectBucket($){let{slug:J,environment:Y,sourceDomain:Q,targetDomain:Z,protocol:U="https"}=$,W=f({slug:J,environment:Y,resourceType:"s3",suffix:"www-redirect"}),z=S(W),G={Type:"AWS::S3::Bucket",Properties:{BucketName:Q,WebsiteConfiguration:{RedirectAllRequestsTo:{HostName:Z,Protocol:U}},PublicAccessBlockConfiguration:{BlockPublicAcls:!1,BlockPublicPolicy:!1,IgnorePublicAcls:!1,RestrictPublicBuckets:!1}}},H={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(z),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadForRedirect",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[u.Join("",[u.GetAtt(z,"Arn"),"/*"])]}]}}};return{bucket:G,bucketPolicy:H,logicalId:z}}static createDocsBucket($){let{slug:J,environment:Y,domain:Q}=$,Z=Q||f({slug:J,environment:Y,resourceType:"s3",suffix:"docs"}),U=S(Z);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:Z,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},Tags:[{Key:"backup",Value:"weekly"}]}},logicalId:U}}static createEmailBucket($){let{slug:J,environment:Y}=$,Q=f({slug:J,environment:Y,resourceType:"s3",suffix:"email"}),Z=S(Q),U={Type:"AWS::S3::Bucket",Properties:{BucketName:Q,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"EmailRetention",Status:"Enabled",ExpirationInDays:90,Transitions:[{TransitionInDays:30,StorageClass:"STANDARD_IA"}]}]}}},W={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(Z),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowSESPuts",Effect:"Allow",Principal:{Service:"ses.amazonaws.com"},Action:"s3:PutObject",Resource:u.Join("",[u.GetAtt(Z,"Arn"),"/*"]),Condition:{StringEquals:{"AWS:SourceAccount":u.Ref("AWS::AccountId")}}}]}}};return{bucket:U,bucketPolicy:W,logicalId:Z}}static docsExist($={}){let{projectRoot:J=process.cwd(),docsPaths:Y=["docs","documentation","doc"]}=$;for(let Q of Y){let Z=e1(J,Q);if(Q$(Z)){let U=["dist","build",".vitepress/dist","_site","out","public"];for(let W of U){let z=e1(Z,W);if(Q$(z))try{if(j4(z).length>0)return{exists:!0,path:Z,hasDistFolder:!0,distPath:z}}catch{}}return{exists:!0,path:Z,hasDistFolder:!1,distPath:null}}}return{exists:!1,path:null,hasDistFolder:!1,distPath:null}}static createDocsBucketIfExists($){let J=X1.docsExist({projectRoot:$.projectRoot,docsPaths:$.docsPaths});if(!J.exists)return{bucket:null,logicalId:null,docsInfo:J};let Y=X1.createDocsBucket({slug:$.slug,environment:$.environment,domain:$.domain});return{bucket:Y.bucket,bucketPolicy:Y.bucketPolicy,logicalId:Y.logicalId,docsInfo:J}}static createPrivateBucket($){let{slug:J,environment:Y,enableVersioning:Q=!0,retentionDays:Z,encryptionKeyArn:U}=$,W=f({slug:J,environment:Y,resourceType:"s3",suffix:"private"}),z=S(W);return{bucket:{Type:"AWS::S3::Bucket",Properties:{BucketName:W,BucketEncryption:{ServerSideEncryptionConfiguration:[{ServerSideEncryptionByDefault:U?{SSEAlgorithm:"aws:kms",KMSMasterKeyID:U}:{SSEAlgorithm:"AES256"}}]},PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},VersioningConfiguration:Q?{Status:"Enabled"}:void 0,LifecycleConfiguration:Z?{Rules:[{Id:"RetentionPolicy",Status:"Enabled",ExpirationInDays:Z}]}:void 0,Tags:[{Key:"backup",Value:"daily"}]}},logicalId:z}}static checkSourcePaths($={}){let{projectRoot:J=process.cwd(),paths:Y={}}=$,Q=Y.web||"views/web/dist",Z=Y.docs||"docs/dist",U=Y.private||"private";return{web:{exists:Q$(e1(J,Q)),path:e1(J,Q)},docs:{exists:Q$(e1(J,Z)),path:e1(J,Z)},private:{exists:Q$(e1(J,U)),path:e1(J,U)}}}static createDeploymentBuckets($){let{slug:J,environment:Y,domain:Q,projectRoot:Z,paths:U}=$,W=X1.checkSourcePaths({projectRoot:Z,paths:U}),z={},G={web:!1,docs:!1,private:!1},H=X1.createBucket({name:"web",slug:J,environment:Y,public:!1,versioning:!1,encryption:!0});if(z[H.logicalId]=H.bucket,G.web=!0,W.docs.exists){let A=X1.createDocsBucket({slug:J,environment:Y,domain:Q?`docs.${Q}`:void 0});if(z[A.logicalId]=A.bucket,A.bucketPolicy)z[`${A.logicalId}Policy`]=A.bucketPolicy;G.docs=!0}if(W.private.exists){let A=X1.createPrivateBucket({slug:J,environment:Y,enableVersioning:!0});z[A.logicalId]=A.bucket,G.private=!0}return{resources:z,created:G,sourcePaths:W}}};T1=class T1{static createRepository($){let{name:J,slug:Y,environment:Q,scanOnPush:Z=!0,imageMutability:U="MUTABLE",encryption:W="AES256",kmsKey:z,lifecyclePolicy:G,tags:H}=$,A=f({slug:Y,environment:Q,resourceType:"ecr",suffix:J}),K=S(A),B={Type:"AWS::ECR::Repository",Properties:{RepositoryName:A,ImageTagMutability:U,ImageScanningConfiguration:{ScanOnPush:Z},EncryptionConfiguration:{EncryptionType:W,...z&&W==="KMS"?{KmsKey:z}:{}}}};if(G)B.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(T1.generateLifecyclePolicy(G))};if(H)B.Properties.Tags=Object.entries(H).map(([j,X])=>({Key:j,Value:X}));return{repository:B,logicalId:K}}static generateLifecyclePolicy($){let J=[];if($.untaggedImageExpireDays!==void 0)J.push({rulePriority:1,description:"Delete untagged images",selection:{tagStatus:"untagged",countType:"sinceImagePushed",countNumber:$.untaggedImageExpireDays,countUnit:"days"},action:{type:"expire"}});if($.maxImageCount!==void 0)J.push({rulePriority:J.length+1,description:"Keep only most recent images",selection:{tagStatus:"any",countType:"imageCountMoreThan",countNumber:$.maxImageCount},action:{type:"expire"}});if($.maxImageAgeDays!==void 0)J.push({rulePriority:J.length+1,description:"Delete images older than specified days",selection:{tagStatus:"any",countType:"sinceImagePushed",countNumber:$.maxImageAgeDays,countUnit:"days"},action:{type:"expire"}});return{rules:J}}static LifecyclePolicies={production:{maxImageCount:10,untaggedImageExpireDays:7},development:{maxImageCount:5,untaggedImageExpireDays:3},minimal:{maxImageCount:3,untaggedImageExpireDays:1},archive:{maxImageCount:50,untaggedImageExpireDays:30}};static enableImmutableTags($){if(!$.Properties)$.Properties={};return $.Properties.ImageTagMutability="IMMUTABLE",$}static enableScanOnPush($){if(!$.Properties)$.Properties={};return $.Properties.ImageScanningConfiguration={ScanOnPush:!0},$}static setLifecyclePolicy($,J){if(!$.Properties)$.Properties={};return $.Properties.LifecyclePolicy={LifecyclePolicyText:JSON.stringify(T1.generateLifecyclePolicy(J))},$}static addCrossAccountAccess($,J){if(!$.Properties)$.Properties={};return $.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"CrossAccountPull",Effect:"Allow",Principal:{AWS:J.map((Y)=>`arn:aws:iam::${Y}:root`)},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:BatchCheckLayerAvailability"]}]},$}static addLambdaAccess($){if(!$.Properties)$.Properties={};return $.Properties.RepositoryPolicyText={Version:"2012-10-17",Statement:[{Sid:"LambdaECRImageRetrievalPolicy",Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage"]}]},$}static generateBunDockerfile($){let{baseImage:J="oven/bun:1-debian",serverPath:Y,port:Q=3000,additionalDirs:Z=[],healthCheckEndpoint:U="/health",nodeCompatible:W=!1,envVars:z={},buildCommands:G=[],runCommand:H}=$,A=["app","config",...Z],K=H||`bun run ${Y}`,B=`# Multi-stage build for Bun application
4609
4609
  # Generated by ts-cloud
4610
4610
 
4611
4611
  # Builder stage
@@ -4688,7 +4688,7 @@ echo "Image: $IMAGE_URI:${Q}"
4688
4688
  docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
4689
4689
  docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest`},...$.ecsCluster&&$.ecsService?[{name:"Deploy to ECS",run:`aws ecs update-service --cluster ${$.ecsCluster} --service ${$.ecsService} --force-new-deployment`}]:[]]}}};return`# Generated by ts-cloud
4690
4690
  ${JSON.stringify(J,null,2).replace(/"/g,"").replace(/,\n/g,`
4691
- `)}`}};static DockerfileTemplates={bunServer:($,J=3000)=>T1.generateBunDockerfile({serverPath:$,port:J}),bunWithBuild:($,J,Y=3000)=>T1.generateBunDockerfile({serverPath:$,port:Y,buildCommands:[J]}),bunFullStack:($,J=3000)=>T1.generateBunDockerfile({serverPath:$,port:J,additionalDirs:["public","views","dist"],buildCommands:["bun run build"]}),bunApi:($,J=3000)=>T1.generateBunDockerfile({serverPath:$,port:J,healthCheckEndpoint:"/api/health"})}};j1=class j1{static createDistribution($){let{slug:J,environment:Y,origin:Q,customDomain:Z,certificateArn:U,errorPages:W,cachePolicy:z,edgeFunctions:G,http3:H=!1,comment:A}=$,K=v({slug:J,environment:Y,resourceType:"cdn"}),B=S(K),j={Id:"DefaultOrigin",DomainName:Q.domainName,OriginPath:Q.originPath||""},X;if(Q.type==="s3"){let _=`${B}OAC`;X={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${K}-oac`,Description:`Origin Access Control for ${K}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},j.OriginAccessControlId=u.Ref(_)}else if(Q.type==="alb"||Q.type==="custom")j.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};let O={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:A||`CDN for ${K}`,DefaultRootObject:"index.html",Origins:[j],DefaultCacheBehavior:{TargetOriginId:"DefaultOrigin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},PriceClass:"PriceClass_100",HttpVersion:H?"http2and3":"http2"}}};if(Z&&U)O.Properties.DistributionConfig.Aliases=[Z],O.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:U,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};if(W&&W.length>0)O.Properties.DistributionConfig.CustomErrorResponses=W.map((_)=>({ErrorCode:_.errorCode,ResponseCode:_.responseCode,ResponsePagePath:_.responsePagePath}));if(G&&G.length>0)O.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=G.map((_)=>({EventType:_.event,LambdaFunctionARN:_.functionArn}));return{distribution:O,originAccessControl:X,logicalId:B}}static setCustomDomain($,J,Y){return $.Properties.DistributionConfig.Aliases=[J],$.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:Y,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"},$}static setErrorPages($,J){return $.Properties.DistributionConfig.CustomErrorResponses=J.map((Y)=>({ErrorCode:Y.errorCode,ResponseCode:Y.responseCode,ResponsePagePath:Y.responsePagePath})),$}static enableHttp3($){return $.Properties.DistributionConfig.HttpVersion="http2and3",$}static addEdgeFunction($,J,Y){if(!$.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations)$.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=[];return $.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations.push({EventType:J,LambdaFunctionARN:Y}),$}static setCachePolicy($,J){return $.Properties.DistributionConfig.Comment=`${$.Properties.DistributionConfig.Comment||""} (TTL: ${J.default||86400}s)`,$}static createSpaDistribution($){return j1.createDistribution({...$,errorPages:[{errorCode:404,responseCode:200,responsePagePath:"/index.html"},{errorCode:403,responseCode:200,responsePagePath:"/index.html"}]})}static createDocsOriginRequestFunction($){let{slug:J,environment:Y}=$,Q=v({slug:J,environment:Y,resourceType:"edge-docs"}),Z=S(Q),U=S(`${Q}-role`),W=S(`${Q}-version`),z={Type:"AWS::IAM::Role",Properties:{RoleName:`${Q}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["lambda.amazonaws.com","edgelambda.amazonaws.com"]},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}},G=`
4691
+ `)}`}};static DockerfileTemplates={bunServer:($,J=3000)=>T1.generateBunDockerfile({serverPath:$,port:J}),bunWithBuild:($,J,Y=3000)=>T1.generateBunDockerfile({serverPath:$,port:Y,buildCommands:[J]}),bunFullStack:($,J=3000)=>T1.generateBunDockerfile({serverPath:$,port:J,additionalDirs:["public","views","dist"],buildCommands:["bun run build"]}),bunApi:($,J=3000)=>T1.generateBunDockerfile({serverPath:$,port:J,healthCheckEndpoint:"/api/health"})}};j1=class j1{static createDistribution($){let{slug:J,environment:Y,origin:Q,customDomain:Z,certificateArn:U,errorPages:W,cachePolicy:z,edgeFunctions:G,http3:H=!1,comment:A}=$,K=f({slug:J,environment:Y,resourceType:"cdn"}),B=S(K),j={Id:"DefaultOrigin",DomainName:Q.domainName,OriginPath:Q.originPath||""},X;if(Q.type==="s3"){let _=`${B}OAC`;X={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${K}-oac`,Description:`Origin Access Control for ${K}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},j.OriginAccessControlId=u.Ref(_)}else if(Q.type==="alb"||Q.type==="custom")j.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};let O={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:A||`CDN for ${K}`,DefaultRootObject:"index.html",Origins:[j],DefaultCacheBehavior:{TargetOriginId:"DefaultOrigin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},PriceClass:"PriceClass_100",HttpVersion:H?"http2and3":"http2"}}};if(Z&&U)O.Properties.DistributionConfig.Aliases=[Z],O.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:U,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};if(W&&W.length>0)O.Properties.DistributionConfig.CustomErrorResponses=W.map((_)=>({ErrorCode:_.errorCode,ResponseCode:_.responseCode,ResponsePagePath:_.responsePagePath}));if(G&&G.length>0)O.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=G.map((_)=>({EventType:_.event,LambdaFunctionARN:_.functionArn}));return{distribution:O,originAccessControl:X,logicalId:B}}static setCustomDomain($,J,Y){return $.Properties.DistributionConfig.Aliases=[J],$.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:Y,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"},$}static setErrorPages($,J){return $.Properties.DistributionConfig.CustomErrorResponses=J.map((Y)=>({ErrorCode:Y.errorCode,ResponseCode:Y.responseCode,ResponsePagePath:Y.responsePagePath})),$}static enableHttp3($){return $.Properties.DistributionConfig.HttpVersion="http2and3",$}static addEdgeFunction($,J,Y){if(!$.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations)$.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=[];return $.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations.push({EventType:J,LambdaFunctionARN:Y}),$}static setCachePolicy($,J){return $.Properties.DistributionConfig.Comment=`${$.Properties.DistributionConfig.Comment||""} (TTL: ${J.default||86400}s)`,$}static createSpaDistribution($){return j1.createDistribution({...$,errorPages:[{errorCode:404,responseCode:200,responsePagePath:"/index.html"},{errorCode:403,responseCode:200,responsePagePath:"/index.html"}]})}static createDocsOriginRequestFunction($){let{slug:J,environment:Y}=$,Q=f({slug:J,environment:Y,resourceType:"edge-docs"}),Z=S(Q),U=S(`${Q}-role`),W=S(`${Q}-version`),z={Type:"AWS::IAM::Role",Properties:{RoleName:`${Q}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["lambda.amazonaws.com","edgelambda.amazonaws.com"]},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}},G=`
4692
4692
  'use strict';
4693
4693
 
4694
4694
  exports.handler = async (event) => {
@@ -4721,7 +4721,7 @@ exports.handler = async (event) => {
4721
4721
 
4722
4722
  return request;
4723
4723
  };
4724
- `.trim();return{lambdaFunction:{Type:"AWS::Lambda::Function",Properties:{FunctionName:Q,Description:"Lambda@Edge origin request handler for docs routing",Runtime:"nodejs20.x",Handler:"index.handler",Role:u.GetAtt(U,"Arn"),Code:{ZipFile:G},MemorySize:128,Timeout:5}},role:z,functionLogicalId:Z,roleLogicalId:U,versionLogicalId:W}}static createDocsDistribution($){let{slug:J,environment:Y,origin:Q,customDomain:Z,certificateArn:U,lambdaEdgeFunctionArn:W}=$,z=j1.createDistribution({slug:J,environment:Y,origin:Q,customDomain:Z,certificateArn:U,comment:`Docs CDN for ${J}`,errorPages:[{errorCode:404,responseCode:404,responsePagePath:"/404.html"},{errorCode:403,responseCode:403,responsePagePath:"/404.html"}]});if(W)j1.addEdgeFunction(z.distribution,"origin-request",W);return z.distribution.Properties.DistributionConfig.DefaultCacheBehavior.DefaultTTL=86400,z.distribution.Properties.DistributionConfig.DefaultCacheBehavior.MaxTTL=604800,z.distribution.Properties.DistributionConfig.DefaultCacheBehavior.MinTTL=0,z}static createApiDistribution($){let{slug:J,environment:Y,albDomainName:Q,customDomain:Z,certificateArn:U,pathPattern:W="/api/*",forwardHeaders:z=["Host","Origin","Authorization","Content-Type","Accept"],forwardCookies:G="all",whitelistedCookies:H,customOriginHeaders:A={}}=$,K=v({slug:J,environment:Y,resourceType:"cdn-api"}),B=S(K),j=Object.entries(A).map(([w,E])=>({HeaderName:w,HeaderValue:E})),X={Id:"ALBOrigin",DomainName:Q,CustomOriginConfig:{HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"],OriginReadTimeout:60,OriginKeepaliveTimeout:60}};if(j.length>0)X.OriginCustomHeaders=j;let O={Forward:G};if(G==="whitelist"&&H)O.WhitelistedNames=H;let _={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:`API CDN for ${K}`,Origins:[X],DefaultCacheBehavior:{TargetOriginId:"ALBOrigin",ViewerProtocolPolicy:"https-only",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,DefaultTTL:0,MaxTTL:0,MinTTL:0,ForwardedValues:{QueryString:!0,Headers:z,Cookies:O}},PriceClass:"PriceClass_100",HttpVersion:"http2"}}};if(Z&&U)_.Properties.DistributionConfig.Aliases=[Z],_.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:U,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};return{distribution:_,logicalId:B}}static createMultiOriginDistribution($){let{slug:J,environment:Y,s3BucketDomainName:Q,albDomainName:Z,apiPathPattern:U="/api/*",customDomain:W,certificateArn:z,customOriginHeaders:G={}}=$,H=v({slug:J,environment:Y,resourceType:"cdn"}),A=S(H),K=`${A}OAC`,B={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${H}-oac`,Description:`Origin Access Control for ${H}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},j=Object.entries(G).map(([w,E])=>({HeaderName:w,HeaderValue:E})),X={Id:"S3Origin",DomainName:Q,OriginAccessControlId:u.Ref(K)},O={Id:"ALBOrigin",DomainName:Z,CustomOriginConfig:{HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"],OriginReadTimeout:60,OriginKeepaliveTimeout:60}};if(j.length>0)O.OriginCustomHeaders=j;let _={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:`Multi-origin CDN for ${H}`,DefaultRootObject:"index.html",Origins:[X,O],DefaultCacheBehavior:{TargetOriginId:"S3Origin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},CacheBehaviors:[{PathPattern:U,TargetOriginId:"ALBOrigin",ViewerProtocolPolicy:"https-only",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,DefaultTTL:0,MaxTTL:0,MinTTL:0,ForwardedValues:{QueryString:!0,Headers:["Host","Origin","Authorization","Content-Type","Accept"],Cookies:{Forward:"all"}}}],PriceClass:"PriceClass_100",HttpVersion:"http2",CustomErrorResponses:[{ErrorCode:404,ResponseCode:200,ResponsePagePath:"/index.html"},{ErrorCode:403,ResponseCode:200,ResponsePagePath:"/index.html"}]}}};if(W&&z)_.Properties.DistributionConfig.Aliases=[W],_.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:z,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};return{distribution:_,originAccessControl:B,logicalId:A,oacLogicalId:K}}static addAlbOrigin($,J){let{originId:Y,domainName:Q,pathPattern:Z,customHeaders:U={},forwardHeaders:W=["Host","Origin","Authorization","Content-Type","Accept"],cacheTtl:z={default:0,max:0,min:0}}=J,G=Object.entries(U).map(([A,K])=>({HeaderName:A,HeaderValue:K})),H={Id:Y,DomainName:Q,CustomOriginConfig:{HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"],OriginReadTimeout:60,OriginKeepaliveTimeout:60}};if(G.length>0)H.OriginCustomHeaders=G;if(!$.Properties.DistributionConfig.Origins)$.Properties.DistributionConfig.Origins=[];if($.Properties.DistributionConfig.Origins.push(H),!$.Properties.DistributionConfig.CacheBehaviors)$.Properties.DistributionConfig.CacheBehaviors=[];return $.Properties.DistributionConfig.CacheBehaviors.push({PathPattern:Z,TargetOriginId:Y,ViewerProtocolPolicy:"https-only",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,DefaultTTL:z.default,MaxTTL:z.max,MinTTL:z.min,ForwardedValues:{QueryString:!0,Headers:W,Cookies:{Forward:"all"}}}),$}static addOriginHeader($,J,Y,Q){let Z=$.Properties.DistributionConfig.Origins?.find((U)=>U.Id===J);if(Z){if(!Z.OriginCustomHeaders)Z.OriginCustomHeaders=[];Z.OriginCustomHeaders.push({HeaderName:Y,HeaderValue:Q})}return $}static EdgeFunctionTemplates={docsOriginRequest:`
4724
+ `.trim();return{lambdaFunction:{Type:"AWS::Lambda::Function",Properties:{FunctionName:Q,Description:"Lambda@Edge origin request handler for docs routing",Runtime:"nodejs20.x",Handler:"index.handler",Role:u.GetAtt(U,"Arn"),Code:{ZipFile:G},MemorySize:128,Timeout:5}},role:z,functionLogicalId:Z,roleLogicalId:U,versionLogicalId:W}}static createDocsDistribution($){let{slug:J,environment:Y,origin:Q,customDomain:Z,certificateArn:U,lambdaEdgeFunctionArn:W}=$,z=j1.createDistribution({slug:J,environment:Y,origin:Q,customDomain:Z,certificateArn:U,comment:`Docs CDN for ${J}`,errorPages:[{errorCode:404,responseCode:404,responsePagePath:"/404.html"},{errorCode:403,responseCode:403,responsePagePath:"/404.html"}]});if(W)j1.addEdgeFunction(z.distribution,"origin-request",W);return z.distribution.Properties.DistributionConfig.DefaultCacheBehavior.DefaultTTL=86400,z.distribution.Properties.DistributionConfig.DefaultCacheBehavior.MaxTTL=604800,z.distribution.Properties.DistributionConfig.DefaultCacheBehavior.MinTTL=0,z}static createApiDistribution($){let{slug:J,environment:Y,albDomainName:Q,customDomain:Z,certificateArn:U,pathPattern:W="/api/*",forwardHeaders:z=["Host","Origin","Authorization","Content-Type","Accept"],forwardCookies:G="all",whitelistedCookies:H,customOriginHeaders:A={}}=$,K=f({slug:J,environment:Y,resourceType:"cdn-api"}),B=S(K),j=Object.entries(A).map(([w,E])=>({HeaderName:w,HeaderValue:E})),X={Id:"ALBOrigin",DomainName:Q,CustomOriginConfig:{HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"],OriginReadTimeout:60,OriginKeepaliveTimeout:60}};if(j.length>0)X.OriginCustomHeaders=j;let O={Forward:G};if(G==="whitelist"&&H)O.WhitelistedNames=H;let _={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:`API CDN for ${K}`,Origins:[X],DefaultCacheBehavior:{TargetOriginId:"ALBOrigin",ViewerProtocolPolicy:"https-only",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,DefaultTTL:0,MaxTTL:0,MinTTL:0,ForwardedValues:{QueryString:!0,Headers:z,Cookies:O}},PriceClass:"PriceClass_100",HttpVersion:"http2"}}};if(Z&&U)_.Properties.DistributionConfig.Aliases=[Z],_.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:U,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};return{distribution:_,logicalId:B}}static createMultiOriginDistribution($){let{slug:J,environment:Y,s3BucketDomainName:Q,albDomainName:Z,apiPathPattern:U="/api/*",customDomain:W,certificateArn:z,customOriginHeaders:G={}}=$,H=f({slug:J,environment:Y,resourceType:"cdn"}),A=S(H),K=`${A}OAC`,B={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${H}-oac`,Description:`Origin Access Control for ${H}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},j=Object.entries(G).map(([w,E])=>({HeaderName:w,HeaderValue:E})),X={Id:"S3Origin",DomainName:Q,OriginAccessControlId:u.Ref(K)},O={Id:"ALBOrigin",DomainName:Z,CustomOriginConfig:{HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"],OriginReadTimeout:60,OriginKeepaliveTimeout:60}};if(j.length>0)O.OriginCustomHeaders=j;let _={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:`Multi-origin CDN for ${H}`,DefaultRootObject:"index.html",Origins:[X,O],DefaultCacheBehavior:{TargetOriginId:"S3Origin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},CacheBehaviors:[{PathPattern:U,TargetOriginId:"ALBOrigin",ViewerProtocolPolicy:"https-only",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,DefaultTTL:0,MaxTTL:0,MinTTL:0,ForwardedValues:{QueryString:!0,Headers:["Host","Origin","Authorization","Content-Type","Accept"],Cookies:{Forward:"all"}}}],PriceClass:"PriceClass_100",HttpVersion:"http2",CustomErrorResponses:[{ErrorCode:404,ResponseCode:200,ResponsePagePath:"/index.html"},{ErrorCode:403,ResponseCode:200,ResponsePagePath:"/index.html"}]}}};if(W&&z)_.Properties.DistributionConfig.Aliases=[W],_.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:z,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};return{distribution:_,originAccessControl:B,logicalId:A,oacLogicalId:K}}static addAlbOrigin($,J){let{originId:Y,domainName:Q,pathPattern:Z,customHeaders:U={},forwardHeaders:W=["Host","Origin","Authorization","Content-Type","Accept"],cacheTtl:z={default:0,max:0,min:0}}=J,G=Object.entries(U).map(([A,K])=>({HeaderName:A,HeaderValue:K})),H={Id:Y,DomainName:Q,CustomOriginConfig:{HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only",OriginSSLProtocols:["TLSv1.2"],OriginReadTimeout:60,OriginKeepaliveTimeout:60}};if(G.length>0)H.OriginCustomHeaders=G;if(!$.Properties.DistributionConfig.Origins)$.Properties.DistributionConfig.Origins=[];if($.Properties.DistributionConfig.Origins.push(H),!$.Properties.DistributionConfig.CacheBehaviors)$.Properties.DistributionConfig.CacheBehaviors=[];return $.Properties.DistributionConfig.CacheBehaviors.push({PathPattern:Z,TargetOriginId:Y,ViewerProtocolPolicy:"https-only",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,DefaultTTL:z.default,MaxTTL:z.max,MinTTL:z.min,ForwardedValues:{QueryString:!0,Headers:W,Cookies:{Forward:"all"}}}),$}static addOriginHeader($,J,Y,Q){let Z=$.Properties.DistributionConfig.Origins?.find((U)=>U.Id===J);if(Z){if(!Z.OriginCustomHeaders)Z.OriginCustomHeaders=[];Z.OriginCustomHeaders.push({HeaderName:Y,HeaderValue:Q})}return $}static EdgeFunctionTemplates={docsOriginRequest:`
4725
4725
  'use strict';
4726
4726
  exports.handler = async (event) => {
4727
4727
  const request = event.Records[0].cf.request;
@@ -4794,7 +4794,7 @@ exports.handler = async (event) => {
4794
4794
 
4795
4795
  return request;
4796
4796
  };
4797
- `.trim()};static Config={ttl:($)=>{let{min:J=0,max:Y=86400,default:Q=86400}=$;return{MinTTL:J,MaxTTL:Y,DefaultTTL:Q}},cookies:($,J)=>{let Y={Forward:$==="allowList"?"whitelist":$};if($==="allowList"&&J)Y.WhitelistedNames=J;return Y},allowedMethods:($)=>{let J={ALL:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return J[$]||J.GET_HEAD},cachedMethods:($)=>{let J={GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return J[$]||J.GET_HEAD},ttlPresets:{static:{min:0,max:31536000,default:31536000},dynamic:{min:0,max:0,default:0},api:{min:0,max:3600,default:60},html:{min:0,max:86400,default:86400},images:{min:0,max:604800,default:604800}},cacheBehavior:($)=>{let{ttl:J={min:0,max:86400,default:86400},cookies:Y="none",allowedCookies:Q,allowedMethods:Z="GET_HEAD",cachedMethods:U="GET_HEAD",compress:W=!0,forwardQueryString:z=!0,forwardHeaders:G=[]}=$;return{MinTTL:J.min,MaxTTL:J.max,DefaultTTL:J.default,Compress:W,AllowedMethods:j1.Config.allowedMethods(Z),CachedMethods:j1.Config.cachedMethods(U),ForwardedValues:{QueryString:z,Headers:G,Cookies:j1.Config.cookies(Y,Q)}}}};static applyConfig($,J){let Y=$.Properties.DistributionConfig.DefaultCacheBehavior;if(J.ttl)Y.MinTTL=J.ttl.min,Y.MaxTTL=J.ttl.max,Y.DefaultTTL=J.ttl.default;if(J.compress!==void 0)Y.Compress=J.compress;if(J.allowedMethods)Y.AllowedMethods=j1.Config.allowedMethods(J.allowedMethods);if(J.cachedMethods)Y.CachedMethods=j1.Config.cachedMethods(J.cachedMethods);if(J.cookies){if(!Y.ForwardedValues)Y.ForwardedValues={QueryString:!0};Y.ForwardedValues.Cookies=j1.Config.cookies(J.cookies,J.allowedCookies)}return $}};p0=class p0{static createHostedZone($){let{domain:J,slug:Y,environment:Q,comment:Z}=$,U=v({slug:Y,environment:Q,resourceType:"hostedzone"}),W=S(`${U}-${J.replace(/\./g,"")}`);return{zone:{Type:"AWS::Route53::HostedZone",Properties:{Name:J,HostedZoneConfig:{Comment:Z||`Hosted zone for ${J}`}}},logicalId:W}}static createRecord($){let{hostedZoneId:J,hostedZoneName:Y,name:Q,type:Z,ttl:U,values:W,aliasTarget:z}=$,G=S(`record-${Q.replace(/\./g,"")}-${Z}`),H={Type:"AWS::Route53::RecordSet",Properties:{Name:Q,Type:Z}};if(J)H.Properties.HostedZoneId=J;else if(Y)H.Properties.HostedZoneName=Y;if(z)H.Properties.AliasTarget={DNSName:z.dnsName,HostedZoneId:z.hostedZoneId,EvaluateTargetHealth:z.evaluateTargetHealth??!1};else H.Properties.TTL=U||300,H.Properties.ResourceRecords=W||[];return{record:H,logicalId:G}}static createCloudFrontAlias($,J,Y){return p0.createRecord({hostedZoneId:Y,name:$,type:"A",aliasTarget:{dnsName:J,hostedZoneId:"Z2FDTNDATAQYW2",evaluateTargetHealth:!1}})}static createAlbAlias($,J,Y,Q){return p0.createRecord({hostedZoneId:Q,name:$,type:"A",aliasTarget:{dnsName:J,hostedZoneId:Y,evaluateTargetHealth:!0}})}static createCname($,J,Y,Q=300){return p0.createRecord({hostedZoneId:Y,name:$,type:"CNAME",ttl:Q,values:[J]})}static createWwwRedirect($,J){return p0.createRecord({hostedZoneId:J,name:`www.${$}`,type:"CNAME",ttl:300,values:[$]})}static createMxRecords($,J,Y,Q=300){return p0.createRecord({hostedZoneId:Y,name:$,type:"MX",ttl:Q,values:J.map((Z)=>`${Z.priority} ${Z.server}`)})}static createTxtRecord($,J,Y,Q=300){return p0.createRecord({hostedZoneId:Y,name:$,type:"TXT",ttl:Q,values:[`"${J}"`]})}static createSpfRecord($,J,Y){return p0.createTxtRecord($,J,Y)}static createDmarcRecord($,J,Y,Q){let Z=`v=DMARC1; p=${J}; rua=mailto:${Y}`;return p0.createTxtRecord(`_dmarc.${$}`,Z,Q)}static createS3WebsiteAlias($,J,Y,Q){return p0.createRecord({hostedZoneId:Q,name:$,type:"A",aliasTarget:{dnsName:J,hostedZoneId:Y,evaluateTargetHealth:!1}})}static S3WebsiteHostedZoneIds={"us-east-1":"Z3AQBSTGFYJSTF","us-east-2":"Z2O1EMRO9K5GLX","us-west-1":"Z2F56UZL2M1ACD","us-west-2":"Z3BJ6K6RIION7M","af-south-1":"Z83WF9RJE8B12","ap-east-1":"ZNB98KWMFR0R6","ap-south-1":"Z11RGJOFQNVJUP","ap-south-2":"Z02976202B4EZMXIPMXF7","ap-northeast-1":"Z2M4EHUR26P7ZW","ap-northeast-2":"Z3W03O7B5YMIYP","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"Z3O0J2DXBE1FTB","ap-southeast-2":"Z1WCIBER6CPFUU","ap-southeast-3":"Z01613992JD795ZI93075","ca-central-1":"Z1QDHH18159H29","eu-central-1":"Z21DNDUVLTQW6Q","eu-central-2":"Z030506016YDQGETNASS","eu-west-1":"Z1BKCTXD74EZPE","eu-west-2":"Z3GKZC51ZF0DB4","eu-west-3":"Z3R1K369G5AVDG","eu-north-1":"Z3BAZG2TWCNX0D","eu-south-1":"Z30OZKI7KPW7MI","eu-south-2":"Z0081959F7139GRJC19J","me-south-1":"Z1MPMWCPA7YB62","me-central-1":"Z06143092I8HRBER9VXCO","sa-east-1":"Z7KQH4QJS55SO"};static getS3WebsiteEndpoint($,J){return`${$}.s3-website-${J}.amazonaws.com`}static createStoreRecord($,J,Y){return p0.createCname(`store.${$}`,J,Y)}static createApiRecord($,J,Y){return p0.createCname(`api.${$}`,J,Y)}static createDocsRecord($,J,Y){return p0.createCname(`docs.${$}`,J,Y)}static CloudFrontHostedZoneId="Z2FDTNDATAQYW2"};L0=class L0{static createCertificate($){let{domain:J,subdomains:Y=[],slug:Q,environment:Z,validationMethod:U="DNS",hostedZoneId:W}=$,z=v({slug:Q,environment:Z,resourceType:"acm"}),G=S(`${z}-${J.replace(/\./g,"")}`),H=[J];for(let K of Y)if(K==="*")H.push(`*.${J}`);else H.push(`${K}.${J}`);let A={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:J,SubjectAlternativeNames:H,ValidationMethod:U}};if(U==="DNS"&&W)A.Properties.DomainValidationOptions=H.map((K)=>({DomainName:K,HostedZoneId:W}));return{certificate:A,logicalId:G}}static createKmsKey($){let{description:J,slug:Y,environment:Q,enableRotation:Z=!0,multiRegion:U=!1}=$,W=v({slug:Y,environment:Q,resourceType:"kms"}),z=S(W),G={Version:"2012-10-17",Statement:[{Sid:"Enable IAM User Permissions",Effect:"Allow",Principal:{AWS:u.Sub("arn:aws:iam::${AWS::AccountId}:root")},Action:"kms:*",Resource:"*"},{Sid:"Allow services to use the key",Effect:"Allow",Principal:{Service:["s3.amazonaws.com","cloudfront.amazonaws.com","logs.amazonaws.com","secretsmanager.amazonaws.com"]},Action:["kms:Decrypt","kms:GenerateDataKey"],Resource:"*"}]},H={Type:"AWS::KMS::Key",Properties:{Description:J,Enabled:!0,EnableKeyRotation:Z,KeyPolicy:G,KeySpec:"SYMMETRIC_DEFAULT",KeyUsage:"ENCRYPT_DECRYPT",MultiRegion:U}},A=S(`${W}-alias`),K={Type:"AWS::KMS::Alias",Properties:{AliasName:`alias/${Y}-${Q}`,TargetKeyId:u.Ref(z)}};return{key:H,alias:K,logicalId:z,aliasId:A}}static createFirewall($){let{slug:J,environment:Y,scope:Q="CLOUDFRONT",defaultAction:Z="allow"}=$,U=v({slug:J,environment:Y,resourceType:"waf"}),W=S(U);return{webAcl:{Type:"AWS::WAFv2::WebACL",Properties:{Name:U,Scope:Q,DefaultAction:Z==="allow"?{Allow:{}}:{Block:{}},Description:`WAF for ${J} ${Y}`,Rules:[],VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${U}-metric`}}},logicalId:W}}static setRateLimit($,J){if(!$.Properties.Rules)$.Properties.Rules=[];return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{RateBasedStatement:{Limit:J.requestsPerWindow,AggregateKeyType:J.aggregateKeyType||"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static blockCountries($,J){if(!$.Properties.Rules)$.Properties.Rules=[];return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{GeoMatchStatement:{CountryCodes:J.countryCodes}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static blockIpAddresses($,J,Y,Q){let Z=v({slug:Y,environment:Q,resourceType:"ipset"}),U=S(`${Z}-${J.name}`),W={Type:"AWS::WAFv2::IPSet",Properties:{Name:`${Z}-${J.name}`,Scope:$.Properties.Scope,IPAddressVersion:J.ipVersion||"IPV4",Addresses:J.ipAddresses,Description:`Blocked IPs for ${J.name}`}};if(!$.Properties.Rules)$.Properties.Rules=[];return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{IPSetReferenceStatement:{Arn:u.GetAtt(U,"Arn")}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),{webAcl:$,ipSet:W,ipSetLogicalId:U}}static addManagedRules($,J){if(!$.Properties.Rules)$.Properties.Rules=[];let Y={ManagedRuleGroupStatement:{VendorName:J.vendorName,Name:J.ruleName}};if(J.excludedRules&&J.excludedRules.length>0)Y.ManagedRuleGroupStatement.ExcludedRules=J.excludedRules.map((Q)=>({Name:Q}));return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:Y,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static ManagedRuleGroups={CoreRuleSet:{vendorName:"AWS",ruleName:"AWSManagedRulesCommonRuleSet"},KnownBadInputs:{vendorName:"AWS",ruleName:"AWSManagedRulesKnownBadInputsRuleSet"},SqlDatabase:{vendorName:"AWS",ruleName:"AWSManagedRulesSQLiRuleSet"},LinuxOS:{vendorName:"AWS",ruleName:"AWSManagedRulesLinuxRuleSet"},PosixOS:{vendorName:"AWS",ruleName:"AWSManagedRulesUnixRuleSet"},AmazonIpReputation:{vendorName:"AWS",ruleName:"AWSManagedRulesAmazonIpReputationList"},AnonymousIpList:{vendorName:"AWS",ruleName:"AWSManagedRulesAnonymousIpList"},BotControl:{vendorName:"AWS",ruleName:"AWSManagedRulesBotControlRuleSet"}};static setPathRateLimit($,J){if(!$.Properties.Rules)$.Properties.Rules=[];let Y=J.paths.map((Q)=>({SearchString:Q,FieldToMatch:{UriPath:{}},TextTransformation:[{Priority:0,Type:"LOWERCASE"}],PositionalConstraint:"STARTS_WITH"}));return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{RateBasedStatement:{Limit:J.requestsPerWindow,AggregateKeyType:J.aggregateKeyType||"IP",ScopeDownStatement:{OrStatement:{Statements:Y.map((Q)=>({ByteMatchStatement:Q}))}}}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static setHeaderRateLimit($,J){if(!$.Properties.Rules)$.Properties.Rules=[];let Y={RateBasedStatement:{Limit:J.requestsPerWindow,AggregateKeyType:"CUSTOM_KEYS",CustomKeys:[{Header:{Name:J.headerName,TextTransformations:[{Priority:0,Type:"NONE"}]}}]}};if(J.headerValue)Y.RateBasedStatement.ScopeDownStatement={ByteMatchStatement:{SearchString:J.headerValue,FieldToMatch:{SingleHeader:{Name:J.headerName}},TextTransformation:[{Priority:0,Type:"NONE"}],PositionalConstraint:"EXACTLY"}};return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:Y,Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static protectLoginEndpoint($,J){let{loginPaths:Y,priority:Q,requestsPerMinute:Z=10}=J;return L0.setPathRateLimit($,{name:"LoginRateLimit",priority:Q,requestsPerWindow:Z*5,paths:Y}),$}static protectApiEndpoints($,J){let{apiPaths:Y,priority:Q,requestsPerMinute:Z=100}=J;return L0.setPathRateLimit($,{name:"ApiRateLimit",priority:Q,requestsPerWindow:Z*5,paths:Y}),$}static createProtectedFirewall($){let{slug:J,environment:Y,scope:Q="CLOUDFRONT",enableBotControl:Z=!1,enableRateLimiting:U=!0,rateLimitPerMinute:W=2000}=$,{webAcl:z,logicalId:G}=L0.createFirewall({slug:J,environment:Y,scope:Q,defaultAction:"allow"}),H=0;if(z=L0.addManagedRules(z,{name:"AWSIPReputationList",priority:H++,...L0.ManagedRuleGroups.AmazonIpReputation}),z=L0.addManagedRules(z,{name:"AWSAnonymousIPList",priority:H++,...L0.ManagedRuleGroups.AnonymousIpList}),z=L0.addManagedRules(z,{name:"AWSCoreRuleSet",priority:H++,...L0.ManagedRuleGroups.CoreRuleSet}),z=L0.addManagedRules(z,{name:"AWSKnownBadInputs",priority:H++,...L0.ManagedRuleGroups.KnownBadInputs}),z=L0.addManagedRules(z,{name:"AWSSQLi",priority:H++,...L0.ManagedRuleGroups.SqlDatabase}),Z)z=L0.addManagedRules(z,{name:"AWSBotControl",priority:H++,...L0.ManagedRuleGroups.BotControl});if(U)z=L0.setRateLimit(z,{name:"GlobalRateLimit",priority:H++,requestsPerWindow:W*5});return{webAcl:z,logicalId:G}}static RateLimitPresets={STANDARD:2000,HIGH_TRAFFIC:1e4,STRICT:100,LOGIN:10,API:100}};n=class n{static createServer($){let{slug:J,environment:Y,instanceType:Q="t3.micro",imageId:Z="ami-0f3caa1cf4417e51b",keyName:U,securityGroupIds:W,subnetId:z,userData:G,volumeSize:H=20,volumeType:A="gp3",encrypted:K=!0}=$,B=v({slug:J,environment:Y,resourceType:"ec2"}),j=S(B),X={Type:"AWS::EC2::Instance",Properties:{ImageId:Z,InstanceType:Q,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:Y}]}};if(U)X.Properties.KeyName=U;if(W)X.Properties.SecurityGroupIds=W;if(z)X.Properties.SubnetId=z;if(G)X.Properties.UserData=u.Base64(G);return X.Properties.BlockDeviceMappings=[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:H,VolumeType:A,Encrypted:K,DeleteOnTermination:!0}}],{instance:X,logicalId:j}}static createSecurityGroup($){let{slug:J,environment:Y,vpcId:Q,description:Z,ingress:U=[],egress:W=[]}=$,z=v({slug:J,environment:Y,resourceType:"sg"}),G=S(z),H={Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:Z||`Security group for ${J} ${Y}`,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(Q)H.Properties.VpcId=Q;if(U.length>0)H.Properties.SecurityGroupIngress=U.map((A)=>({IpProtocol:A.protocol,FromPort:A.fromPort,ToPort:A.toPort,CidrIp:A.cidr,SourceSecurityGroupId:A.sourceSecurityGroupId}));if(W.length>0)H.Properties.SecurityGroupEgress=W.map((A)=>({IpProtocol:A.protocol,FromPort:A.fromPort,ToPort:A.toPort,CidrIp:A.cidr,DestinationSecurityGroupId:A.sourceSecurityGroupId}));return{securityGroup:H,logicalId:G}}static createWebServerSecurityGroup($,J,Y){return n.createSecurityGroup({slug:$,environment:J,vpcId:Y,description:"Security group for web servers - HTTP, HTTPS, SSH",ingress:[{protocol:"tcp",fromPort:80,toPort:80,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:443,toPort:443,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:22,toPort:22,cidr:"0.0.0.0/0"}],egress:[{protocol:"-1",fromPort:0,toPort:0,cidr:"0.0.0.0/0"}]})}static createLoadBalancer($){let{slug:J,environment:Y,scheme:Q="internet-facing",subnets:Z,securityGroups:U,type:W="application"}=$,z=v({slug:J,environment:Y,resourceType:"alb"}),G=S(z),H={Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:z,Scheme:Q,Type:W,Subnets:Z,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(U)H.Properties.SecurityGroups=U;return{loadBalancer:H,logicalId:G}}static createTargetGroup($){let{slug:J,environment:Y,port:Q,protocol:Z="HTTP",vpcId:U,targetType:W="ip",healthCheckPath:z="/",healthCheckInterval:G=30,healthCheckTimeout:H=5,healthyThreshold:A=2,unhealthyThreshold:K=3}=$,B=v({slug:J,environment:Y,resourceType:"tg"}),j=S(B);return{targetGroup:{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:B,Port:Q,Protocol:Z,VpcId:U,TargetType:W,HealthCheckEnabled:!0,HealthCheckProtocol:Z,HealthCheckPath:z,HealthCheckIntervalSeconds:G,HealthCheckTimeoutSeconds:H,HealthyThresholdCount:A,UnhealthyThresholdCount:K,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:Y}]}},logicalId:j}}static createListener($,J){let{port:Y,protocol:Q="HTTP",certificateArn:Z,defaultTargetGroupArn:U}=J,W=S(`listener-${$}-${Y}`),z={Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:u.Ref($),Port:Y,Protocol:Q,DefaultActions:[{Type:"forward",TargetGroupArn:U}]}};if(Q==="HTTPS"&&Z)z.Properties.Certificates=[{CertificateArn:Z}],z.Properties.SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06";return{listener:z,logicalId:W}}static createEcsCluster($,J){let Y=v({slug:$,environment:J,resourceType:"ecs-cluster"}),Q=S(Y);return{cluster:{Type:"AWS::ECS::Cluster",Properties:{ClusterName:Y,Tags:[{Key:"Name",Value:Y},{Key:"Environment",Value:J}]}},logicalId:Q}}static createFargateService($){let{slug:J,environment:Y,image:Q,cpu:Z="256",memory:U="512",desiredCount:W=1,containerPort:z=8080,environmentVariables:G={},secrets:H=[],healthCheck:A,logGroup:K,subnets:B,securityGroups:j,targetGroupArn:X}=$,{cluster:O,logicalId:_}=n.createEcsCluster(J,Y),w=v({slug:J,environment:Y,resourceType:"fargate"}),E=S(`${w}-execution-role`),M={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]}},T=S(`${w}-task-role`),D={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]}}},N=S(`${w}-task`),x={Type:"AWS::ECS::TaskDefinition",Properties:{Family:w,TaskRoleArn:u.GetAtt(T,"Arn"),ExecutionRoleArn:u.GetAtt(E,"Arn"),NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:Z,Memory:U,ContainerDefinitions:[{Name:J,Image:Q,Essential:!0,PortMappings:[{ContainerPort:z,Protocol:"tcp"}],Environment:Object.entries(G).map(([b,I])=>({Name:b,Value:I})),Secrets:H.map((b)=>({Name:b.name,ValueFrom:b.valueFrom}))}],Tags:[{Key:"Name",Value:w},{Key:"Environment",Value:Y}]}};if(A)x.Properties.ContainerDefinitions[0].HealthCheck={Command:A.command,Interval:A.interval||30,Timeout:A.timeout||5,Retries:A.retries||3,StartPeriod:60};if(K)x.Properties.ContainerDefinitions[0].LogConfiguration={LogDriver:"awslogs",Options:{"awslogs-group":K,"awslogs-region":u.Ref("AWS::Region"),"awslogs-stream-prefix":J}};let h=S(`${w}-service`),k={Type:"AWS::ECS::Service",Properties:{ServiceName:w,Cluster:u.Ref(_),TaskDefinition:u.Ref(N),DesiredCount:W,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{Subnets:B,SecurityGroups:j,AssignPublicIp:"ENABLED"}},Tags:[{Key:"Name",Value:w},{Key:"Environment",Value:Y}]}};if(X)k.Properties.LoadBalancers=[{TargetGroupArn:X,ContainerName:J,ContainerPort:z}];return{cluster:O,taskDefinition:x,service:k,taskRole:D,executionRole:M,clusterLogicalId:_,taskDefinitionLogicalId:N,serviceLogicalId:h,taskRoleLogicalId:T,executionRoleLogicalId:E}}static createLambdaFunction($){let{slug:J,environment:Y,runtime:Q,handler:Z,code:U,timeout:W=30,memorySize:z=128,environmentVariables:G={},vpcConfig:H}=$,A=v({slug:J,environment:Y,resourceType:"lambda"}),K=S(A),B=S(`${A}-role`),j={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}};if(H)j.Properties.ManagedPolicyArns.push("arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole");let X={Type:"AWS::Lambda::Function",Properties:{FunctionName:A,Runtime:Q,Role:u.GetAtt(B,"Arn"),Handler:Z,Code:{...U.s3Bucket&&{S3Bucket:U.s3Bucket},...U.s3Key&&{S3Key:U.s3Key},...U.zipFile&&{ZipFile:U.zipFile}},Timeout:W,MemorySize:z,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:Y}]}};if(Object.keys(G).length>0)X.Properties.Environment={Variables:G};if(H)X.Properties.VpcConfig={SecurityGroupIds:H.securityGroupIds,SubnetIds:H.subnetIds};return{lambdaFunction:X,role:j,logicalId:K,roleLogicalId:B}}static generateNodeServerUserData($={}){let{nodeVersion:J="20",appRepo:Y,environment:Q={}}=$,Z=Object.entries(Q).map(([U,W])=>`echo "export ${U}='${W}'" >> /etc/environment`).join(`
4797
+ `.trim()};static Config={ttl:($)=>{let{min:J=0,max:Y=86400,default:Q=86400}=$;return{MinTTL:J,MaxTTL:Y,DefaultTTL:Q}},cookies:($,J)=>{let Y={Forward:$==="allowList"?"whitelist":$};if($==="allowList"&&J)Y.WhitelistedNames=J;return Y},allowedMethods:($)=>{let J={ALL:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return J[$]||J.GET_HEAD},cachedMethods:($)=>{let J={GET_HEAD:["GET","HEAD"],GET_HEAD_OPTIONS:["GET","HEAD","OPTIONS"]};return J[$]||J.GET_HEAD},ttlPresets:{static:{min:0,max:31536000,default:31536000},dynamic:{min:0,max:0,default:0},api:{min:0,max:3600,default:60},html:{min:0,max:86400,default:86400},images:{min:0,max:604800,default:604800}},cacheBehavior:($)=>{let{ttl:J={min:0,max:86400,default:86400},cookies:Y="none",allowedCookies:Q,allowedMethods:Z="GET_HEAD",cachedMethods:U="GET_HEAD",compress:W=!0,forwardQueryString:z=!0,forwardHeaders:G=[]}=$;return{MinTTL:J.min,MaxTTL:J.max,DefaultTTL:J.default,Compress:W,AllowedMethods:j1.Config.allowedMethods(Z),CachedMethods:j1.Config.cachedMethods(U),ForwardedValues:{QueryString:z,Headers:G,Cookies:j1.Config.cookies(Y,Q)}}}};static applyConfig($,J){let Y=$.Properties.DistributionConfig.DefaultCacheBehavior;if(J.ttl)Y.MinTTL=J.ttl.min,Y.MaxTTL=J.ttl.max,Y.DefaultTTL=J.ttl.default;if(J.compress!==void 0)Y.Compress=J.compress;if(J.allowedMethods)Y.AllowedMethods=j1.Config.allowedMethods(J.allowedMethods);if(J.cachedMethods)Y.CachedMethods=j1.Config.cachedMethods(J.cachedMethods);if(J.cookies){if(!Y.ForwardedValues)Y.ForwardedValues={QueryString:!0};Y.ForwardedValues.Cookies=j1.Config.cookies(J.cookies,J.allowedCookies)}return $}};p0=class p0{static createHostedZone($){let{domain:J,slug:Y,environment:Q,comment:Z}=$,U=f({slug:Y,environment:Q,resourceType:"hostedzone"}),W=S(`${U}-${J.replace(/\./g,"")}`);return{zone:{Type:"AWS::Route53::HostedZone",Properties:{Name:J,HostedZoneConfig:{Comment:Z||`Hosted zone for ${J}`}}},logicalId:W}}static createRecord($){let{hostedZoneId:J,hostedZoneName:Y,name:Q,type:Z,ttl:U,values:W,aliasTarget:z}=$,G=S(`record-${Q.replace(/\./g,"")}-${Z}`),H={Type:"AWS::Route53::RecordSet",Properties:{Name:Q,Type:Z}};if(J)H.Properties.HostedZoneId=J;else if(Y)H.Properties.HostedZoneName=Y;if(z)H.Properties.AliasTarget={DNSName:z.dnsName,HostedZoneId:z.hostedZoneId,EvaluateTargetHealth:z.evaluateTargetHealth??!1};else H.Properties.TTL=U||300,H.Properties.ResourceRecords=W||[];return{record:H,logicalId:G}}static createCloudFrontAlias($,J,Y){return p0.createRecord({hostedZoneId:Y,name:$,type:"A",aliasTarget:{dnsName:J,hostedZoneId:"Z2FDTNDATAQYW2",evaluateTargetHealth:!1}})}static createAlbAlias($,J,Y,Q){return p0.createRecord({hostedZoneId:Q,name:$,type:"A",aliasTarget:{dnsName:J,hostedZoneId:Y,evaluateTargetHealth:!0}})}static createCname($,J,Y,Q=300){return p0.createRecord({hostedZoneId:Y,name:$,type:"CNAME",ttl:Q,values:[J]})}static createWwwRedirect($,J){return p0.createRecord({hostedZoneId:J,name:`www.${$}`,type:"CNAME",ttl:300,values:[$]})}static createMxRecords($,J,Y,Q=300){return p0.createRecord({hostedZoneId:Y,name:$,type:"MX",ttl:Q,values:J.map((Z)=>`${Z.priority} ${Z.server}`)})}static createTxtRecord($,J,Y,Q=300){return p0.createRecord({hostedZoneId:Y,name:$,type:"TXT",ttl:Q,values:[`"${J}"`]})}static createSpfRecord($,J,Y){return p0.createTxtRecord($,J,Y)}static createDmarcRecord($,J,Y,Q){let Z=`v=DMARC1; p=${J}; rua=mailto:${Y}`;return p0.createTxtRecord(`_dmarc.${$}`,Z,Q)}static createS3WebsiteAlias($,J,Y,Q){return p0.createRecord({hostedZoneId:Q,name:$,type:"A",aliasTarget:{dnsName:J,hostedZoneId:Y,evaluateTargetHealth:!1}})}static S3WebsiteHostedZoneIds={"us-east-1":"Z3AQBSTGFYJSTF","us-east-2":"Z2O1EMRO9K5GLX","us-west-1":"Z2F56UZL2M1ACD","us-west-2":"Z3BJ6K6RIION7M","af-south-1":"Z83WF9RJE8B12","ap-east-1":"ZNB98KWMFR0R6","ap-south-1":"Z11RGJOFQNVJUP","ap-south-2":"Z02976202B4EZMXIPMXF7","ap-northeast-1":"Z2M4EHUR26P7ZW","ap-northeast-2":"Z3W03O7B5YMIYP","ap-northeast-3":"Z2YQB5RD63NC85","ap-southeast-1":"Z3O0J2DXBE1FTB","ap-southeast-2":"Z1WCIBER6CPFUU","ap-southeast-3":"Z01613992JD795ZI93075","ca-central-1":"Z1QDHH18159H29","eu-central-1":"Z21DNDUVLTQW6Q","eu-central-2":"Z030506016YDQGETNASS","eu-west-1":"Z1BKCTXD74EZPE","eu-west-2":"Z3GKZC51ZF0DB4","eu-west-3":"Z3R1K369G5AVDG","eu-north-1":"Z3BAZG2TWCNX0D","eu-south-1":"Z30OZKI7KPW7MI","eu-south-2":"Z0081959F7139GRJC19J","me-south-1":"Z1MPMWCPA7YB62","me-central-1":"Z06143092I8HRBER9VXCO","sa-east-1":"Z7KQH4QJS55SO"};static getS3WebsiteEndpoint($,J){return`${$}.s3-website-${J}.amazonaws.com`}static createStoreRecord($,J,Y){return p0.createCname(`store.${$}`,J,Y)}static createApiRecord($,J,Y){return p0.createCname(`api.${$}`,J,Y)}static createDocsRecord($,J,Y){return p0.createCname(`docs.${$}`,J,Y)}static CloudFrontHostedZoneId="Z2FDTNDATAQYW2"};L0=class L0{static createCertificate($){let{domain:J,subdomains:Y=[],slug:Q,environment:Z,validationMethod:U="DNS",hostedZoneId:W}=$,z=f({slug:Q,environment:Z,resourceType:"acm"}),G=S(`${z}-${J.replace(/\./g,"")}`),H=[J];for(let K of Y)if(K==="*")H.push(`*.${J}`);else H.push(`${K}.${J}`);let A={Type:"AWS::CertificateManager::Certificate",Properties:{DomainName:J,SubjectAlternativeNames:H,ValidationMethod:U}};if(U==="DNS"&&W)A.Properties.DomainValidationOptions=H.map((K)=>({DomainName:K,HostedZoneId:W}));return{certificate:A,logicalId:G}}static createKmsKey($){let{description:J,slug:Y,environment:Q,enableRotation:Z=!0,multiRegion:U=!1}=$,W=f({slug:Y,environment:Q,resourceType:"kms"}),z=S(W),G={Version:"2012-10-17",Statement:[{Sid:"Enable IAM User Permissions",Effect:"Allow",Principal:{AWS:u.Sub("arn:aws:iam::${AWS::AccountId}:root")},Action:"kms:*",Resource:"*"},{Sid:"Allow services to use the key",Effect:"Allow",Principal:{Service:["s3.amazonaws.com","cloudfront.amazonaws.com","logs.amazonaws.com","secretsmanager.amazonaws.com"]},Action:["kms:Decrypt","kms:GenerateDataKey"],Resource:"*"}]},H={Type:"AWS::KMS::Key",Properties:{Description:J,Enabled:!0,EnableKeyRotation:Z,KeyPolicy:G,KeySpec:"SYMMETRIC_DEFAULT",KeyUsage:"ENCRYPT_DECRYPT",MultiRegion:U}},A=S(`${W}-alias`),K={Type:"AWS::KMS::Alias",Properties:{AliasName:`alias/${Y}-${Q}`,TargetKeyId:u.Ref(z)}};return{key:H,alias:K,logicalId:z,aliasId:A}}static createFirewall($){let{slug:J,environment:Y,scope:Q="CLOUDFRONT",defaultAction:Z="allow"}=$,U=f({slug:J,environment:Y,resourceType:"waf"}),W=S(U);return{webAcl:{Type:"AWS::WAFv2::WebACL",Properties:{Name:U,Scope:Q,DefaultAction:Z==="allow"?{Allow:{}}:{Block:{}},Description:`WAF for ${J} ${Y}`,Rules:[],VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${U}-metric`}}},logicalId:W}}static setRateLimit($,J){if(!$.Properties.Rules)$.Properties.Rules=[];return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{RateBasedStatement:{Limit:J.requestsPerWindow,AggregateKeyType:J.aggregateKeyType||"IP"}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static blockCountries($,J){if(!$.Properties.Rules)$.Properties.Rules=[];return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{GeoMatchStatement:{CountryCodes:J.countryCodes}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static blockIpAddresses($,J,Y,Q){let Z=f({slug:Y,environment:Q,resourceType:"ipset"}),U=S(`${Z}-${J.name}`),W={Type:"AWS::WAFv2::IPSet",Properties:{Name:`${Z}-${J.name}`,Scope:$.Properties.Scope,IPAddressVersion:J.ipVersion||"IPV4",Addresses:J.ipAddresses,Description:`Blocked IPs for ${J.name}`}};if(!$.Properties.Rules)$.Properties.Rules=[];return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{IPSetReferenceStatement:{Arn:u.GetAtt(U,"Arn")}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),{webAcl:$,ipSet:W,ipSetLogicalId:U}}static addManagedRules($,J){if(!$.Properties.Rules)$.Properties.Rules=[];let Y={ManagedRuleGroupStatement:{VendorName:J.vendorName,Name:J.ruleName}};if(J.excludedRules&&J.excludedRules.length>0)Y.ManagedRuleGroupStatement.ExcludedRules=J.excludedRules.map((Q)=>({Name:Q}));return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:Y,VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static ManagedRuleGroups={CoreRuleSet:{vendorName:"AWS",ruleName:"AWSManagedRulesCommonRuleSet"},KnownBadInputs:{vendorName:"AWS",ruleName:"AWSManagedRulesKnownBadInputsRuleSet"},SqlDatabase:{vendorName:"AWS",ruleName:"AWSManagedRulesSQLiRuleSet"},LinuxOS:{vendorName:"AWS",ruleName:"AWSManagedRulesLinuxRuleSet"},PosixOS:{vendorName:"AWS",ruleName:"AWSManagedRulesUnixRuleSet"},AmazonIpReputation:{vendorName:"AWS",ruleName:"AWSManagedRulesAmazonIpReputationList"},AnonymousIpList:{vendorName:"AWS",ruleName:"AWSManagedRulesAnonymousIpList"},BotControl:{vendorName:"AWS",ruleName:"AWSManagedRulesBotControlRuleSet"}};static setPathRateLimit($,J){if(!$.Properties.Rules)$.Properties.Rules=[];let Y=J.paths.map((Q)=>({SearchString:Q,FieldToMatch:{UriPath:{}},TextTransformation:[{Priority:0,Type:"LOWERCASE"}],PositionalConstraint:"STARTS_WITH"}));return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:{RateBasedStatement:{Limit:J.requestsPerWindow,AggregateKeyType:J.aggregateKeyType||"IP",ScopeDownStatement:{OrStatement:{Statements:Y.map((Q)=>({ByteMatchStatement:Q}))}}}},Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static setHeaderRateLimit($,J){if(!$.Properties.Rules)$.Properties.Rules=[];let Y={RateBasedStatement:{Limit:J.requestsPerWindow,AggregateKeyType:"CUSTOM_KEYS",CustomKeys:[{Header:{Name:J.headerName,TextTransformations:[{Priority:0,Type:"NONE"}]}}]}};if(J.headerValue)Y.RateBasedStatement.ScopeDownStatement={ByteMatchStatement:{SearchString:J.headerValue,FieldToMatch:{SingleHeader:{Name:J.headerName}},TextTransformation:[{Priority:0,Type:"NONE"}],PositionalConstraint:"EXACTLY"}};return $.Properties.Rules.push({Name:J.name,Priority:J.priority,Statement:Y,Action:{Block:{}},VisibilityConfig:{SampledRequestsEnabled:!0,CloudWatchMetricsEnabled:!0,MetricName:`${J.name}-metric`}}),$}static protectLoginEndpoint($,J){let{loginPaths:Y,priority:Q,requestsPerMinute:Z=10}=J;return L0.setPathRateLimit($,{name:"LoginRateLimit",priority:Q,requestsPerWindow:Z*5,paths:Y}),$}static protectApiEndpoints($,J){let{apiPaths:Y,priority:Q,requestsPerMinute:Z=100}=J;return L0.setPathRateLimit($,{name:"ApiRateLimit",priority:Q,requestsPerWindow:Z*5,paths:Y}),$}static createProtectedFirewall($){let{slug:J,environment:Y,scope:Q="CLOUDFRONT",enableBotControl:Z=!1,enableRateLimiting:U=!0,rateLimitPerMinute:W=2000}=$,{webAcl:z,logicalId:G}=L0.createFirewall({slug:J,environment:Y,scope:Q,defaultAction:"allow"}),H=0;if(z=L0.addManagedRules(z,{name:"AWSIPReputationList",priority:H++,...L0.ManagedRuleGroups.AmazonIpReputation}),z=L0.addManagedRules(z,{name:"AWSAnonymousIPList",priority:H++,...L0.ManagedRuleGroups.AnonymousIpList}),z=L0.addManagedRules(z,{name:"AWSCoreRuleSet",priority:H++,...L0.ManagedRuleGroups.CoreRuleSet}),z=L0.addManagedRules(z,{name:"AWSKnownBadInputs",priority:H++,...L0.ManagedRuleGroups.KnownBadInputs}),z=L0.addManagedRules(z,{name:"AWSSQLi",priority:H++,...L0.ManagedRuleGroups.SqlDatabase}),Z)z=L0.addManagedRules(z,{name:"AWSBotControl",priority:H++,...L0.ManagedRuleGroups.BotControl});if(U)z=L0.setRateLimit(z,{name:"GlobalRateLimit",priority:H++,requestsPerWindow:W*5});return{webAcl:z,logicalId:G}}static RateLimitPresets={STANDARD:2000,HIGH_TRAFFIC:1e4,STRICT:100,LOGIN:10,API:100}};n=class n{static createServer($){let{slug:J,environment:Y,instanceType:Q="t3.micro",imageId:Z="ami-0f3caa1cf4417e51b",keyName:U,securityGroupIds:W,subnetId:z,userData:G,volumeSize:H=20,volumeType:A="gp3",encrypted:K=!0}=$,B=f({slug:J,environment:Y,resourceType:"ec2"}),j=S(B),X={Type:"AWS::EC2::Instance",Properties:{ImageId:Z,InstanceType:Q,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:Y}]}};if(U)X.Properties.KeyName=U;if(W)X.Properties.SecurityGroupIds=W;if(z)X.Properties.SubnetId=z;if(G)X.Properties.UserData=u.Base64(G);return X.Properties.BlockDeviceMappings=[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:H,VolumeType:A,Encrypted:K,DeleteOnTermination:!0}}],{instance:X,logicalId:j}}static createSecurityGroup($){let{slug:J,environment:Y,vpcId:Q,description:Z,ingress:U=[],egress:W=[]}=$,z=f({slug:J,environment:Y,resourceType:"sg"}),G=S(z),H={Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:Z||`Security group for ${J} ${Y}`,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(Q)H.Properties.VpcId=Q;if(U.length>0)H.Properties.SecurityGroupIngress=U.map((A)=>({IpProtocol:A.protocol,FromPort:A.fromPort,ToPort:A.toPort,CidrIp:A.cidr,SourceSecurityGroupId:A.sourceSecurityGroupId}));if(W.length>0)H.Properties.SecurityGroupEgress=W.map((A)=>({IpProtocol:A.protocol,FromPort:A.fromPort,ToPort:A.toPort,CidrIp:A.cidr,DestinationSecurityGroupId:A.sourceSecurityGroupId}));return{securityGroup:H,logicalId:G}}static createWebServerSecurityGroup($,J,Y){return n.createSecurityGroup({slug:$,environment:J,vpcId:Y,description:"Security group for web servers - HTTP, HTTPS, SSH",ingress:[{protocol:"tcp",fromPort:80,toPort:80,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:443,toPort:443,cidr:"0.0.0.0/0"},{protocol:"tcp",fromPort:22,toPort:22,cidr:"0.0.0.0/0"}],egress:[{protocol:"-1",fromPort:0,toPort:0,cidr:"0.0.0.0/0"}]})}static createLoadBalancer($){let{slug:J,environment:Y,scheme:Q="internet-facing",subnets:Z,securityGroups:U,type:W="application"}=$,z=f({slug:J,environment:Y,resourceType:"alb"}),G=S(z),H={Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:z,Scheme:Q,Type:W,Subnets:Z,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(U)H.Properties.SecurityGroups=U;return{loadBalancer:H,logicalId:G}}static createTargetGroup($){let{slug:J,environment:Y,port:Q,protocol:Z="HTTP",vpcId:U,targetType:W="ip",healthCheckPath:z="/",healthCheckInterval:G=30,healthCheckTimeout:H=5,healthyThreshold:A=2,unhealthyThreshold:K=3}=$,B=f({slug:J,environment:Y,resourceType:"tg"}),j=S(B);return{targetGroup:{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:B,Port:Q,Protocol:Z,VpcId:U,TargetType:W,HealthCheckEnabled:!0,HealthCheckProtocol:Z,HealthCheckPath:z,HealthCheckIntervalSeconds:G,HealthCheckTimeoutSeconds:H,HealthyThresholdCount:A,UnhealthyThresholdCount:K,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:Y}]}},logicalId:j}}static createListener($,J){let{port:Y,protocol:Q="HTTP",certificateArn:Z,defaultTargetGroupArn:U}=J,W=S(`listener-${$}-${Y}`),z={Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:u.Ref($),Port:Y,Protocol:Q,DefaultActions:[{Type:"forward",TargetGroupArn:U}]}};if(Q==="HTTPS"&&Z)z.Properties.Certificates=[{CertificateArn:Z}],z.Properties.SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06";return{listener:z,logicalId:W}}static createEcsCluster($,J){let Y=f({slug:$,environment:J,resourceType:"ecs-cluster"}),Q=S(Y);return{cluster:{Type:"AWS::ECS::Cluster",Properties:{ClusterName:Y,Tags:[{Key:"Name",Value:Y},{Key:"Environment",Value:J}]}},logicalId:Q}}static createFargateService($){let{slug:J,environment:Y,image:Q,cpu:Z="256",memory:U="512",desiredCount:W=1,containerPort:z=8080,environmentVariables:G={},secrets:H=[],healthCheck:A,logGroup:K,subnets:B,securityGroups:j,targetGroupArn:X}=$,{cluster:O,logicalId:_}=n.createEcsCluster(J,Y),w=f({slug:J,environment:Y,resourceType:"fargate"}),E=S(`${w}-execution-role`),M={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]}},T=S(`${w}-task-role`),D={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]}}},N=S(`${w}-task`),x={Type:"AWS::ECS::TaskDefinition",Properties:{Family:w,TaskRoleArn:u.GetAtt(T,"Arn"),ExecutionRoleArn:u.GetAtt(E,"Arn"),NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:Z,Memory:U,ContainerDefinitions:[{Name:J,Image:Q,Essential:!0,PortMappings:[{ContainerPort:z,Protocol:"tcp"}],Environment:Object.entries(G).map(([b,k])=>({Name:b,Value:k})),Secrets:H.map((b)=>({Name:b.name,ValueFrom:b.valueFrom}))}],Tags:[{Key:"Name",Value:w},{Key:"Environment",Value:Y}]}};if(A)x.Properties.ContainerDefinitions[0].HealthCheck={Command:A.command,Interval:A.interval||30,Timeout:A.timeout||5,Retries:A.retries||3,StartPeriod:60};if(K)x.Properties.ContainerDefinitions[0].LogConfiguration={LogDriver:"awslogs",Options:{"awslogs-group":K,"awslogs-region":u.Ref("AWS::Region"),"awslogs-stream-prefix":J}};let h=S(`${w}-service`),I={Type:"AWS::ECS::Service",Properties:{ServiceName:w,Cluster:u.Ref(_),TaskDefinition:u.Ref(N),DesiredCount:W,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{Subnets:B,SecurityGroups:j,AssignPublicIp:"ENABLED"}},Tags:[{Key:"Name",Value:w},{Key:"Environment",Value:Y}]}};if(X)I.Properties.LoadBalancers=[{TargetGroupArn:X,ContainerName:J,ContainerPort:z}];return{cluster:O,taskDefinition:x,service:I,taskRole:D,executionRole:M,clusterLogicalId:_,taskDefinitionLogicalId:N,serviceLogicalId:h,taskRoleLogicalId:T,executionRoleLogicalId:E}}static createLambdaFunction($){let{slug:J,environment:Y,runtime:Q,handler:Z,code:U,timeout:W=30,memorySize:z=128,environmentVariables:G={},vpcConfig:H}=$,A=f({slug:J,environment:Y,resourceType:"lambda"}),K=S(A),B=S(`${A}-role`),j={Type:"AWS::IAM::Role",Properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}};if(H)j.Properties.ManagedPolicyArns.push("arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole");let X={Type:"AWS::Lambda::Function",Properties:{FunctionName:A,Runtime:Q,Role:u.GetAtt(B,"Arn"),Handler:Z,Code:{...U.s3Bucket&&{S3Bucket:U.s3Bucket},...U.s3Key&&{S3Key:U.s3Key},...U.zipFile&&{ZipFile:U.zipFile}},Timeout:W,MemorySize:z,Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:Y}]}};if(Object.keys(G).length>0)X.Properties.Environment={Variables:G};if(H)X.Properties.VpcConfig={SecurityGroupIds:H.securityGroupIds,SubnetIds:H.subnetIds};return{lambdaFunction:X,role:j,logicalId:K,roleLogicalId:B}}static generateNodeServerUserData($={}){let{nodeVersion:J="20",appRepo:Y,environment:Q={}}=$,Z=Object.entries(Q).map(([U,W])=>`echo "export ${U}='${W}'" >> /etc/environment`).join(`
4798
4798
  `);return`#!/bin/bash
4799
4799
  # Update system
4800
4800
  yum update -y
@@ -4895,7 +4895,7 @@ systemctl enable caddy
4895
4895
  systemctl start caddy
4896
4896
 
4897
4897
  echo "Bun server setup complete!"
4898
- `}static createLaunchConfiguration($){let{slug:J,environment:Y,imageId:Q,instanceType:Z,keyName:U,securityGroups:W,userData:z,volumeSize:G=20,volumeType:H="gp3",encrypted:A=!0,iamInstanceProfile:K}=$,B=v({slug:J,environment:Y,resourceType:"launch-config"}),j=S(B),X={Type:"AWS::AutoScaling::LaunchConfiguration",Properties:{ImageId:Q,InstanceType:Z,BlockDeviceMappings:[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:G,VolumeType:H,Encrypted:A,DeleteOnTermination:!0}}]}};if(U)X.Properties.KeyName=U;if(W)X.Properties.SecurityGroups=W;if(z)X.Properties.UserData=u.Base64(z);if(K)X.Properties.IamInstanceProfile=K;return{launchConfiguration:X,logicalId:j}}static createAutoScalingGroup($){let{slug:J,environment:Y,launchConfigurationName:Q,minSize:Z,maxSize:U,desiredCapacity:W,vpcZoneIdentifier:z,targetGroupArns:G,healthCheckType:H="EC2",healthCheckGracePeriod:A=300,cooldown:K=300,tags:B={}}=$,j=v({slug:J,environment:Y,resourceType:"asg"}),X=S(j),O={Type:"AWS::AutoScaling::AutoScalingGroup",Properties:{AutoScalingGroupName:j,LaunchConfigurationName:Q,MinSize:Z,MaxSize:U,HealthCheckType:H,HealthCheckGracePeriod:A,Cooldown:K,Tags:[{Key:"Name",Value:j,PropagateAtLaunch:!0},{Key:"Environment",Value:Y,PropagateAtLaunch:!0},...Object.entries(B).map(([_,w])=>({Key:_,Value:w,PropagateAtLaunch:!0}))]}};if(W!==void 0)O.Properties.DesiredCapacity=W;if(z)O.Properties.VPCZoneIdentifier=z;if(G)O.Properties.TargetGroupARNs=G;return O.UpdatePolicy={AutoScalingRollingUpdate:{MaxBatchSize:1,MinInstancesInService:Math.max(0,Z-1),PauseTime:"PT5M",WaitOnResourceSignals:!1}},{autoScalingGroup:O,logicalId:X}}static createScalingPolicy($){let{slug:J,environment:Y,autoScalingGroupName:Q,policyType:Z="TargetTrackingScaling",targetValue:U=70,predefinedMetricType:W="ASGAverageCPUUtilization"}=$,z=v({slug:J,environment:Y,resourceType:"scaling-policy"}),G=S(z),H={Type:"AWS::AutoScaling::ScalingPolicy",Properties:{AutoScalingGroupName:Q,PolicyType:Z}};if(Z==="TargetTrackingScaling")H.Properties.TargetTrackingConfiguration={PredefinedMetricSpecification:{PredefinedMetricType:W},TargetValue:U};return{scalingPolicy:H,logicalId:G}}static AutoScaling={smallWebServer:($,J,Y,Q,Z)=>{return n.createAutoScalingGroup({slug:$,environment:J,launchConfigurationName:Y,minSize:2,maxSize:4,desiredCapacity:2,vpcZoneIdentifier:Q,targetGroupArns:Z,healthCheckType:Z?"ELB":"EC2",healthCheckGracePeriod:300})},mediumWebServer:($,J,Y,Q,Z)=>{return n.createAutoScalingGroup({slug:$,environment:J,launchConfigurationName:Y,minSize:3,maxSize:10,desiredCapacity:3,vpcZoneIdentifier:Q,targetGroupArns:Z,healthCheckType:Z?"ELB":"EC2",healthCheckGracePeriod:300})},largeWebServer:($,J,Y,Q,Z)=>{return n.createAutoScalingGroup({slug:$,environment:J,launchConfigurationName:Y,minSize:5,maxSize:20,desiredCapacity:5,vpcZoneIdentifier:Q,targetGroupArns:Z,healthCheckType:Z?"ELB":"EC2",healthCheckGracePeriod:300})},cpuScaling:($,J,Y,Q=70)=>{return n.createScalingPolicy({slug:$,environment:J,autoScalingGroupName:Y,policyType:"TargetTrackingScaling",predefinedMetricType:"ASGAverageCPUUtilization",targetValue:Q})},requestCountScaling:($,J,Y,Q=1000)=>{return n.createScalingPolicy({slug:$,environment:J,autoScalingGroupName:Y,policyType:"TargetTrackingScaling",predefinedMetricType:"ALBRequestCountPerTarget",targetValue:Q})}};static Secrets={fromSecretsManager:($)=>{return Object.entries($).map(([J,Y])=>({name:J,valueFrom:Y}))},fromJsonSecret:($,J)=>{return`${$}:${J}::`},fromSecretVersion:($,J)=>{return`${$}::${J}:`},fromSecretVersionStage:($,J)=>{return`${$}:::${J}`},createAccessPolicy:($)=>({PolicyName:"SecretsManagerAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],Resource:$}]}}),createKmsPolicy:($)=>({PolicyName:"KMSDecryptAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["kms:Decrypt"],Resource:$}]}}),buildSecretArn:($)=>{return`arn:aws:secretsmanager:${$.region}:${$.accountId}:secret:${$.secretName}`},buildSecretArnPattern:($)=>{let J=$.region||"*",Y=$.accountId||"*";return`arn:aws:secretsmanager:${J}:${Y}:secret:${$.secretNamePrefix}*`},commonAppSecrets:($)=>({DATABASE_URL:`${$}/database-url`,DATABASE_PASSWORD:`${$}/database-password`,REDIS_URL:`${$}/redis-url`,REDIS_PASSWORD:`${$}/redis-password`,API_KEY:`${$}/api-key`,JWT_SECRET:`${$}/jwt-secret`,ENCRYPTION_KEY:`${$}/encryption-key`,AWS_ACCESS_KEY_ID:`${$}/aws-access-key-id`,AWS_SECRET_ACCESS_KEY:`${$}/aws-secret-access-key`,MAIL_PASSWORD:`${$}/mail-password`,STRIPE_SECRET_KEY:`${$}/stripe-secret-key`,STRIPE_WEBHOOK_SECRET:`${$}/stripe-webhook-secret`})};static createFargateServiceWithSecrets($){let{secretArns:J=[],kmsKeyArns:Y=[],...Q}=$,Z=n.createFargateService(Q);if(J.length>0){if(!Z.executionRole.Properties.Policies)Z.executionRole.Properties.Policies=[];if(Z.executionRole.Properties.Policies.push(n.Secrets.createAccessPolicy(J)),Y.length>0)Z.executionRole.Properties.Policies.push(n.Secrets.createKmsPolicy(Y))}return Z}static generateSecretReferences($){return $.secrets.map((J)=>{let Y=`arn:aws:secretsmanager:${$.region}:${$.accountId}:secret:${$.secretPrefix}/${J}`;return{name:J.toUpperCase().replace(/-/g,"_"),valueFrom:Y}})}static EnvSecrets={database:($)=>[{name:"DB_HOST",valueFrom:`${$}:host::`},{name:"DB_PORT",valueFrom:`${$}:port::`},{name:"DB_USERNAME",valueFrom:`${$}:username::`},{name:"DB_PASSWORD",valueFrom:`${$}:password::`},{name:"DB_NAME",valueFrom:`${$}:dbname::`}],redis:($)=>[{name:"REDIS_HOST",valueFrom:`${$}:host::`},{name:"REDIS_PORT",valueFrom:`${$}:port::`},{name:"REDIS_PASSWORD",valueFrom:`${$}:password::`}],apiCredentials:($)=>[{name:"API_KEY",valueFrom:`${$}:apiKey::`},{name:"API_SECRET",valueFrom:`${$}:apiSecret::`}],mail:($)=>[{name:"MAIL_HOST",valueFrom:`${$}:host::`},{name:"MAIL_PORT",valueFrom:`${$}:port::`},{name:"MAIL_USERNAME",valueFrom:`${$}:username::`},{name:"MAIL_PASSWORD",valueFrom:`${$}:password::`}],awsCredentials:($)=>[{name:"AWS_ACCESS_KEY_ID",valueFrom:`${$}:accessKeyId::`},{name:"AWS_SECRET_ACCESS_KEY",valueFrom:`${$}:secretAccessKey::`}]};static createJumpBox($){let{slug:J,environment:Y,vpcId:Q,subnetId:Z,keyName:U,instanceType:W="t3.micro",imageId:z="ami-0f3caa1cf4417e51b",allowedCidrs:G=["0.0.0.0/0"],mountEfs:H}=$,A=v({slug:J,environment:Y,resourceType:"jumpbox"}),K=S(`${A}-sg`),B={Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:`${A}-sg`,GroupDescription:`Security group for ${A} JumpBox SSH access`,VpcId:Q,SecurityGroupIngress:G.map((D)=>({IpProtocol:"tcp",FromPort:22,ToPort:22,CidrIp:D,Description:`SSH access from ${D}`})),SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound traffic"}],Tags:[{Key:"Name",Value:`${A}-sg`},{Key:"Environment",Value:Y}]}},j=S(`${A}-role`),X={Type:"AWS::IAM::Role",Properties:{RoleName:`${A}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"],Policies:H?[{PolicyName:"EFSAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:ClientRootAccess"],Resource:"*"}]}}]:void 0}},O=S(`${A}-profile`),_={Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:`${A}-profile`,Roles:[u.Ref(j)]}},w=`#!/bin/bash
4898
+ `}static createLaunchConfiguration($){let{slug:J,environment:Y,imageId:Q,instanceType:Z,keyName:U,securityGroups:W,userData:z,volumeSize:G=20,volumeType:H="gp3",encrypted:A=!0,iamInstanceProfile:K}=$,B=f({slug:J,environment:Y,resourceType:"launch-config"}),j=S(B),X={Type:"AWS::AutoScaling::LaunchConfiguration",Properties:{ImageId:Q,InstanceType:Z,BlockDeviceMappings:[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:G,VolumeType:H,Encrypted:A,DeleteOnTermination:!0}}]}};if(U)X.Properties.KeyName=U;if(W)X.Properties.SecurityGroups=W;if(z)X.Properties.UserData=u.Base64(z);if(K)X.Properties.IamInstanceProfile=K;return{launchConfiguration:X,logicalId:j}}static createAutoScalingGroup($){let{slug:J,environment:Y,launchConfigurationName:Q,minSize:Z,maxSize:U,desiredCapacity:W,vpcZoneIdentifier:z,targetGroupArns:G,healthCheckType:H="EC2",healthCheckGracePeriod:A=300,cooldown:K=300,tags:B={}}=$,j=f({slug:J,environment:Y,resourceType:"asg"}),X=S(j),O={Type:"AWS::AutoScaling::AutoScalingGroup",Properties:{AutoScalingGroupName:j,LaunchConfigurationName:Q,MinSize:Z,MaxSize:U,HealthCheckType:H,HealthCheckGracePeriod:A,Cooldown:K,Tags:[{Key:"Name",Value:j,PropagateAtLaunch:!0},{Key:"Environment",Value:Y,PropagateAtLaunch:!0},...Object.entries(B).map(([_,w])=>({Key:_,Value:w,PropagateAtLaunch:!0}))]}};if(W!==void 0)O.Properties.DesiredCapacity=W;if(z)O.Properties.VPCZoneIdentifier=z;if(G)O.Properties.TargetGroupARNs=G;return O.UpdatePolicy={AutoScalingRollingUpdate:{MaxBatchSize:1,MinInstancesInService:Math.max(0,Z-1),PauseTime:"PT5M",WaitOnResourceSignals:!1}},{autoScalingGroup:O,logicalId:X}}static createScalingPolicy($){let{slug:J,environment:Y,autoScalingGroupName:Q,policyType:Z="TargetTrackingScaling",targetValue:U=70,predefinedMetricType:W="ASGAverageCPUUtilization"}=$,z=f({slug:J,environment:Y,resourceType:"scaling-policy"}),G=S(z),H={Type:"AWS::AutoScaling::ScalingPolicy",Properties:{AutoScalingGroupName:Q,PolicyType:Z}};if(Z==="TargetTrackingScaling")H.Properties.TargetTrackingConfiguration={PredefinedMetricSpecification:{PredefinedMetricType:W},TargetValue:U};return{scalingPolicy:H,logicalId:G}}static AutoScaling={smallWebServer:($,J,Y,Q,Z)=>{return n.createAutoScalingGroup({slug:$,environment:J,launchConfigurationName:Y,minSize:2,maxSize:4,desiredCapacity:2,vpcZoneIdentifier:Q,targetGroupArns:Z,healthCheckType:Z?"ELB":"EC2",healthCheckGracePeriod:300})},mediumWebServer:($,J,Y,Q,Z)=>{return n.createAutoScalingGroup({slug:$,environment:J,launchConfigurationName:Y,minSize:3,maxSize:10,desiredCapacity:3,vpcZoneIdentifier:Q,targetGroupArns:Z,healthCheckType:Z?"ELB":"EC2",healthCheckGracePeriod:300})},largeWebServer:($,J,Y,Q,Z)=>{return n.createAutoScalingGroup({slug:$,environment:J,launchConfigurationName:Y,minSize:5,maxSize:20,desiredCapacity:5,vpcZoneIdentifier:Q,targetGroupArns:Z,healthCheckType:Z?"ELB":"EC2",healthCheckGracePeriod:300})},cpuScaling:($,J,Y,Q=70)=>{return n.createScalingPolicy({slug:$,environment:J,autoScalingGroupName:Y,policyType:"TargetTrackingScaling",predefinedMetricType:"ASGAverageCPUUtilization",targetValue:Q})},requestCountScaling:($,J,Y,Q=1000)=>{return n.createScalingPolicy({slug:$,environment:J,autoScalingGroupName:Y,policyType:"TargetTrackingScaling",predefinedMetricType:"ALBRequestCountPerTarget",targetValue:Q})}};static Secrets={fromSecretsManager:($)=>{return Object.entries($).map(([J,Y])=>({name:J,valueFrom:Y}))},fromJsonSecret:($,J)=>{return`${$}:${J}::`},fromSecretVersion:($,J)=>{return`${$}::${J}:`},fromSecretVersionStage:($,J)=>{return`${$}:::${J}`},createAccessPolicy:($)=>({PolicyName:"SecretsManagerAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],Resource:$}]}}),createKmsPolicy:($)=>({PolicyName:"KMSDecryptAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["kms:Decrypt"],Resource:$}]}}),buildSecretArn:($)=>{return`arn:aws:secretsmanager:${$.region}:${$.accountId}:secret:${$.secretName}`},buildSecretArnPattern:($)=>{let J=$.region||"*",Y=$.accountId||"*";return`arn:aws:secretsmanager:${J}:${Y}:secret:${$.secretNamePrefix}*`},commonAppSecrets:($)=>({DATABASE_URL:`${$}/database-url`,DATABASE_PASSWORD:`${$}/database-password`,REDIS_URL:`${$}/redis-url`,REDIS_PASSWORD:`${$}/redis-password`,API_KEY:`${$}/api-key`,JWT_SECRET:`${$}/jwt-secret`,ENCRYPTION_KEY:`${$}/encryption-key`,AWS_ACCESS_KEY_ID:`${$}/aws-access-key-id`,AWS_SECRET_ACCESS_KEY:`${$}/aws-secret-access-key`,MAIL_PASSWORD:`${$}/mail-password`,STRIPE_SECRET_KEY:`${$}/stripe-secret-key`,STRIPE_WEBHOOK_SECRET:`${$}/stripe-webhook-secret`})};static createFargateServiceWithSecrets($){let{secretArns:J=[],kmsKeyArns:Y=[],...Q}=$,Z=n.createFargateService(Q);if(J.length>0){if(!Z.executionRole.Properties.Policies)Z.executionRole.Properties.Policies=[];if(Z.executionRole.Properties.Policies.push(n.Secrets.createAccessPolicy(J)),Y.length>0)Z.executionRole.Properties.Policies.push(n.Secrets.createKmsPolicy(Y))}return Z}static generateSecretReferences($){return $.secrets.map((J)=>{let Y=`arn:aws:secretsmanager:${$.region}:${$.accountId}:secret:${$.secretPrefix}/${J}`;return{name:J.toUpperCase().replace(/-/g,"_"),valueFrom:Y}})}static EnvSecrets={database:($)=>[{name:"DB_HOST",valueFrom:`${$}:host::`},{name:"DB_PORT",valueFrom:`${$}:port::`},{name:"DB_USERNAME",valueFrom:`${$}:username::`},{name:"DB_PASSWORD",valueFrom:`${$}:password::`},{name:"DB_NAME",valueFrom:`${$}:dbname::`}],redis:($)=>[{name:"REDIS_HOST",valueFrom:`${$}:host::`},{name:"REDIS_PORT",valueFrom:`${$}:port::`},{name:"REDIS_PASSWORD",valueFrom:`${$}:password::`}],apiCredentials:($)=>[{name:"API_KEY",valueFrom:`${$}:apiKey::`},{name:"API_SECRET",valueFrom:`${$}:apiSecret::`}],mail:($)=>[{name:"MAIL_HOST",valueFrom:`${$}:host::`},{name:"MAIL_PORT",valueFrom:`${$}:port::`},{name:"MAIL_USERNAME",valueFrom:`${$}:username::`},{name:"MAIL_PASSWORD",valueFrom:`${$}:password::`}],awsCredentials:($)=>[{name:"AWS_ACCESS_KEY_ID",valueFrom:`${$}:accessKeyId::`},{name:"AWS_SECRET_ACCESS_KEY",valueFrom:`${$}:secretAccessKey::`}]};static createJumpBox($){let{slug:J,environment:Y,vpcId:Q,subnetId:Z,keyName:U,instanceType:W="t3.micro",imageId:z="ami-0f3caa1cf4417e51b",allowedCidrs:G=["0.0.0.0/0"],mountEfs:H}=$,A=f({slug:J,environment:Y,resourceType:"jumpbox"}),K=S(`${A}-sg`),B={Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:`${A}-sg`,GroupDescription:`Security group for ${A} JumpBox SSH access`,VpcId:Q,SecurityGroupIngress:G.map((D)=>({IpProtocol:"tcp",FromPort:22,ToPort:22,CidrIp:D,Description:`SSH access from ${D}`})),SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound traffic"}],Tags:[{Key:"Name",Value:`${A}-sg`},{Key:"Environment",Value:Y}]}},j=S(`${A}-role`),X={Type:"AWS::IAM::Role",Properties:{RoleName:`${A}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"],Policies:H?[{PolicyName:"EFSAccess",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["elasticfilesystem:ClientMount","elasticfilesystem:ClientWrite","elasticfilesystem:ClientRootAccess"],Resource:"*"}]}}]:void 0}},O=S(`${A}-profile`),_={Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:`${A}-profile`,Roles:[u.Ref(j)]}},w=`#!/bin/bash
4899
4899
  yum update -y
4900
4900
  yum install -y amazon-efs-utils nfs-utils jq curl wget htop
4901
4901
  `;if(H){let D=H.mountPath||"/mnt/efs";w+=`
@@ -5189,7 +5189,7 @@ ufw default allow outgoing
5189
5189
  ${$.map((J)=>`ufw allow ${J}`).join(`
5190
5190
  `)}
5191
5191
  ufw --force enable
5192
- `},Presets:{bunWithNginx:($,J=3000)=>n.UserData.generateAppServerScript({runtime:"bun",webServer:"nginx",processManager:"systemd",domain:$,appPort:J,enableSsl:!0}),bunWithCaddy:($,J=3000)=>n.UserData.generateAppServerScript({runtime:"bun",webServer:"caddy",processManager:"systemd",domain:$,appPort:J,enableSsl:!1}),nodeWithPm2:($,J=3000)=>n.UserData.generateAppServerScript({runtime:"node",webServer:"nginx",processManager:"pm2",domain:$,appPort:J,enableSsl:!0}),worker:($="bun")=>n.UserData.generateAppServerScript({runtime:$,webServer:"none",processManager:"systemd",enableSsl:!1})}};static createElasticIp($){let{slug:J,environment:Y,domain:Q,instanceLogicalId:Z}=$,U=v({slug:J,environment:Y,resourceType:"eip"}),W=S(U),z={Type:"AWS::EC2::EIP",Properties:{Domain:"vpc",Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Y},...Q?[{Key:"Domain",Value:Q}]:[]]}},G={[W]:z},H,A;if(Z)A=S(`${U}-assoc`),H={Type:"AWS::EC2::EIPAssociation",Properties:{AllocationId:u.GetAtt(W,"AllocationId"),InstanceId:u.Ref(Z)}},G[A]=H;return{eip:z,eipAssociation:H,eipLogicalId:W,associationLogicalId:A,resources:G}}static createServerModeStack($){let{slug:J,environment:Y,vpcId:Q,subnetId:Z,instanceType:U="t3.small",imageId:W="ami-0f3caa1cf4417e51b",keyName:z,domain:G,userData:H,allowedPorts:A=[22,80,443],volumeSize:K=20,volumeType:B="gp3"}=$,j={},X=v({slug:J,environment:Y,resourceType:"server-sg"}),O=S(X),_={Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:X,GroupDescription:`Security group for ${J} server`,VpcId:Q,SecurityGroupIngress:A.map((p)=>({IpProtocol:"tcp",FromPort:p,ToPort:p,CidrIp:"0.0.0.0/0",Description:`Port ${p}`})),SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:X},{Key:"Environment",Value:Y}]}};j[O]=_;let w=v({slug:J,environment:Y,resourceType:"server-role"}),E=S(w),M={Type:"AWS::IAM::Role",Properties:{RoleName:w,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore","arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"],Policies:[{PolicyName:"StacksServerPermissions",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["ses:SendEmail","ses:SendRawEmail","ses:SendBulkEmail","ses:VerifyDomainIdentity","ses:VerifyDomainDkim","ses:GetIdentityDkimAttributes","ses:GetIdentityVerificationAttributes"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:ListBucket"],Resource:"*"},{Effect:"Allow",Action:["route53:ChangeResourceRecordSets","route53:ListResourceRecordSets","route53:GetHostedZone"],Resource:"*"},{Effect:"Allow",Action:["ssm:GetParameter","ssm:GetParameters"],Resource:"*"}]}}]}};j[E]=M;let T=v({slug:J,environment:Y,resourceType:"server-profile"}),D=S(T),N={Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:T,Roles:[u.Ref(E)]}};j[D]=N;let x=v({slug:J,environment:Y,resourceType:"server"}),h=S(x),k={Type:"AWS::EC2::Instance",DependsOn:[D],Properties:{ImageId:W,InstanceType:U,KeyName:z,SubnetId:Z,SecurityGroupIds:[u.Ref(O)],IamInstanceProfile:u.Ref(D),BlockDeviceMappings:[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:K,VolumeType:B,Encrypted:!0,DeleteOnTermination:!0}}],Tags:[{Key:"Name",Value:x},{Key:"Environment",Value:Y},...G?[{Key:"Domain",Value:G}]:[]]}};if(H)k.Properties.UserData=u.Base64(H);j[h]=k;let{eip:b,eipAssociation:I,eipLogicalId:f,associationLogicalId:m,resources:l}=n.createElasticIp({slug:J,environment:Y,domain:G,instanceLogicalId:h});return Object.assign(j,l),{instance:k,securityGroup:_,eip:b,eipAssociation:I,instanceRole:M,instanceProfile:N,resources:j,outputs:{instanceLogicalId:h,securityGroupLogicalId:O,eipLogicalId:f,associationLogicalId:m,roleLogicalId:E,profileLogicalId:D}}}static ServerMode={webServer:($)=>{let J=n.UserData.generateAppServerScript({runtime:$.runtime||"bun",webServer:$.webServer||"nginx",domain:$.domain,enableSsl:!0});return n.createServerModeStack({...$,userData:J,instanceType:"t3.small",allowedPorts:[22,80,443]})},workerServer:($)=>{let J=n.UserData.generateAppServerScript({runtime:$.runtime||"bun",webServer:"none",installRedis:$.installRedis});return n.createServerModeStack({...$,userData:J,instanceType:"t3.medium",allowedPorts:[22]})},cacheServer:($)=>{return n.createServerModeStack({...$,userData:`#!/bin/bash
5192
+ `},Presets:{bunWithNginx:($,J=3000)=>n.UserData.generateAppServerScript({runtime:"bun",webServer:"nginx",processManager:"systemd",domain:$,appPort:J,enableSsl:!0}),bunWithCaddy:($,J=3000)=>n.UserData.generateAppServerScript({runtime:"bun",webServer:"caddy",processManager:"systemd",domain:$,appPort:J,enableSsl:!1}),nodeWithPm2:($,J=3000)=>n.UserData.generateAppServerScript({runtime:"node",webServer:"nginx",processManager:"pm2",domain:$,appPort:J,enableSsl:!0}),worker:($="bun")=>n.UserData.generateAppServerScript({runtime:$,webServer:"none",processManager:"systemd",enableSsl:!1})}};static createElasticIp($){let{slug:J,environment:Y,domain:Q,instanceLogicalId:Z}=$,U=f({slug:J,environment:Y,resourceType:"eip"}),W=S(U),z={Type:"AWS::EC2::EIP",Properties:{Domain:"vpc",Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Y},...Q?[{Key:"Domain",Value:Q}]:[]]}},G={[W]:z},H,A;if(Z)A=S(`${U}-assoc`),H={Type:"AWS::EC2::EIPAssociation",Properties:{AllocationId:u.GetAtt(W,"AllocationId"),InstanceId:u.Ref(Z)}},G[A]=H;return{eip:z,eipAssociation:H,eipLogicalId:W,associationLogicalId:A,resources:G}}static createServerModeStack($){let{slug:J,environment:Y,vpcId:Q,subnetId:Z,instanceType:U="t3.small",imageId:W="ami-0f3caa1cf4417e51b",keyName:z,domain:G,userData:H,allowedPorts:A=[22,80,443],volumeSize:K=20,volumeType:B="gp3"}=$,j={},X=f({slug:J,environment:Y,resourceType:"server-sg"}),O=S(X),_={Type:"AWS::EC2::SecurityGroup",Properties:{GroupName:X,GroupDescription:`Security group for ${J} server`,VpcId:Q,SecurityGroupIngress:A.map((p)=>({IpProtocol:"tcp",FromPort:p,ToPort:p,CidrIp:"0.0.0.0/0",Description:`Port ${p}`})),SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:X},{Key:"Environment",Value:Y}]}};j[O]=_;let w=f({slug:J,environment:Y,resourceType:"server-role"}),E=S(w),M={Type:"AWS::IAM::Role",Properties:{RoleName:w,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ec2.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore","arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"],Policies:[{PolicyName:"StacksServerPermissions",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["ses:SendEmail","ses:SendRawEmail","ses:SendBulkEmail","ses:VerifyDomainIdentity","ses:VerifyDomainDkim","ses:GetIdentityDkimAttributes","ses:GetIdentityVerificationAttributes"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:ListBucket"],Resource:"*"},{Effect:"Allow",Action:["route53:ChangeResourceRecordSets","route53:ListResourceRecordSets","route53:GetHostedZone"],Resource:"*"},{Effect:"Allow",Action:["ssm:GetParameter","ssm:GetParameters"],Resource:"*"}]}}]}};j[E]=M;let T=f({slug:J,environment:Y,resourceType:"server-profile"}),D=S(T),N={Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:T,Roles:[u.Ref(E)]}};j[D]=N;let x=f({slug:J,environment:Y,resourceType:"server"}),h=S(x),I={Type:"AWS::EC2::Instance",DependsOn:[D],Properties:{ImageId:W,InstanceType:U,KeyName:z,SubnetId:Z,SecurityGroupIds:[u.Ref(O)],IamInstanceProfile:u.Ref(D),BlockDeviceMappings:[{DeviceName:"/dev/xvda",Ebs:{VolumeSize:K,VolumeType:B,Encrypted:!0,DeleteOnTermination:!0}}],Tags:[{Key:"Name",Value:x},{Key:"Environment",Value:Y},...G?[{Key:"Domain",Value:G}]:[]]}};if(H)I.Properties.UserData=u.Base64(H);j[h]=I;let{eip:b,eipAssociation:k,eipLogicalId:y,associationLogicalId:m,resources:l}=n.createElasticIp({slug:J,environment:Y,domain:G,instanceLogicalId:h});return Object.assign(j,l),{instance:I,securityGroup:_,eip:b,eipAssociation:k,instanceRole:M,instanceProfile:N,resources:j,outputs:{instanceLogicalId:h,securityGroupLogicalId:O,eipLogicalId:y,associationLogicalId:m,roleLogicalId:E,profileLogicalId:D}}}static ServerMode={webServer:($)=>{let J=n.UserData.generateAppServerScript({runtime:$.runtime||"bun",webServer:$.webServer||"nginx",domain:$.domain,enableSsl:!0});return n.createServerModeStack({...$,userData:J,instanceType:"t3.small",allowedPorts:[22,80,443]})},workerServer:($)=>{let J=n.UserData.generateAppServerScript({runtime:$.runtime||"bun",webServer:"none",installRedis:$.installRedis});return n.createServerModeStack({...$,userData:J,instanceType:"t3.medium",allowedPorts:[22]})},cacheServer:($)=>{return n.createServerModeStack({...$,userData:`#!/bin/bash
5193
5193
  set -e
5194
5194
  apt-get update && apt-get upgrade -y
5195
5195
  apt-get install -y redis-server
@@ -5197,7 +5197,7 @@ sed -i 's/bind 127.0.0.1/bind 0.0.0.0/' /etc/redis/redis.conf
5197
5197
  systemctl enable redis-server
5198
5198
  systemctl restart redis-server
5199
5199
  echo "Redis server setup complete!"
5200
- `,instanceType:"t3.medium",allowedPorts:[22,6379]})}}};H0=class H0{static verifyDomain($){let{domain:J,slug:Y,environment:Q,enableDkim:Z=!0,dkimKeyLength:U="RSA_2048_BIT"}=$,W=v({slug:Y,environment:Q,resourceType:"ses-identity"}),z=S(`${W}-${J.replace(/\./g,"")}`),G={Type:"AWS::SES::EmailIdentity",Properties:{EmailIdentity:J,FeedbackAttributes:{EmailForwardingEnabled:!0}}};if(Z)G.Properties.DkimSigningAttributes={NextSigningKeyLength:U};return{emailIdentity:G,logicalId:z}}static createDkimRecords($,J,Y){let Q=[];for(let Z=0;Z<J.length;Z++){let U=J[Z],W=S(`dkim-${$.replace(/\./g,"")}-${Z+1}`),z={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:Y,Name:`${U}._domainkey.${$}`,Type:"CNAME",TTL:1800,ResourceRecords:[`${U}.dkim.amazonses.com`]}};Q.push({record:z,logicalId:W})}return Q}static createConfigurationSet($){let{slug:J,environment:Y,name:Q,reputationMetrics:Z=!0,sendingEnabled:U=!0,suppressBounces:W=!0,suppressComplaints:z=!0}=$,G=Q||v({slug:J,environment:Y,resourceType:"ses-config"}),H=S(G),A=[];if(W)A.push("BOUNCE");if(z)A.push("COMPLAINT");return{configurationSet:{Type:"AWS::SES::ConfigurationSet",Properties:{Name:G,ReputationOptions:{ReputationMetricsEnabled:Z},SendingOptions:{SendingEnabled:U},SuppressionOptions:{SuppressedReasons:A}}},logicalId:H}}static createReceiptRuleSet($){let{slug:J,environment:Y,name:Q}=$,Z=Q||v({slug:J,environment:Y,resourceType:"ses-ruleset"}),U=S(Z);return{ruleSet:{Type:"AWS::SES::ReceiptRuleSet",Properties:{RuleSetName:Z}},logicalId:U}}static createReceiptRule($,J){let{slug:Y,environment:Q,ruleSetName:Z,recipients:U,enabled:W=!0,scanEnabled:z=!0,tlsPolicy:G="Require",s3Action:H,lambdaAction:A,snsAction:K}=J,B=v({slug:Y,environment:Q,resourceType:"ses-rule"}),j=S(B),X=[];if(H)X.push({S3Action:{BucketName:H.bucketName,ObjectKeyPrefix:H.prefix,KmsKeyArn:H.kmsKeyArn}});if(A)X.push({LambdaAction:{FunctionArn:A.functionArn,InvocationType:A.invocationType||"Event"}});if(K)X.push({SNSAction:{TopicArn:K.topicArn,Encoding:K.encoding||"UTF-8"}});return{receiptRule:{Type:"AWS::SES::ReceiptRule",Properties:{RuleSetName:Z,Rule:{Name:B,Enabled:W,ScanEnabled:z,TlsPolicy:G,Recipients:U,Actions:X.length>0?X:void 0}}},logicalId:j}}static createMxRecord($,J,Y){let Q=S(`mx-${$.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:J,Name:$,Type:"MX",TTL:300,ResourceRecords:[`10 inbound-smtp.${Y}.amazonaws.com`]}},logicalId:Q}}static createVerificationRecord($,J,Y){let Q=S(`verification-${$.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:Y,Name:`_amazonses.${$}`,Type:"TXT",TTL:1800,ResourceRecords:[`"${J}"`]}},logicalId:Q}}static getSmtpEndpoint($){return`email-smtp.${$}.amazonaws.com`}static SmtpPorts={TLS:587,SSL:465,Unencrypted:25};static createSpfRecord($,J,Y){let{includeDomains:Q=[],softFail:Z=!1}=Y||{},U=S(`spf-${$.replace(/\./g,"")}`),W="v=spf1 include:amazonses.com";for(let G of Q)W+=` include:${G}`;return W+=Z?" ~all":" -all",{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:J,Name:$,Type:"TXT",TTL:300,ResourceRecords:[`"${W}"`]}},logicalId:U}}static createDmarcRecord($,J,Y){let{policy:Q="none",subdomainPolicy:Z,percentage:U=100,reportingEmail:W,forensicEmail:z}=Y||{},G=S(`dmarc-${$.replace(/\./g,"")}`),H=`v=DMARC1; p=${Q}; pct=${U}`;if(Z)H+=`; sp=${Z}`;if(W)H+=`; rua=mailto:${W}`;if(z)H+=`; ruf=mailto:${z}`;return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:J,Name:`_dmarc.${$}`,Type:"TXT",TTL:300,ResourceRecords:[`"${H}"`]}},logicalId:G}}static createInboundEmailSetup($){let{slug:J,environment:Y,domain:Q,s3BucketName:Z,s3KeyPrefix:U="inbound/",region:W,hostedZoneId:z,lambdaFunctionArn:G,snsTopicArn:H}=$,A={},{ruleSet:K,logicalId:B}=H0.createReceiptRuleSet({slug:J,environment:Y});A[B]=K;let{receiptRule:j,logicalId:X}=H0.createReceiptRule(B,{slug:J,environment:Y,ruleSetName:K.Properties.RuleSetName||`${J}-${Y}-receipt-rule-set`,recipients:[Q],s3Action:{bucketName:Z,prefix:U},lambdaAction:G?{functionArn:G,invocationType:"Event"}:void 0,snsAction:H?{topicArn:H}:void 0});A[X]=j;let{record:O,logicalId:_}=H0.createMxRecord(Q,z,W);return A[_]=O,{resources:A,outputs:{ruleSetLogicalId:B,ruleLogicalId:X,mxRecordLogicalId:_}}}static createCompleteDomainSetup($){let{slug:J,environment:Y,domain:Q,hostedZoneId:Z,region:U,enableInbound:W=!1,inboundS3Bucket:z,dmarcReportingEmail:G}=$,H={},{emailIdentity:A,logicalId:K}=H0.verifyDomain({domain:Q,slug:J,environment:Y});H[K]=A;let{configurationSet:B,logicalId:j}=H0.createConfigurationSet({slug:J,environment:Y});H[j]=B;let{record:X,logicalId:O}=H0.createSpfRecord(Q,Z);H[O]=X;let{record:_,logicalId:w}=H0.createDmarcRecord(Q,Z,{policy:"none",reportingEmail:G||`dmarc-reports@${Q}`});if(H[w]=_,W&&z){let E=H0.createInboundEmailSetup({slug:J,environment:Y,domain:Q,s3BucketName:z,region:U,hostedZoneId:Z});Object.assign(H,E.resources)}return{resources:H,outputs:{identityLogicalId:K,configSetLogicalId:j}}}static InboundSmtpEndpoints={"us-east-1":"inbound-smtp.us-east-1.amazonaws.com","us-west-2":"inbound-smtp.us-west-2.amazonaws.com","eu-west-1":"inbound-smtp.eu-west-1.amazonaws.com"};static supportsInboundEmail($){return $ in H0.InboundSmtpEndpoints}static createEmailLambdaRole($){let{slug:J,environment:Y,s3BucketArn:Q,sesIdentityArn:Z}=$,U=v({slug:J,environment:Y,resourceType:"email-lambda-role"}),W=S(U),z=S(`${U}-policy`),G={Type:"AWS::IAM::Role",Properties:{RoleName:U,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Y}]}},H=[{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucket"],Resource:[Q,`${Q}/*`]}];if(Z)H.push({Effect:"Allow",Action:["ses:SendEmail","ses:SendRawEmail"],Resource:Z});let A={Type:"AWS::IAM::Policy",Properties:{PolicyName:`${U}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:H},Roles:[u.Ref(W)]}};return{role:G,policy:A,roleLogicalId:W,policyLogicalId:z}}static createOutboundEmailLambda($){let{slug:J,environment:Y,roleArn:Q,domain:Z,configurationSetName:U,timeout:W=30,memorySize:z=256}=$,G=v({slug:J,environment:Y,resourceType:"outbound-email"}),H=S(G);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:G,Runtime:"nodejs20.x",Handler:"index.handler",Role:Q,Timeout:W,MemorySize:z,Environment:{Variables:{DOMAIN:Z,CONFIGURATION_SET:U||""}},Code:{ZipFile:H0.LambdaCode.outboundEmail},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"OutboundEmail"}]}},logicalId:H}}static createInboundEmailLambda($){let{slug:J,environment:Y,roleArn:Q,s3BucketName:Z,organizedPrefix:U="organized/",timeout:W=60,memorySize:z=512}=$,G=v({slug:J,environment:Y,resourceType:"inbound-email"}),H=S(G),A=S(`${G}-permission`),K={Type:"AWS::Lambda::Function",Properties:{FunctionName:G,Runtime:"nodejs20.x",Handler:"index.handler",Role:Q,Timeout:W,MemorySize:z,Environment:{Variables:{S3_BUCKET:Z,ORGANIZED_PREFIX:U}},Code:{ZipFile:H0.LambdaCode.inboundEmail},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"InboundEmail"}]}},B={Type:"AWS::Lambda::Permission",Properties:{FunctionName:u.Ref(H),Action:"lambda:InvokeFunction",Principal:"ses.amazonaws.com",SourceAccount:u.Ref("AWS::AccountId")}};return{function:K,permission:B,logicalId:H,permissionLogicalId:A}}static createEmailConversionLambda($){let{slug:J,environment:Y,roleArn:Q,s3BucketName:Z,convertedPrefix:U="converted/",timeout:W=60,memorySize:z=512}=$,G=v({slug:J,environment:Y,resourceType:"email-conversion"}),H=S(G);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:G,Runtime:"nodejs20.x",Handler:"index.handler",Role:Q,Timeout:W,MemorySize:z,Environment:{Variables:{S3_BUCKET:Z,CONVERTED_PREFIX:U}},Code:{ZipFile:H0.LambdaCode.emailConversion},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"EmailConversion"}]}},logicalId:H}}static createEmailBucketNotification($){let{lambdaArn:J,prefix:Y="inbound/",suffix:Q,events:Z=["s3:ObjectCreated:*"]}=$,U={};if(Y||Q){if(U.S3Key={Rules:[]},Y)U.S3Key.Rules.push({Name:"prefix",Value:Y});if(Q)U.S3Key.Rules.push({Name:"suffix",Value:Q})}return{notificationConfiguration:{LambdaConfigurations:[{Event:Z[0],Function:J,Filter:Object.keys(U).length>0?U:void 0}]}}}static createS3LambdaPermission($){let{slug:J,environment:Y,lambdaLogicalId:Q,s3BucketArn:Z}=$,U=v({slug:J,environment:Y,resourceType:"s3-lambda-permission"}),W=S(U);return{permission:{Type:"AWS::Lambda::Permission",Properties:{FunctionName:u.Ref(Q),Action:"lambda:InvokeFunction",Principal:"s3.amazonaws.com",SourceArn:Z}},logicalId:W}}static createEmailProcessingStack($){let{slug:J,environment:Y,domain:Q,s3BucketName:Z,s3BucketArn:U,configurationSetName:W,enableInbound:z=!0,enableConversion:G=!0}=$,H={},{role:A,policy:K,roleLogicalId:B,policyLogicalId:j}=H0.createEmailLambdaRole({slug:J,environment:Y,s3BucketArn:U,sesIdentityArn:`arn:aws:ses:*:*:identity/${Q}`});H[B]=A,H[j]=K;let{function:X,logicalId:O}=H0.createOutboundEmailLambda({slug:J,environment:Y,roleArn:u.GetAtt(B,"Arn"),domain:Q,configurationSetName:W});H[O]=X;let _={roleLogicalId:B,outboundLambdaLogicalId:O};if(z){let{function:w,permission:E,logicalId:M,permissionLogicalId:T}=H0.createInboundEmailLambda({slug:J,environment:Y,roleArn:u.GetAtt(B,"Arn"),s3BucketName:Z});H[M]=w,H[T]=E;let{permission:D,logicalId:N}=H0.createS3LambdaPermission({slug:J,environment:Y,lambdaLogicalId:M,s3BucketArn:U});H[N]=D,_.inboundLambdaLogicalId=M}if(G){let{function:w,logicalId:E}=H0.createEmailConversionLambda({slug:J,environment:Y,roleArn:u.GetAtt(B,"Arn"),s3BucketName:Z});H[E]=w,_.conversionLambdaLogicalId=E}return{resources:H,outputs:_}}static LambdaCode={outboundEmail:`
5200
+ `,instanceType:"t3.medium",allowedPorts:[22,6379]})}}};H0=class H0{static verifyDomain($){let{domain:J,slug:Y,environment:Q,enableDkim:Z=!0,dkimKeyLength:U="RSA_2048_BIT"}=$,W=f({slug:Y,environment:Q,resourceType:"ses-identity"}),z=S(`${W}-${J.replace(/\./g,"")}`),G={Type:"AWS::SES::EmailIdentity",Properties:{EmailIdentity:J,FeedbackAttributes:{EmailForwardingEnabled:!0}}};if(Z)G.Properties.DkimSigningAttributes={NextSigningKeyLength:U};return{emailIdentity:G,logicalId:z}}static createDkimRecords($,J,Y){let Q=[];for(let Z=0;Z<J.length;Z++){let U=J[Z],W=S(`dkim-${$.replace(/\./g,"")}-${Z+1}`),z={Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:Y,Name:`${U}._domainkey.${$}`,Type:"CNAME",TTL:1800,ResourceRecords:[`${U}.dkim.amazonses.com`]}};Q.push({record:z,logicalId:W})}return Q}static createConfigurationSet($){let{slug:J,environment:Y,name:Q,reputationMetrics:Z=!0,sendingEnabled:U=!0,suppressBounces:W=!0,suppressComplaints:z=!0}=$,G=Q||f({slug:J,environment:Y,resourceType:"ses-config"}),H=S(G),A=[];if(W)A.push("BOUNCE");if(z)A.push("COMPLAINT");return{configurationSet:{Type:"AWS::SES::ConfigurationSet",Properties:{Name:G,ReputationOptions:{ReputationMetricsEnabled:Z},SendingOptions:{SendingEnabled:U},SuppressionOptions:{SuppressedReasons:A}}},logicalId:H}}static createReceiptRuleSet($){let{slug:J,environment:Y,name:Q}=$,Z=Q||f({slug:J,environment:Y,resourceType:"ses-ruleset"}),U=S(Z);return{ruleSet:{Type:"AWS::SES::ReceiptRuleSet",Properties:{RuleSetName:Z}},logicalId:U}}static createReceiptRule($,J){let{slug:Y,environment:Q,ruleSetName:Z,recipients:U,enabled:W=!0,scanEnabled:z=!0,tlsPolicy:G="Require",s3Action:H,lambdaAction:A,snsAction:K}=J,B=f({slug:Y,environment:Q,resourceType:"ses-rule"}),j=S(B),X=[];if(H)X.push({S3Action:{BucketName:H.bucketName,ObjectKeyPrefix:H.prefix,KmsKeyArn:H.kmsKeyArn}});if(A)X.push({LambdaAction:{FunctionArn:A.functionArn,InvocationType:A.invocationType||"Event"}});if(K)X.push({SNSAction:{TopicArn:K.topicArn,Encoding:K.encoding||"UTF-8"}});return{receiptRule:{Type:"AWS::SES::ReceiptRule",Properties:{RuleSetName:Z,Rule:{Name:B,Enabled:W,ScanEnabled:z,TlsPolicy:G,Recipients:U,Actions:X.length>0?X:void 0}}},logicalId:j}}static createMxRecord($,J,Y){let Q=S(`mx-${$.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:J,Name:$,Type:"MX",TTL:300,ResourceRecords:[`10 inbound-smtp.${Y}.amazonaws.com`]}},logicalId:Q}}static createVerificationRecord($,J,Y){let Q=S(`verification-${$.replace(/\./g,"")}`);return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:Y,Name:`_amazonses.${$}`,Type:"TXT",TTL:1800,ResourceRecords:[`"${J}"`]}},logicalId:Q}}static getSmtpEndpoint($){return`email-smtp.${$}.amazonaws.com`}static SmtpPorts={TLS:587,SSL:465,Unencrypted:25};static createSpfRecord($,J,Y){let{includeDomains:Q=[],softFail:Z=!1}=Y||{},U=S(`spf-${$.replace(/\./g,"")}`),W="v=spf1 include:amazonses.com";for(let G of Q)W+=` include:${G}`;return W+=Z?" ~all":" -all",{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:J,Name:$,Type:"TXT",TTL:300,ResourceRecords:[`"${W}"`]}},logicalId:U}}static createDmarcRecord($,J,Y){let{policy:Q="none",subdomainPolicy:Z,percentage:U=100,reportingEmail:W,forensicEmail:z}=Y||{},G=S(`dmarc-${$.replace(/\./g,"")}`),H=`v=DMARC1; p=${Q}; pct=${U}`;if(Z)H+=`; sp=${Z}`;if(W)H+=`; rua=mailto:${W}`;if(z)H+=`; ruf=mailto:${z}`;return{record:{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:J,Name:`_dmarc.${$}`,Type:"TXT",TTL:300,ResourceRecords:[`"${H}"`]}},logicalId:G}}static createInboundEmailSetup($){let{slug:J,environment:Y,domain:Q,s3BucketName:Z,s3KeyPrefix:U="inbound/",region:W,hostedZoneId:z,lambdaFunctionArn:G,snsTopicArn:H}=$,A={},{ruleSet:K,logicalId:B}=H0.createReceiptRuleSet({slug:J,environment:Y});A[B]=K;let{receiptRule:j,logicalId:X}=H0.createReceiptRule(B,{slug:J,environment:Y,ruleSetName:K.Properties.RuleSetName||`${J}-${Y}-receipt-rule-set`,recipients:[Q],s3Action:{bucketName:Z,prefix:U},lambdaAction:G?{functionArn:G,invocationType:"Event"}:void 0,snsAction:H?{topicArn:H}:void 0});A[X]=j;let{record:O,logicalId:_}=H0.createMxRecord(Q,z,W);return A[_]=O,{resources:A,outputs:{ruleSetLogicalId:B,ruleLogicalId:X,mxRecordLogicalId:_}}}static createCompleteDomainSetup($){let{slug:J,environment:Y,domain:Q,hostedZoneId:Z,region:U,enableInbound:W=!1,inboundS3Bucket:z,dmarcReportingEmail:G}=$,H={},{emailIdentity:A,logicalId:K}=H0.verifyDomain({domain:Q,slug:J,environment:Y});H[K]=A;let{configurationSet:B,logicalId:j}=H0.createConfigurationSet({slug:J,environment:Y});H[j]=B;let{record:X,logicalId:O}=H0.createSpfRecord(Q,Z);H[O]=X;let{record:_,logicalId:w}=H0.createDmarcRecord(Q,Z,{policy:"none",reportingEmail:G||`dmarc-reports@${Q}`});if(H[w]=_,W&&z){let E=H0.createInboundEmailSetup({slug:J,environment:Y,domain:Q,s3BucketName:z,region:U,hostedZoneId:Z});Object.assign(H,E.resources)}return{resources:H,outputs:{identityLogicalId:K,configSetLogicalId:j}}}static InboundSmtpEndpoints={"us-east-1":"inbound-smtp.us-east-1.amazonaws.com","us-west-2":"inbound-smtp.us-west-2.amazonaws.com","eu-west-1":"inbound-smtp.eu-west-1.amazonaws.com"};static supportsInboundEmail($){return $ in H0.InboundSmtpEndpoints}static createEmailLambdaRole($){let{slug:J,environment:Y,s3BucketArn:Q,sesIdentityArn:Z}=$,U=f({slug:J,environment:Y,resourceType:"email-lambda-role"}),W=S(U),z=S(`${U}-policy`),G={Type:"AWS::IAM::Role",Properties:{RoleName:U,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Y}]}},H=[{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucket"],Resource:[Q,`${Q}/*`]}];if(Z)H.push({Effect:"Allow",Action:["ses:SendEmail","ses:SendRawEmail"],Resource:Z});let A={Type:"AWS::IAM::Policy",Properties:{PolicyName:`${U}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:H},Roles:[u.Ref(W)]}};return{role:G,policy:A,roleLogicalId:W,policyLogicalId:z}}static createOutboundEmailLambda($){let{slug:J,environment:Y,roleArn:Q,domain:Z,configurationSetName:U,timeout:W=30,memorySize:z=256}=$,G=f({slug:J,environment:Y,resourceType:"outbound-email"}),H=S(G);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:G,Runtime:"nodejs20.x",Handler:"index.handler",Role:Q,Timeout:W,MemorySize:z,Environment:{Variables:{DOMAIN:Z,CONFIGURATION_SET:U||""}},Code:{ZipFile:H0.LambdaCode.outboundEmail},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"OutboundEmail"}]}},logicalId:H}}static createInboundEmailLambda($){let{slug:J,environment:Y,roleArn:Q,s3BucketName:Z,organizedPrefix:U="organized/",timeout:W=60,memorySize:z=512}=$,G=f({slug:J,environment:Y,resourceType:"inbound-email"}),H=S(G),A=S(`${G}-permission`),K={Type:"AWS::Lambda::Function",Properties:{FunctionName:G,Runtime:"nodejs20.x",Handler:"index.handler",Role:Q,Timeout:W,MemorySize:z,Environment:{Variables:{S3_BUCKET:Z,ORGANIZED_PREFIX:U}},Code:{ZipFile:H0.LambdaCode.inboundEmail},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"InboundEmail"}]}},B={Type:"AWS::Lambda::Permission",Properties:{FunctionName:u.Ref(H),Action:"lambda:InvokeFunction",Principal:"ses.amazonaws.com",SourceAccount:u.Ref("AWS::AccountId")}};return{function:K,permission:B,logicalId:H,permissionLogicalId:A}}static createEmailConversionLambda($){let{slug:J,environment:Y,roleArn:Q,s3BucketName:Z,convertedPrefix:U="converted/",timeout:W=60,memorySize:z=512}=$,G=f({slug:J,environment:Y,resourceType:"email-conversion"}),H=S(G);return{function:{Type:"AWS::Lambda::Function",Properties:{FunctionName:G,Runtime:"nodejs20.x",Handler:"index.handler",Role:Q,Timeout:W,MemorySize:z,Environment:{Variables:{S3_BUCKET:Z,CONVERTED_PREFIX:U}},Code:{ZipFile:H0.LambdaCode.emailConversion},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"EmailConversion"}]}},logicalId:H}}static createEmailBucketNotification($){let{lambdaArn:J,prefix:Y="inbound/",suffix:Q,events:Z=["s3:ObjectCreated:*"]}=$,U={};if(Y||Q){if(U.S3Key={Rules:[]},Y)U.S3Key.Rules.push({Name:"prefix",Value:Y});if(Q)U.S3Key.Rules.push({Name:"suffix",Value:Q})}return{notificationConfiguration:{LambdaConfigurations:[{Event:Z[0],Function:J,Filter:Object.keys(U).length>0?U:void 0}]}}}static createS3LambdaPermission($){let{slug:J,environment:Y,lambdaLogicalId:Q,s3BucketArn:Z}=$,U=f({slug:J,environment:Y,resourceType:"s3-lambda-permission"}),W=S(U);return{permission:{Type:"AWS::Lambda::Permission",Properties:{FunctionName:u.Ref(Q),Action:"lambda:InvokeFunction",Principal:"s3.amazonaws.com",SourceArn:Z}},logicalId:W}}static createEmailProcessingStack($){let{slug:J,environment:Y,domain:Q,s3BucketName:Z,s3BucketArn:U,configurationSetName:W,enableInbound:z=!0,enableConversion:G=!0}=$,H={},{role:A,policy:K,roleLogicalId:B,policyLogicalId:j}=H0.createEmailLambdaRole({slug:J,environment:Y,s3BucketArn:U,sesIdentityArn:`arn:aws:ses:*:*:identity/${Q}`});H[B]=A,H[j]=K;let{function:X,logicalId:O}=H0.createOutboundEmailLambda({slug:J,environment:Y,roleArn:u.GetAtt(B,"Arn"),domain:Q,configurationSetName:W});H[O]=X;let _={roleLogicalId:B,outboundLambdaLogicalId:O};if(z){let{function:w,permission:E,logicalId:M,permissionLogicalId:T}=H0.createInboundEmailLambda({slug:J,environment:Y,roleArn:u.GetAtt(B,"Arn"),s3BucketName:Z});H[M]=w,H[T]=E;let{permission:D,logicalId:N}=H0.createS3LambdaPermission({slug:J,environment:Y,lambdaLogicalId:M,s3BucketArn:U});H[N]=D,_.inboundLambdaLogicalId=M}if(G){let{function:w,logicalId:E}=H0.createEmailConversionLambda({slug:J,environment:Y,roleArn:u.GetAtt(B,"Arn"),s3BucketName:Z});H[E]=w,_.conversionLambdaLogicalId=E}return{resources:H,outputs:_}}static LambdaCode={outboundEmail:`
5201
5201
  const { SESClient, SendRawEmailCommand } = require('@aws-sdk/client-ses');
5202
5202
  const ses = new SESClient({});
5203
5203
 
@@ -5743,14 +5743,14 @@ else if (encoding === 'quoted-printable') {
5743
5743
 
5744
5744
  return content;
5745
5745
  }
5746
- `}};yQ={};q2(yQ,{handler:()=>q6,default:()=>X4});X4=q6;R1=class R1{static LambdaCode={incomingCall:q6,voicemail:O4,missedCall:_4};static createConnectInstance($){let{slug:J,environment:Y,instanceAlias:Q,inboundCallsEnabled:Z=!0,outboundCallsEnabled:U=!0}=$;return{[`${J}ConnectInstance`]:{Type:"AWS::Connect::Instance",Properties:{InstanceAlias:Q,IdentityManagementType:"CONNECT_MANAGED",Attributes:{InboundCalls:Z,OutboundCalls:U,ContactflowLogs:!0,ContactLens:!0,AutoResolveBestVoices:!0,UseCustomTTSVoices:!1,EarlyMedia:!0}}}}}static createHoursOfOperation($){return{[`${$.slug}HoursOfOperation`]:{Type:"AWS::Connect::HoursOfOperation",Properties:{InstanceArn:$.instanceArn,Name:$.name,TimeZone:$.timezone,Config:$.schedule.map((J)=>({Day:J.day,StartTime:{Hours:J.startHour,Minutes:J.startMinute},EndTime:{Hours:J.endHour,Minutes:J.endMinute}}))}}}}static createQueue($){return{[`${$.slug}Queue`]:{Type:"AWS::Connect::Queue",Properties:{InstanceArn:$.instanceArn,Name:$.name,HoursOfOperationArn:$.hoursOfOperationArn,MaxContacts:$.maxContacts||10}}}}static createContactFlow($){return{[`${$.slug}ContactFlow`]:{Type:"AWS::Connect::ContactFlow",Properties:{InstanceArn:$.instanceArn,Name:$.name,Type:$.type,Content:$.content}}}}static createBasicIvrFlow($){let J={Version:"2019-10-30",StartAction:"greeting",Actions:[{Identifier:"greeting",Type:"MessageParticipant",Parameters:{Text:$.greeting},Transitions:{NextAction:"transfer_to_queue",Errors:[{NextAction:"disconnect"}]}},{Identifier:"transfer_to_queue",Type:"TransferToQueue",Parameters:{QueueId:$.queueArn},Transitions:{NextAction:$.voicemailLambdaArn?"voicemail":"disconnect",Errors:[{NextAction:"disconnect"}]}},...$.voicemailLambdaArn?[{Identifier:"voicemail",Type:"InvokeLambdaFunction",Parameters:{LambdaFunctionARN:$.voicemailLambdaArn},Transitions:{NextAction:"disconnect",Errors:[{NextAction:"disconnect"}]}}]:[],{Identifier:"disconnect",Type:"DisconnectParticipant",Parameters:{},Transitions:{}}]};return JSON.stringify(J)}static createPhoneLambdaRole($){return{[`${$.slug}PhoneLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${$.slug}-phone-lambda-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"PhoneLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject"],Resource:"*"},{Effect:"Allow",Action:["transcribe:StartTranscriptionJob","transcribe:GetTranscriptionJob"],Resource:"*"},{Effect:"Allow",Action:["connect:*"],Resource:"*"}]}}]}}}}static createIncomingCallLambda($){return{[`${$.slug}IncomingCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-incoming-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:R1.LambdaCode.incomingCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",CALL_LOG_TABLE:$.callLogTable||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createVoicemailLambda($){return{[`${$.slug}VoicemailLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-voicemail`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:300,MemorySize:512,Code:{ZipFile:R1.LambdaCode.voicemail},Environment:{Variables:{VOICEMAIL_BUCKET:$.voicemailBucket,NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",CALL_LOG_TABLE:$.callLogTable||"",TRANSCRIPTION_ENABLED:$.transcriptionEnabled?"true":"false"}}}}}}static createMissedCallLambda($){return{[`${$.slug}MissedCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-missed-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:R1.LambdaCode.missedCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",CALL_LOG_TABLE:$.callLogTable||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createCallLogTable($){return{[`${$.slug}CallLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$.slug}-call-log`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"contactId",AttributeType:"S"}],KeySchema:[{AttributeName:"contactId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createCompleteSetup($){let J={},Y={};Object.assign(J,R1.createPhoneLambdaRole({slug:$.slug})),Object.assign(J,R1.createCallLogTable({slug:$.slug})),J[`${$.slug}PhoneNotificationTopic`]={Type:"AWS::SNS::Topic",Properties:{TopicName:`${$.slug}-phone-notifications`}},J[`${$.slug}VoicemailBucket`]={Type:"AWS::S3::Bucket",Properties:{BucketName:`${$.slug}-voicemails`,LifecycleConfiguration:{Rules:[{Id:"DeleteOldVoicemails",Status:"Enabled",ExpirationInDays:90}]}}};let Q={"Fn::GetAtt":[`${$.slug}PhoneLambdaRole`,"Arn"]},Z={Ref:`${$.slug}PhoneNotificationTopic`},U={Ref:`${$.slug}CallLogTable`},W={Ref:`${$.slug}VoicemailBucket`};if(Object.assign(J,R1.createIncomingCallLambda({slug:$.slug,roleArn:Q,notificationTopicArn:Z,callLogTable:U,webhookUrl:$.webhookUrl})),$.voicemailEnabled!==!1)Object.assign(J,R1.createVoicemailLambda({slug:$.slug,roleArn:Q,voicemailBucket:W,notificationTopicArn:Z,callLogTable:U,transcriptionEnabled:$.transcriptionEnabled}));return Object.assign(J,R1.createMissedCallLambda({slug:$.slug,roleArn:Q,notificationTopicArn:Z,callLogTable:U,webhookUrl:$.webhookUrl})),Y[`${$.slug}PhoneNotificationTopicArn`]={Description:"Phone notification topic ARN",Value:{Ref:`${$.slug}PhoneNotificationTopic`}},Y[`${$.slug}CallLogTableName`]={Description:"Call log table name",Value:{Ref:`${$.slug}CallLogTable`}},Y[`${$.slug}VoicemailBucketName`]={Description:"Voicemail bucket name",Value:{Ref:`${$.slug}VoicemailBucket`}},{resources:J,outputs:Y}}};t0=class t0{static createQueue($){let{slug:J,environment:Y,name:Q,delaySeconds:Z=0,visibilityTimeout:U=30,messageRetentionPeriod:W=345600,maxMessageSize:z=262144,receiveMessageWaitTime:G=0,fifo:H=!1,contentBasedDeduplication:A=!1,encrypted:K=!0,kmsKeyId:B}=$,j=Q||v({slug:J,environment:Y,resourceType:"queue"}),X=H?`${j}.fifo`:j,O=S(j),_={Type:"AWS::SQS::Queue",Properties:{QueueName:X,DelaySeconds:Z,MaximumMessageSize:z,MessageRetentionPeriod:W,ReceiveMessageWaitTimeSeconds:G,VisibilityTimeout:U,Tags:[{Key:"Name",Value:X},{Key:"Environment",Value:Y}]}};if(H)_.Properties.FifoQueue=!0,_.Properties.ContentBasedDeduplication=A;if(K)if(B)_.Properties.KmsMasterKeyId=B;else _.Properties.SqsManagedSseEnabled=!0;return{queue:_,logicalId:O}}static createDeadLetterQueue($,J){let{slug:Y,environment:Q,maxReceiveCount:Z=3}=J,U=v({slug:Y,environment:Q,resourceType:"dlq"}),W=S(U),z={Type:"AWS::SQS::Queue",Properties:{QueueName:U,MessageRetentionPeriod:1209600,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q},{Key:"Type",Value:"DeadLetterQueue"}]}},G={Type:"AWS::SQS::Queue",Properties:{RedrivePolicy:{deadLetterTargetArn:u.GetAtt(W,"Arn"),maxReceiveCount:Z}}};return{deadLetterQueue:z,updatedSourceQueue:G,deadLetterLogicalId:W}}static createSchedule($,J){let{slug:Y,environment:Q,name:Z,description:U,enabled:W=!0}=J,z=Z||v({slug:Y,environment:Q,resourceType:"schedule"}),G=S(z);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:z,Description:U,ScheduleExpression:$,State:W?"ENABLED":"DISABLED",Targets:[]}},logicalId:G}}static scheduleEcsTask($,J,Y){let{slug:Q,environment:Z,name:U,description:W,enabled:z=!0,taskDefinitionArn:G,clusterArn:H,subnets:A,securityGroups:K=[],assignPublicIp:B=!1,taskCount:j=1,containerOverrides:X}=Y,O=U||v({slug:Q,environment:Z,resourceType:"ecs-schedule"}),_=S(O),E={Id:"1",Arn:H,RoleArn:J,EcsParameters:{TaskDefinitionArn:G,TaskCount:j,LaunchType:"FARGATE",NetworkConfiguration:{awsvpcConfiguration:{Subnets:A,SecurityGroups:K,AssignPublicIp:B?"ENABLED":"DISABLED"}},PlatformVersion:"LATEST"}};if(X&&X.length>0)E.Input=JSON.stringify({containerOverrides:X});return{rule:{Type:"AWS::Events::Rule",Properties:{Name:O,Description:W||`Scheduled ECS task: ${G}`,ScheduleExpression:$,State:z?"ENABLED":"DISABLED",Targets:[E]}},logicalId:_}}static scheduleLambda($,J){let{slug:Y,environment:Q,name:Z,description:U,enabled:W=!0,functionArn:z,input:G}=J,H=Z||v({slug:Y,environment:Q,resourceType:"lambda-schedule"}),A=S(H),K={Id:"1",Arn:z};if(G)K.Input=JSON.stringify(G);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:H,Description:U||`Scheduled Lambda: ${z}`,ScheduleExpression:$,State:W?"ENABLED":"DISABLED",Targets:[K]}},logicalId:A}}static scheduleSqsMessage($,J){let{slug:Y,environment:Q,name:Z,description:U,enabled:W=!0,queueArn:z,messageGroupId:G}=J,H=Z||v({slug:Y,environment:Q,resourceType:"sqs-schedule"}),A=S(H),K={Id:"1",Arn:z};if(G)K.SqsParameters={MessageGroupId:G};return{rule:{Type:"AWS::Events::Rule",Properties:{Name:H,Description:U||`Scheduled SQS message: ${z}`,ScheduleExpression:$,State:W?"ENABLED":"DISABLED",Targets:[K]}},logicalId:A}}static addTarget($,J){if(!$.Properties.Targets)$.Properties.Targets=[];let Y={Id:J.id,Arn:J.arn};if(J.roleArn)Y.RoleArn=J.roleArn;if(J.input)Y.Input=JSON.stringify(J.input);return $.Properties.Targets.push(Y),$}static toCronExpression($){if($.startsWith("cron(")||$.startsWith("rate("))return $;return`cron(${$})`}static rateExpression($,J){return`rate(${$} ${J})`}static CronExpressions={EveryMinute:"cron(* * * * ? *)",Every5Minutes:"cron(*/5 * * * ? *)",Every15Minutes:"cron(*/15 * * * ? *)",Every30Minutes:"cron(*/30 * * * ? *)",Hourly:"cron(0 * * * ? *)",Daily:"cron(0 0 * * ? *)",DailyAt9AM:"cron(0 9 * * ? *)",DailyAtMidnight:"cron(0 0 * * ? *)",Weekly:"cron(0 0 ? * SUN *)",Monthly:"cron(0 0 1 * ? *)"};static RateExpressions={Every1Minute:"rate(1 minute)",Every5Minutes:"rate(5 minutes)",Every10Minutes:"rate(10 minutes)",Every15Minutes:"rate(15 minutes)",Every30Minutes:"rate(30 minutes)",Every1Hour:"rate(1 hour)",Every6Hours:"rate(6 hours)",Every12Hours:"rate(12 hours)",Every1Day:"rate(1 day)"};static rateStringToExpression($){let J=$.toLowerCase().trim(),Y=J.match(/^every\s+(\d+)\s+(minute|minutes|hour|hours|day|days)$/i);if(Y){let H=parseInt(Y[1],10),A=Y[2].toLowerCase(),K=A.endsWith("s")&&H===1?A.slice(0,-1):A,B=!A.endsWith("s")&&H>1?`${A}s`:A;return`rate(${H} ${H===1?K:B})`}let Q=J.match(/^every\s+(minute|hour|day)$/i);if(Q)return`rate(1 ${Q[1]})`;let Z={"every minute":"rate(1 minute)","every hour":"rate(1 hour)","every day":"rate(1 day)",hourly:"cron(0 * * * ? *)",daily:"cron(0 0 * * ? *)","daily at midnight":"cron(0 0 * * ? *)",weekly:"cron(0 0 ? * SUN *)",monthly:"cron(0 0 1 * ? *)",yearly:"cron(0 0 1 1 ? *)"};if(Z[J])return Z[J];let U=J.match(/^daily\s+at\s+(\d{1,2})\s*(am|pm)?$/i);if(U){let H=parseInt(U[1],10),A=U[2]?.toLowerCase();if(A==="pm"&&H!==12)H+=12;else if(A==="am"&&H===12)H=0;return`cron(0 ${H} * * ? *)`}let W=J.match(/^at\s+(\d{1,2}):(\d{2})$/i);if(W){let H=parseInt(W[1],10);return`cron(${parseInt(W[2],10)} ${H} * * ? *)`}let z={monday:"MON",tuesday:"TUE",wednesday:"WED",thursday:"THU",friday:"FRI",saturday:"SAT",sunday:"SUN"},G=J.match(/^every\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/i);if(G)return`cron(0 0 ? * ${z[G[1].toLowerCase()]} *)`;return t0.toCronExpression($)}static JobConfig={create:($)=>{let{name:J,handler:Y,retries:Q=3,backoff:Z="exponential",backoffDelay:U=1000,maxDelay:W=30000,timeout:z=60000,jitter:G=!0}=$;return{name:J,handler:Y,retries:Q,backoff:Z,backoffDelay:U,maxDelay:W,timeout:z,jitter:G}},calculateDelay:($,J)=>{let{backoff:Y,backoffDelay:Q,maxDelay:Z,jitter:U}=J,W;switch(Y){case"linear":W=Q*$;break;case"exponential":W=Q*2**($-1);break;case"fixed":default:W=Q}if(W=Math.min(W,Z||Number.MAX_SAFE_INTEGER),U){let z=W*0.25*Math.random();W+=z}return Math.floor(W)},presets:{fastRetry:{retries:5,backoff:"exponential",backoffDelay:100,maxDelay:5000,jitter:!0},standard:{retries:3,backoff:"exponential",backoffDelay:1000,maxDelay:30000,jitter:!0},longRunning:{retries:2,backoff:"exponential",backoffDelay:5000,maxDelay:60000,timeout:300000,jitter:!0},critical:{retries:10,backoff:"exponential",backoffDelay:500,maxDelay:60000,jitter:!0},noRetry:{retries:0,backoff:"fixed",backoffDelay:0,maxDelay:0,jitter:!1}}};static createJobContainerOverride($){let{containerName:J,jobClass:Y,jobData:Q,environment:Z={}}=$,U=[{name:"JOB_CLASS",value:Y}];if(Q)U.push({name:"JOB_DATA",value:JSON.stringify(Q)});for(let[W,z]of Object.entries(Z))U.push({name:W,value:z});return{name:J,command:["bun","run","app/Jobs/runner.ts"],environment:U}}static createScheduledJob($){let{slug:J,environment:Y,schedule:Q,jobClass:Z,jobData:U,taskDefinitionArn:W,clusterArn:z,subnets:G,securityGroups:H=[],roleArn:A,containerName:K="app"}=$,B=t0.rateStringToExpression(Q),j=t0.createJobContainerOverride({containerName:K,jobClass:Z,jobData:U});return t0.scheduleEcsTask(B,A,{slug:J,environment:Y,name:`${J}-${Z.toLowerCase().replace(/[^a-z0-9]/g,"-")}`,description:`Scheduled job: ${Z}`,taskDefinitionArn:W,clusterArn:z,subnets:G,securityGroups:H,containerOverrides:[j]})}static QueuePresets={highThroughput:($,J)=>t0.createQueue({slug:$,environment:J,visibilityTimeout:30,receiveMessageWaitTime:0,delaySeconds:0}),longRunning:($,J)=>t0.createQueue({slug:$,environment:J,visibilityTimeout:300,messageRetentionPeriod:1209600}),fifo:($,J)=>t0.createQueue({slug:$,environment:J,fifo:!0,contentBasedDeduplication:!0}),delayed:($,J,Y=60)=>t0.createQueue({slug:$,environment:J,delaySeconds:Y})}};q4={loadJobs:m1.discoverJobs,loadActions:m1.discoverActions,generateScheduledJobs:m1.generateScheduledJobResources,generateRunner:m1.generateJobRunnerScript,paths:{jobs:"app/Jobs",actions:"app/Actions",runner:"app/Jobs/runner.ts"}},vQ={};q2(vQ,{handler:()=>E6,default:()=>E4});E4=E6;r0=class r0{static LambdaCode={send:E6,receive:w4,deliveryStatus:V4};static createPinpointApp($){return{[`${$.slug}PinpointApp`]:{Type:"AWS::Pinpoint::App",Properties:{Name:$.name||`${$.slug}-sms`}}}}static createSmsChannel($){let J={ApplicationId:$.applicationId,Enabled:$.enabled!==!1};if($.senderId)J.SenderId=$.senderId;if($.shortCode)J.ShortCode=$.shortCode;return{[`${$.slug}SmsChannel`]:{Type:"AWS::Pinpoint::SMSChannel",Properties:J}}}static createSmsLambdaRole($){return{[`${$.slug}SmsLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${$.slug}-sms-lambda-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"SmsLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["mobiletargeting:SendMessages","mobiletargeting:GetSmsChannel"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem","dynamodb:DeleteItem"],Resource:"*"}]}}]}}}}static createSendLambda($){return{[`${$.slug}SmsSendLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-sms-send`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:r0.LambdaCode.send},Environment:{Variables:{PINPOINT_APP_ID:$.pinpointAppId,MESSAGE_LOG_TABLE:$.messageLogTable||"",SMS_SENDER_ID:$.senderId||"",SMS_ORIGINATION_NUMBER:$.originationNumber||""}}}}}}static createReceiveLambda($){return{[`${$.slug}SmsReceiveLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-sms-receive`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:r0.LambdaCode.receive},Environment:{Variables:{OPT_OUT_TABLE:$.optOutTable||"",MESSAGE_LOG_TABLE:$.messageLogTable||"",NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createDeliveryStatusLambda($){return{[`${$.slug}SmsDeliveryStatusLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-sms-delivery-status`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:r0.LambdaCode.deliveryStatus},Environment:{Variables:{MESSAGE_LOG_TABLE:$.messageLogTable||"",NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createMessageLogTable($){return{[`${$.slug}SmsMessageLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$.slug}-sms-messages`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"messageId",AttributeType:"S"}],KeySchema:[{AttributeName:"messageId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createOptOutTable($){return{[`${$.slug}SmsOptOutTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$.slug}-sms-optouts`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"phoneNumber",AttributeType:"S"}],KeySchema:[{AttributeName:"phoneNumber",KeyType:"HASH"}]}}}}static createNotificationTopic($){return{[`${$.slug}SmsNotificationTopic`]:{Type:"AWS::SNS::Topic",Properties:{TopicName:`${$.slug}-sms-notifications`}}}}static createCompleteSetup($){let J={},Y={};Object.assign(J,r0.createPinpointApp({slug:$.slug})),Object.assign(J,r0.createSmsChannel({slug:$.slug,applicationId:{Ref:`${$.slug}PinpointApp`},senderId:$.senderId})),Object.assign(J,r0.createSmsLambdaRole({slug:$.slug})),Object.assign(J,r0.createMessageLogTable({slug:$.slug})),Object.assign(J,r0.createOptOutTable({slug:$.slug})),Object.assign(J,r0.createNotificationTopic({slug:$.slug}));let Q={"Fn::GetAtt":[`${$.slug}SmsLambdaRole`,"Arn"]},Z={Ref:`${$.slug}PinpointApp`},U={Ref:`${$.slug}SmsMessageLogTable`},W={Ref:`${$.slug}SmsOptOutTable`},z={Ref:`${$.slug}SmsNotificationTopic`};if(Object.assign(J,r0.createSendLambda({slug:$.slug,roleArn:Q,pinpointAppId:Z,messageLogTable:U,senderId:$.senderId,originationNumber:$.originationNumber})),$.twoWayEnabled)Object.assign(J,r0.createReceiveLambda({slug:$.slug,roleArn:Q,optOutTable:W,messageLogTable:U,notificationTopicArn:z,webhookUrl:$.webhookUrl}));return Object.assign(J,r0.createDeliveryStatusLambda({slug:$.slug,roleArn:Q,messageLogTable:U,notificationTopicArn:z,webhookUrl:$.webhookUrl})),Y[`${$.slug}PinpointAppId`]={Description:"Pinpoint application ID",Value:{Ref:`${$.slug}PinpointApp`}},Y[`${$.slug}SmsSendLambdaArn`]={Description:"SMS send Lambda ARN",Value:{"Fn::GetAtt":[`${$.slug}SmsSendLambda`,"Arn"]}},Y[`${$.slug}SmsNotificationTopicArn`]={Description:"SMS notification topic ARN",Value:{Ref:`${$.slug}SmsNotificationTopic`}},Y[`${$.slug}SmsMessageLogTableName`]={Description:"SMS message log table name",Value:{Ref:`${$.slug}SmsMessageLogTable`}},{resources:J,outputs:Y}}};O1=class O1{static createBedrockRole($,J){let{slug:Y,environment:Q,name:Z,models:U=["*"],allowStreaming:W=!0}=J,z=Z||v({slug:Y,environment:Q,resourceType:"bedrock-role"}),G=S(z),H=["bedrock:InvokeModel"];if(W)H.push("bedrock:InvokeModelWithResponseStream");let A=U.map((B)=>B==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${B}`);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:$},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:`${z}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:H,Resource:A}]}}],Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Q}]}},logicalId:G}}static createBedrockPolicy($){let{slug:J,environment:Y,name:Q,models:Z=["*"],allowInvoke:U=!0,allowStreaming:W=!0,allowAsync:z=!1}=$,G=Q||v({slug:J,environment:Y,resourceType:"bedrock-policy"}),H=S(G),A=[];if(U)A.push("bedrock:InvokeModel");if(W)A.push("bedrock:InvokeModelWithResponseStream");if(z)A.push("bedrock:InvokeModelAsync");let K=Z.map((j)=>j==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${j}`);return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:G,PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"BedrockModelInvocation",Effect:"Allow",Action:A,Resource:K}]}}},logicalId:H}}static enableBedrockForLambda($){return O1.createBedrockRole("lambda.amazonaws.com",$)}static enableBedrockForEcs($){return O1.createBedrockRole("ecs-tasks.amazonaws.com",$)}static enableBedrockForEc2($){return O1.createBedrockRole("ec2.amazonaws.com",$)}static addBedrockPermissions($,J=["*"],Y=!0){let Q=["bedrock:InvokeModel"];if(Y)Q.push("bedrock:InvokeModelWithResponseStream");let Z=J.map((U)=>U==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${U}`);if(!$.Properties.Policies)$.Properties.Policies=[];return $.Properties.Policies.push({PolicyName:"bedrock-permissions",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:Q,Resource:Z}]}}),$}static Models={Claude3_5_Sonnet:"anthropic.claude-3-5-sonnet-20241022-v2:0",Claude3_5_Haiku:"anthropic.claude-3-5-haiku-20241022-v1:0",Claude3_Opus:"anthropic.claude-3-opus-20240229-v1:0",Claude3_Sonnet:"anthropic.claude-3-sonnet-20240229-v1:0",Claude3_Haiku:"anthropic.claude-3-haiku-20240307-v1:0",TitanTextG1Express:"amazon.titan-text-express-v1",TitanTextG1Lite:"amazon.titan-text-lite-v1",TitanEmbedG1Text:"amazon.titan-embed-text-v1",TitanImageG1:"amazon.titan-image-generator-v1",JurassicUltra:"ai21.j2-ultra-v1",JurassicMid:"ai21.j2-mid-v1",CommandText:"cohere.command-text-v14",CommandLight:"cohere.command-light-text-v14",EmbedEnglish:"cohere.embed-english-v3",EmbedMultilingual:"cohere.embed-multilingual-v3",Llama3_2_1B:"meta.llama3-2-1b-instruct-v1:0",Llama3_2_3B:"meta.llama3-2-3b-instruct-v1:0",Llama3_2_11B:"meta.llama3-2-11b-instruct-v1:0",Llama3_2_90B:"meta.llama3-2-90b-instruct-v1:0",Llama3_1_8B:"meta.llama3-1-8b-instruct-v1:0",Llama3_1_70B:"meta.llama3-1-70b-instruct-v1:0",Llama3_1_405B:"meta.llama3-1-405b-instruct-v1:0",Mistral7B:"mistral.mistral-7b-instruct-v0:2",Mixtral8x7B:"mistral.mixtral-8x7b-instruct-v0:1",MistralLarge:"mistral.mistral-large-2402-v1:0",StableDiffusionXL:"stability.stable-diffusion-xl-v1"};static ModelGroups={AllClaude:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","anthropic.claude-3-opus-20240229-v1:0","anthropic.claude-3-sonnet-20240229-v1:0","anthropic.claude-3-haiku-20240307-v1:0"],AllTitan:["amazon.titan-text-express-v1","amazon.titan-text-lite-v1","amazon.titan-embed-text-v1","amazon.titan-image-generator-v1"],AllLlama:["meta.llama3-2-1b-instruct-v1:0","meta.llama3-2-3b-instruct-v1:0","meta.llama3-2-11b-instruct-v1:0","meta.llama3-2-90b-instruct-v1:0","meta.llama3-1-8b-instruct-v1:0","meta.llama3-1-70b-instruct-v1:0","meta.llama3-1-405b-instruct-v1:0"],TextModels:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","amazon.titan-text-express-v1","meta.llama3-2-11b-instruct-v1:0","mistral.mistral-7b-instruct-v0:2"],EmbeddingModels:["amazon.titan-embed-text-v1","cohere.embed-english-v3","cohere.embed-multilingual-v3"],ImageModels:["amazon.titan-image-generator-v1","stability.stable-diffusion-xl-v1"]}};Q2=class Q2{static createPostgres($){return Q2.createRDSInstance("postgres","16.2",$)}static createMysql($){return Q2.createRDSInstance("mysql","8.0.35",$)}static createRDSInstance($,J,Y){let{slug:Q,environment:Z,instanceClass:U="db.t3.micro",allocatedStorage:W=20,storageType:z="gp3",masterUsername:G="admin",masterPassword:H,databaseName:A,subnetIds:K,securityGroupIds:B,encrypted:j=!0,kmsKeyId:X,multiAz:O=!1,backupRetentionDays:_=7,publiclyAccessible:w=!1,enableCloudwatchLogs:E=!0,deletionProtection:M=!0}=Y,T=v({slug:Q,environment:Z,resourceType:`${$}-db`}),D=S(T),N,x;if(K&&K.length>0){let k=v({slug:Q,environment:Z,resourceType:"db-subnet-group"});x=S(k),N={Type:"AWS::RDS::DBSubnetGroup",Properties:{DBSubnetGroupName:k,DBSubnetGroupDescription:`Subnet group for ${T}`,SubnetIds:K,Tags:[{Key:"Name",Value:k},{Key:"Environment",Value:Z}]}}}let h={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:T,DBInstanceClass:U,Engine:$,EngineVersion:J,MasterUsername:G,MasterUserPassword:H,AllocatedStorage:W,StorageType:z,StorageEncrypted:j,MultiAZ:O,BackupRetentionPeriod:_,PubliclyAccessible:w,DeletionProtection:M,Tags:[{Key:"Name",Value:T},{Key:"Environment",Value:Z}]}};if(A)h.Properties.DBName=A;if(X)h.Properties.KmsKeyId=X;if(x)h.Properties.DBSubnetGroupName=u.Ref(x);if(B&&B.length>0)h.Properties.VPCSecurityGroups=B;if(E)h.Properties.EnableCloudwatchLogsExports=$==="postgres"?["postgresql"]:["error","general","slowquery"];return{dbInstance:h,subnetGroup:N,logicalId:D,subnetGroupId:x}}static createReadReplica($,J){let{slug:Y,environment:Q,instanceClass:Z="db.t3.micro",securityGroupIds:U,publiclyAccessible:W=!1}=J,z=v({slug:Y,environment:Q,resourceType:"db-replica"}),G=S(z),H={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:z,DBInstanceClass:Z,SourceDBInstanceIdentifier:u.Ref($),PubliclyAccessible:W,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Q},{Key:"Type",Value:"ReadReplica"}]}};if(U&&U.length>0)H.Properties.VPCSecurityGroups=U;return{replica:H,logicalId:G}}static createParameterGroup($,J,Y){let{slug:Q,environment:Z,parameters:U={}}=Y,W=v({slug:Q,environment:Z,resourceType:"db-params"}),z=S(W),G=$==="postgres"?`postgres${J.split(".")[0]}`:`mysql${J.split(".")[0]}.${J.split(".")[1]}`;return{parameterGroup:{Type:"AWS::RDS::DBParameterGroup",Properties:{DBParameterGroupName:W,Description:`Parameter group for ${W}`,Family:G,Parameters:U,Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Z}]}},logicalId:z}}static enableBackup($,J=7){return $.Properties.BackupRetentionPeriod=J,$}static createTable($){let{slug:J,environment:Y,tableName:Q,partitionKey:Z,sortKey:U,billingMode:W="PAY_PER_REQUEST",readCapacity:z=5,writeCapacity:G=5,streamEnabled:H=!1,streamViewType:A="NEW_AND_OLD_IMAGES",encrypted:K=!0,kmsKeyId:B,pointInTimeRecovery:j=!0,ttlAttribute:X}=$,O=Q||v({slug:J,environment:Y,resourceType:"table"}),_=S(O),w=[{AttributeName:Z.name,AttributeType:Z.type}];if(U)w.push({AttributeName:U.name,AttributeType:U.type});let E=[{AttributeName:Z.name,KeyType:"HASH"}];if(U)E.push({AttributeName:U.name,KeyType:"RANGE"});let M={Type:"AWS::DynamoDB::Table",Properties:{TableName:O,BillingMode:W,AttributeDefinitions:w,KeySchema:E,Tags:[{Key:"Name",Value:O},{Key:"Environment",Value:Y}]}};if(W==="PROVISIONED")M.Properties.ProvisionedThroughput={ReadCapacityUnits:z,WriteCapacityUnits:G};if(H)M.Properties.StreamSpecification={StreamViewType:A};if(K)M.Properties.SSESpecification={SSEEnabled:!0,SSEType:B?"KMS":"AES256",KMSMasterKeyId:B};if(j)M.Properties.PointInTimeRecoverySpecification={PointInTimeRecoveryEnabled:!0};if(X)M.Properties.TimeToLiveSpecification={AttributeName:X,Enabled:!0};return{table:M,logicalId:_}}static addGlobalSecondaryIndex($,J){let{indexName:Y,partitionKey:Q,sortKey:Z,projectionType:U="ALL",nonKeyAttributes:W,readCapacity:z=5,writeCapacity:G=5}=J;if(!$.Properties.AttributeDefinitions.some((K)=>K.AttributeName===Q.name))$.Properties.AttributeDefinitions.push({AttributeName:Q.name,AttributeType:Q.type});if(Z&&!$.Properties.AttributeDefinitions.some((K)=>K.AttributeName===Z.name))$.Properties.AttributeDefinitions.push({AttributeName:Z.name,AttributeType:Z.type});let H=[{AttributeName:Q.name,KeyType:"HASH"}];if(Z)H.push({AttributeName:Z.name,KeyType:"RANGE"});let A={IndexName:Y,KeySchema:H,Projection:{ProjectionType:U,NonKeyAttributes:U==="INCLUDE"?W:void 0},ProvisionedThroughput:void 0};if($.Properties.BillingMode==="PROVISIONED")A.ProvisionedThroughput={ReadCapacityUnits:z,WriteCapacityUnits:G};if(!$.Properties.GlobalSecondaryIndexes)$.Properties.GlobalSecondaryIndexes=[];return $.Properties.GlobalSecondaryIndexes.push(A),$}static enableStreams($,J="NEW_AND_OLD_IMAGES"){return $.Properties.StreamSpecification={StreamViewType:J},$}static InstanceClasses={T3_Micro:"db.t3.micro",T3_Small:"db.t3.small",T3_Medium:"db.t3.medium",T3_Large:"db.t3.large",T4g_Micro:"db.t4g.micro",T4g_Small:"db.t4g.small",T4g_Medium:"db.t4g.medium",M5_Large:"db.m5.large",M5_XLarge:"db.m5.xlarge",M5_2XLarge:"db.m5.2xlarge",R5_Large:"db.r5.large",R5_XLarge:"db.r5.xlarge",R5_2XLarge:"db.r5.2xlarge"}};O$=class O${static createRedis($){let{slug:J,environment:Y,nodeType:Q="cache.t3.micro",engineVersion:Z="7.1",port:U=6379,subnetIds:W,securityGroupIds:z,numCacheClusters:G=2,automaticFailover:H=!0,multiAz:A=!0,clusterMode:K=!1,numNodeGroups:B=1,replicasPerNodeGroup:j=1,atRestEncryption:X=!0,transitEncryption:O=!0,authToken:_,kmsKeyId:w,snapshotRetentionDays:E=7,snapshotWindow:M,maintenanceWindow:T}=$,D=v({slug:J,environment:Y,resourceType:"redis"}),N=S(D),x,h;if(W&&W.length>0){let b=v({slug:J,environment:Y,resourceType:"cache-subnet-group"});h=S(b),x={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:b,Description:`Subnet group for ${D}`,SubnetIds:W,Tags:[{Key:"Name",Value:b},{Key:"Environment",Value:Y}]}}}let k={Type:"AWS::ElastiCache::ReplicationGroup",Properties:{ReplicationGroupId:D,ReplicationGroupDescription:`Redis cluster for ${J} ${Y}`,Engine:"redis",EngineVersion:Z,CacheNodeType:Q,Port:U,AutomaticFailoverEnabled:H,MultiAZEnabled:A,AtRestEncryptionEnabled:X,TransitEncryptionEnabled:O,SnapshotRetentionLimit:E,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:D},{Key:"Environment",Value:Y}]}};if(K)k.Properties.NumNodeGroups=B,k.Properties.ReplicasPerNodeGroup=j;else k.Properties.NumCacheClusters=G;if(_)k.Properties.AuthToken=_;if(w)k.Properties.KmsKeyId=w;if(h)k.Properties.CacheSubnetGroupName=u.Ref(h);if(z&&z.length>0)k.Properties.SecurityGroupIds=z;if(M)k.Properties.SnapshotWindow=M;if(T)k.Properties.PreferredMaintenanceWindow=T;return{replicationGroup:k,subnetGroup:x,logicalId:N,subnetGroupId:h}}static createMemcached($){let{slug:J,environment:Y,nodeType:Q="cache.t3.micro",engineVersion:Z="1.6.22",port:U=11211,numCacheNodes:W=2,subnetIds:z,securityGroupIds:G,azMode:H="cross-az",preferredAzs:A,maintenanceWindow:K}=$,B=v({slug:J,environment:Y,resourceType:"memcached"}),j=S(B),X,O;if(z&&z.length>0){let w=v({slug:J,environment:Y,resourceType:"cache-subnet-group"});O=S(w),X={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:w,Description:`Subnet group for ${B}`,SubnetIds:z,Tags:[{Key:"Name",Value:w},{Key:"Environment",Value:Y}]}}}let _={Type:"AWS::ElastiCache::CacheCluster",Properties:{ClusterName:B,CacheNodeType:Q,Engine:"memcached",EngineVersion:Z,NumCacheNodes:W,Port:U,AZMode:H,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:Y}]}};if(O)_.Properties.CacheSubnetGroupName=u.Ref(O);if(G&&G.length>0)_.Properties.VpcSecurityGroupIds=G;if(A&&A.length>0)_.Properties.PreferredAvailabilityZones=A;if(K)_.Properties.PreferredMaintenanceWindow=K;return{cluster:_,subnetGroup:X,logicalId:j,subnetGroupId:O}}static enableClusterMode($,J=3,Y=2){return delete $.Properties.NumCacheClusters,$.Properties.NumNodeGroups=J,$.Properties.ReplicasPerNodeGroup=Y,$}static createRedisParameterGroup($,J){let{slug:Y,environment:Q,parameters:Z={}}=J,U=v({slug:Y,environment:Q,resourceType:"redis-params"}),W=S(U);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`redis${$.split(".")[0]}.x`,Description:`Parameter group for ${U}`,Properties:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q}]}},logicalId:W}}static createMemcachedParameterGroup($,J){let{slug:Y,environment:Q,parameters:Z={}}=J,U=v({slug:Y,environment:Q,resourceType:"memcached-params"}),W=S(U);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`memcached${$.split(".")[0]}.${$.split(".")[1]}`,Description:`Parameter group for ${U}`,Properties:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q}]}},logicalId:W}}static NodeTypes={T3_Micro:"cache.t3.micro",T3_Small:"cache.t3.small",T3_Medium:"cache.t3.medium",T4g_Micro:"cache.t4g.micro",T4g_Small:"cache.t4g.small",T4g_Medium:"cache.t4g.medium",M5_Large:"cache.m5.large",M5_XLarge:"cache.m5.xlarge",M5_2XLarge:"cache.m5.2xlarge",R5_Large:"cache.r5.large",R5_XLarge:"cache.r5.xlarge",R5_2XLarge:"cache.r5.2xlarge",R5_4XLarge:"cache.r5.4xlarge",R6g_Large:"cache.r6g.large",R6g_XLarge:"cache.r6g.xlarge",R6g_2XLarge:"cache.r6g.2xlarge"}};Y1=class Y1{static createUser($){let{slug:J,environment:Y,userName:Q,groups:Z,managedPolicyArns:U}=$,W=Q||v({slug:J,environment:Y,resourceType:"user"}),z=S(W),G={Type:"AWS::IAM::User",Properties:{UserName:W,Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Y}]}};if(Z&&Z.length>0)G.Properties.Groups=Z;if(U&&U.length>0)G.Properties.ManagedPolicyArns=U;return{user:G,logicalId:z}}static createRole($){let{slug:J,environment:Y,roleName:Q,servicePrincipal:Z,awsPrincipal:U,managedPolicyArns:W}=$,z=Q||v({slug:J,environment:Y,resourceType:"role"}),G=S(z),H={};if(Z)H.Service=Z;if(U)H.AWS=U;let A={Type:"AWS::IAM::Role",Properties:{RoleName:z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:H,Action:"sts:AssumeRole"}]},Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(W&&W.length>0)A.Properties.ManagedPolicyArns=W;return{role:A,logicalId:G}}static createGroup($){let{slug:J,environment:Y,groupName:Q,managedPolicyArns:Z}=$,U=Q||v({slug:J,environment:Y,resourceType:"group"}),W=S(U),z={Type:"AWS::IAM::Group",Properties:{GroupName:U}};if(Z&&Z.length>0)z.Properties.ManagedPolicyArns=Z;return{group:z,logicalId:W}}static createPolicy($){let{slug:J,environment:Y,policyName:Q,description:Z,statements:U}=$,W=Q||v({slug:J,environment:Y,resourceType:"policy"}),z=S(W),G=U.map((A)=>({Sid:A.sid,Effect:A.effect||"Allow",Action:A.actions,Resource:A.resources,Condition:A.conditions}));return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:W,Description:Z||`Managed policy for ${W}`,PolicyDocument:{Version:"2012-10-17",Statement:G}}},logicalId:z}}static attachPolicyToRole($,J){if(!$.Properties.ManagedPolicyArns)$.Properties.ManagedPolicyArns=[];if(!$.Properties.ManagedPolicyArns.includes(J))$.Properties.ManagedPolicyArns.push(J);return $}static attachPolicyToUser($,J){if(!$.Properties.ManagedPolicyArns)$.Properties.ManagedPolicyArns=[];if(!$.Properties.ManagedPolicyArns.includes(J))$.Properties.ManagedPolicyArns.push(J);return $}static attachPolicyToGroup($,J){if(!$.Properties.ManagedPolicyArns)$.Properties.ManagedPolicyArns=[];if(!$.Properties.ManagedPolicyArns.includes(J))$.Properties.ManagedPolicyArns.push(J);return $}static addInlinePolicyToRole($,J,Y){if(!$.Properties.Policies)$.Properties.Policies=[];let Q=Y.map((Z)=>({Effect:Z.effect||"Allow",Action:Z.actions,Resource:Z.resources}));return $.Properties.Policies.push({PolicyName:J,PolicyDocument:{Version:"2012-10-17",Statement:Q}}),$}static addInlinePolicyToUser($,J,Y){if(!$.Properties.Policies)$.Properties.Policies=[];let Q=Y.map((Z)=>({Effect:Z.effect||"Allow",Action:Z.actions,Resource:Z.resources}));return $.Properties.Policies.push({PolicyName:J,PolicyDocument:{Version:"2012-10-17",Statement:Q}}),$}static createAccessKey($,J){let{slug:Y,environment:Q,status:Z="Active"}=J,U=v({slug:Y,environment:Q,resourceType:"access-key"}),W=S(U);return{accessKey:{Type:"AWS::IAM::AccessKey",Properties:{UserName:u.Ref($),Status:Z}},logicalId:W}}static createInstanceProfile($,J){let{slug:Y,environment:Q,profileName:Z}=J,U=Z||v({slug:Y,environment:Q,resourceType:"instance-profile"}),W=S(U);return{instanceProfile:{Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:U,Roles:[u.Ref($)]}},logicalId:W}}static ManagedPolicies={AdministratorAccess:"arn:aws:iam::aws:policy/AdministratorAccess",PowerUserAccess:"arn:aws:iam::aws:policy/PowerUserAccess",ReadOnlyAccess:"arn:aws:iam::aws:policy/ReadOnlyAccess",S3FullAccess:"arn:aws:iam::aws:policy/AmazonS3FullAccess",S3ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess",DynamoDBFullAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess",DynamoDBReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess",RDSFullAccess:"arn:aws:iam::aws:policy/AmazonRDSFullAccess",RDSReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess",LambdaFullAccess:"arn:aws:iam::aws:policy/AWSLambda_FullAccess",LambdaReadOnlyAccess:"arn:aws:iam::aws:policy/AWSLambda_ReadOnlyAccess",LambdaBasicExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",LambdaVPCAccessExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole",EC2FullAccess:"arn:aws:iam::aws:policy/AmazonEC2FullAccess",EC2ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess",EC2ContainerRegistryReadOnly:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",EC2ContainerRegistryPowerUser:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser",ECSTaskExecutionRole:"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",ECSFullAccess:"arn:aws:iam::aws:policy/AmazonECS_FullAccess",CloudWatchFullAccess:"arn:aws:iam::aws:policy/CloudWatchFullAccess",CloudWatchLogsFullAccess:"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess",SESFullAccess:"arn:aws:iam::aws:policy/AmazonSESFullAccess",SNSFullAccess:"arn:aws:iam::aws:policy/AmazonSNSFullAccess",SQSFullAccess:"arn:aws:iam::aws:policy/AmazonSQSFullAccess",SecretsManagerReadWrite:"arn:aws:iam::aws:policy/SecretsManagerReadWrite"};static ServicePrincipals={Lambda:"lambda.amazonaws.com",EC2:"ec2.amazonaws.com",ECS:"ecs.amazonaws.com",ECSTaskExecution:"ecs-tasks.amazonaws.com",APIGateway:"apigateway.amazonaws.com",Events:"events.amazonaws.com",States:"states.amazonaws.com",CodeBuild:"codebuild.amazonaws.com",CodeDeploy:"codedeploy.amazonaws.com",CloudFormation:"cloudformation.amazonaws.com"};static createCiCdUser($){let{slug:J,environment:Y,permissions:Q,createAccessKey:Z=!0}=$,U={},W=[];if(Q.s3Buckets&&Q.s3Buckets.length>0)W.push({sid:"S3Access",actions:["s3:GetBucketLocation","s3:ListBucket","s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucketMultipartUploads","s3:AbortMultipartUpload"],resources:[...Q.s3Buckets,...Q.s3Buckets.map((j)=>`${j}/*`)]});if(Q.cloudFrontDistributions&&Q.cloudFrontDistributions.length>0)W.push({sid:"CloudFrontAccess",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations","cloudfront:GetDistribution"],resources:Q.cloudFrontDistributions});if(Q.ecrRepositories&&Q.ecrRepositories.length>0)W.push({sid:"ECRAccess",actions:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:DescribeRepositories","ecr:ListImages","ecr:DescribeImages","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:Q.ecrRepositories}),W.push({sid:"ECRLogin",actions:["ecr:GetAuthorizationToken"],resources:"*"});if(Q.ecsServices&&Q.ecsServices.length>0)W.push({sid:"ECSAccess",actions:["ecs:DescribeServices","ecs:DescribeTaskDefinition","ecs:DescribeTasks","ecs:ListTasks","ecs:RegisterTaskDefinition","ecs:UpdateService","ecs:RunTask","ecs:StopTask"],resources:Q.ecsServices}),W.push({sid:"ECSTaskDefinitions",actions:["ecs:RegisterTaskDefinition","ecs:DeregisterTaskDefinition"],resources:"*"}),W.push({sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}});if(Q.cloudFormationStacks&&Q.cloudFormationStacks.length>0)W.push({sid:"CloudFormationAccess",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:DescribeStackResources","cloudformation:GetTemplate","cloudformation:ListStackResources","cloudformation:ValidateTemplate"],resources:Q.cloudFormationStacks});if(Q.lambdaFunctions&&Q.lambdaFunctions.length>0)W.push({sid:"LambdaAccess",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion","lambda:UpdateAlias","lambda:CreateAlias"],resources:Q.lambdaFunctions});if(Q.secretsManagerSecrets&&Q.secretsManagerSecrets.length>0)W.push({sid:"SecretsManagerAccess",actions:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],resources:Q.secretsManagerSecrets});let{policy:z,logicalId:G}=Y1.createPolicy({slug:J,environment:Y,policyName:v({slug:J,environment:Y,resourceType:"cicd-policy"}),description:`CI/CD deployment policy for ${J} (${Y})`,statements:W});U[G]=z;let{user:H,logicalId:A}=Y1.createUser({slug:J,environment:Y,userName:v({slug:J,environment:Y,resourceType:"cicd-user"}),managedPolicyArns:[u.Ref(G)]});U[A]=H;let K,B;if(Z){let j=Y1.createAccessKey(A,{slug:J,environment:Y});K=j.accessKey,B=j.logicalId,U[B]=K}return{user:H,accessKey:K,policy:z,userLogicalId:A,accessKeyLogicalId:B,policyLogicalId:G,resources:U}}static createCrossAccountRole($){let{slug:J,environment:Y,trustedAccountIds:Q,externalId:Z,permissions:U,maxSessionDuration:W=3600}=$,z={},{policy:G,logicalId:H}=Y1.createPolicy({slug:J,environment:Y,policyName:v({slug:J,environment:Y,resourceType:"cross-account-policy"}),description:`Cross-account access policy for ${J} (${Y})`,statements:U});z[H]=G;let A=v({slug:J,environment:Y,resourceType:"cross-account-role"}),K=S(A),B={};if(Z)B.StringEquals={"sts:ExternalId":Z};let j={Type:"AWS::IAM::Role",Properties:{RoleName:A,MaxSessionDuration:W,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:Q.map((X)=>`arn:aws:iam::${X}:root`)},Action:"sts:AssumeRole",...Object.keys(B).length>0?{Condition:B}:{}}]},ManagedPolicyArns:[u.Ref(H)],Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"Cross-Account Access"}]}};return z[K]=j,{role:j,policy:G,roleLogicalId:K,policyLogicalId:H,resources:z}}static createCliUser($){let{slug:J,environment:Y,permissions:Q="readonly"}=$,Z={},U=[],W=[];switch(Q){case"readonly":W=[Y1.ManagedPolicies.ReadOnlyAccess];break;case"deploy":U=[{sid:"S3Deploy",actions:["s3:*"],resources:"*"},{sid:"CloudFrontDeploy",actions:["cloudfront:*"],resources:"*"},{sid:"ECSDeploy",actions:["ecs:*"],resources:"*"},{sid:"ECRDeploy",actions:["ecr:*"],resources:"*"},{sid:"LambdaDeploy",actions:["lambda:*"],resources:"*"},{sid:"CloudFormationDeploy",actions:["cloudformation:*"],resources:"*"},{sid:"IAMPassRole",actions:["iam:PassRole"],resources:"*"}];break;case"admin":W=[Y1.ManagedPolicies.AdministratorAccess];break}let z,G;if(U.length>0){let j=Y1.createPolicy({slug:J,environment:Y,policyName:v({slug:J,environment:Y,resourceType:"cli-policy"}),description:`CLI access policy for ${J} (${Y})`,statements:U});z=j.policy,G=j.logicalId,Z[G]=z,W=[u.Ref(G)]}let{user:H,logicalId:A}=Y1.createUser({slug:J,environment:Y,userName:v({slug:J,environment:Y,resourceType:"cli-user"}),managedPolicyArns:W});Z[A]=H;let{accessKey:K,logicalId:B}=Y1.createAccessKey(A,{slug:J,environment:Y});return Z[B]=K,{user:H,accessKey:K,policy:z,userLogicalId:A,accessKeyLogicalId:B,policyLogicalId:G,resources:Z}}static CiCdPolicies={s3Deployment:($)=>[{sid:"S3ListBuckets",actions:["s3:ListBucket","s3:GetBucketLocation"],resources:$},{sid:"S3Objects",actions:["s3:GetObject","s3:PutObject","s3:DeleteObject"],resources:$.map((J)=>`${J}/*`)}],cloudFrontInvalidation:($)=>[{sid:"CloudFrontInvalidation",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations"],resources:$}],ecsDeployment:()=>[{sid:"ECSServices",actions:["ecs:DescribeServices","ecs:UpdateService","ecs:DescribeTaskDefinition","ecs:RegisterTaskDefinition"],resources:"*"},{sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}}],ecrPush:($)=>[{sid:"ECRAuth",actions:["ecr:GetAuthorizationToken"],resources:"*"},{sid:"ECRPush",actions:["ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:$}],lambdaDeployment:($)=>[{sid:"LambdaDeploy",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion"],resources:$}],cloudFormationDeployment:($)=>[{sid:"CloudFormationDeploy",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:GetTemplate"],resources:$}]}};x9=class x9{static createRestApi($){let{slug:J,environment:Y,name:Q,description:Z,endpointType:U="REGIONAL",binaryMediaTypes:W,compressionSize:z}=$,G=Q||v({slug:J,environment:Y,resourceType:"rest-api"}),H=S(G),A={Type:"AWS::ApiGateway::RestApi",Properties:{Name:G,Description:Z||`REST API for ${J} ${Y}`,EndpointConfiguration:{Types:[U]},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y}]}};if(W&&W.length>0)A.Properties.BinaryMediaTypes=W;if(z!==void 0)A.Properties.MinimumCompressionSize=z;return{restApi:A,logicalId:H}}static createHttpApi($){let{slug:J,environment:Y,name:Q,description:Z,corsEnabled:U=!0,corsOrigins:W=["*"],corsMethods:z=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],corsHeaders:G=["*"],corsMaxAge:H=86400,corsAllowCredentials:A=!1}=$,K=Q||v({slug:J,environment:Y,resourceType:"http-api"}),B=S(K),j={Type:"AWS::ApiGatewayV2::Api",Properties:{Name:K,Description:Z||`HTTP API for ${J} ${Y}`,ProtocolType:"HTTP",Tags:{Name:K,Environment:Y}}};if(U)j.Properties.CorsConfiguration={AllowOrigins:W,AllowMethods:z,AllowHeaders:G,MaxAge:H,AllowCredentials:A};return{httpApi:j,logicalId:B}}static createWebSocketApi($){let{slug:J,environment:Y,name:Q,description:Z}=$,U=Q||v({slug:J,environment:Y,resourceType:"ws-api"}),W=S(U);return{webSocketApi:{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:U,Description:Z||`WebSocket API for ${J} ${Y}`,ProtocolType:"WEBSOCKET",Tags:{Name:U,Environment:Y}}},logicalId:W}}static createDeployment($,J){let{slug:Y,environment:Q,description:Z}=J,U=v({slug:Y,environment:Q,resourceType:"api-deployment"}),W=S(U);return{deployment:{Type:"AWS::ApiGateway::Deployment",Properties:{RestApiId:u.Ref($),Description:Z||`Deployment for ${U}`}},logicalId:W}}static createStage($,J,Y){let{slug:Q,environment:Z,stageName:U,description:W,cacheEnabled:z=!1,cacheSize:G="0.5",variables:H,throttling:A}=Y,K=v({slug:Q,environment:Z,resourceType:"api-stage"}),B=S(K),j={Type:"AWS::ApiGateway::Stage",Properties:{StageName:U||Z,RestApiId:u.Ref($),DeploymentId:u.Ref(J),Description:W,CacheClusterEnabled:z,Tags:[{Key:"Name",Value:K},{Key:"Environment",Value:Z}]}};if(z)j.Properties.CacheClusterSize=G;if(H)j.Properties.Variables=H;if(A)j.Properties.MethodSettings=[{HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:A.burstLimit,ThrottlingRateLimit:A.rateLimit}];return{stage:j,logicalId:B}}static createAuthorizer($,J){let{slug:Y,environment:Q,name:Z,type:U,functionArn:W,identitySource:z,userPoolArns:G,ttl:H=300}=J,A=Z||v({slug:Y,environment:Q,resourceType:"api-authorizer"}),K=S(A),B={Type:"AWS::ApiGateway::Authorizer",Properties:{Name:A,Type:U,RestApiId:u.Ref($),AuthorizerResultTtlInSeconds:H}};if(U==="TOKEN"||U==="REQUEST"){if(!W)throw Error("Lambda authorizer requires functionArn");B.Properties.AuthorizerUri=W,B.Properties.IdentitySource=z||"method.request.header.Authorization"}if(U==="COGNITO_USER_POOLS"){if(!G||G.length===0)throw Error("Cognito authorizer requires userPoolArns");B.Properties.ProviderARNs=G,B.Properties.IdentitySource=z||"method.request.header.Authorization"}return{authorizer:B,logicalId:K}}static setCors($,J={}){let{origins:Y=["*"],methods:Q=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],headers:Z=["*"],maxAge:U=86400,allowCredentials:W=!1}=J;return $.Properties.CorsConfiguration={AllowOrigins:Y,AllowMethods:Q,AllowHeaders:Z,MaxAge:U,AllowCredentials:W},$}static addThrottling($,J=5000,Y=1e4){if(!$.Properties.MethodSettings)$.Properties.MethodSettings=[];return $.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:J,ThrottlingRateLimit:Y}),$}static enableCaching($,J="0.5",Y=300){if($.Properties.CacheClusterEnabled=!0,$.Properties.CacheClusterSize=J,!$.Properties.MethodSettings)$.Properties.MethodSettings=[];return $.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",CachingEnabled:!0,CacheTtlInSeconds:Y}),$}static CacheSizes={Small:"0.5",Medium:"1.6",Large:"6.1",XLarge:"13.5",XXLarge:"28.4",XXXLarge:"58.2",Huge:"118",Massive:"237"};static ThrottlingPresets={Light:{burstLimit:100,rateLimit:50},Medium:{burstLimit:500,rateLimit:250},Heavy:{burstLimit:2000,rateLimit:1000},Default:{burstLimit:5000,rateLimit:1e4}}};$1=class $1{static createTopic($){let{slug:J,environment:Y,topicName:Q,displayName:Z,encrypted:U=!1,kmsKeyId:W}=$,z=Q||v({slug:J,environment:Y,resourceType:"topic"}),G=S(z),H={Type:"AWS::SNS::Topic",Properties:{TopicName:z,DisplayName:Z||z,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(U&&W)H.Properties.KmsMasterKeyId=W;return{topic:H,logicalId:G}}static subscribe($,J){let{slug:Y,environment:Q,protocol:Z,endpoint:U,filterPolicy:W,rawMessageDelivery:z=!1}=J,G=v({slug:Y,environment:Q,resourceType:"subscription"}),H=U.replace(/[^a-zA-Z0-9]/g,""),A=H.length>12?H.slice(-12):H,K=S(`${G}-${Z}-${A}`),B={Type:"AWS::SNS::Subscription",Properties:{TopicArn:u.Ref($),Protocol:Z,Endpoint:U,RawMessageDelivery:z}};if(W)B.Properties.FilterPolicy=W;return{subscription:B,logicalId:K}}static subscribeEmail($,J,Y){return $1.subscribe($,{...Y,protocol:"email",endpoint:J})}static subscribeLambda($,J,Y){return $1.subscribe($,{...Y,protocol:"lambda",endpoint:J,rawMessageDelivery:!0})}static subscribeSqs($,J,Y){return $1.subscribe($,{...Y,protocol:"sqs",endpoint:J})}static subscribeHttp($,J,Y){let Q=J.startsWith("https://")?"https":"http";return $1.subscribe($,{...Y,protocol:Q,endpoint:J})}static subscribeSms($,J,Y){return $1.subscribe($,{...Y,protocol:"sms",endpoint:J})}static setTopicPolicy($,J){let{slug:Y,environment:Q,allowedPrincipals:Z,allowedServices:U,actions:W="SNS:Publish"}=J,z=v({slug:Y,environment:Q,resourceType:"topic-policy"}),G=S(z),H={};if(Z)H.AWS=Z;if(U)H.Service=U;return{policy:{Type:"AWS::SNS::TopicPolicy",Properties:{Topics:[u.Ref($)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:H,Action:W,Resource:u.Ref($)}]}}},logicalId:G}}static allowCloudWatchAlarms($,J){return $1.setTopicPolicy($,{...J,allowedServices:"cloudwatch.amazonaws.com",actions:"SNS:Publish"})}static allowEventBridge($,J){return $1.setTopicPolicy($,{...J,allowedServices:"events.amazonaws.com",actions:"SNS:Publish"})}static allowS3($,J){return $1.setTopicPolicy($,{...J,allowedServices:"s3.amazonaws.com",actions:"SNS:Publish"})}static enableEncryption($,J){if(!$.Properties)$.Properties={};return $.Properties.KmsMasterKeyId=J,$}static addInlineSubscription($,J,Y){if(!$.Properties)$.Properties={};if(!$.Properties.Subscription)$.Properties.Subscription=[];return $.Properties.Subscription.push({Protocol:J,Endpoint:Y}),$}static FilterPolicies={eventType:($)=>({eventType:$}),status:($)=>({status:$}),numericRange:($,J,Y)=>({[$]:[{numeric:[">=",J,"<=",Y]}]}),prefix:($,J)=>({[$]:[{prefix:J}]}),and:(...$)=>{return Object.assign({},...$)},exists:($,J)=>({[$]:[{exists:J}]})};static UseCases={createAlertTopic:($)=>{return $1.createTopic({...$,topicName:$.topicName||`${$.slug}-${$.environment}-alerts`,displayName:$.displayName||"Alert Notifications"})},createEventFanout:($)=>{return $1.createTopic({...$,topicName:$.topicName||`${$.slug}-${$.environment}-events`,displayName:$.displayName||"Event Fanout"})},createNotificationTopic:($)=>{return $1.createTopic({...$,topicName:$.topicName||`${$.slug}-${$.environment}-notifications`,displayName:$.displayName||"User Notifications"})}}};fQ=class fQ{static createStateMachine($){let{slug:J,environment:Y,stateMachineName:Q,type:Z="STANDARD",definition:U,roleArn:W,loggingConfiguration:z,tracingConfiguration:G}=$,H=Q||v({slug:J,environment:Y,resourceType:"state-machine"}),A=S(H),K,B,j;if(W)j=W;else{let O=v({slug:J,environment:Y,resourceType:"state-machine-role"});B=S(O),K={Type:"AWS::IAM::Role",Properties:{RoleName:O,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"states.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"],Tags:[{Key:"Name",Value:O},{Key:"Environment",Value:Y}]}},j=u.GetAtt(B,"Arn")}let X={Type:"AWS::StepFunctions::StateMachine",Properties:{StateMachineName:H,StateMachineType:Z,DefinitionString:JSON.stringify(U),RoleArn:j,Tags:[{Key:"Name",Value:H},{Key:"Environment",Value:Y}]}};if(z)X.Properties.LoggingConfiguration={Level:z.level,IncludeExecutionData:z.includeExecutionData,Destinations:z.destinations?.map((O)=>({CloudWatchLogsLogGroup:{LogGroupArn:O}}))};if(G)X.Properties.TracingConfiguration={Enabled:G.enabled};return{stateMachine:X,logicalId:A,role:K,roleLogicalId:B}}static createLambdaTask($,J){return{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Parameters:{FunctionName:$,Payload:J?.parameters||{"Input.$":"$"}},ResultPath:J?.resultPath,Retry:J?.retry,Catch:J?.catch,Next:J?.next,End:J?.end}}static createDynamoDBTask($,J,Y,Q){return{Type:"Task",Resource:{GetItem:"arn:aws:states:::dynamodb:getItem",PutItem:"arn:aws:states:::dynamodb:putItem",UpdateItem:"arn:aws:states:::dynamodb:updateItem",DeleteItem:"arn:aws:states:::dynamodb:deleteItem"}[$],Parameters:{TableName:J,...Y},ResultPath:Q?.resultPath,Retry:Q?.retry,Catch:Q?.catch,Next:Q?.next,End:Q?.end}}static createSNSPublishTask($,J,Y){return{Type:"Task",Resource:"arn:aws:states:::sns:publish",Parameters:{TopicArn:$,Message:J},ResultPath:Y?.resultPath,Retry:Y?.retry,Catch:Y?.catch,Next:Y?.next,End:Y?.end}}static createSQSSendMessageTask($,J,Y){return{Type:"Task",Resource:"arn:aws:states:::sqs:sendMessage",Parameters:{QueueUrl:$,MessageBody:J},ResultPath:Y?.resultPath,Retry:Y?.retry,Catch:Y?.catch,Next:Y?.next,End:Y?.end}}static createPassState($){return{Type:"Pass",Result:$?.result,ResultPath:$?.resultPath,Parameters:$?.parameters,Next:$?.next,End:$?.end}}static createWaitState($){return{Type:"Wait",Seconds:$.seconds,Timestamp:$.timestamp,SecondsPath:$.secondsPath,TimestampPath:$.timestampPath,Next:$.next,End:$.end}}static createChoiceState($,J){return{Type:"Choice",Choices:$,Default:J}}static createParallelState($,J){return{Type:"Parallel",Branches:$,ResultPath:J?.resultPath,Retry:J?.retry,Catch:J?.catch,Next:J?.next,End:J?.end}}static createMapState($,J){return{Type:"Map",ItemsPath:J?.itemsPath||"$.items",Iterator:$,MaxConcurrency:J?.maxConcurrency,ResultPath:J?.resultPath,Retry:J?.retry,Catch:J?.catch,Next:J?.next,End:J?.end}}static createSucceedState(){return{Type:"Succeed"}}static createFailState($,J){return{Type:"Fail",Error:$,Cause:J}}static RetryPolicies={standard:()=>({ErrorEquals:["States.ALL"],IntervalSeconds:2,MaxAttempts:3,BackoffRate:2}),aggressive:()=>({ErrorEquals:["States.TaskFailed","States.Timeout"],IntervalSeconds:1,MaxAttempts:5,BackoffRate:1.5}),custom:($,J,Y,Q)=>({ErrorEquals:$,IntervalSeconds:J,MaxAttempts:Y,BackoffRate:Q})};static CatchPolicies={all:($,J)=>({ErrorEquals:["States.ALL"],Next:$,ResultPath:J||"$.error"}),specific:($,J,Y)=>({ErrorEquals:$,Next:J,ResultPath:Y||"$.error"})};static Patterns={sequential:($,J,Y)=>{let Q={};return Y.forEach((Z,U)=>{let W=U===Y.length-1;Q[Z.name]={...Z.state,Next:W?void 0:Y[U+1].name,End:W}}),{Comment:"Sequential workflow",StartAt:Y[0].name,States:Q}},fanout:($,J,Y)=>{return{Comment:"Fan-out workflow",StartAt:"Parallel",States:{Parallel:{Type:"Parallel",Branches:Y.map((Q)=>Q.definition),End:!0}}}},map:($,J,Y,Q)=>{return{Comment:"Map workflow",StartAt:"Map",States:{Map:{Type:"Map",ItemsPath:"$.items",Iterator:Y,MaxConcurrency:Q,End:!0}}}},withErrorHandling:($,J,Y,Q)=>{return{Comment:"Workflow with error handling",StartAt:"Main",States:{Main:{...Y,Catch:[{ErrorEquals:["States.ALL"],Next:"ErrorHandler"}],Next:"Success"},ErrorHandler:Q,Success:{Type:"Succeed"}}}}}};_$=class _${static createAlarm($){let{slug:J,environment:Y,alarmName:Q,metricName:Z,namespace:U,statistic:W="Average",period:z=300,evaluationPeriods:G=1,threshold:H,comparisonOperator:A,treatMissingData:K="notBreaching",actionsEnabled:B=!0,alarmActions:j,okActions:X,insufficientDataActions:O,dimensions:_,unit:w,datapointsToAlarm:E}=$,M=Q||v({slug:J,environment:Y,resourceType:"alarm"}),T=S(M),D={Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:M,MetricName:Z,Namespace:U,Statistic:W,Period:z,EvaluationPeriods:G,Threshold:H,ComparisonOperator:A,TreatMissingData:K,ActionsEnabled:B}};if(j&&j.length>0)D.Properties.AlarmActions=j;if(X&&X.length>0)D.Properties.OKActions=X;if(O&&O.length>0)D.Properties.InsufficientDataActions=O;if(_)D.Properties.Dimensions=Object.entries(_).map(([N,x])=>({Name:N,Value:x}));if(w)D.Properties.Unit=w;if(E!==void 0)D.Properties.DatapointsToAlarm=E;return{alarm:D,logicalId:T}}static createCompositeAlarm($){let{slug:J,environment:Y,alarmName:Q,alarmRule:Z,actionsEnabled:U=!0,alarmActions:W,okActions:z,insufficientDataActions:G}=$,H=Q||v({slug:J,environment:Y,resourceType:"composite-alarm"}),A=S(H),K={Type:"AWS::CloudWatch::CompositeAlarm",Properties:{AlarmName:H,AlarmRule:Z,ActionsEnabled:U}};if(W&&W.length>0)K.Properties.AlarmActions=W;if(z&&z.length>0)K.Properties.OKActions=z;if(G&&G.length>0)K.Properties.InsufficientDataActions=G;return{alarm:K,logicalId:A}}static createDashboard($){let{slug:J,environment:Y,dashboardName:Q,widgets:Z}=$,U=Q||v({slug:J,environment:Y,resourceType:"dashboard"}),W=S(U),z={widgets:Z.map((H)=>({type:H.type,x:H.x,y:H.y,width:H.width,height:H.height,properties:H.properties}))};return{dashboard:{Type:"AWS::CloudWatch::Dashboard",Properties:{DashboardName:U,DashboardBody:JSON.stringify(z)}},logicalId:W}}static createLogGroup($){let{slug:J,environment:Y,logGroupName:Q,retentionInDays:Z,kmsKeyId:U}=$,W=Q||v({slug:J,environment:Y,resourceType:"log-group"}),z=S(W),G={Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:W}};if(Z!==void 0)G.Properties.RetentionInDays=Z;if(U)G.Properties.KmsKeyId=U;return{logGroup:G,logicalId:z}}static createLogStream($,J){let{slug:Y,environment:Q,logStreamName:Z}=J,U=Z||v({slug:Y,environment:Q,resourceType:"log-stream"}),W=S(U);return{logStream:{Type:"AWS::Logs::LogStream",Properties:{LogGroupName:u.Ref($),LogStreamName:U}},logicalId:W}}static createMetricFilter($,J){let{slug:Y,environment:Q,filterName:Z,filterPattern:U,metricTransformations:W}=J,z=Z||v({slug:Y,environment:Q,resourceType:"metric-filter"}),G=S(z);return{metricFilter:{Type:"AWS::Logs::MetricFilter",Properties:{LogGroupName:u.Ref($),FilterPattern:U,MetricTransformations:W.map((A)=>({MetricName:A.metricName,MetricNamespace:A.metricNamespace,MetricValue:A.metricValue,DefaultValue:A.defaultValue,Unit:A.unit}))}},logicalId:G}}static AlarmTypes={highCpu:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-high-cpu`,metricName:"CPUUtilization",namespace:"AWS/EC2",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y},alarmActions:Z?[Z]:void 0}),highMemory:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-high-memory`,metricName:"MemoryUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y},alarmActions:Z?[Z]:void 0}),highDisk:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-high-disk`,metricName:"DiskSpaceUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y,Filesystem:"/dev/xvda1",MountPath:"/"},alarmActions:Z?[Z]:void 0}),lambdaErrors:($,J,Y,Q=5,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-lambda-errors`,metricName:"Errors",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:Y},alarmActions:Z?[Z]:void 0}),lambdaThrottles:($,J,Y,Q=10,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-lambda-throttles`,metricName:"Throttles",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:Y},alarmActions:Z?[Z]:void 0}),apiGateway5xxErrors:($,J,Y,Q=10,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-api-5xx-errors`,metricName:"5XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:Y},alarmActions:Z?[Z]:void 0}),apiGateway4xxErrors:($,J,Y,Q=50,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-api-4xx-errors`,metricName:"4XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:Y},alarmActions:Z?[Z]:void 0}),dynamoDBThrottles:($,J,Y,Q=5,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-dynamodb-throttles`,metricName:"UserErrors",namespace:"AWS/DynamoDB",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{TableName:Y},alarmActions:Z?[Z]:void 0}),rdsCpu:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-rds-cpu`,metricName:"CPUUtilization",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{DBInstanceIdentifier:Y},alarmActions:Z?[Z]:void 0}),rdsFreeStorage:($,J,Y,Q=5368709120,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-rds-storage`,metricName:"FreeStorageSpace",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"LessThanThreshold",dimensions:{DBInstanceIdentifier:Y},alarmActions:Z?[Z]:void 0,unit:"Bytes"}),sqsQueueDepth:($,J,Y,Q=100,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-sqs-depth`,metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{QueueName:Y},alarmActions:Z?[Z]:void 0}),albUnhealthyTargets:($,J,Y,Q,Z=1,U)=>({slug:$,environment:J,alarmName:`${$}-${J}-alb-unhealthy`,metricName:"UnHealthyHostCount",namespace:"AWS/ApplicationELB",statistic:"Average",period:300,evaluationPeriods:2,threshold:Z,comparisonOperator:"GreaterThanThreshold",dimensions:{LoadBalancer:Y,TargetGroup:Q},alarmActions:U?[U]:void 0}),sesBounceRate:($,J,Y=5,Q)=>({slug:$,environment:J,alarmName:`${$}-${J}-ses-bounce-rate`,metricName:"Reputation.BounceRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:Y/100,comparisonOperator:"GreaterThanThreshold",alarmActions:Q?[Q]:void 0}),sesComplaintRate:($,J,Y=0.1,Q)=>({slug:$,environment:J,alarmName:`${$}-${J}-ses-complaint-rate`,metricName:"Reputation.ComplaintRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:Y/100,comparisonOperator:"GreaterThanThreshold",alarmActions:Q?[Q]:void 0}),smsDeliveryFailure:($,J,Y,Q=10,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-sms-delivery-failure`,metricName:"DirectSendMessagePermanentFailure",namespace:"AWS/Pinpoint",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{ApplicationId:Y},alarmActions:Z?[Z]:void 0}),smsSpendLimit:($,J,Y=100,Q)=>({slug:$,environment:J,alarmName:`${$}-${J}-sms-spend-limit`,metricName:"DirectSendMessageSpend",namespace:"AWS/Pinpoint",statistic:"Sum",period:86400,evaluationPeriods:1,threshold:Y,comparisonOperator:"GreaterThanThreshold",alarmActions:Q?[Q]:void 0}),connectMissedCalls:($,J,Y,Q=5,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-connect-missed-calls`,metricName:"MissedCalls",namespace:"AWS/Connect",statistic:"Sum",period:3600,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y},alarmActions:Z?[Z]:void 0})};static DashboardWidgets={metric:($,J,Y,Q,Z,U)=>({type:"metric",x:$,y:J,width:Y,height:Q,properties:{metrics:Z,title:U||"Metrics",region:"us-east-1",period:300}}),text:($,J,Y,Q,Z)=>({type:"text",x:$,y:J,width:Y,height:Q,properties:{markdown:Z}}),log:($,J,Y,Q,Z,U)=>({type:"log",x:$,y:J,width:Y,height:Q,properties:{query:`SOURCE '${Z.join("' | SOURCE '")}'
5746
+ `}};yQ={};q2(yQ,{handler:()=>q6,default:()=>X4});X4=q6;R1=class R1{static LambdaCode={incomingCall:q6,voicemail:O4,missedCall:_4};static createConnectInstance($){let{slug:J,environment:Y,instanceAlias:Q,inboundCallsEnabled:Z=!0,outboundCallsEnabled:U=!0}=$;return{[`${J}ConnectInstance`]:{Type:"AWS::Connect::Instance",Properties:{InstanceAlias:Q,IdentityManagementType:"CONNECT_MANAGED",Attributes:{InboundCalls:Z,OutboundCalls:U,ContactflowLogs:!0,ContactLens:!0,AutoResolveBestVoices:!0,UseCustomTTSVoices:!1,EarlyMedia:!0}}}}}static createHoursOfOperation($){return{[`${$.slug}HoursOfOperation`]:{Type:"AWS::Connect::HoursOfOperation",Properties:{InstanceArn:$.instanceArn,Name:$.name,TimeZone:$.timezone,Config:$.schedule.map((J)=>({Day:J.day,StartTime:{Hours:J.startHour,Minutes:J.startMinute},EndTime:{Hours:J.endHour,Minutes:J.endMinute}}))}}}}static createQueue($){return{[`${$.slug}Queue`]:{Type:"AWS::Connect::Queue",Properties:{InstanceArn:$.instanceArn,Name:$.name,HoursOfOperationArn:$.hoursOfOperationArn,MaxContacts:$.maxContacts||10}}}}static createContactFlow($){return{[`${$.slug}ContactFlow`]:{Type:"AWS::Connect::ContactFlow",Properties:{InstanceArn:$.instanceArn,Name:$.name,Type:$.type,Content:$.content}}}}static createBasicIvrFlow($){let J={Version:"2019-10-30",StartAction:"greeting",Actions:[{Identifier:"greeting",Type:"MessageParticipant",Parameters:{Text:$.greeting},Transitions:{NextAction:"transfer_to_queue",Errors:[{NextAction:"disconnect"}]}},{Identifier:"transfer_to_queue",Type:"TransferToQueue",Parameters:{QueueId:$.queueArn},Transitions:{NextAction:$.voicemailLambdaArn?"voicemail":"disconnect",Errors:[{NextAction:"disconnect"}]}},...$.voicemailLambdaArn?[{Identifier:"voicemail",Type:"InvokeLambdaFunction",Parameters:{LambdaFunctionARN:$.voicemailLambdaArn},Transitions:{NextAction:"disconnect",Errors:[{NextAction:"disconnect"}]}}]:[],{Identifier:"disconnect",Type:"DisconnectParticipant",Parameters:{},Transitions:{}}]};return JSON.stringify(J)}static createPhoneLambdaRole($){return{[`${$.slug}PhoneLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${$.slug}-phone-lambda-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"PhoneLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject"],Resource:"*"},{Effect:"Allow",Action:["transcribe:StartTranscriptionJob","transcribe:GetTranscriptionJob"],Resource:"*"},{Effect:"Allow",Action:["connect:*"],Resource:"*"}]}}]}}}}static createIncomingCallLambda($){return{[`${$.slug}IncomingCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-incoming-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:R1.LambdaCode.incomingCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",CALL_LOG_TABLE:$.callLogTable||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createVoicemailLambda($){return{[`${$.slug}VoicemailLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-voicemail`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:300,MemorySize:512,Code:{ZipFile:R1.LambdaCode.voicemail},Environment:{Variables:{VOICEMAIL_BUCKET:$.voicemailBucket,NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",CALL_LOG_TABLE:$.callLogTable||"",TRANSCRIPTION_ENABLED:$.transcriptionEnabled?"true":"false"}}}}}}static createMissedCallLambda($){return{[`${$.slug}MissedCallLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-missed-call`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:R1.LambdaCode.missedCall},Environment:{Variables:{NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",CALL_LOG_TABLE:$.callLogTable||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createCallLogTable($){return{[`${$.slug}CallLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$.slug}-call-log`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"contactId",AttributeType:"S"}],KeySchema:[{AttributeName:"contactId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createCompleteSetup($){let J={},Y={};Object.assign(J,R1.createPhoneLambdaRole({slug:$.slug})),Object.assign(J,R1.createCallLogTable({slug:$.slug})),J[`${$.slug}PhoneNotificationTopic`]={Type:"AWS::SNS::Topic",Properties:{TopicName:`${$.slug}-phone-notifications`}},J[`${$.slug}VoicemailBucket`]={Type:"AWS::S3::Bucket",Properties:{BucketName:`${$.slug}-voicemails`,LifecycleConfiguration:{Rules:[{Id:"DeleteOldVoicemails",Status:"Enabled",ExpirationInDays:90}]}}};let Q={"Fn::GetAtt":[`${$.slug}PhoneLambdaRole`,"Arn"]},Z={Ref:`${$.slug}PhoneNotificationTopic`},U={Ref:`${$.slug}CallLogTable`},W={Ref:`${$.slug}VoicemailBucket`};if(Object.assign(J,R1.createIncomingCallLambda({slug:$.slug,roleArn:Q,notificationTopicArn:Z,callLogTable:U,webhookUrl:$.webhookUrl})),$.voicemailEnabled!==!1)Object.assign(J,R1.createVoicemailLambda({slug:$.slug,roleArn:Q,voicemailBucket:W,notificationTopicArn:Z,callLogTable:U,transcriptionEnabled:$.transcriptionEnabled}));return Object.assign(J,R1.createMissedCallLambda({slug:$.slug,roleArn:Q,notificationTopicArn:Z,callLogTable:U,webhookUrl:$.webhookUrl})),Y[`${$.slug}PhoneNotificationTopicArn`]={Description:"Phone notification topic ARN",Value:{Ref:`${$.slug}PhoneNotificationTopic`}},Y[`${$.slug}CallLogTableName`]={Description:"Call log table name",Value:{Ref:`${$.slug}CallLogTable`}},Y[`${$.slug}VoicemailBucketName`]={Description:"Voicemail bucket name",Value:{Ref:`${$.slug}VoicemailBucket`}},{resources:J,outputs:Y}}};t0=class t0{static createQueue($){let{slug:J,environment:Y,name:Q,delaySeconds:Z=0,visibilityTimeout:U=30,messageRetentionPeriod:W=345600,maxMessageSize:z=262144,receiveMessageWaitTime:G=0,fifo:H=!1,contentBasedDeduplication:A=!1,encrypted:K=!0,kmsKeyId:B}=$,j=Q||f({slug:J,environment:Y,resourceType:"queue"}),X=H?`${j}.fifo`:j,O=S(j),_={Type:"AWS::SQS::Queue",Properties:{QueueName:X,DelaySeconds:Z,MaximumMessageSize:z,MessageRetentionPeriod:W,ReceiveMessageWaitTimeSeconds:G,VisibilityTimeout:U,Tags:[{Key:"Name",Value:X},{Key:"Environment",Value:Y}]}};if(H)_.Properties.FifoQueue=!0,_.Properties.ContentBasedDeduplication=A;if(K)if(B)_.Properties.KmsMasterKeyId=B;else _.Properties.SqsManagedSseEnabled=!0;return{queue:_,logicalId:O}}static createDeadLetterQueue($,J){let{slug:Y,environment:Q,maxReceiveCount:Z=3}=J,U=f({slug:Y,environment:Q,resourceType:"dlq"}),W=S(U),z={Type:"AWS::SQS::Queue",Properties:{QueueName:U,MessageRetentionPeriod:1209600,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q},{Key:"Type",Value:"DeadLetterQueue"}]}},G={Type:"AWS::SQS::Queue",Properties:{RedrivePolicy:{deadLetterTargetArn:u.GetAtt(W,"Arn"),maxReceiveCount:Z}}};return{deadLetterQueue:z,updatedSourceQueue:G,deadLetterLogicalId:W}}static createSchedule($,J){let{slug:Y,environment:Q,name:Z,description:U,enabled:W=!0}=J,z=Z||f({slug:Y,environment:Q,resourceType:"schedule"}),G=S(z);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:z,Description:U,ScheduleExpression:$,State:W?"ENABLED":"DISABLED",Targets:[]}},logicalId:G}}static scheduleEcsTask($,J,Y){let{slug:Q,environment:Z,name:U,description:W,enabled:z=!0,taskDefinitionArn:G,clusterArn:H,subnets:A,securityGroups:K=[],assignPublicIp:B=!1,taskCount:j=1,containerOverrides:X}=Y,O=U||f({slug:Q,environment:Z,resourceType:"ecs-schedule"}),_=S(O),E={Id:"1",Arn:H,RoleArn:J,EcsParameters:{TaskDefinitionArn:G,TaskCount:j,LaunchType:"FARGATE",NetworkConfiguration:{awsvpcConfiguration:{Subnets:A,SecurityGroups:K,AssignPublicIp:B?"ENABLED":"DISABLED"}},PlatformVersion:"LATEST"}};if(X&&X.length>0)E.Input=JSON.stringify({containerOverrides:X});return{rule:{Type:"AWS::Events::Rule",Properties:{Name:O,Description:W||`Scheduled ECS task: ${G}`,ScheduleExpression:$,State:z?"ENABLED":"DISABLED",Targets:[E]}},logicalId:_}}static scheduleLambda($,J){let{slug:Y,environment:Q,name:Z,description:U,enabled:W=!0,functionArn:z,input:G}=J,H=Z||f({slug:Y,environment:Q,resourceType:"lambda-schedule"}),A=S(H),K={Id:"1",Arn:z};if(G)K.Input=JSON.stringify(G);return{rule:{Type:"AWS::Events::Rule",Properties:{Name:H,Description:U||`Scheduled Lambda: ${z}`,ScheduleExpression:$,State:W?"ENABLED":"DISABLED",Targets:[K]}},logicalId:A}}static scheduleSqsMessage($,J){let{slug:Y,environment:Q,name:Z,description:U,enabled:W=!0,queueArn:z,messageGroupId:G}=J,H=Z||f({slug:Y,environment:Q,resourceType:"sqs-schedule"}),A=S(H),K={Id:"1",Arn:z};if(G)K.SqsParameters={MessageGroupId:G};return{rule:{Type:"AWS::Events::Rule",Properties:{Name:H,Description:U||`Scheduled SQS message: ${z}`,ScheduleExpression:$,State:W?"ENABLED":"DISABLED",Targets:[K]}},logicalId:A}}static addTarget($,J){if(!$.Properties.Targets)$.Properties.Targets=[];let Y={Id:J.id,Arn:J.arn};if(J.roleArn)Y.RoleArn=J.roleArn;if(J.input)Y.Input=JSON.stringify(J.input);return $.Properties.Targets.push(Y),$}static toCronExpression($){if($.startsWith("cron(")||$.startsWith("rate("))return $;return`cron(${$})`}static rateExpression($,J){return`rate(${$} ${J})`}static CronExpressions={EveryMinute:"cron(* * * * ? *)",Every5Minutes:"cron(*/5 * * * ? *)",Every15Minutes:"cron(*/15 * * * ? *)",Every30Minutes:"cron(*/30 * * * ? *)",Hourly:"cron(0 * * * ? *)",Daily:"cron(0 0 * * ? *)",DailyAt9AM:"cron(0 9 * * ? *)",DailyAtMidnight:"cron(0 0 * * ? *)",Weekly:"cron(0 0 ? * SUN *)",Monthly:"cron(0 0 1 * ? *)"};static RateExpressions={Every1Minute:"rate(1 minute)",Every5Minutes:"rate(5 minutes)",Every10Minutes:"rate(10 minutes)",Every15Minutes:"rate(15 minutes)",Every30Minutes:"rate(30 minutes)",Every1Hour:"rate(1 hour)",Every6Hours:"rate(6 hours)",Every12Hours:"rate(12 hours)",Every1Day:"rate(1 day)"};static rateStringToExpression($){let J=$.toLowerCase().trim(),Y=J.match(/^every\s+(\d+)\s+(minute|minutes|hour|hours|day|days)$/i);if(Y){let H=parseInt(Y[1],10),A=Y[2].toLowerCase(),K=A.endsWith("s")&&H===1?A.slice(0,-1):A,B=!A.endsWith("s")&&H>1?`${A}s`:A;return`rate(${H} ${H===1?K:B})`}let Q=J.match(/^every\s+(minute|hour|day)$/i);if(Q)return`rate(1 ${Q[1]})`;let Z={"every minute":"rate(1 minute)","every hour":"rate(1 hour)","every day":"rate(1 day)",hourly:"cron(0 * * * ? *)",daily:"cron(0 0 * * ? *)","daily at midnight":"cron(0 0 * * ? *)",weekly:"cron(0 0 ? * SUN *)",monthly:"cron(0 0 1 * ? *)",yearly:"cron(0 0 1 1 ? *)"};if(Z[J])return Z[J];let U=J.match(/^daily\s+at\s+(\d{1,2})\s*(am|pm)?$/i);if(U){let H=parseInt(U[1],10),A=U[2]?.toLowerCase();if(A==="pm"&&H!==12)H+=12;else if(A==="am"&&H===12)H=0;return`cron(0 ${H} * * ? *)`}let W=J.match(/^at\s+(\d{1,2}):(\d{2})$/i);if(W){let H=parseInt(W[1],10);return`cron(${parseInt(W[2],10)} ${H} * * ? *)`}let z={monday:"MON",tuesday:"TUE",wednesday:"WED",thursday:"THU",friday:"FRI",saturday:"SAT",sunday:"SUN"},G=J.match(/^every\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/i);if(G)return`cron(0 0 ? * ${z[G[1].toLowerCase()]} *)`;return t0.toCronExpression($)}static JobConfig={create:($)=>{let{name:J,handler:Y,retries:Q=3,backoff:Z="exponential",backoffDelay:U=1000,maxDelay:W=30000,timeout:z=60000,jitter:G=!0}=$;return{name:J,handler:Y,retries:Q,backoff:Z,backoffDelay:U,maxDelay:W,timeout:z,jitter:G}},calculateDelay:($,J)=>{let{backoff:Y,backoffDelay:Q,maxDelay:Z,jitter:U}=J,W;switch(Y){case"linear":W=Q*$;break;case"exponential":W=Q*2**($-1);break;case"fixed":default:W=Q}if(W=Math.min(W,Z||Number.MAX_SAFE_INTEGER),U){let z=W*0.25*Math.random();W+=z}return Math.floor(W)},presets:{fastRetry:{retries:5,backoff:"exponential",backoffDelay:100,maxDelay:5000,jitter:!0},standard:{retries:3,backoff:"exponential",backoffDelay:1000,maxDelay:30000,jitter:!0},longRunning:{retries:2,backoff:"exponential",backoffDelay:5000,maxDelay:60000,timeout:300000,jitter:!0},critical:{retries:10,backoff:"exponential",backoffDelay:500,maxDelay:60000,jitter:!0},noRetry:{retries:0,backoff:"fixed",backoffDelay:0,maxDelay:0,jitter:!1}}};static createJobContainerOverride($){let{containerName:J,jobClass:Y,jobData:Q,environment:Z={}}=$,U=[{name:"JOB_CLASS",value:Y}];if(Q)U.push({name:"JOB_DATA",value:JSON.stringify(Q)});for(let[W,z]of Object.entries(Z))U.push({name:W,value:z});return{name:J,command:["bun","run","app/Jobs/runner.ts"],environment:U}}static createScheduledJob($){let{slug:J,environment:Y,schedule:Q,jobClass:Z,jobData:U,taskDefinitionArn:W,clusterArn:z,subnets:G,securityGroups:H=[],roleArn:A,containerName:K="app"}=$,B=t0.rateStringToExpression(Q),j=t0.createJobContainerOverride({containerName:K,jobClass:Z,jobData:U});return t0.scheduleEcsTask(B,A,{slug:J,environment:Y,name:`${J}-${Z.toLowerCase().replace(/[^a-z0-9]/g,"-")}`,description:`Scheduled job: ${Z}`,taskDefinitionArn:W,clusterArn:z,subnets:G,securityGroups:H,containerOverrides:[j]})}static QueuePresets={highThroughput:($,J)=>t0.createQueue({slug:$,environment:J,visibilityTimeout:30,receiveMessageWaitTime:0,delaySeconds:0}),longRunning:($,J)=>t0.createQueue({slug:$,environment:J,visibilityTimeout:300,messageRetentionPeriod:1209600}),fifo:($,J)=>t0.createQueue({slug:$,environment:J,fifo:!0,contentBasedDeduplication:!0}),delayed:($,J,Y=60)=>t0.createQueue({slug:$,environment:J,delaySeconds:Y})}};q4={loadJobs:m1.discoverJobs,loadActions:m1.discoverActions,generateScheduledJobs:m1.generateScheduledJobResources,generateRunner:m1.generateJobRunnerScript,paths:{jobs:"app/Jobs",actions:"app/Actions",runner:"app/Jobs/runner.ts"}},vQ={};q2(vQ,{handler:()=>E6,default:()=>E4});E4=E6;r0=class r0{static LambdaCode={send:E6,receive:w4,deliveryStatus:V4};static createPinpointApp($){return{[`${$.slug}PinpointApp`]:{Type:"AWS::Pinpoint::App",Properties:{Name:$.name||`${$.slug}-sms`}}}}static createSmsChannel($){let J={ApplicationId:$.applicationId,Enabled:$.enabled!==!1};if($.senderId)J.SenderId=$.senderId;if($.shortCode)J.ShortCode=$.shortCode;return{[`${$.slug}SmsChannel`]:{Type:"AWS::Pinpoint::SMSChannel",Properties:J}}}static createSmsLambdaRole($){return{[`${$.slug}SmsLambdaRole`]:{Type:"AWS::IAM::Role",Properties:{RoleName:`${$.slug}-sms-lambda-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"SmsLambdaPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["mobiletargeting:SendMessages","mobiletargeting:GetSmsChannel"],Resource:"*"},{Effect:"Allow",Action:["sns:Publish"],Resource:"*"},{Effect:"Allow",Action:["dynamodb:PutItem","dynamodb:UpdateItem","dynamodb:GetItem","dynamodb:DeleteItem"],Resource:"*"}]}}]}}}}static createSendLambda($){return{[`${$.slug}SmsSendLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-sms-send`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:r0.LambdaCode.send},Environment:{Variables:{PINPOINT_APP_ID:$.pinpointAppId,MESSAGE_LOG_TABLE:$.messageLogTable||"",SMS_SENDER_ID:$.senderId||"",SMS_ORIGINATION_NUMBER:$.originationNumber||""}}}}}}static createReceiveLambda($){return{[`${$.slug}SmsReceiveLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-sms-receive`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:r0.LambdaCode.receive},Environment:{Variables:{OPT_OUT_TABLE:$.optOutTable||"",MESSAGE_LOG_TABLE:$.messageLogTable||"",NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createDeliveryStatusLambda($){return{[`${$.slug}SmsDeliveryStatusLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$.slug}-sms-delivery-status`,Runtime:"nodejs20.x",Handler:"index.handler",Role:$.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:r0.LambdaCode.deliveryStatus},Environment:{Variables:{MESSAGE_LOG_TABLE:$.messageLogTable||"",NOTIFICATION_TOPIC_ARN:$.notificationTopicArn||"",WEBHOOK_URL:$.webhookUrl||""}}}}}}static createMessageLogTable($){return{[`${$.slug}SmsMessageLogTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$.slug}-sms-messages`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"messageId",AttributeType:"S"}],KeySchema:[{AttributeName:"messageId",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createOptOutTable($){return{[`${$.slug}SmsOptOutTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$.slug}-sms-optouts`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"phoneNumber",AttributeType:"S"}],KeySchema:[{AttributeName:"phoneNumber",KeyType:"HASH"}]}}}}static createNotificationTopic($){return{[`${$.slug}SmsNotificationTopic`]:{Type:"AWS::SNS::Topic",Properties:{TopicName:`${$.slug}-sms-notifications`}}}}static createCompleteSetup($){let J={},Y={};Object.assign(J,r0.createPinpointApp({slug:$.slug})),Object.assign(J,r0.createSmsChannel({slug:$.slug,applicationId:{Ref:`${$.slug}PinpointApp`},senderId:$.senderId})),Object.assign(J,r0.createSmsLambdaRole({slug:$.slug})),Object.assign(J,r0.createMessageLogTable({slug:$.slug})),Object.assign(J,r0.createOptOutTable({slug:$.slug})),Object.assign(J,r0.createNotificationTopic({slug:$.slug}));let Q={"Fn::GetAtt":[`${$.slug}SmsLambdaRole`,"Arn"]},Z={Ref:`${$.slug}PinpointApp`},U={Ref:`${$.slug}SmsMessageLogTable`},W={Ref:`${$.slug}SmsOptOutTable`},z={Ref:`${$.slug}SmsNotificationTopic`};if(Object.assign(J,r0.createSendLambda({slug:$.slug,roleArn:Q,pinpointAppId:Z,messageLogTable:U,senderId:$.senderId,originationNumber:$.originationNumber})),$.twoWayEnabled)Object.assign(J,r0.createReceiveLambda({slug:$.slug,roleArn:Q,optOutTable:W,messageLogTable:U,notificationTopicArn:z,webhookUrl:$.webhookUrl}));return Object.assign(J,r0.createDeliveryStatusLambda({slug:$.slug,roleArn:Q,messageLogTable:U,notificationTopicArn:z,webhookUrl:$.webhookUrl})),Y[`${$.slug}PinpointAppId`]={Description:"Pinpoint application ID",Value:{Ref:`${$.slug}PinpointApp`}},Y[`${$.slug}SmsSendLambdaArn`]={Description:"SMS send Lambda ARN",Value:{"Fn::GetAtt":[`${$.slug}SmsSendLambda`,"Arn"]}},Y[`${$.slug}SmsNotificationTopicArn`]={Description:"SMS notification topic ARN",Value:{Ref:`${$.slug}SmsNotificationTopic`}},Y[`${$.slug}SmsMessageLogTableName`]={Description:"SMS message log table name",Value:{Ref:`${$.slug}SmsMessageLogTable`}},{resources:J,outputs:Y}}};O1=class O1{static createBedrockRole($,J){let{slug:Y,environment:Q,name:Z,models:U=["*"],allowStreaming:W=!0}=J,z=Z||f({slug:Y,environment:Q,resourceType:"bedrock-role"}),G=S(z),H=["bedrock:InvokeModel"];if(W)H.push("bedrock:InvokeModelWithResponseStream");let A=U.map((B)=>B==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${B}`);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:$},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:`${z}-policy`,PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:H,Resource:A}]}}],Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Q}]}},logicalId:G}}static createBedrockPolicy($){let{slug:J,environment:Y,name:Q,models:Z=["*"],allowInvoke:U=!0,allowStreaming:W=!0,allowAsync:z=!1}=$,G=Q||f({slug:J,environment:Y,resourceType:"bedrock-policy"}),H=S(G),A=[];if(U)A.push("bedrock:InvokeModel");if(W)A.push("bedrock:InvokeModelWithResponseStream");if(z)A.push("bedrock:InvokeModelAsync");let K=Z.map((j)=>j==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${j}`);return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:G,PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"BedrockModelInvocation",Effect:"Allow",Action:A,Resource:K}]}}},logicalId:H}}static enableBedrockForLambda($){return O1.createBedrockRole("lambda.amazonaws.com",$)}static enableBedrockForEcs($){return O1.createBedrockRole("ecs-tasks.amazonaws.com",$)}static enableBedrockForEc2($){return O1.createBedrockRole("ec2.amazonaws.com",$)}static addBedrockPermissions($,J=["*"],Y=!0){let Q=["bedrock:InvokeModel"];if(Y)Q.push("bedrock:InvokeModelWithResponseStream");let Z=J.map((U)=>U==="*"?"arn:aws:bedrock:*::foundation-model/*":`arn:aws:bedrock:*::foundation-model/${U}`);if(!$.Properties.Policies)$.Properties.Policies=[];return $.Properties.Policies.push({PolicyName:"bedrock-permissions",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:Q,Resource:Z}]}}),$}static Models={Claude3_5_Sonnet:"anthropic.claude-3-5-sonnet-20241022-v2:0",Claude3_5_Haiku:"anthropic.claude-3-5-haiku-20241022-v1:0",Claude3_Opus:"anthropic.claude-3-opus-20240229-v1:0",Claude3_Sonnet:"anthropic.claude-3-sonnet-20240229-v1:0",Claude3_Haiku:"anthropic.claude-3-haiku-20240307-v1:0",TitanTextG1Express:"amazon.titan-text-express-v1",TitanTextG1Lite:"amazon.titan-text-lite-v1",TitanEmbedG1Text:"amazon.titan-embed-text-v1",TitanImageG1:"amazon.titan-image-generator-v1",JurassicUltra:"ai21.j2-ultra-v1",JurassicMid:"ai21.j2-mid-v1",CommandText:"cohere.command-text-v14",CommandLight:"cohere.command-light-text-v14",EmbedEnglish:"cohere.embed-english-v3",EmbedMultilingual:"cohere.embed-multilingual-v3",Llama3_2_1B:"meta.llama3-2-1b-instruct-v1:0",Llama3_2_3B:"meta.llama3-2-3b-instruct-v1:0",Llama3_2_11B:"meta.llama3-2-11b-instruct-v1:0",Llama3_2_90B:"meta.llama3-2-90b-instruct-v1:0",Llama3_1_8B:"meta.llama3-1-8b-instruct-v1:0",Llama3_1_70B:"meta.llama3-1-70b-instruct-v1:0",Llama3_1_405B:"meta.llama3-1-405b-instruct-v1:0",Mistral7B:"mistral.mistral-7b-instruct-v0:2",Mixtral8x7B:"mistral.mixtral-8x7b-instruct-v0:1",MistralLarge:"mistral.mistral-large-2402-v1:0",StableDiffusionXL:"stability.stable-diffusion-xl-v1"};static ModelGroups={AllClaude:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","anthropic.claude-3-opus-20240229-v1:0","anthropic.claude-3-sonnet-20240229-v1:0","anthropic.claude-3-haiku-20240307-v1:0"],AllTitan:["amazon.titan-text-express-v1","amazon.titan-text-lite-v1","amazon.titan-embed-text-v1","amazon.titan-image-generator-v1"],AllLlama:["meta.llama3-2-1b-instruct-v1:0","meta.llama3-2-3b-instruct-v1:0","meta.llama3-2-11b-instruct-v1:0","meta.llama3-2-90b-instruct-v1:0","meta.llama3-1-8b-instruct-v1:0","meta.llama3-1-70b-instruct-v1:0","meta.llama3-1-405b-instruct-v1:0"],TextModels:["anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-5-haiku-20241022-v1:0","amazon.titan-text-express-v1","meta.llama3-2-11b-instruct-v1:0","mistral.mistral-7b-instruct-v0:2"],EmbeddingModels:["amazon.titan-embed-text-v1","cohere.embed-english-v3","cohere.embed-multilingual-v3"],ImageModels:["amazon.titan-image-generator-v1","stability.stable-diffusion-xl-v1"]}};Q2=class Q2{static createPostgres($){return Q2.createRDSInstance("postgres","16.2",$)}static createMysql($){return Q2.createRDSInstance("mysql","8.0.35",$)}static createRDSInstance($,J,Y){let{slug:Q,environment:Z,instanceClass:U="db.t3.micro",allocatedStorage:W=20,storageType:z="gp3",masterUsername:G="admin",masterPassword:H,databaseName:A,subnetIds:K,securityGroupIds:B,encrypted:j=!0,kmsKeyId:X,multiAz:O=!1,backupRetentionDays:_=7,publiclyAccessible:w=!1,enableCloudwatchLogs:E=!0,deletionProtection:M=!0}=Y,T=f({slug:Q,environment:Z,resourceType:`${$}-db`}),D=S(T),N,x;if(K&&K.length>0){let I=f({slug:Q,environment:Z,resourceType:"db-subnet-group"});x=S(I),N={Type:"AWS::RDS::DBSubnetGroup",Properties:{DBSubnetGroupName:I,DBSubnetGroupDescription:`Subnet group for ${T}`,SubnetIds:K,Tags:[{Key:"Name",Value:I},{Key:"Environment",Value:Z}]}}}let h={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:T,DBInstanceClass:U,Engine:$,EngineVersion:J,MasterUsername:G,MasterUserPassword:H,AllocatedStorage:W,StorageType:z,StorageEncrypted:j,MultiAZ:O,BackupRetentionPeriod:_,PubliclyAccessible:w,DeletionProtection:M,Tags:[{Key:"Name",Value:T},{Key:"Environment",Value:Z}]}};if(A)h.Properties.DBName=A;if(X)h.Properties.KmsKeyId=X;if(x)h.Properties.DBSubnetGroupName=u.Ref(x);if(B&&B.length>0)h.Properties.VPCSecurityGroups=B;if(E)h.Properties.EnableCloudwatchLogsExports=$==="postgres"?["postgresql"]:["error","general","slowquery"];return{dbInstance:h,subnetGroup:N,logicalId:D,subnetGroupId:x}}static createReadReplica($,J){let{slug:Y,environment:Q,instanceClass:Z="db.t3.micro",securityGroupIds:U,publiclyAccessible:W=!1}=J,z=f({slug:Y,environment:Q,resourceType:"db-replica"}),G=S(z),H={Type:"AWS::RDS::DBInstance",Properties:{DBInstanceIdentifier:z,DBInstanceClass:Z,SourceDBInstanceIdentifier:u.Ref($),PubliclyAccessible:W,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Q},{Key:"Type",Value:"ReadReplica"}]}};if(U&&U.length>0)H.Properties.VPCSecurityGroups=U;return{replica:H,logicalId:G}}static createParameterGroup($,J,Y){let{slug:Q,environment:Z,parameters:U={}}=Y,W=f({slug:Q,environment:Z,resourceType:"db-params"}),z=S(W),G=$==="postgres"?`postgres${J.split(".")[0]}`:`mysql${J.split(".")[0]}.${J.split(".")[1]}`;return{parameterGroup:{Type:"AWS::RDS::DBParameterGroup",Properties:{DBParameterGroupName:W,Description:`Parameter group for ${W}`,Family:G,Parameters:U,Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Z}]}},logicalId:z}}static enableBackup($,J=7){return $.Properties.BackupRetentionPeriod=J,$}static createTable($){let{slug:J,environment:Y,tableName:Q,partitionKey:Z,sortKey:U,billingMode:W="PAY_PER_REQUEST",readCapacity:z=5,writeCapacity:G=5,streamEnabled:H=!1,streamViewType:A="NEW_AND_OLD_IMAGES",encrypted:K=!0,kmsKeyId:B,pointInTimeRecovery:j=!0,ttlAttribute:X}=$,O=Q||f({slug:J,environment:Y,resourceType:"table"}),_=S(O),w=[{AttributeName:Z.name,AttributeType:Z.type}];if(U)w.push({AttributeName:U.name,AttributeType:U.type});let E=[{AttributeName:Z.name,KeyType:"HASH"}];if(U)E.push({AttributeName:U.name,KeyType:"RANGE"});let M={Type:"AWS::DynamoDB::Table",Properties:{TableName:O,BillingMode:W,AttributeDefinitions:w,KeySchema:E,Tags:[{Key:"Name",Value:O},{Key:"Environment",Value:Y}]}};if(W==="PROVISIONED")M.Properties.ProvisionedThroughput={ReadCapacityUnits:z,WriteCapacityUnits:G};if(H)M.Properties.StreamSpecification={StreamViewType:A};if(K)M.Properties.SSESpecification={SSEEnabled:!0,SSEType:B?"KMS":"AES256",KMSMasterKeyId:B};if(j)M.Properties.PointInTimeRecoverySpecification={PointInTimeRecoveryEnabled:!0};if(X)M.Properties.TimeToLiveSpecification={AttributeName:X,Enabled:!0};return{table:M,logicalId:_}}static addGlobalSecondaryIndex($,J){let{indexName:Y,partitionKey:Q,sortKey:Z,projectionType:U="ALL",nonKeyAttributes:W,readCapacity:z=5,writeCapacity:G=5}=J;if(!$.Properties.AttributeDefinitions.some((K)=>K.AttributeName===Q.name))$.Properties.AttributeDefinitions.push({AttributeName:Q.name,AttributeType:Q.type});if(Z&&!$.Properties.AttributeDefinitions.some((K)=>K.AttributeName===Z.name))$.Properties.AttributeDefinitions.push({AttributeName:Z.name,AttributeType:Z.type});let H=[{AttributeName:Q.name,KeyType:"HASH"}];if(Z)H.push({AttributeName:Z.name,KeyType:"RANGE"});let A={IndexName:Y,KeySchema:H,Projection:{ProjectionType:U,NonKeyAttributes:U==="INCLUDE"?W:void 0},ProvisionedThroughput:void 0};if($.Properties.BillingMode==="PROVISIONED")A.ProvisionedThroughput={ReadCapacityUnits:z,WriteCapacityUnits:G};if(!$.Properties.GlobalSecondaryIndexes)$.Properties.GlobalSecondaryIndexes=[];return $.Properties.GlobalSecondaryIndexes.push(A),$}static enableStreams($,J="NEW_AND_OLD_IMAGES"){return $.Properties.StreamSpecification={StreamViewType:J},$}static InstanceClasses={T3_Micro:"db.t3.micro",T3_Small:"db.t3.small",T3_Medium:"db.t3.medium",T3_Large:"db.t3.large",T4g_Micro:"db.t4g.micro",T4g_Small:"db.t4g.small",T4g_Medium:"db.t4g.medium",M5_Large:"db.m5.large",M5_XLarge:"db.m5.xlarge",M5_2XLarge:"db.m5.2xlarge",R5_Large:"db.r5.large",R5_XLarge:"db.r5.xlarge",R5_2XLarge:"db.r5.2xlarge"}};O$=class O${static createRedis($){let{slug:J,environment:Y,nodeType:Q="cache.t3.micro",engineVersion:Z="7.1",port:U=6379,subnetIds:W,securityGroupIds:z,numCacheClusters:G=2,automaticFailover:H=!0,multiAz:A=!0,clusterMode:K=!1,numNodeGroups:B=1,replicasPerNodeGroup:j=1,atRestEncryption:X=!0,transitEncryption:O=!0,authToken:_,kmsKeyId:w,snapshotRetentionDays:E=7,snapshotWindow:M,maintenanceWindow:T}=$,D=f({slug:J,environment:Y,resourceType:"redis"}),N=S(D),x,h;if(W&&W.length>0){let b=f({slug:J,environment:Y,resourceType:"cache-subnet-group"});h=S(b),x={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:b,Description:`Subnet group for ${D}`,SubnetIds:W,Tags:[{Key:"Name",Value:b},{Key:"Environment",Value:Y}]}}}let I={Type:"AWS::ElastiCache::ReplicationGroup",Properties:{ReplicationGroupId:D,ReplicationGroupDescription:`Redis cluster for ${J} ${Y}`,Engine:"redis",EngineVersion:Z,CacheNodeType:Q,Port:U,AutomaticFailoverEnabled:H,MultiAZEnabled:A,AtRestEncryptionEnabled:X,TransitEncryptionEnabled:O,SnapshotRetentionLimit:E,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:D},{Key:"Environment",Value:Y}]}};if(K)I.Properties.NumNodeGroups=B,I.Properties.ReplicasPerNodeGroup=j;else I.Properties.NumCacheClusters=G;if(_)I.Properties.AuthToken=_;if(w)I.Properties.KmsKeyId=w;if(h)I.Properties.CacheSubnetGroupName=u.Ref(h);if(z&&z.length>0)I.Properties.SecurityGroupIds=z;if(M)I.Properties.SnapshotWindow=M;if(T)I.Properties.PreferredMaintenanceWindow=T;return{replicationGroup:I,subnetGroup:x,logicalId:N,subnetGroupId:h}}static createMemcached($){let{slug:J,environment:Y,nodeType:Q="cache.t3.micro",engineVersion:Z="1.6.22",port:U=11211,numCacheNodes:W=2,subnetIds:z,securityGroupIds:G,azMode:H="cross-az",preferredAzs:A,maintenanceWindow:K}=$,B=f({slug:J,environment:Y,resourceType:"memcached"}),j=S(B),X,O;if(z&&z.length>0){let w=f({slug:J,environment:Y,resourceType:"cache-subnet-group"});O=S(w),X={Type:"AWS::ElastiCache::SubnetGroup",Properties:{CacheSubnetGroupName:w,Description:`Subnet group for ${B}`,SubnetIds:z,Tags:[{Key:"Name",Value:w},{Key:"Environment",Value:Y}]}}}let _={Type:"AWS::ElastiCache::CacheCluster",Properties:{ClusterName:B,CacheNodeType:Q,Engine:"memcached",EngineVersion:Z,NumCacheNodes:W,Port:U,AZMode:H,AutoMinorVersionUpgrade:!0,Tags:[{Key:"Name",Value:B},{Key:"Environment",Value:Y}]}};if(O)_.Properties.CacheSubnetGroupName=u.Ref(O);if(G&&G.length>0)_.Properties.VpcSecurityGroupIds=G;if(A&&A.length>0)_.Properties.PreferredAvailabilityZones=A;if(K)_.Properties.PreferredMaintenanceWindow=K;return{cluster:_,subnetGroup:X,logicalId:j,subnetGroupId:O}}static enableClusterMode($,J=3,Y=2){return delete $.Properties.NumCacheClusters,$.Properties.NumNodeGroups=J,$.Properties.ReplicasPerNodeGroup=Y,$}static createRedisParameterGroup($,J){let{slug:Y,environment:Q,parameters:Z={}}=J,U=f({slug:Y,environment:Q,resourceType:"redis-params"}),W=S(U);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`redis${$.split(".")[0]}.x`,Description:`Parameter group for ${U}`,Properties:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q}]}},logicalId:W}}static createMemcachedParameterGroup($,J){let{slug:Y,environment:Q,parameters:Z={}}=J,U=f({slug:Y,environment:Q,resourceType:"memcached-params"}),W=S(U);return{parameterGroup:{Type:"AWS::ElastiCache::ParameterGroup",Properties:{CacheParameterGroupFamily:`memcached${$.split(".")[0]}.${$.split(".")[1]}`,Description:`Parameter group for ${U}`,Properties:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Q}]}},logicalId:W}}static NodeTypes={T3_Micro:"cache.t3.micro",T3_Small:"cache.t3.small",T3_Medium:"cache.t3.medium",T4g_Micro:"cache.t4g.micro",T4g_Small:"cache.t4g.small",T4g_Medium:"cache.t4g.medium",M5_Large:"cache.m5.large",M5_XLarge:"cache.m5.xlarge",M5_2XLarge:"cache.m5.2xlarge",R5_Large:"cache.r5.large",R5_XLarge:"cache.r5.xlarge",R5_2XLarge:"cache.r5.2xlarge",R5_4XLarge:"cache.r5.4xlarge",R6g_Large:"cache.r6g.large",R6g_XLarge:"cache.r6g.xlarge",R6g_2XLarge:"cache.r6g.2xlarge"}};Y1=class Y1{static createUser($){let{slug:J,environment:Y,userName:Q,groups:Z,managedPolicyArns:U}=$,W=Q||f({slug:J,environment:Y,resourceType:"user"}),z=S(W),G={Type:"AWS::IAM::User",Properties:{UserName:W,Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Y}]}};if(Z&&Z.length>0)G.Properties.Groups=Z;if(U&&U.length>0)G.Properties.ManagedPolicyArns=U;return{user:G,logicalId:z}}static createRole($){let{slug:J,environment:Y,roleName:Q,servicePrincipal:Z,awsPrincipal:U,managedPolicyArns:W}=$,z=Q||f({slug:J,environment:Y,resourceType:"role"}),G=S(z),H={};if(Z)H.Service=Z;if(U)H.AWS=U;let A={Type:"AWS::IAM::Role",Properties:{RoleName:z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:H,Action:"sts:AssumeRole"}]},Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(W&&W.length>0)A.Properties.ManagedPolicyArns=W;return{role:A,logicalId:G}}static createGroup($){let{slug:J,environment:Y,groupName:Q,managedPolicyArns:Z}=$,U=Q||f({slug:J,environment:Y,resourceType:"group"}),W=S(U),z={Type:"AWS::IAM::Group",Properties:{GroupName:U}};if(Z&&Z.length>0)z.Properties.ManagedPolicyArns=Z;return{group:z,logicalId:W}}static createPolicy($){let{slug:J,environment:Y,policyName:Q,description:Z,statements:U}=$,W=Q||f({slug:J,environment:Y,resourceType:"policy"}),z=S(W),G=U.map((A)=>({Sid:A.sid,Effect:A.effect||"Allow",Action:A.actions,Resource:A.resources,Condition:A.conditions}));return{policy:{Type:"AWS::IAM::ManagedPolicy",Properties:{ManagedPolicyName:W,Description:Z||`Managed policy for ${W}`,PolicyDocument:{Version:"2012-10-17",Statement:G}}},logicalId:z}}static attachPolicyToRole($,J){if(!$.Properties.ManagedPolicyArns)$.Properties.ManagedPolicyArns=[];if(!$.Properties.ManagedPolicyArns.includes(J))$.Properties.ManagedPolicyArns.push(J);return $}static attachPolicyToUser($,J){if(!$.Properties.ManagedPolicyArns)$.Properties.ManagedPolicyArns=[];if(!$.Properties.ManagedPolicyArns.includes(J))$.Properties.ManagedPolicyArns.push(J);return $}static attachPolicyToGroup($,J){if(!$.Properties.ManagedPolicyArns)$.Properties.ManagedPolicyArns=[];if(!$.Properties.ManagedPolicyArns.includes(J))$.Properties.ManagedPolicyArns.push(J);return $}static addInlinePolicyToRole($,J,Y){if(!$.Properties.Policies)$.Properties.Policies=[];let Q=Y.map((Z)=>({Effect:Z.effect||"Allow",Action:Z.actions,Resource:Z.resources}));return $.Properties.Policies.push({PolicyName:J,PolicyDocument:{Version:"2012-10-17",Statement:Q}}),$}static addInlinePolicyToUser($,J,Y){if(!$.Properties.Policies)$.Properties.Policies=[];let Q=Y.map((Z)=>({Effect:Z.effect||"Allow",Action:Z.actions,Resource:Z.resources}));return $.Properties.Policies.push({PolicyName:J,PolicyDocument:{Version:"2012-10-17",Statement:Q}}),$}static createAccessKey($,J){let{slug:Y,environment:Q,status:Z="Active"}=J,U=f({slug:Y,environment:Q,resourceType:"access-key"}),W=S(U);return{accessKey:{Type:"AWS::IAM::AccessKey",Properties:{UserName:u.Ref($),Status:Z}},logicalId:W}}static createInstanceProfile($,J){let{slug:Y,environment:Q,profileName:Z}=J,U=Z||f({slug:Y,environment:Q,resourceType:"instance-profile"}),W=S(U);return{instanceProfile:{Type:"AWS::IAM::InstanceProfile",Properties:{InstanceProfileName:U,Roles:[u.Ref($)]}},logicalId:W}}static ManagedPolicies={AdministratorAccess:"arn:aws:iam::aws:policy/AdministratorAccess",PowerUserAccess:"arn:aws:iam::aws:policy/PowerUserAccess",ReadOnlyAccess:"arn:aws:iam::aws:policy/ReadOnlyAccess",S3FullAccess:"arn:aws:iam::aws:policy/AmazonS3FullAccess",S3ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess",DynamoDBFullAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess",DynamoDBReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess",RDSFullAccess:"arn:aws:iam::aws:policy/AmazonRDSFullAccess",RDSReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess",LambdaFullAccess:"arn:aws:iam::aws:policy/AWSLambda_FullAccess",LambdaReadOnlyAccess:"arn:aws:iam::aws:policy/AWSLambda_ReadOnlyAccess",LambdaBasicExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",LambdaVPCAccessExecutionRole:"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole",EC2FullAccess:"arn:aws:iam::aws:policy/AmazonEC2FullAccess",EC2ReadOnlyAccess:"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess",EC2ContainerRegistryReadOnly:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",EC2ContainerRegistryPowerUser:"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser",ECSTaskExecutionRole:"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",ECSFullAccess:"arn:aws:iam::aws:policy/AmazonECS_FullAccess",CloudWatchFullAccess:"arn:aws:iam::aws:policy/CloudWatchFullAccess",CloudWatchLogsFullAccess:"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess",SESFullAccess:"arn:aws:iam::aws:policy/AmazonSESFullAccess",SNSFullAccess:"arn:aws:iam::aws:policy/AmazonSNSFullAccess",SQSFullAccess:"arn:aws:iam::aws:policy/AmazonSQSFullAccess",SecretsManagerReadWrite:"arn:aws:iam::aws:policy/SecretsManagerReadWrite"};static ServicePrincipals={Lambda:"lambda.amazonaws.com",EC2:"ec2.amazonaws.com",ECS:"ecs.amazonaws.com",ECSTaskExecution:"ecs-tasks.amazonaws.com",APIGateway:"apigateway.amazonaws.com",Events:"events.amazonaws.com",States:"states.amazonaws.com",CodeBuild:"codebuild.amazonaws.com",CodeDeploy:"codedeploy.amazonaws.com",CloudFormation:"cloudformation.amazonaws.com"};static createCiCdUser($){let{slug:J,environment:Y,permissions:Q,createAccessKey:Z=!0}=$,U={},W=[];if(Q.s3Buckets&&Q.s3Buckets.length>0)W.push({sid:"S3Access",actions:["s3:GetBucketLocation","s3:ListBucket","s3:GetObject","s3:PutObject","s3:DeleteObject","s3:ListBucketMultipartUploads","s3:AbortMultipartUpload"],resources:[...Q.s3Buckets,...Q.s3Buckets.map((j)=>`${j}/*`)]});if(Q.cloudFrontDistributions&&Q.cloudFrontDistributions.length>0)W.push({sid:"CloudFrontAccess",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations","cloudfront:GetDistribution"],resources:Q.cloudFrontDistributions});if(Q.ecrRepositories&&Q.ecrRepositories.length>0)W.push({sid:"ECRAccess",actions:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:DescribeRepositories","ecr:ListImages","ecr:DescribeImages","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:Q.ecrRepositories}),W.push({sid:"ECRLogin",actions:["ecr:GetAuthorizationToken"],resources:"*"});if(Q.ecsServices&&Q.ecsServices.length>0)W.push({sid:"ECSAccess",actions:["ecs:DescribeServices","ecs:DescribeTaskDefinition","ecs:DescribeTasks","ecs:ListTasks","ecs:RegisterTaskDefinition","ecs:UpdateService","ecs:RunTask","ecs:StopTask"],resources:Q.ecsServices}),W.push({sid:"ECSTaskDefinitions",actions:["ecs:RegisterTaskDefinition","ecs:DeregisterTaskDefinition"],resources:"*"}),W.push({sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}});if(Q.cloudFormationStacks&&Q.cloudFormationStacks.length>0)W.push({sid:"CloudFormationAccess",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:DescribeStackResources","cloudformation:GetTemplate","cloudformation:ListStackResources","cloudformation:ValidateTemplate"],resources:Q.cloudFormationStacks});if(Q.lambdaFunctions&&Q.lambdaFunctions.length>0)W.push({sid:"LambdaAccess",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion","lambda:UpdateAlias","lambda:CreateAlias"],resources:Q.lambdaFunctions});if(Q.secretsManagerSecrets&&Q.secretsManagerSecrets.length>0)W.push({sid:"SecretsManagerAccess",actions:["secretsmanager:GetSecretValue","secretsmanager:DescribeSecret"],resources:Q.secretsManagerSecrets});let{policy:z,logicalId:G}=Y1.createPolicy({slug:J,environment:Y,policyName:f({slug:J,environment:Y,resourceType:"cicd-policy"}),description:`CI/CD deployment policy for ${J} (${Y})`,statements:W});U[G]=z;let{user:H,logicalId:A}=Y1.createUser({slug:J,environment:Y,userName:f({slug:J,environment:Y,resourceType:"cicd-user"}),managedPolicyArns:[u.Ref(G)]});U[A]=H;let K,B;if(Z){let j=Y1.createAccessKey(A,{slug:J,environment:Y});K=j.accessKey,B=j.logicalId,U[B]=K}return{user:H,accessKey:K,policy:z,userLogicalId:A,accessKeyLogicalId:B,policyLogicalId:G,resources:U}}static createCrossAccountRole($){let{slug:J,environment:Y,trustedAccountIds:Q,externalId:Z,permissions:U,maxSessionDuration:W=3600}=$,z={},{policy:G,logicalId:H}=Y1.createPolicy({slug:J,environment:Y,policyName:f({slug:J,environment:Y,resourceType:"cross-account-policy"}),description:`Cross-account access policy for ${J} (${Y})`,statements:U});z[H]=G;let A=f({slug:J,environment:Y,resourceType:"cross-account-role"}),K=S(A),B={};if(Z)B.StringEquals={"sts:ExternalId":Z};let j={Type:"AWS::IAM::Role",Properties:{RoleName:A,MaxSessionDuration:W,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:Q.map((X)=>`arn:aws:iam::${X}:root`)},Action:"sts:AssumeRole",...Object.keys(B).length>0?{Condition:B}:{}}]},ManagedPolicyArns:[u.Ref(H)],Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"Cross-Account Access"}]}};return z[K]=j,{role:j,policy:G,roleLogicalId:K,policyLogicalId:H,resources:z}}static createCliUser($){let{slug:J,environment:Y,permissions:Q="readonly"}=$,Z={},U=[],W=[];switch(Q){case"readonly":W=[Y1.ManagedPolicies.ReadOnlyAccess];break;case"deploy":U=[{sid:"S3Deploy",actions:["s3:*"],resources:"*"},{sid:"CloudFrontDeploy",actions:["cloudfront:*"],resources:"*"},{sid:"ECSDeploy",actions:["ecs:*"],resources:"*"},{sid:"ECRDeploy",actions:["ecr:*"],resources:"*"},{sid:"LambdaDeploy",actions:["lambda:*"],resources:"*"},{sid:"CloudFormationDeploy",actions:["cloudformation:*"],resources:"*"},{sid:"IAMPassRole",actions:["iam:PassRole"],resources:"*"}];break;case"admin":W=[Y1.ManagedPolicies.AdministratorAccess];break}let z,G;if(U.length>0){let j=Y1.createPolicy({slug:J,environment:Y,policyName:f({slug:J,environment:Y,resourceType:"cli-policy"}),description:`CLI access policy for ${J} (${Y})`,statements:U});z=j.policy,G=j.logicalId,Z[G]=z,W=[u.Ref(G)]}let{user:H,logicalId:A}=Y1.createUser({slug:J,environment:Y,userName:f({slug:J,environment:Y,resourceType:"cli-user"}),managedPolicyArns:W});Z[A]=H;let{accessKey:K,logicalId:B}=Y1.createAccessKey(A,{slug:J,environment:Y});return Z[B]=K,{user:H,accessKey:K,policy:z,userLogicalId:A,accessKeyLogicalId:B,policyLogicalId:G,resources:Z}}static CiCdPolicies={s3Deployment:($)=>[{sid:"S3ListBuckets",actions:["s3:ListBucket","s3:GetBucketLocation"],resources:$},{sid:"S3Objects",actions:["s3:GetObject","s3:PutObject","s3:DeleteObject"],resources:$.map((J)=>`${J}/*`)}],cloudFrontInvalidation:($)=>[{sid:"CloudFrontInvalidation",actions:["cloudfront:CreateInvalidation","cloudfront:GetInvalidation","cloudfront:ListInvalidations"],resources:$}],ecsDeployment:()=>[{sid:"ECSServices",actions:["ecs:DescribeServices","ecs:UpdateService","ecs:DescribeTaskDefinition","ecs:RegisterTaskDefinition"],resources:"*"},{sid:"ECSPassRole",actions:["iam:PassRole"],resources:"*",conditions:{StringLike:{"iam:PassedToService":"ecs-tasks.amazonaws.com"}}}],ecrPush:($)=>[{sid:"ECRAuth",actions:["ecr:GetAuthorizationToken"],resources:"*"},{sid:"ECRPush",actions:["ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:PutImage"],resources:$}],lambdaDeployment:($)=>[{sid:"LambdaDeploy",actions:["lambda:GetFunction","lambda:UpdateFunctionCode","lambda:UpdateFunctionConfiguration","lambda:PublishVersion"],resources:$}],cloudFormationDeployment:($)=>[{sid:"CloudFormationDeploy",actions:["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DescribeStacks","cloudformation:DescribeStackEvents","cloudformation:GetTemplate"],resources:$}]}};x9=class x9{static createRestApi($){let{slug:J,environment:Y,name:Q,description:Z,endpointType:U="REGIONAL",binaryMediaTypes:W,compressionSize:z}=$,G=Q||f({slug:J,environment:Y,resourceType:"rest-api"}),H=S(G),A={Type:"AWS::ApiGateway::RestApi",Properties:{Name:G,Description:Z||`REST API for ${J} ${Y}`,EndpointConfiguration:{Types:[U]},Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y}]}};if(W&&W.length>0)A.Properties.BinaryMediaTypes=W;if(z!==void 0)A.Properties.MinimumCompressionSize=z;return{restApi:A,logicalId:H}}static createHttpApi($){let{slug:J,environment:Y,name:Q,description:Z,corsEnabled:U=!0,corsOrigins:W=["*"],corsMethods:z=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],corsHeaders:G=["*"],corsMaxAge:H=86400,corsAllowCredentials:A=!1}=$,K=Q||f({slug:J,environment:Y,resourceType:"http-api"}),B=S(K),j={Type:"AWS::ApiGatewayV2::Api",Properties:{Name:K,Description:Z||`HTTP API for ${J} ${Y}`,ProtocolType:"HTTP",Tags:{Name:K,Environment:Y}}};if(U)j.Properties.CorsConfiguration={AllowOrigins:W,AllowMethods:z,AllowHeaders:G,MaxAge:H,AllowCredentials:A};return{httpApi:j,logicalId:B}}static createWebSocketApi($){let{slug:J,environment:Y,name:Q,description:Z}=$,U=Q||f({slug:J,environment:Y,resourceType:"ws-api"}),W=S(U);return{webSocketApi:{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:U,Description:Z||`WebSocket API for ${J} ${Y}`,ProtocolType:"WEBSOCKET",Tags:{Name:U,Environment:Y}}},logicalId:W}}static createDeployment($,J){let{slug:Y,environment:Q,description:Z}=J,U=f({slug:Y,environment:Q,resourceType:"api-deployment"}),W=S(U);return{deployment:{Type:"AWS::ApiGateway::Deployment",Properties:{RestApiId:u.Ref($),Description:Z||`Deployment for ${U}`}},logicalId:W}}static createStage($,J,Y){let{slug:Q,environment:Z,stageName:U,description:W,cacheEnabled:z=!1,cacheSize:G="0.5",variables:H,throttling:A}=Y,K=f({slug:Q,environment:Z,resourceType:"api-stage"}),B=S(K),j={Type:"AWS::ApiGateway::Stage",Properties:{StageName:U||Z,RestApiId:u.Ref($),DeploymentId:u.Ref(J),Description:W,CacheClusterEnabled:z,Tags:[{Key:"Name",Value:K},{Key:"Environment",Value:Z}]}};if(z)j.Properties.CacheClusterSize=G;if(H)j.Properties.Variables=H;if(A)j.Properties.MethodSettings=[{HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:A.burstLimit,ThrottlingRateLimit:A.rateLimit}];return{stage:j,logicalId:B}}static createAuthorizer($,J){let{slug:Y,environment:Q,name:Z,type:U,functionArn:W,identitySource:z,userPoolArns:G,ttl:H=300}=J,A=Z||f({slug:Y,environment:Q,resourceType:"api-authorizer"}),K=S(A),B={Type:"AWS::ApiGateway::Authorizer",Properties:{Name:A,Type:U,RestApiId:u.Ref($),AuthorizerResultTtlInSeconds:H}};if(U==="TOKEN"||U==="REQUEST"){if(!W)throw Error("Lambda authorizer requires functionArn");B.Properties.AuthorizerUri=W,B.Properties.IdentitySource=z||"method.request.header.Authorization"}if(U==="COGNITO_USER_POOLS"){if(!G||G.length===0)throw Error("Cognito authorizer requires userPoolArns");B.Properties.ProviderARNs=G,B.Properties.IdentitySource=z||"method.request.header.Authorization"}return{authorizer:B,logicalId:K}}static setCors($,J={}){let{origins:Y=["*"],methods:Q=["GET","POST","PUT","PATCH","DELETE","OPTIONS"],headers:Z=["*"],maxAge:U=86400,allowCredentials:W=!1}=J;return $.Properties.CorsConfiguration={AllowOrigins:Y,AllowMethods:Q,AllowHeaders:Z,MaxAge:U,AllowCredentials:W},$}static addThrottling($,J=5000,Y=1e4){if(!$.Properties.MethodSettings)$.Properties.MethodSettings=[];return $.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",ThrottlingBurstLimit:J,ThrottlingRateLimit:Y}),$}static enableCaching($,J="0.5",Y=300){if($.Properties.CacheClusterEnabled=!0,$.Properties.CacheClusterSize=J,!$.Properties.MethodSettings)$.Properties.MethodSettings=[];return $.Properties.MethodSettings.push({HttpMethod:"*",ResourcePath:"/*",CachingEnabled:!0,CacheTtlInSeconds:Y}),$}static CacheSizes={Small:"0.5",Medium:"1.6",Large:"6.1",XLarge:"13.5",XXLarge:"28.4",XXXLarge:"58.2",Huge:"118",Massive:"237"};static ThrottlingPresets={Light:{burstLimit:100,rateLimit:50},Medium:{burstLimit:500,rateLimit:250},Heavy:{burstLimit:2000,rateLimit:1000},Default:{burstLimit:5000,rateLimit:1e4}}};$1=class $1{static createTopic($){let{slug:J,environment:Y,topicName:Q,displayName:Z,encrypted:U=!1,kmsKeyId:W}=$,z=Q||f({slug:J,environment:Y,resourceType:"topic"}),G=S(z),H={Type:"AWS::SNS::Topic",Properties:{TopicName:z,DisplayName:Z||z,Tags:[{Key:"Name",Value:z},{Key:"Environment",Value:Y}]}};if(U&&W)H.Properties.KmsMasterKeyId=W;return{topic:H,logicalId:G}}static subscribe($,J){let{slug:Y,environment:Q,protocol:Z,endpoint:U,filterPolicy:W,rawMessageDelivery:z=!1}=J,G=f({slug:Y,environment:Q,resourceType:"subscription"}),H=U.replace(/[^a-zA-Z0-9]/g,""),A=H.length>12?H.slice(-12):H,K=S(`${G}-${Z}-${A}`),B={Type:"AWS::SNS::Subscription",Properties:{TopicArn:u.Ref($),Protocol:Z,Endpoint:U,RawMessageDelivery:z}};if(W)B.Properties.FilterPolicy=W;return{subscription:B,logicalId:K}}static subscribeEmail($,J,Y){return $1.subscribe($,{...Y,protocol:"email",endpoint:J})}static subscribeLambda($,J,Y){return $1.subscribe($,{...Y,protocol:"lambda",endpoint:J,rawMessageDelivery:!0})}static subscribeSqs($,J,Y){return $1.subscribe($,{...Y,protocol:"sqs",endpoint:J})}static subscribeHttp($,J,Y){let Q=J.startsWith("https://")?"https":"http";return $1.subscribe($,{...Y,protocol:Q,endpoint:J})}static subscribeSms($,J,Y){return $1.subscribe($,{...Y,protocol:"sms",endpoint:J})}static setTopicPolicy($,J){let{slug:Y,environment:Q,allowedPrincipals:Z,allowedServices:U,actions:W="SNS:Publish"}=J,z=f({slug:Y,environment:Q,resourceType:"topic-policy"}),G=S(z),H={};if(Z)H.AWS=Z;if(U)H.Service=U;return{policy:{Type:"AWS::SNS::TopicPolicy",Properties:{Topics:[u.Ref($)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:H,Action:W,Resource:u.Ref($)}]}}},logicalId:G}}static allowCloudWatchAlarms($,J){return $1.setTopicPolicy($,{...J,allowedServices:"cloudwatch.amazonaws.com",actions:"SNS:Publish"})}static allowEventBridge($,J){return $1.setTopicPolicy($,{...J,allowedServices:"events.amazonaws.com",actions:"SNS:Publish"})}static allowS3($,J){return $1.setTopicPolicy($,{...J,allowedServices:"s3.amazonaws.com",actions:"SNS:Publish"})}static enableEncryption($,J){if(!$.Properties)$.Properties={};return $.Properties.KmsMasterKeyId=J,$}static addInlineSubscription($,J,Y){if(!$.Properties)$.Properties={};if(!$.Properties.Subscription)$.Properties.Subscription=[];return $.Properties.Subscription.push({Protocol:J,Endpoint:Y}),$}static FilterPolicies={eventType:($)=>({eventType:$}),status:($)=>({status:$}),numericRange:($,J,Y)=>({[$]:[{numeric:[">=",J,"<=",Y]}]}),prefix:($,J)=>({[$]:[{prefix:J}]}),and:(...$)=>{return Object.assign({},...$)},exists:($,J)=>({[$]:[{exists:J}]})};static UseCases={createAlertTopic:($)=>{return $1.createTopic({...$,topicName:$.topicName||`${$.slug}-${$.environment}-alerts`,displayName:$.displayName||"Alert Notifications"})},createEventFanout:($)=>{return $1.createTopic({...$,topicName:$.topicName||`${$.slug}-${$.environment}-events`,displayName:$.displayName||"Event Fanout"})},createNotificationTopic:($)=>{return $1.createTopic({...$,topicName:$.topicName||`${$.slug}-${$.environment}-notifications`,displayName:$.displayName||"User Notifications"})}}};fQ=class fQ{static createStateMachine($){let{slug:J,environment:Y,stateMachineName:Q,type:Z="STANDARD",definition:U,roleArn:W,loggingConfiguration:z,tracingConfiguration:G}=$,H=Q||f({slug:J,environment:Y,resourceType:"state-machine"}),A=S(H),K,B,j;if(W)j=W;else{let O=f({slug:J,environment:Y,resourceType:"state-machine-role"});B=S(O),K={Type:"AWS::IAM::Role",Properties:{RoleName:O,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"states.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"],Tags:[{Key:"Name",Value:O},{Key:"Environment",Value:Y}]}},j=u.GetAtt(B,"Arn")}let X={Type:"AWS::StepFunctions::StateMachine",Properties:{StateMachineName:H,StateMachineType:Z,DefinitionString:JSON.stringify(U),RoleArn:j,Tags:[{Key:"Name",Value:H},{Key:"Environment",Value:Y}]}};if(z)X.Properties.LoggingConfiguration={Level:z.level,IncludeExecutionData:z.includeExecutionData,Destinations:z.destinations?.map((O)=>({CloudWatchLogsLogGroup:{LogGroupArn:O}}))};if(G)X.Properties.TracingConfiguration={Enabled:G.enabled};return{stateMachine:X,logicalId:A,role:K,roleLogicalId:B}}static createLambdaTask($,J){return{Type:"Task",Resource:"arn:aws:states:::lambda:invoke",Parameters:{FunctionName:$,Payload:J?.parameters||{"Input.$":"$"}},ResultPath:J?.resultPath,Retry:J?.retry,Catch:J?.catch,Next:J?.next,End:J?.end}}static createDynamoDBTask($,J,Y,Q){return{Type:"Task",Resource:{GetItem:"arn:aws:states:::dynamodb:getItem",PutItem:"arn:aws:states:::dynamodb:putItem",UpdateItem:"arn:aws:states:::dynamodb:updateItem",DeleteItem:"arn:aws:states:::dynamodb:deleteItem"}[$],Parameters:{TableName:J,...Y},ResultPath:Q?.resultPath,Retry:Q?.retry,Catch:Q?.catch,Next:Q?.next,End:Q?.end}}static createSNSPublishTask($,J,Y){return{Type:"Task",Resource:"arn:aws:states:::sns:publish",Parameters:{TopicArn:$,Message:J},ResultPath:Y?.resultPath,Retry:Y?.retry,Catch:Y?.catch,Next:Y?.next,End:Y?.end}}static createSQSSendMessageTask($,J,Y){return{Type:"Task",Resource:"arn:aws:states:::sqs:sendMessage",Parameters:{QueueUrl:$,MessageBody:J},ResultPath:Y?.resultPath,Retry:Y?.retry,Catch:Y?.catch,Next:Y?.next,End:Y?.end}}static createPassState($){return{Type:"Pass",Result:$?.result,ResultPath:$?.resultPath,Parameters:$?.parameters,Next:$?.next,End:$?.end}}static createWaitState($){return{Type:"Wait",Seconds:$.seconds,Timestamp:$.timestamp,SecondsPath:$.secondsPath,TimestampPath:$.timestampPath,Next:$.next,End:$.end}}static createChoiceState($,J){return{Type:"Choice",Choices:$,Default:J}}static createParallelState($,J){return{Type:"Parallel",Branches:$,ResultPath:J?.resultPath,Retry:J?.retry,Catch:J?.catch,Next:J?.next,End:J?.end}}static createMapState($,J){return{Type:"Map",ItemsPath:J?.itemsPath||"$.items",Iterator:$,MaxConcurrency:J?.maxConcurrency,ResultPath:J?.resultPath,Retry:J?.retry,Catch:J?.catch,Next:J?.next,End:J?.end}}static createSucceedState(){return{Type:"Succeed"}}static createFailState($,J){return{Type:"Fail",Error:$,Cause:J}}static RetryPolicies={standard:()=>({ErrorEquals:["States.ALL"],IntervalSeconds:2,MaxAttempts:3,BackoffRate:2}),aggressive:()=>({ErrorEquals:["States.TaskFailed","States.Timeout"],IntervalSeconds:1,MaxAttempts:5,BackoffRate:1.5}),custom:($,J,Y,Q)=>({ErrorEquals:$,IntervalSeconds:J,MaxAttempts:Y,BackoffRate:Q})};static CatchPolicies={all:($,J)=>({ErrorEquals:["States.ALL"],Next:$,ResultPath:J||"$.error"}),specific:($,J,Y)=>({ErrorEquals:$,Next:J,ResultPath:Y||"$.error"})};static Patterns={sequential:($,J,Y)=>{let Q={};return Y.forEach((Z,U)=>{let W=U===Y.length-1;Q[Z.name]={...Z.state,Next:W?void 0:Y[U+1].name,End:W}}),{Comment:"Sequential workflow",StartAt:Y[0].name,States:Q}},fanout:($,J,Y)=>{return{Comment:"Fan-out workflow",StartAt:"Parallel",States:{Parallel:{Type:"Parallel",Branches:Y.map((Q)=>Q.definition),End:!0}}}},map:($,J,Y,Q)=>{return{Comment:"Map workflow",StartAt:"Map",States:{Map:{Type:"Map",ItemsPath:"$.items",Iterator:Y,MaxConcurrency:Q,End:!0}}}},withErrorHandling:($,J,Y,Q)=>{return{Comment:"Workflow with error handling",StartAt:"Main",States:{Main:{...Y,Catch:[{ErrorEquals:["States.ALL"],Next:"ErrorHandler"}],Next:"Success"},ErrorHandler:Q,Success:{Type:"Succeed"}}}}}};_$=class _${static createAlarm($){let{slug:J,environment:Y,alarmName:Q,metricName:Z,namespace:U,statistic:W="Average",period:z=300,evaluationPeriods:G=1,threshold:H,comparisonOperator:A,treatMissingData:K="notBreaching",actionsEnabled:B=!0,alarmActions:j,okActions:X,insufficientDataActions:O,dimensions:_,unit:w,datapointsToAlarm:E}=$,M=Q||f({slug:J,environment:Y,resourceType:"alarm"}),T=S(M),D={Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:M,MetricName:Z,Namespace:U,Statistic:W,Period:z,EvaluationPeriods:G,Threshold:H,ComparisonOperator:A,TreatMissingData:K,ActionsEnabled:B}};if(j&&j.length>0)D.Properties.AlarmActions=j;if(X&&X.length>0)D.Properties.OKActions=X;if(O&&O.length>0)D.Properties.InsufficientDataActions=O;if(_)D.Properties.Dimensions=Object.entries(_).map(([N,x])=>({Name:N,Value:x}));if(w)D.Properties.Unit=w;if(E!==void 0)D.Properties.DatapointsToAlarm=E;return{alarm:D,logicalId:T}}static createCompositeAlarm($){let{slug:J,environment:Y,alarmName:Q,alarmRule:Z,actionsEnabled:U=!0,alarmActions:W,okActions:z,insufficientDataActions:G}=$,H=Q||f({slug:J,environment:Y,resourceType:"composite-alarm"}),A=S(H),K={Type:"AWS::CloudWatch::CompositeAlarm",Properties:{AlarmName:H,AlarmRule:Z,ActionsEnabled:U}};if(W&&W.length>0)K.Properties.AlarmActions=W;if(z&&z.length>0)K.Properties.OKActions=z;if(G&&G.length>0)K.Properties.InsufficientDataActions=G;return{alarm:K,logicalId:A}}static createDashboard($){let{slug:J,environment:Y,dashboardName:Q,widgets:Z}=$,U=Q||f({slug:J,environment:Y,resourceType:"dashboard"}),W=S(U),z={widgets:Z.map((H)=>({type:H.type,x:H.x,y:H.y,width:H.width,height:H.height,properties:H.properties}))};return{dashboard:{Type:"AWS::CloudWatch::Dashboard",Properties:{DashboardName:U,DashboardBody:JSON.stringify(z)}},logicalId:W}}static createLogGroup($){let{slug:J,environment:Y,logGroupName:Q,retentionInDays:Z,kmsKeyId:U}=$,W=Q||f({slug:J,environment:Y,resourceType:"log-group"}),z=S(W),G={Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:W}};if(Z!==void 0)G.Properties.RetentionInDays=Z;if(U)G.Properties.KmsKeyId=U;return{logGroup:G,logicalId:z}}static createLogStream($,J){let{slug:Y,environment:Q,logStreamName:Z}=J,U=Z||f({slug:Y,environment:Q,resourceType:"log-stream"}),W=S(U);return{logStream:{Type:"AWS::Logs::LogStream",Properties:{LogGroupName:u.Ref($),LogStreamName:U}},logicalId:W}}static createMetricFilter($,J){let{slug:Y,environment:Q,filterName:Z,filterPattern:U,metricTransformations:W}=J,z=Z||f({slug:Y,environment:Q,resourceType:"metric-filter"}),G=S(z);return{metricFilter:{Type:"AWS::Logs::MetricFilter",Properties:{LogGroupName:u.Ref($),FilterPattern:U,MetricTransformations:W.map((A)=>({MetricName:A.metricName,MetricNamespace:A.metricNamespace,MetricValue:A.metricValue,DefaultValue:A.defaultValue,Unit:A.unit}))}},logicalId:G}}static AlarmTypes={highCpu:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-high-cpu`,metricName:"CPUUtilization",namespace:"AWS/EC2",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y},alarmActions:Z?[Z]:void 0}),highMemory:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-high-memory`,metricName:"MemoryUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y},alarmActions:Z?[Z]:void 0}),highDisk:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-high-disk`,metricName:"DiskSpaceUtilization",namespace:"System/Linux",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y,Filesystem:"/dev/xvda1",MountPath:"/"},alarmActions:Z?[Z]:void 0}),lambdaErrors:($,J,Y,Q=5,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-lambda-errors`,metricName:"Errors",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:Y},alarmActions:Z?[Z]:void 0}),lambdaThrottles:($,J,Y,Q=10,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-lambda-throttles`,metricName:"Throttles",namespace:"AWS/Lambda",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{FunctionName:Y},alarmActions:Z?[Z]:void 0}),apiGateway5xxErrors:($,J,Y,Q=10,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-api-5xx-errors`,metricName:"5XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:Y},alarmActions:Z?[Z]:void 0}),apiGateway4xxErrors:($,J,Y,Q=50,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-api-4xx-errors`,metricName:"4XXError",namespace:"AWS/ApiGateway",statistic:"Sum",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{ApiName:Y},alarmActions:Z?[Z]:void 0}),dynamoDBThrottles:($,J,Y,Q=5,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-dynamodb-throttles`,metricName:"UserErrors",namespace:"AWS/DynamoDB",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{TableName:Y},alarmActions:Z?[Z]:void 0}),rdsCpu:($,J,Y,Q=80,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-rds-cpu`,metricName:"CPUUtilization",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{DBInstanceIdentifier:Y},alarmActions:Z?[Z]:void 0}),rdsFreeStorage:($,J,Y,Q=5368709120,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-rds-storage`,metricName:"FreeStorageSpace",namespace:"AWS/RDS",statistic:"Average",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"LessThanThreshold",dimensions:{DBInstanceIdentifier:Y},alarmActions:Z?[Z]:void 0,unit:"Bytes"}),sqsQueueDepth:($,J,Y,Q=100,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-sqs-depth`,metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS",statistic:"Average",period:300,evaluationPeriods:2,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{QueueName:Y},alarmActions:Z?[Z]:void 0}),albUnhealthyTargets:($,J,Y,Q,Z=1,U)=>({slug:$,environment:J,alarmName:`${$}-${J}-alb-unhealthy`,metricName:"UnHealthyHostCount",namespace:"AWS/ApplicationELB",statistic:"Average",period:300,evaluationPeriods:2,threshold:Z,comparisonOperator:"GreaterThanThreshold",dimensions:{LoadBalancer:Y,TargetGroup:Q},alarmActions:U?[U]:void 0}),sesBounceRate:($,J,Y=5,Q)=>({slug:$,environment:J,alarmName:`${$}-${J}-ses-bounce-rate`,metricName:"Reputation.BounceRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:Y/100,comparisonOperator:"GreaterThanThreshold",alarmActions:Q?[Q]:void 0}),sesComplaintRate:($,J,Y=0.1,Q)=>({slug:$,environment:J,alarmName:`${$}-${J}-ses-complaint-rate`,metricName:"Reputation.ComplaintRate",namespace:"AWS/SES",statistic:"Average",period:3600,evaluationPeriods:1,threshold:Y/100,comparisonOperator:"GreaterThanThreshold",alarmActions:Q?[Q]:void 0}),smsDeliveryFailure:($,J,Y,Q=10,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-sms-delivery-failure`,metricName:"DirectSendMessagePermanentFailure",namespace:"AWS/Pinpoint",statistic:"Sum",period:300,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{ApplicationId:Y},alarmActions:Z?[Z]:void 0}),smsSpendLimit:($,J,Y=100,Q)=>({slug:$,environment:J,alarmName:`${$}-${J}-sms-spend-limit`,metricName:"DirectSendMessageSpend",namespace:"AWS/Pinpoint",statistic:"Sum",period:86400,evaluationPeriods:1,threshold:Y,comparisonOperator:"GreaterThanThreshold",alarmActions:Q?[Q]:void 0}),connectMissedCalls:($,J,Y,Q=5,Z)=>({slug:$,environment:J,alarmName:`${$}-${J}-connect-missed-calls`,metricName:"MissedCalls",namespace:"AWS/Connect",statistic:"Sum",period:3600,evaluationPeriods:1,threshold:Q,comparisonOperator:"GreaterThanThreshold",dimensions:{InstanceId:Y},alarmActions:Z?[Z]:void 0})};static DashboardWidgets={metric:($,J,Y,Q,Z,U)=>({type:"metric",x:$,y:J,width:Y,height:Q,properties:{metrics:Z,title:U||"Metrics",region:"us-east-1",period:300}}),text:($,J,Y,Q,Z)=>({type:"text",x:$,y:J,width:Y,height:Q,properties:{markdown:Z}}),log:($,J,Y,Q,Z,U)=>({type:"log",x:$,y:J,width:Y,height:Q,properties:{query:`SOURCE '${Z.join("' | SOURCE '")}'
5747
5747
  | fields @timestamp, @message
5748
5748
  | sort @timestamp desc
5749
5749
  | limit 20`,region:"us-east-1",title:U||"Logs"}})};static RetentionPeriods={ONE_DAY:1,THREE_DAYS:3,FIVE_DAYS:5,ONE_WEEK:7,TWO_WEEKS:14,ONE_MONTH:30,TWO_MONTHS:60,THREE_MONTHS:90,FOUR_MONTHS:120,FIVE_MONTHS:150,SIX_MONTHS:180,ONE_YEAR:365,THIRTEEN_MONTHS:400,EIGHTEEN_MONTHS:545,TWO_YEARS:731,FIVE_YEARS:1827,TEN_YEARS:3653,NEVER_EXPIRE:void 0};static FilterPatterns={errors:"[time, request_id, event_type = ERROR*, ...]",all:"",jsonField:($,J)=>`{ $.${$} = "${J}" }`,httpStatus:($)=>`[..., status_code = ${$}, ...]`,http4xx:"[..., status_code = 4*, ...]",http5xx:"[..., status_code = 5*, ...]"};static createApplicationDashboard($){let{slug:J,environment:Y,region:Q="us-east-1",components:Z={}}=$,U=[],W=0;if(U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:`# ${J.toUpperCase()} Dashboard (${Y})`}}),W+=1,Z.ec2InstanceIds&&Z.ec2InstanceIds.length>0)U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:"## EC2 Instances"}}),W+=1,U.push({type:"metric",x:0,y:W,width:8,height:6,properties:{title:"CPU Utilization",region:Q,metrics:Z.ec2InstanceIds.map((z)=>["AWS/EC2","CPUUtilization","InstanceId",z]),period:300,stat:"Average"}}),U.push({type:"metric",x:8,y:W,width:8,height:6,properties:{title:"Network Traffic",region:Q,metrics:[...Z.ec2InstanceIds.flatMap((z)=>[["AWS/EC2","NetworkIn","InstanceId",z,{label:`${z} In`}],["AWS/EC2","NetworkOut","InstanceId",z,{label:`${z} Out`}]])],period:300,stat:"Sum"}}),U.push({type:"metric",x:16,y:W,width:8,height:6,properties:{title:"Status Checks",region:Q,metrics:Z.ec2InstanceIds.map((z)=>["AWS/EC2","StatusCheckFailed","InstanceId",z]),period:60,stat:"Maximum"}}),W+=6;if(Z.lambdaFunctionNames&&Z.lambdaFunctionNames.length>0)U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:"## Lambda Functions"}}),W+=1,U.push({type:"metric",x:0,y:W,width:8,height:6,properties:{title:"Invocations",region:Q,metrics:Z.lambdaFunctionNames.map((z)=>["AWS/Lambda","Invocations","FunctionName",z]),period:300,stat:"Sum"}}),U.push({type:"metric",x:8,y:W,width:8,height:6,properties:{title:"Duration",region:Q,metrics:Z.lambdaFunctionNames.map((z)=>["AWS/Lambda","Duration","FunctionName",z]),period:300,stat:"Average"}}),U.push({type:"metric",x:16,y:W,width:8,height:6,properties:{title:"Errors",region:Q,metrics:Z.lambdaFunctionNames.map((z)=>["AWS/Lambda","Errors","FunctionName",z]),period:300,stat:"Sum"}}),W+=6;if(Z.ecsClusterName&&Z.ecsServiceName)U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:"## ECS Service"}}),W+=1,U.push({type:"metric",x:0,y:W,width:8,height:6,properties:{title:"CPU Utilization",region:Q,metrics:[["AWS/ECS","CPUUtilization","ClusterName",Z.ecsClusterName,"ServiceName",Z.ecsServiceName]],period:300,stat:"Average"}}),U.push({type:"metric",x:8,y:W,width:8,height:6,properties:{title:"Memory Utilization",region:Q,metrics:[["AWS/ECS","MemoryUtilization","ClusterName",Z.ecsClusterName,"ServiceName",Z.ecsServiceName]],period:300,stat:"Average"}}),U.push({type:"metric",x:16,y:W,width:8,height:6,properties:{title:"Running Tasks",region:Q,metrics:[["ECS/ContainerInsights","RunningTaskCount","ClusterName",Z.ecsClusterName,"ServiceName",Z.ecsServiceName]],period:60,stat:"Average"}}),W+=6;if(Z.albName)U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:"## Application Load Balancer"}}),W+=1,U.push({type:"metric",x:0,y:W,width:8,height:6,properties:{title:"Request Count",region:Q,metrics:[["AWS/ApplicationELB","RequestCount","LoadBalancer",Z.albName]],period:60,stat:"Sum"}}),U.push({type:"metric",x:8,y:W,width:8,height:6,properties:{title:"Response Time",region:Q,metrics:[["AWS/ApplicationELB","TargetResponseTime","LoadBalancer",Z.albName]],period:60,stat:"Average"}}),U.push({type:"metric",x:16,y:W,width:8,height:6,properties:{title:"HTTP Errors",region:Q,metrics:[["AWS/ApplicationELB","HTTPCode_Target_4XX_Count","LoadBalancer",Z.albName,{label:"4XX"}],["AWS/ApplicationELB","HTTPCode_Target_5XX_Count","LoadBalancer",Z.albName,{label:"5XX"}]],period:60,stat:"Sum"}}),W+=6;if(Z.rdsInstanceId)U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:"## RDS Database"}}),W+=1,U.push({type:"metric",x:0,y:W,width:8,height:6,properties:{title:"CPU Utilization",region:Q,metrics:[["AWS/RDS","CPUUtilization","DBInstanceIdentifier",Z.rdsInstanceId]],period:300,stat:"Average"}}),U.push({type:"metric",x:8,y:W,width:8,height:6,properties:{title:"Database Connections",region:Q,metrics:[["AWS/RDS","DatabaseConnections","DBInstanceIdentifier",Z.rdsInstanceId]],period:60,stat:"Sum"}}),U.push({type:"metric",x:16,y:W,width:8,height:6,properties:{title:"Free Storage Space",region:Q,metrics:[["AWS/RDS","FreeStorageSpace","DBInstanceIdentifier",Z.rdsInstanceId]],period:300,stat:"Average"}}),W+=6;if(Z.sqsQueueNames&&Z.sqsQueueNames.length>0)U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:"## SQS Queues"}}),W+=1,U.push({type:"metric",x:0,y:W,width:12,height:6,properties:{title:"Messages Visible",region:Q,metrics:Z.sqsQueueNames.map((z)=>["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName",z]),period:60,stat:"Sum"}}),U.push({type:"metric",x:12,y:W,width:12,height:6,properties:{title:"Message Age",region:Q,metrics:Z.sqsQueueNames.map((z)=>["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName",z]),period:60,stat:"Maximum"}}),W+=6;if(Z.logGroupNames&&Z.logGroupNames.length>0)U.push({type:"text",x:0,y:W,width:24,height:1,properties:{markdown:"## Application Logs"}}),W+=1,U.push({type:"log",x:0,y:W,width:24,height:6,properties:{query:`SOURCE '${Z.logGroupNames.join("' | SOURCE '")}'
5750
5750
  | fields @timestamp, @message
5751
5751
  | filter @message like /ERROR|WARN|Exception/
5752
5752
  | sort @timestamp desc
5753
- | limit 50`,region:Q,title:"Recent Errors and Warnings"}}),W+=6;return _$.createDashboard({slug:J,environment:Y,widgets:U})}static DashboardTemplates={staticWebsite:($)=>({slug:$.slug,environment:$.environment,widgets:[{type:"text",x:0,y:0,width:24,height:1,properties:{markdown:`# ${$.slug.toUpperCase()} Static Website Dashboard`}},{type:"metric",x:0,y:1,width:8,height:6,properties:{title:"CloudFront Requests",region:"us-east-1",metrics:[["AWS/CloudFront","Requests","DistributionId",$.cloudFrontDistributionId,"Region","Global"]],period:300,stat:"Sum"}},{type:"metric",x:8,y:1,width:8,height:6,properties:{title:"Error Rate",region:"us-east-1",metrics:[["AWS/CloudFront","4xxErrorRate","DistributionId",$.cloudFrontDistributionId,"Region","Global",{label:"4XX"}],["AWS/CloudFront","5xxErrorRate","DistributionId",$.cloudFrontDistributionId,"Region","Global",{label:"5XX"}]],period:300,stat:"Average"}},{type:"metric",x:16,y:1,width:8,height:6,properties:{title:"Bytes Downloaded",region:"us-east-1",metrics:[["AWS/CloudFront","BytesDownloaded","DistributionId",$.cloudFrontDistributionId,"Region","Global"]],period:300,stat:"Sum"}},{type:"metric",x:0,y:7,width:12,height:6,properties:{title:"S3 Bucket Size",region:$.region||"us-east-1",metrics:[["AWS/S3","BucketSizeBytes","BucketName",$.s3BucketName,"StorageType","StandardStorage"]],period:86400,stat:"Average"}},{type:"metric",x:12,y:7,width:12,height:6,properties:{title:"S3 Number of Objects",region:$.region||"us-east-1",metrics:[["AWS/S3","NumberOfObjects","BucketName",$.s3BucketName,"StorageType","AllStorageTypes"]],period:86400,stat:"Average"}}]}),serverlessApi:($)=>({slug:$.slug,environment:$.environment,widgets:[{type:"text",x:0,y:0,width:24,height:1,properties:{markdown:`# ${$.slug.toUpperCase()} Serverless API Dashboard`}},{type:"metric",x:0,y:1,width:8,height:6,properties:{title:"API Requests",region:$.region||"us-east-1",metrics:[["AWS/ApiGateway","Count","ApiName",$.apiGatewayName]],period:60,stat:"Sum"}},{type:"metric",x:8,y:1,width:8,height:6,properties:{title:"API Latency",region:$.region||"us-east-1",metrics:[["AWS/ApiGateway","Latency","ApiName",$.apiGatewayName]],period:60,stat:"Average"}},{type:"metric",x:16,y:1,width:8,height:6,properties:{title:"API Errors",region:$.region||"us-east-1",metrics:[["AWS/ApiGateway","4XXError","ApiName",$.apiGatewayName,{label:"4XX"}],["AWS/ApiGateway","5XXError","ApiName",$.apiGatewayName,{label:"5XX"}]],period:60,stat:"Sum"}},...$.lambdaFunctionNames.map((J,Y)=>({type:"metric",x:Y%3*8,y:7+Math.floor(Y/3)*6,width:8,height:6,properties:{title:`${J} Metrics`,region:$.region||"us-east-1",metrics:[["AWS/Lambda","Invocations","FunctionName",J],["AWS/Lambda","Duration","FunctionName",J],["AWS/Lambda","Errors","FunctionName",J]],period:300,stat:"Sum"}}))]}),containerService:($)=>({slug:$.slug,environment:$.environment,widgets:[{type:"text",x:0,y:0,width:24,height:1,properties:{markdown:`# ${$.slug.toUpperCase()} Container Service Dashboard`}},{type:"metric",x:0,y:1,width:8,height:6,properties:{title:"ECS CPU",region:$.region||"us-east-1",metrics:[["AWS/ECS","CPUUtilization","ClusterName",$.ecsClusterName,"ServiceName",$.ecsServiceName]],period:60,stat:"Average"}},{type:"metric",x:8,y:1,width:8,height:6,properties:{title:"ECS Memory",region:$.region||"us-east-1",metrics:[["AWS/ECS","MemoryUtilization","ClusterName",$.ecsClusterName,"ServiceName",$.ecsServiceName]],period:60,stat:"Average"}},{type:"metric",x:16,y:1,width:8,height:6,properties:{title:"Running Tasks",region:$.region||"us-east-1",metrics:[["ECS/ContainerInsights","RunningTaskCount","ClusterName",$.ecsClusterName,"ServiceName",$.ecsServiceName]],period:60,stat:"Average"}},{type:"metric",x:0,y:7,width:8,height:6,properties:{title:"ALB Requests",region:$.region||"us-east-1",metrics:[["AWS/ApplicationELB","RequestCount","LoadBalancer",$.albName]],period:60,stat:"Sum"}},{type:"metric",x:8,y:7,width:8,height:6,properties:{title:"Response Time",region:$.region||"us-east-1",metrics:[["AWS/ApplicationELB","TargetResponseTime","LoadBalancer",$.albName]],period:60,stat:"Average"}},{type:"metric",x:16,y:7,width:8,height:6,properties:{title:"Healthy Hosts",region:$.region||"us-east-1",metrics:[["AWS/ApplicationELB","HealthyHostCount","LoadBalancer",$.albName]],period:60,stat:"Average"}},...$.rdsInstanceId?[{type:"metric",x:0,y:13,width:12,height:6,properties:{title:"RDS CPU",region:$.region||"us-east-1",metrics:[["AWS/RDS","CPUUtilization","DBInstanceIdentifier",$.rdsInstanceId]],period:300,stat:"Average"}},{type:"metric",x:12,y:13,width:12,height:6,properties:{title:"RDS Connections",region:$.region||"us-east-1",metrics:[["AWS/RDS","DatabaseConnections","DBInstanceIdentifier",$.rdsInstanceId]],period:60,stat:"Sum"}}]:[]]})};static Config={createAlarmConfig:($)=>{let{metricName:J,namespace:Y,threshold:Q,comparisonOperator:Z="GreaterThanThreshold",evaluationPeriods:U=1,period:W=300,statistic:z="Average",treatMissingData:G="missing"}=$;return{MetricName:J,Namespace:Y,Threshold:Q,ComparisonOperator:Z,EvaluationPeriods:U,Period:W,Statistic:z,TreatMissingData:G}},namespaces:{ec2:"AWS/EC2",ecs:"AWS/ECS",lambda:"AWS/Lambda",rds:"AWS/RDS",sqs:"AWS/SQS",sns:"AWS/SNS",s3:"AWS/S3",cloudfront:"AWS/CloudFront",alb:"AWS/ApplicationELB",nlb:"AWS/NetworkELB",apiGateway:"AWS/ApiGateway",dynamodb:"AWS/DynamoDB",elasticache:"AWS/ElastiCache"},comparisonOperators:{greaterThan:"GreaterThanThreshold",greaterOrEqual:"GreaterThanOrEqualToThreshold",lessThan:"LessThanThreshold",lessOrEqual:"LessThanOrEqualToThreshold"},metrics:{ec2:{cpu:{metricName:"CPUUtilization",namespace:"AWS/EC2"},networkIn:{metricName:"NetworkIn",namespace:"AWS/EC2"},networkOut:{metricName:"NetworkOut",namespace:"AWS/EC2"},statusCheck:{metricName:"StatusCheckFailed",namespace:"AWS/EC2"}},ecs:{cpu:{metricName:"CPUUtilization",namespace:"AWS/ECS"},memory:{metricName:"MemoryUtilization",namespace:"AWS/ECS"}},lambda:{invocations:{metricName:"Invocations",namespace:"AWS/Lambda"},errors:{metricName:"Errors",namespace:"AWS/Lambda"},duration:{metricName:"Duration",namespace:"AWS/Lambda"},throttles:{metricName:"Throttles",namespace:"AWS/Lambda"},concurrentExecutions:{metricName:"ConcurrentExecutions",namespace:"AWS/Lambda"}},rds:{cpu:{metricName:"CPUUtilization",namespace:"AWS/RDS"},connections:{metricName:"DatabaseConnections",namespace:"AWS/RDS"},freeStorage:{metricName:"FreeStorageSpace",namespace:"AWS/RDS"},readLatency:{metricName:"ReadLatency",namespace:"AWS/RDS"},writeLatency:{metricName:"WriteLatency",namespace:"AWS/RDS"}},alb:{requestCount:{metricName:"RequestCount",namespace:"AWS/ApplicationELB"},responseTime:{metricName:"TargetResponseTime",namespace:"AWS/ApplicationELB"},httpCode4xx:{metricName:"HTTPCode_Target_4XX_Count",namespace:"AWS/ApplicationELB"},httpCode5xx:{metricName:"HTTPCode_Target_5XX_Count",namespace:"AWS/ApplicationELB"},healthyHosts:{metricName:"HealthyHostCount",namespace:"AWS/ApplicationELB"}},sqs:{messagesVisible:{metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS"},messagesDelayed:{metricName:"ApproximateNumberOfMessagesDelayed",namespace:"AWS/SQS"},messageAge:{metricName:"ApproximateAgeOfOldestMessage",namespace:"AWS/SQS"}}},presets:{highCpu:($=80)=>({metricName:"CPUUtilization",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),highMemory:($=80)=>({metricName:"MemoryUtilization",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),highErrors:($=10)=>({metricName:"Errors",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:1,period:60,statistic:"Sum"}),highLatency:($=5000)=>({metricName:"Duration",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),lowHealthyHosts:($=1)=>({metricName:"HealthyHostCount",namespace:"AWS/ApplicationELB",threshold:$,comparisonOperator:"LessThanThreshold",evaluationPeriods:2,period:60,statistic:"Minimum"}),queueDepth:($=1000)=>({metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),lowStorage:($=10737418240)=>({metricName:"FreeStorageSpace",namespace:"AWS/RDS",threshold:$,comparisonOperator:"LessThanThreshold",evaluationPeriods:1,period:300,statistic:"Average"})}}};n0=class n0{static createUserPool($){let{slug:J,environment:Y,userPoolName:Q,aliasAttributes:Z,autoVerifiedAttributes:U,passwordPolicy:W,mfaConfiguration:z,emailConfiguration:G,smsConfiguration:H,lambdaTriggers:A,userPoolAddOns:K,accountRecoverySetting:B}=$,j=Q||v({slug:J,environment:Y,resourceType:"user-pool"}),X=S(j),O={Type:"AWS::Cognito::UserPool",Properties:{UserPoolName:j,Policies:W?{PasswordPolicy:{MinimumLength:W.minimumLength,RequireLowercase:W.requireLowercase,RequireUppercase:W.requireUppercase,RequireNumbers:W.requireNumbers,RequireSymbols:W.requireSymbols,TemporaryPasswordValidityDays:W.temporaryPasswordValidityDays}}:void 0,MfaConfiguration:z,Schema:[{Name:"email",AttributeDataType:"String",Required:!0,Mutable:!1}]}};if(Z&&Z.length>0)O.Properties.UsernameAttributes=Z;if(U&&U.length>0)O.Properties.AutoVerifiedAttributes=U;if(G)O.Properties.EmailConfiguration={EmailSendingAccount:G.emailSendingAccount,From:G.from,ReplyToEmailAddress:G.replyToEmailAddress,SourceArn:G.sourceArn,ConfigurationSet:G.configurationSet};if(H)O.Properties.SmsConfiguration={ExternalId:H.externalId,SnsCallerArn:H.snsCallerArn};if(A)O.Properties.LambdaConfig={PreSignUp:A.preSignUp,PostConfirmation:A.postConfirmation,PreAuthentication:A.preAuthentication,PostAuthentication:A.postAuthentication,CustomMessage:A.customMessage,DefineAuthChallenge:A.defineAuthChallenge,CreateAuthChallenge:A.createAuthChallenge,VerifyAuthChallengeResponse:A.verifyAuthChallengeResponse,PreTokenGeneration:A.preTokenGeneration,UserMigration:A.userMigration};if(K)O.Properties.UserPoolAddOns={AdvancedSecurityMode:K.advancedSecurityMode};if(B)O.Properties.AccountRecoverySetting={RecoveryMechanisms:B.recoveryMechanisms};return{userPool:O,logicalId:X}}static createUserPoolClient($,J){let{slug:Y,environment:Q,clientName:Z,generateSecret:U=!1,refreshTokenValidity:W,accessTokenValidity:z,idTokenValidity:G,tokenValidityUnits:H,readAttributes:A,writeAttributes:K,explicitAuthFlows:B,preventUserExistenceErrors:j,enableTokenRevocation:X,callbackURLs:O,logoutURLs:_,allowedOAuthFlows:w,allowedOAuthScopes:E,allowedOAuthFlowsUserPoolClient:M,supportedIdentityProviders:T}=J,D=Z||v({slug:Y,environment:Q,resourceType:"user-pool-client"}),N=S(D);return{client:{Type:"AWS::Cognito::UserPoolClient",Properties:{ClientName:D,UserPoolId:u.Ref($),GenerateSecret:U,RefreshTokenValidity:W,AccessTokenValidity:z,IdTokenValidity:G,TokenValidityUnits:H,ReadAttributes:A,WriteAttributes:K,ExplicitAuthFlows:B,PreventUserExistenceErrors:j,EnableTokenRevocation:X,CallbackURLs:O,LogoutURLs:_,AllowedOAuthFlows:w,AllowedOAuthScopes:E,AllowedOAuthFlowsUserPoolClient:M,SupportedIdentityProviders:T}},logicalId:N}}static createUserPoolDomain($,J){let{slug:Y,environment:Q,domain:Z,customDomainConfig:U}=J,W=v({slug:Y,environment:Q,resourceType:"user-pool-domain"}),z=S(W);return{domain:{Type:"AWS::Cognito::UserPoolDomain",Properties:{Domain:Z,UserPoolId:u.Ref($),CustomDomainConfig:U}},logicalId:z}}static createIdentityPool($){let{slug:J,environment:Y,identityPoolName:Q,allowUnauthenticatedIdentities:Z=!1,cognitoIdentityProviders:U,supportedLoginProviders:W,samlProviderARNs:z,openIdConnectProviderARNs:G}=$,H=Q||v({slug:J,environment:Y,resourceType:"identity-pool"}),A=S(H);return{identityPool:{Type:"AWS::Cognito::IdentityPool",Properties:{IdentityPoolName:H,AllowUnauthenticatedIdentities:Z,CognitoIdentityProviders:U,SupportedLoginProviders:W,SamlProviderARNs:z,OpenIdConnectProviderARNs:G}},logicalId:A}}static createIdentityPoolRoleAttachment($,J){let{slug:Y,environment:Q,authenticatedRole:Z,unauthenticatedRole:U,roleMappings:W}=J,z=v({slug:Y,environment:Q,resourceType:"identity-pool-role-attachment"}),G=S(z),H={authenticated:Z};if(U)H.unauthenticated=U;return{attachment:{Type:"AWS::Cognito::IdentityPoolRoleAttachment",Properties:{IdentityPoolId:u.Ref($),Roles:H,RoleMappings:W}},logicalId:G}}static createAuthenticatedRole($){let{slug:J,environment:Y,identityPoolLogicalId:Q}=$,Z=v({slug:J,environment:Y,resourceType:"cognito-authenticated-role"}),U=S(Z);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:Z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Federated:"cognito-identity.amazonaws.com"},Action:"sts:AssumeRoleWithWebIdentity",Condition:{StringEquals:{"cognito-identity.amazonaws.com:aud":u.Ref(Q)},"ForAnyValue:StringLike":{"cognito-identity.amazonaws.com:amr":"authenticated"}}}]},Policies:[{PolicyName:"CognitoAuthenticatedPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["cognito-sync:*","cognito-identity:*"],Resource:"*"}]}}],Tags:[{Key:"Name",Value:Z},{Key:"Environment",Value:Y}]}},logicalId:U}}static createUnauthenticatedRole($){let{slug:J,environment:Y,identityPoolLogicalId:Q}=$,Z=v({slug:J,environment:Y,resourceType:"cognito-unauthenticated-role"}),U=S(Z);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:Z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Federated:"cognito-identity.amazonaws.com"},Action:"sts:AssumeRoleWithWebIdentity",Condition:{StringEquals:{"cognito-identity.amazonaws.com:aud":u.Ref(Q)},"ForAnyValue:StringLike":{"cognito-identity.amazonaws.com:amr":"unauthenticated"}}}]},Policies:[{PolicyName:"CognitoUnauthenticatedPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["cognito-sync:*"],Resource:"*"}]}}],Tags:[{Key:"Name",Value:Z},{Key:"Environment",Value:Y}]}},logicalId:U}}static PasswordPolicies={relaxed:()=>({minimumLength:8,requireLowercase:!1,requireUppercase:!1,requireNumbers:!1,requireSymbols:!1,temporaryPasswordValidityDays:7}),standard:()=>({minimumLength:8,requireLowercase:!0,requireUppercase:!0,requireNumbers:!0,requireSymbols:!1,temporaryPasswordValidityDays:3}),strict:()=>({minimumLength:12,requireLowercase:!0,requireUppercase:!0,requireNumbers:!0,requireSymbols:!0,temporaryPasswordValidityDays:1})};static AuthFlows={standard:["ALLOW_USER_SRP_AUTH","ALLOW_REFRESH_TOKEN_AUTH"],admin:["ALLOW_ADMIN_USER_PASSWORD_AUTH","ALLOW_REFRESH_TOKEN_AUTH"],custom:["ALLOW_CUSTOM_AUTH","ALLOW_REFRESH_TOKEN_AUTH"],all:["ALLOW_USER_SRP_AUTH","ALLOW_USER_PASSWORD_AUTH","ALLOW_ADMIN_USER_PASSWORD_AUTH","ALLOW_CUSTOM_AUTH","ALLOW_REFRESH_TOKEN_AUTH"]};static OAuthScopes={basic:["openid","email","profile"],all:["openid","email","profile","phone","aws.cognito.signin.user.admin"]};static UseCases={webApp:($,J,Y)=>{let{userPool:Q,logicalId:Z}=n0.createUserPool({slug:$,environment:J,aliasAttributes:["email"],autoVerifiedAttributes:["email"],passwordPolicy:n0.PasswordPolicies.standard(),mfaConfiguration:"OPTIONAL"}),{client:U,logicalId:W}=n0.createUserPoolClient(Z,{slug:$,environment:J,explicitAuthFlows:[...n0.AuthFlows.standard],callbackURLs:[Y],allowedOAuthFlows:["code"],allowedOAuthScopes:[...n0.OAuthScopes.basic],allowedOAuthFlowsUserPoolClient:!0});return{userPool:Q,poolId:Z,client:U,clientId:W}},mobileApp:($,J)=>{let{userPool:Y,logicalId:Q}=n0.createUserPool({slug:$,environment:J,aliasAttributes:["email"],autoVerifiedAttributes:["email"],passwordPolicy:n0.PasswordPolicies.standard(),mfaConfiguration:"OPTIONAL"}),{client:Z,logicalId:U}=n0.createUserPoolClient(Q,{slug:$,environment:J,explicitAuthFlows:[...n0.AuthFlows.standard]}),{identityPool:W,logicalId:z}=n0.createIdentityPool({slug:$,environment:J,allowUnauthenticatedIdentities:!1,cognitoIdentityProviders:[{ClientId:u.Ref(U),ProviderName:u.GetAtt(Q,"ProviderName")}]}),{role:G,logicalId:H}=n0.createAuthenticatedRole({slug:$,environment:J,identityPoolLogicalId:z}),{attachment:A,logicalId:K}=n0.createIdentityPoolRoleAttachment(z,{slug:$,environment:J,authenticatedRole:u.GetAtt(H,"Arn")});return{userPool:Y,poolId:Q,client:Z,clientId:U,identityPool:W,identityPoolId:z,authRole:G,authRoleId:H,attachment:A,attachmentId:K}}}};a0=class a0{static createApplication($){let{slug:J,environment:Y,applicationName:Q,computePlatform:Z}=$,U=Q||v({slug:J,environment:Y,resourceType:"deploy-app"}),W=S(U);return{application:{Type:"AWS::CodeDeploy::Application",Properties:{ApplicationName:U,ComputePlatform:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Y}]}},logicalId:W}}static createDeploymentGroup($,J){let{slug:Y,environment:Q,deploymentGroupName:Z,serviceRoleArn:U,autoScalingGroups:W,ec2TagFilters:z,deploymentConfigName:G,autoRollbackConfiguration:H,alarmConfiguration:A,loadBalancerInfo:K,blueGreenDeploymentConfiguration:B}=J,j=Z||v({slug:Y,environment:Q,resourceType:"deploy-group"}),X=S(j);return{deploymentGroup:{Type:"AWS::CodeDeploy::DeploymentGroup",Properties:{ApplicationName:u.Ref($),DeploymentGroupName:j,ServiceRoleArn:U,AutoScalingGroups:W,Ec2TagFilters:z?.map((_)=>({Key:_.key,Value:_.value,Type:_.type})),DeploymentConfigName:G,AutoRollbackConfiguration:H?{Enabled:H.enabled,Events:H.events}:void 0,AlarmConfiguration:A?{Enabled:A.enabled,Alarms:A.alarms?.map((_)=>({Name:_.name})),IgnorePollAlarmFailure:A.ignorePollAlarmFailure}:void 0,LoadBalancerInfo:K?{TargetGroupInfoList:K.targetGroupInfoList?.map((_)=>({Name:_.name})),ElbInfoList:K.elbInfoList?.map((_)=>({Name:_.name}))}:void 0,BlueGreenDeploymentConfiguration:B?{TerminateBlueInstancesOnDeploymentSuccess:B.terminateBlueInstancesOnDeploymentSuccess?{Action:B.terminateBlueInstancesOnDeploymentSuccess.action,TerminationWaitTimeInMinutes:B.terminateBlueInstancesOnDeploymentSuccess.terminationWaitTimeInMinutes}:void 0,DeploymentReadyOption:B.deploymentReadyOption?{ActionOnTimeout:B.deploymentReadyOption.actionOnTimeout,WaitTimeInMinutes:B.deploymentReadyOption.waitTimeInMinutes}:void 0,GreenFleetProvisioningOption:B.greenFleetProvisioningOption?{Action:B.greenFleetProvisioningOption.action}:void 0}:void 0,Tags:[{Key:"Name",Value:j},{Key:"Environment",Value:Q}]}},logicalId:X}}static createDeploymentConfig($){let{slug:J,environment:Y,deploymentConfigName:Q,minimumHealthyHosts:Z,trafficRoutingConfig:U}=$,W=Q||v({slug:J,environment:Y,resourceType:"deploy-config"}),z=S(W);return{deploymentConfig:{Type:"AWS::CodeDeploy::DeploymentConfig",Properties:{DeploymentConfigName:W,MinimumHealthyHosts:Z?{Type:Z.type,Value:Z.value}:void 0,TrafficRoutingConfig:U?{Type:U.type,TimeBasedCanary:U.timeBasedCanary?{CanaryPercentage:U.timeBasedCanary.canaryPercentage,CanaryInterval:U.timeBasedCanary.canaryInterval}:void 0,TimeBasedLinear:U.timeBasedLinear?{LinearPercentage:U.timeBasedLinear.linearPercentage,LinearInterval:U.timeBasedLinear.linearInterval}:void 0}:void 0}},logicalId:z}}static DeploymentConfigs={allAtOnce:()=>({type:"FLEET_PERCENT",value:0}),halfAtATime:()=>({type:"FLEET_PERCENT",value:50}),oneAtATime:()=>({type:"HOST_COUNT",value:1}),custom:($,J)=>({type:$,value:J})};static TrafficRouting={allAtOnce:()=>({type:"AllAtOnce"}),canary:($,J)=>({type:"TimeBasedCanary",timeBasedCanary:{canaryPercentage:$,canaryInterval:J}}),linear:($,J)=>({type:"TimeBasedLinear",timeBasedLinear:{linearPercentage:$,linearInterval:J}})};static RollbackConfigs={onFailure:()=>({enabled:!0,events:["DEPLOYMENT_FAILURE"]}),onAlarmOrFailure:()=>({enabled:!0,events:["DEPLOYMENT_FAILURE","DEPLOYMENT_STOP_ON_ALARM"]}),onAllEvents:()=>({enabled:!0,events:["DEPLOYMENT_FAILURE","DEPLOYMENT_STOP_ON_ALARM","DEPLOYMENT_STOP_ON_REQUEST"]}),disabled:()=>({enabled:!1})};static BlueGreenConfigs={standard:()=>({terminateBlueInstancesOnDeploymentSuccess:{action:"TERMINATE",terminationWaitTimeInMinutes:5},deploymentReadyOption:{actionOnTimeout:"CONTINUE_DEPLOYMENT",waitTimeInMinutes:0},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}}),withDelay:($)=>({terminateBlueInstancesOnDeploymentSuccess:{action:"TERMINATE",terminationWaitTimeInMinutes:$},deploymentReadyOption:{actionOnTimeout:"CONTINUE_DEPLOYMENT",waitTimeInMinutes:0},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}}),withManualApproval:($)=>({terminateBlueInstancesOnDeploymentSuccess:{action:"TERMINATE",terminationWaitTimeInMinutes:5},deploymentReadyOption:{actionOnTimeout:"STOP_DEPLOYMENT",waitTimeInMinutes:$},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}}),keepBlue:()=>({terminateBlueInstancesOnDeploymentSuccess:{action:"KEEP_ALIVE"},deploymentReadyOption:{actionOnTimeout:"CONTINUE_DEPLOYMENT",waitTimeInMinutes:0},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}})};static UseCases={ec2Deployment:($,J,Y,Q)=>{let{application:Z,logicalId:U}=a0.createApplication({slug:$,environment:J,computePlatform:"Server"}),{deploymentGroup:W,logicalId:z}=a0.createDeploymentGroup(U,{slug:$,environment:J,serviceRoleArn:Y,autoScalingGroups:Q,deploymentConfigName:"CodeDeployDefault.OneAtATime",autoRollbackConfiguration:a0.RollbackConfigs.onFailure()});return{application:Z,appId:U,deploymentGroup:W,groupId:z}},lambdaCanaryDeployment:($,J,Y,Q=10,Z=5)=>{let{application:U,logicalId:W}=a0.createApplication({slug:$,environment:J,computePlatform:"Lambda"}),{deploymentConfig:z,logicalId:G}=a0.createDeploymentConfig({slug:$,environment:J,trafficRoutingConfig:a0.TrafficRouting.canary(Q,Z)}),{deploymentGroup:H,logicalId:A}=a0.createDeploymentGroup(W,{slug:$,environment:J,serviceRoleArn:Y,deploymentConfigName:u.Ref(G),autoRollbackConfiguration:a0.RollbackConfigs.onAlarmOrFailure()});return{application:U,appId:W,deploymentConfig:z,configId:G,deploymentGroup:H,groupId:A}},ecsBlueGreenDeployment:($,J,Y,Q)=>{let{application:Z,logicalId:U}=a0.createApplication({slug:$,environment:J,computePlatform:"ECS"}),{deploymentGroup:W,logicalId:z}=a0.createDeploymentGroup(U,{slug:$,environment:J,serviceRoleArn:Y,loadBalancerInfo:{targetGroupInfoList:[{name:Q}]},blueGreenDeploymentConfiguration:a0.BlueGreenConfigs.standard(),autoRollbackConfiguration:a0.RollbackConfigs.onFailure()});return{application:Z,appId:U,deploymentGroup:W,groupId:z}}};static Strategies={rolling:($=25)=>({type:"rolling",batchPercentage:$}),blueGreen:()=>({type:"blue-green"}),canary:($=10,J=5)=>({type:"canary",canaryPercentage:$,canaryInterval:J}),allAtOnce:()=>({type:"all-at-once"})}};h0=class h0{static ContentTypes={".html":"text/html",".htm":"text/html",".css":"text/css",".js":"application/javascript",".mjs":"application/javascript",".json":"application/json",".xml":"application/xml",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".avif":"image/avif",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".map":"application/json"};static NoHashPatterns=[/^index\.html$/,/^favicon\.ico$/,/^robots\.txt$/,/^sitemap\.xml$/,/^manifest\.json$/,/^\.well-known\//,/^_redirects$/,/^_headers$/];static computeFileHash($,J="md5"){let Y=_9($);return L4(J).update(Y).digest("hex")}static computeShortHash($){return h0.computeFileHash($).slice(0,8)}static getContentType($){let J=zQ($).toLowerCase();return h0.ContentTypes[J]||"application/octet-stream"}static shouldHashFile($,J){return![...h0.NoHashPatterns,...J||[]].some((Q)=>Q.test($))}static generateHashedFilename($,J){let Y=zQ($),Q=D4($,Y),Z=WQ($);if(Z===".")return`${Q}.${J}${Y}`;return Z$(Z,`${Q}.${J}${Y}`)}static collectFiles($,J){let Y=[],Q=J||$;if(!U6($))return Y;let Z=M4($,{withFileTypes:!0});for(let U of Z){let W=Z$($,U.name);if(U.isDirectory())Y.push(...h0.collectFiles(W,Q));else if(U.isFile())Y.push(W)}return Y}static hashDirectory($){let{sourceDir:J,outputDir:Y,excludePatterns:Q=[],hashAlgorithm:Z="md5",copyUnhashed:U=!0}=$,W=h0.collectFiles(J),z=[],G={};for(let A of W){let K=A.replace(J,"").replace(/^[/\\]/,""),B=h0.shouldHashFile(K,Q),j=T4(A),X=B?h0.computeFileHash(A,Z).slice(0,8):"",O=B?h0.generateHashedFilename(K,X):K,_={originalPath:K,hashedPath:O,hash:X,size:j.size,contentType:h0.getContentType(A)};if(z.push(_),G[K]=O,Y){let w=Z$(Y,O),E=WQ(w);if(!U6(E)){let{mkdirSync:M}=cG("node:fs");M(E,{recursive:!0})}if(B||U)R4(A,w)}}let H={version:"1.0",timestamp:new Date().toISOString(),assets:z,hashMap:G};if(Y){let A=Z$(Y,"asset-manifest.json");q9(A,JSON.stringify(H,null,2))}return H}static getInvalidationPaths($,J){let Y=[];if(!$)return["/*"];let Q=$.hashMap,Z=J.hashMap;for(let[U,W]of Object.entries(Z)){let z=Q[U];if(!z||z!==W){if(Y.push(`/${U}`),z&&z!==W)Y.push(`/${z}`)}}for(let[U,W]of Object.entries(Q))if(!Z[U])Y.push(`/${U}`),Y.push(`/${W}`);if(Y.length>100)return["/*"];return[...new Set(Y)]}static updateHtmlReferences($){let{htmlDir:J,manifest:Y,basePath:Q=""}=$,Z=h0.collectFiles(J).filter((U)=>U.endsWith(".html")||U.endsWith(".htm"));for(let U of Z){let W=_9(U,"utf-8");for(let[z,G]of Object.entries(Y.hashMap)){if(z===G)continue;let H=[new RegExp(`(src|href)=["']${Q}/?${h0.escapeRegExp(z)}["']`,"g"),new RegExp(`url\\(["']?${Q}/?${h0.escapeRegExp(z)}["']?\\)`,"g")];for(let A of H)W=W.replace(A,(K)=>{return K.replace(z,G)})}q9(U,W)}}static updateCssReferences($){let{cssDir:J,manifest:Y,basePath:Q=""}=$,Z=h0.collectFiles(J).filter((U)=>U.endsWith(".css"));for(let U of Z){let W=_9(U,"utf-8");for(let[z,G]of Object.entries(Y.hashMap)){if(z===G)continue;let H=new RegExp(`url\\(["']?${Q}/?${h0.escapeRegExp(z)}["']?\\)`,"g");W=W.replace(H,`url(${Q}/${G})`)}q9(U,W)}}static escapeRegExp($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}static generateS3DeploymentManifest($){let{sourceDir:J,keyPrefix:Y="",excludePatterns:Q=[],cacheControl:Z={hashed:"public, max-age=31536000, immutable",unhashed:"public, max-age=3600",html:"public, max-age=0, must-revalidate"}}=$;return h0.hashDirectory({sourceDir:J,excludePatterns:Q}).assets.map((W)=>{let z=W.hash!=="",G=W.contentType==="text/html",H=Z.unhashed||"public, max-age=3600";if(G)H=Z.html||"public, max-age=0, must-revalidate";else if(z)H=Z.hashed||"public, max-age=31536000, immutable";return{localPath:Z$(J,W.originalPath),s3Key:Y?`${Y}/${W.hashedPath}`:W.hashedPath,contentType:W.contentType,cacheControl:H,hash:W.hash}})}static compareManifests($,J){let Y={added:[],removed:[],changed:[],unchanged:[]},Q=new Set(Object.keys($.hashMap)),Z=new Set(Object.keys(J.hashMap));for(let U of Z)if(!Q.has(U))Y.added.push(U);for(let U of Q)if(!Z.has(U))Y.removed.push(U);for(let U of Z)if(Q.has(U))if($.hashMap[U]!==J.hashMap[U])Y.changed.push(U);else Y.unchanged.push(U);return Y}static loadManifest($){if(!U6($))return null;try{let J=_9($,"utf-8");return JSON.parse(J)}catch{return null}}static saveManifest($,J){q9(J,JSON.stringify($,null,2))}};g2=class g2{static createSecret($){let{slug:J,environment:Y,secretName:Q,description:Z,secretString:U,kmsKeyId:W,tags:z}=$,G=Q||v({slug:J,environment:Y,resourceType:"secret"}),H=S(G),A={Type:"AWS::SecretsManager::Secret",Properties:{Name:G,Description:Z,SecretString:U,Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},...z?Object.entries(z).map(([K,B])=>({Key:K,Value:B})):[]]}};if(W)A.Properties.KmsKeyId=W;return{secret:A,logicalId:H}}static createGeneratedSecret($){let{slug:J,environment:Y,secretName:Q,description:Z,excludeCharacters:U,excludeLowercase:W,excludeNumbers:z,excludePunctuation:G,excludeUppercase:H,passwordLength:A,requireEachIncludedType:K,kmsKeyId:B,tags:j}=$,X=Q||v({slug:J,environment:Y,resourceType:"secret"}),O=S(X),_={Type:"AWS::SecretsManager::Secret",Properties:{Name:X,Description:Z,GenerateSecretString:{ExcludeCharacters:U,ExcludeLowercase:W,ExcludeNumbers:z,ExcludePunctuation:G,ExcludeUppercase:H,PasswordLength:A||32,RequireEachIncludedType:K!==!1},Tags:[{Key:"Name",Value:X},{Key:"Environment",Value:Y},...j?Object.entries(j).map(([w,E])=>({Key:w,Value:E})):[]]}};if(B)_.Properties.KmsKeyId=B;return{secret:_,logicalId:O}}static createDatabaseSecret($){let{slug:J,environment:Y,secretName:Q,username:Z,dbname:U,engine:W,host:z,port:G,kmsKeyId:H}=$,A=Q||v({slug:J,environment:Y,resourceType:"db-secret"}),K=S(A),B={username:Z};if(U)B.dbname=U;if(W)B.engine=W;if(z)B.host=z;if(G)B.port=G;let j={Type:"AWS::SecretsManager::Secret",Properties:{Name:A,Description:`Database credentials for ${Z}`,GenerateSecretString:{SecretStringTemplate:JSON.stringify(B),GenerateStringKey:"password",PasswordLength:32,ExcludeCharacters:'"@/\\',RequireEachIncludedType:!0},Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:Y},{Key:"Type",Value:"database"}]}};if(H)j.Properties.KmsKeyId=H;return{secret:j,logicalId:K}}static attachToDatabase($){let{slug:J,environment:Y,secretId:Q,targetId:Z,targetType:U}=$,W=v({slug:J,environment:Y,resourceType:"secret-attachment"}),z=S(W);return{attachment:{Type:"AWS::SecretsManager::SecretTargetAttachment",Properties:{SecretId:Q,TargetId:Z,TargetType:U}},logicalId:z}}static enableRotation($){let{slug:J,environment:Y,secretId:Q,rotationLambdaArn:Z,automaticallyAfterDays:U,rotationType:W,kmsKeyArn:z,vpcSecurityGroupIds:G,vpcSubnetIds:H}=$,A=v({slug:J,environment:Y,resourceType:"secret-rotation"}),K=S(A),B={Type:"AWS::SecretsManager::RotationSchedule",Properties:{SecretId:Q,RotationRules:{AutomaticallyAfterDays:U||30}}};if(Z)B.Properties.RotationLambdaARN=Z;else if(W)B.Properties.HostedRotationLambda={RotationType:W,KmsKeyArn:z,VpcSecurityGroupIds:G,VpcSubnetIds:H};return{rotation:B,logicalId:K}}static SecretTypes={apiKey:($,J,Y)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-${Y}-api-key`,description:`API key for ${Y}`,passwordLength:32,excludePunctuation:!0,excludeLowercase:!1,excludeUppercase:!1,excludeNumbers:!1})},oauthClientSecret:($,J,Y)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-${Y}-oauth-secret`,description:`OAuth client secret for ${Y}`,passwordLength:64,excludeCharacters:"\"'`\\/@",requireEachIncludedType:!0})},jwtSecret:($,J)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-jwt-secret`,description:"JWT signing secret",passwordLength:64,excludePunctuation:!0})},encryptionKey:($,J)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-encryption-key`,description:"Data encryption key",passwordLength:64,excludeCharacters:"+/=",excludePunctuation:!0})}};static RotationTypes={MySQLSingleUser:"MySQLSingleUser",MySQLMultiUser:"MySQLMultiUser",PostgreSQLSingleUser:"PostgreSQLSingleUser",PostgreSQLMultiUser:"PostgreSQLMultiUser",OracleSingleUser:"OracleSingleUser",OracleMultiUser:"OracleMultiUser",MariaDBSingleUser:"MariaDBSingleUser",MariaDBMultiUser:"MariaDBMultiUser",SQLServerSingleUser:"SQLServerSingleUser",SQLServerMultiUser:"SQLServerMultiUser",RedshiftSingleUser:"RedshiftSingleUser",RedshiftMultiUser:"RedshiftMultiUser",MongoDBSingleUser:"MongoDBSingleUser",MongoDBMultiUser:"MongoDBMultiUser"}};D0=class D0{static createParameter($){let{slug:J,environment:Y,parameterName:Q,value:Z,type:U="String",description:W,tier:z="Standard",tags:G}=$,H=Q||v({slug:J,environment:Y,resourceType:"parameter"}),A=S(H);return{parameter:{Type:"AWS::SSM::Parameter",Properties:{Name:`/${J}/${Y}/${H}`,Type:U,Value:Z,Description:W,Tier:z,Tags:{Name:H,Environment:Y,...G}}},logicalId:A}}static createString($,J,Y,Q,Z){return D0.createParameter({slug:$,environment:J,parameterName:Y,value:Q,type:"String",description:Z})}static createSecureString($,J,Y,Q,Z){return D0.createParameter({slug:$,environment:J,parameterName:Y,value:Q,type:"SecureString",description:Z})}static createStringList($,J,Y,Q,Z){return D0.createParameter({slug:$,environment:J,parameterName:Y,value:Q.join(","),type:"StringList",description:Z})}static Parameters={databaseUrl:($,J,Y)=>{return D0.createSecureString($,J,"database-url",Y,"Database connection URL")},apiEndpoint:($,J,Y)=>{return D0.createString($,J,"api-endpoint",Y,"API endpoint URL")},appVersion:($,J,Y)=>{return D0.createString($,J,"app-version",Y,"Application version")},featureFlags:($,J,Y)=>{return D0.createStringList($,J,"feature-flags",Y,"Enabled feature flags")},apiKey:($,J,Y,Q)=>{return D0.createSecureString($,J,`${Y}-api-key`,Q,`API key for ${Y}`)},oauthCredentials:($,J,Y,Q)=>{let Z=D0.createString($,J,"oauth-client-id",Y,"OAuth client ID"),U=D0.createSecureString($,J,"oauth-client-secret",Q,"OAuth client secret");return{clientId:Z,clientSecret:U}},smtpCredentials:($,J,Y,Q,Z,U)=>{let W=D0.createString($,J,"smtp-username",Y,"SMTP username"),z=D0.createSecureString($,J,"smtp-password",Q,"SMTP password"),G=D0.createString($,J,"smtp-host",Z,"SMTP host"),H=D0.createString($,J,"smtp-port",U.toString(),"SMTP port");return{username:W,password:z,host:G,port:H}},redisUrl:($,J,Y)=>{return D0.createSecureString($,J,"redis-url",Y,"Redis connection URL")},s3Bucket:($,J,Y)=>{return D0.createString($,J,"s3-bucket",Y,"S3 bucket name")},cloudFrontDistribution:($,J,Y)=>{return D0.createString($,J,"cloudfront-distribution-id",Y,"CloudFront distribution ID")}}};Y2=class Y2{static createDomain($){let{slug:J,environment:Y,domainName:Q,engineVersion:Z="OpenSearch_2.11",instanceType:U="t3.small.search",instanceCount:W=1,volumeSize:z=10,volumeType:G="gp3",dedicatedMaster:H=!1,dedicatedMasterType:A,dedicatedMasterCount:K=3,multiAz:B=!1,availabilityZoneCount:j=2,vpc:X,encryption:O,enforceHttps:_=!0,tlsSecurityPolicy:w="Policy-Min-TLS-1-2-2019-07",advancedSecurity:E,autoSnapshotHour:M=0,autoTune:T=!0,tags:D={}}=$,N=Q||v({slug:J,environment:Y,resourceType:"search"}),x=S(N);return{domain:{Type:"AWS::OpenSearchService::Domain",Properties:{DomainName:N,EngineVersion:Z,ClusterConfig:{InstanceType:U,InstanceCount:W,DedicatedMasterEnabled:H,...H&&{DedicatedMasterType:A||U,DedicatedMasterCount:K},ZoneAwarenessEnabled:B,...B&&{ZoneAwarenessConfig:{AvailabilityZoneCount:j}}},EBSOptions:{EBSEnabled:!0,VolumeType:G,VolumeSize:z},DomainEndpointOptions:{EnforceHTTPS:_,TLSSecurityPolicy:w},SnapshotOptions:{AutomatedSnapshotStartHour:M},...X&&{VPCOptions:{SubnetIds:X.subnetIds,SecurityGroupIds:X.securityGroupIds}},...O&&{EncryptionAtRestOptions:{Enabled:O.atRest??!0,...O.kmsKeyId&&{KmsKeyId:O.kmsKeyId}},NodeToNodeEncryptionOptions:{Enabled:O.nodeToNode??!0}},...E&&{AdvancedSecurityOptions:{Enabled:E.enabled,InternalUserDatabaseEnabled:E.internalUserDatabase??!0,...E.masterUserName&&E.masterUserPassword&&{MasterUserOptions:{MasterUserName:E.masterUserName,MasterUserPassword:E.masterUserPassword}},...E.masterUserArn&&{MasterUserOptions:{MasterUserARN:E.masterUserArn}}}},...T&&{AutoTuneOptions:{DesiredState:"ENABLED"}},Tags:[{Key:"Name",Value:N},{Key:"Environment",Value:Y},...Object.entries(D).map(([k,b])=>({Key:k,Value:b}))]}},logicalId:x}}static createAccessPolicy($,J){let{ipAddresses:Y,iamPrincipalArns:Q,allowAll:Z,vpcEndpoint:U}=J;if(Z)return{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:$}]};let W=[];if(Q&&Q.length>0)W.push({Effect:"Allow",Principal:{AWS:Q},Action:"es:*",Resource:$});if(Y&&Y.length>0)W.push({Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:$,Condition:{IpAddress:{"aws:SourceIp":Y}}});if(U)return{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:$}]};return{Version:"2012-10-17",Statement:W}}static DomainPresets={development:($,J)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"t3.small.search",instanceCount:1,volumeSize:10,multiAz:!1,dedicatedMaster:!1,encryption:{atRest:!0,nodeToNode:!0},autoTune:!1})},production:($,J,Y)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"m6g.large.search",instanceCount:3,volumeSize:100,volumeType:"gp3",multiAz:!0,availabilityZoneCount:3,dedicatedMaster:!0,dedicatedMasterType:"m6g.large.search",dedicatedMasterCount:3,vpc:Y,encryption:{atRest:!0,nodeToNode:!0},advancedSecurity:{enabled:!0,internalUserDatabase:!0},autoTune:!0})},costOptimized:($,J)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"t3.medium.search",instanceCount:2,volumeSize:20,volumeType:"gp3",multiAz:!0,dedicatedMaster:!1,encryption:{atRest:!0,nodeToNode:!0},autoTune:!0})},highPerformance:($,J,Y)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"r6g.2xlarge.search",instanceCount:6,volumeSize:500,volumeType:"gp3",multiAz:!0,availabilityZoneCount:3,dedicatedMaster:!0,dedicatedMasterType:"c6g.xlarge.search",dedicatedMasterCount:3,vpc:Y,encryption:{atRest:!0,nodeToNode:!0},advancedSecurity:{enabled:!0,internalUserDatabase:!1},autoTune:!0})}};static InstanceTypes={"t3.small.search":"t3.small.search","t3.medium.search":"t3.medium.search","m6g.large.search":"m6g.large.search","m6g.xlarge.search":"m6g.xlarge.search","m6g.2xlarge.search":"m6g.2xlarge.search","r6g.large.search":"r6g.large.search","r6g.xlarge.search":"r6g.xlarge.search","r6g.2xlarge.search":"r6g.2xlarge.search","r6g.4xlarge.search":"r6g.4xlarge.search","c6g.large.search":"c6g.large.search","c6g.xlarge.search":"c6g.xlarge.search","c6g.2xlarge.search":"c6g.2xlarge.search"};static EngineVersions={"OpenSearch_2.11":"OpenSearch_2.11","OpenSearch_2.9":"OpenSearch_2.9","OpenSearch_2.7":"OpenSearch_2.7","OpenSearch_1.3":"OpenSearch_1.3","Elasticsearch_7.10":"Elasticsearch_7.10"}};c1=class c1{static createDomainRedirectBucket($){let{slug:J,environment:Y,sourceDomain:Q,targetDomain:Z,protocol:U="https"}=$,W=v({slug:J,environment:Y,resourceType:"s3",suffix:"redirect"}),z=S(W),G=S(`${W}-policy`),H={Type:"AWS::S3::Bucket",Properties:{BucketName:Q,WebsiteConfiguration:{RedirectAllRequestsTo:{HostName:Z,Protocol:U}},PublicAccessBlockConfiguration:{BlockPublicAcls:!1,BlockPublicPolicy:!1,IgnorePublicAcls:!1,RestrictPublicBuckets:!1},Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"Domain Redirect"}]}},A={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(z),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadForRedirect",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[u.Join("",[u.GetAtt(z,"Arn"),"/*"])]}]}}};return{bucket:H,bucketPolicy:A,logicalId:z,policyLogicalId:G}}static createPathRedirectFunction($){let{slug:J,environment:Y,rules:Q}=$,Z=v({slug:J,environment:Y,resourceType:"cf-redirect"}),U=S(Z),W=c1.generateRedirectFunctionCode(Q);return{function:{Type:"AWS::CloudFront::Function",Properties:{Name:Z,AutoPublish:!0,FunctionConfig:{Comment:`Path redirect function for ${J} (${Y})`,Runtime:"cloudfront-js-2.0"},FunctionCode:W}},logicalId:U,functionCode:W}}static generateRedirectFunctionCode($){return`function handler(event) {
5753
+ | limit 50`,region:Q,title:"Recent Errors and Warnings"}}),W+=6;return _$.createDashboard({slug:J,environment:Y,widgets:U})}static DashboardTemplates={staticWebsite:($)=>({slug:$.slug,environment:$.environment,widgets:[{type:"text",x:0,y:0,width:24,height:1,properties:{markdown:`# ${$.slug.toUpperCase()} Static Website Dashboard`}},{type:"metric",x:0,y:1,width:8,height:6,properties:{title:"CloudFront Requests",region:"us-east-1",metrics:[["AWS/CloudFront","Requests","DistributionId",$.cloudFrontDistributionId,"Region","Global"]],period:300,stat:"Sum"}},{type:"metric",x:8,y:1,width:8,height:6,properties:{title:"Error Rate",region:"us-east-1",metrics:[["AWS/CloudFront","4xxErrorRate","DistributionId",$.cloudFrontDistributionId,"Region","Global",{label:"4XX"}],["AWS/CloudFront","5xxErrorRate","DistributionId",$.cloudFrontDistributionId,"Region","Global",{label:"5XX"}]],period:300,stat:"Average"}},{type:"metric",x:16,y:1,width:8,height:6,properties:{title:"Bytes Downloaded",region:"us-east-1",metrics:[["AWS/CloudFront","BytesDownloaded","DistributionId",$.cloudFrontDistributionId,"Region","Global"]],period:300,stat:"Sum"}},{type:"metric",x:0,y:7,width:12,height:6,properties:{title:"S3 Bucket Size",region:$.region||"us-east-1",metrics:[["AWS/S3","BucketSizeBytes","BucketName",$.s3BucketName,"StorageType","StandardStorage"]],period:86400,stat:"Average"}},{type:"metric",x:12,y:7,width:12,height:6,properties:{title:"S3 Number of Objects",region:$.region||"us-east-1",metrics:[["AWS/S3","NumberOfObjects","BucketName",$.s3BucketName,"StorageType","AllStorageTypes"]],period:86400,stat:"Average"}}]}),serverlessApi:($)=>({slug:$.slug,environment:$.environment,widgets:[{type:"text",x:0,y:0,width:24,height:1,properties:{markdown:`# ${$.slug.toUpperCase()} Serverless API Dashboard`}},{type:"metric",x:0,y:1,width:8,height:6,properties:{title:"API Requests",region:$.region||"us-east-1",metrics:[["AWS/ApiGateway","Count","ApiName",$.apiGatewayName]],period:60,stat:"Sum"}},{type:"metric",x:8,y:1,width:8,height:6,properties:{title:"API Latency",region:$.region||"us-east-1",metrics:[["AWS/ApiGateway","Latency","ApiName",$.apiGatewayName]],period:60,stat:"Average"}},{type:"metric",x:16,y:1,width:8,height:6,properties:{title:"API Errors",region:$.region||"us-east-1",metrics:[["AWS/ApiGateway","4XXError","ApiName",$.apiGatewayName,{label:"4XX"}],["AWS/ApiGateway","5XXError","ApiName",$.apiGatewayName,{label:"5XX"}]],period:60,stat:"Sum"}},...$.lambdaFunctionNames.map((J,Y)=>({type:"metric",x:Y%3*8,y:7+Math.floor(Y/3)*6,width:8,height:6,properties:{title:`${J} Metrics`,region:$.region||"us-east-1",metrics:[["AWS/Lambda","Invocations","FunctionName",J],["AWS/Lambda","Duration","FunctionName",J],["AWS/Lambda","Errors","FunctionName",J]],period:300,stat:"Sum"}}))]}),containerService:($)=>({slug:$.slug,environment:$.environment,widgets:[{type:"text",x:0,y:0,width:24,height:1,properties:{markdown:`# ${$.slug.toUpperCase()} Container Service Dashboard`}},{type:"metric",x:0,y:1,width:8,height:6,properties:{title:"ECS CPU",region:$.region||"us-east-1",metrics:[["AWS/ECS","CPUUtilization","ClusterName",$.ecsClusterName,"ServiceName",$.ecsServiceName]],period:60,stat:"Average"}},{type:"metric",x:8,y:1,width:8,height:6,properties:{title:"ECS Memory",region:$.region||"us-east-1",metrics:[["AWS/ECS","MemoryUtilization","ClusterName",$.ecsClusterName,"ServiceName",$.ecsServiceName]],period:60,stat:"Average"}},{type:"metric",x:16,y:1,width:8,height:6,properties:{title:"Running Tasks",region:$.region||"us-east-1",metrics:[["ECS/ContainerInsights","RunningTaskCount","ClusterName",$.ecsClusterName,"ServiceName",$.ecsServiceName]],period:60,stat:"Average"}},{type:"metric",x:0,y:7,width:8,height:6,properties:{title:"ALB Requests",region:$.region||"us-east-1",metrics:[["AWS/ApplicationELB","RequestCount","LoadBalancer",$.albName]],period:60,stat:"Sum"}},{type:"metric",x:8,y:7,width:8,height:6,properties:{title:"Response Time",region:$.region||"us-east-1",metrics:[["AWS/ApplicationELB","TargetResponseTime","LoadBalancer",$.albName]],period:60,stat:"Average"}},{type:"metric",x:16,y:7,width:8,height:6,properties:{title:"Healthy Hosts",region:$.region||"us-east-1",metrics:[["AWS/ApplicationELB","HealthyHostCount","LoadBalancer",$.albName]],period:60,stat:"Average"}},...$.rdsInstanceId?[{type:"metric",x:0,y:13,width:12,height:6,properties:{title:"RDS CPU",region:$.region||"us-east-1",metrics:[["AWS/RDS","CPUUtilization","DBInstanceIdentifier",$.rdsInstanceId]],period:300,stat:"Average"}},{type:"metric",x:12,y:13,width:12,height:6,properties:{title:"RDS Connections",region:$.region||"us-east-1",metrics:[["AWS/RDS","DatabaseConnections","DBInstanceIdentifier",$.rdsInstanceId]],period:60,stat:"Sum"}}]:[]]})};static Config={createAlarmConfig:($)=>{let{metricName:J,namespace:Y,threshold:Q,comparisonOperator:Z="GreaterThanThreshold",evaluationPeriods:U=1,period:W=300,statistic:z="Average",treatMissingData:G="missing"}=$;return{MetricName:J,Namespace:Y,Threshold:Q,ComparisonOperator:Z,EvaluationPeriods:U,Period:W,Statistic:z,TreatMissingData:G}},namespaces:{ec2:"AWS/EC2",ecs:"AWS/ECS",lambda:"AWS/Lambda",rds:"AWS/RDS",sqs:"AWS/SQS",sns:"AWS/SNS",s3:"AWS/S3",cloudfront:"AWS/CloudFront",alb:"AWS/ApplicationELB",nlb:"AWS/NetworkELB",apiGateway:"AWS/ApiGateway",dynamodb:"AWS/DynamoDB",elasticache:"AWS/ElastiCache"},comparisonOperators:{greaterThan:"GreaterThanThreshold",greaterOrEqual:"GreaterThanOrEqualToThreshold",lessThan:"LessThanThreshold",lessOrEqual:"LessThanOrEqualToThreshold"},metrics:{ec2:{cpu:{metricName:"CPUUtilization",namespace:"AWS/EC2"},networkIn:{metricName:"NetworkIn",namespace:"AWS/EC2"},networkOut:{metricName:"NetworkOut",namespace:"AWS/EC2"},statusCheck:{metricName:"StatusCheckFailed",namespace:"AWS/EC2"}},ecs:{cpu:{metricName:"CPUUtilization",namespace:"AWS/ECS"},memory:{metricName:"MemoryUtilization",namespace:"AWS/ECS"}},lambda:{invocations:{metricName:"Invocations",namespace:"AWS/Lambda"},errors:{metricName:"Errors",namespace:"AWS/Lambda"},duration:{metricName:"Duration",namespace:"AWS/Lambda"},throttles:{metricName:"Throttles",namespace:"AWS/Lambda"},concurrentExecutions:{metricName:"ConcurrentExecutions",namespace:"AWS/Lambda"}},rds:{cpu:{metricName:"CPUUtilization",namespace:"AWS/RDS"},connections:{metricName:"DatabaseConnections",namespace:"AWS/RDS"},freeStorage:{metricName:"FreeStorageSpace",namespace:"AWS/RDS"},readLatency:{metricName:"ReadLatency",namespace:"AWS/RDS"},writeLatency:{metricName:"WriteLatency",namespace:"AWS/RDS"}},alb:{requestCount:{metricName:"RequestCount",namespace:"AWS/ApplicationELB"},responseTime:{metricName:"TargetResponseTime",namespace:"AWS/ApplicationELB"},httpCode4xx:{metricName:"HTTPCode_Target_4XX_Count",namespace:"AWS/ApplicationELB"},httpCode5xx:{metricName:"HTTPCode_Target_5XX_Count",namespace:"AWS/ApplicationELB"},healthyHosts:{metricName:"HealthyHostCount",namespace:"AWS/ApplicationELB"}},sqs:{messagesVisible:{metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS"},messagesDelayed:{metricName:"ApproximateNumberOfMessagesDelayed",namespace:"AWS/SQS"},messageAge:{metricName:"ApproximateAgeOfOldestMessage",namespace:"AWS/SQS"}}},presets:{highCpu:($=80)=>({metricName:"CPUUtilization",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),highMemory:($=80)=>({metricName:"MemoryUtilization",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),highErrors:($=10)=>({metricName:"Errors",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:1,period:60,statistic:"Sum"}),highLatency:($=5000)=>({metricName:"Duration",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),lowHealthyHosts:($=1)=>({metricName:"HealthyHostCount",namespace:"AWS/ApplicationELB",threshold:$,comparisonOperator:"LessThanThreshold",evaluationPeriods:2,period:60,statistic:"Minimum"}),queueDepth:($=1000)=>({metricName:"ApproximateNumberOfMessagesVisible",namespace:"AWS/SQS",threshold:$,comparisonOperator:"GreaterThanThreshold",evaluationPeriods:3,period:300,statistic:"Average"}),lowStorage:($=10737418240)=>({metricName:"FreeStorageSpace",namespace:"AWS/RDS",threshold:$,comparisonOperator:"LessThanThreshold",evaluationPeriods:1,period:300,statistic:"Average"})}}};n0=class n0{static createUserPool($){let{slug:J,environment:Y,userPoolName:Q,aliasAttributes:Z,autoVerifiedAttributes:U,passwordPolicy:W,mfaConfiguration:z,emailConfiguration:G,smsConfiguration:H,lambdaTriggers:A,userPoolAddOns:K,accountRecoverySetting:B}=$,j=Q||f({slug:J,environment:Y,resourceType:"user-pool"}),X=S(j),O={Type:"AWS::Cognito::UserPool",Properties:{UserPoolName:j,Policies:W?{PasswordPolicy:{MinimumLength:W.minimumLength,RequireLowercase:W.requireLowercase,RequireUppercase:W.requireUppercase,RequireNumbers:W.requireNumbers,RequireSymbols:W.requireSymbols,TemporaryPasswordValidityDays:W.temporaryPasswordValidityDays}}:void 0,MfaConfiguration:z,Schema:[{Name:"email",AttributeDataType:"String",Required:!0,Mutable:!1}]}};if(Z&&Z.length>0)O.Properties.UsernameAttributes=Z;if(U&&U.length>0)O.Properties.AutoVerifiedAttributes=U;if(G)O.Properties.EmailConfiguration={EmailSendingAccount:G.emailSendingAccount,From:G.from,ReplyToEmailAddress:G.replyToEmailAddress,SourceArn:G.sourceArn,ConfigurationSet:G.configurationSet};if(H)O.Properties.SmsConfiguration={ExternalId:H.externalId,SnsCallerArn:H.snsCallerArn};if(A)O.Properties.LambdaConfig={PreSignUp:A.preSignUp,PostConfirmation:A.postConfirmation,PreAuthentication:A.preAuthentication,PostAuthentication:A.postAuthentication,CustomMessage:A.customMessage,DefineAuthChallenge:A.defineAuthChallenge,CreateAuthChallenge:A.createAuthChallenge,VerifyAuthChallengeResponse:A.verifyAuthChallengeResponse,PreTokenGeneration:A.preTokenGeneration,UserMigration:A.userMigration};if(K)O.Properties.UserPoolAddOns={AdvancedSecurityMode:K.advancedSecurityMode};if(B)O.Properties.AccountRecoverySetting={RecoveryMechanisms:B.recoveryMechanisms};return{userPool:O,logicalId:X}}static createUserPoolClient($,J){let{slug:Y,environment:Q,clientName:Z,generateSecret:U=!1,refreshTokenValidity:W,accessTokenValidity:z,idTokenValidity:G,tokenValidityUnits:H,readAttributes:A,writeAttributes:K,explicitAuthFlows:B,preventUserExistenceErrors:j,enableTokenRevocation:X,callbackURLs:O,logoutURLs:_,allowedOAuthFlows:w,allowedOAuthScopes:E,allowedOAuthFlowsUserPoolClient:M,supportedIdentityProviders:T}=J,D=Z||f({slug:Y,environment:Q,resourceType:"user-pool-client"}),N=S(D);return{client:{Type:"AWS::Cognito::UserPoolClient",Properties:{ClientName:D,UserPoolId:u.Ref($),GenerateSecret:U,RefreshTokenValidity:W,AccessTokenValidity:z,IdTokenValidity:G,TokenValidityUnits:H,ReadAttributes:A,WriteAttributes:K,ExplicitAuthFlows:B,PreventUserExistenceErrors:j,EnableTokenRevocation:X,CallbackURLs:O,LogoutURLs:_,AllowedOAuthFlows:w,AllowedOAuthScopes:E,AllowedOAuthFlowsUserPoolClient:M,SupportedIdentityProviders:T}},logicalId:N}}static createUserPoolDomain($,J){let{slug:Y,environment:Q,domain:Z,customDomainConfig:U}=J,W=f({slug:Y,environment:Q,resourceType:"user-pool-domain"}),z=S(W);return{domain:{Type:"AWS::Cognito::UserPoolDomain",Properties:{Domain:Z,UserPoolId:u.Ref($),CustomDomainConfig:U}},logicalId:z}}static createIdentityPool($){let{slug:J,environment:Y,identityPoolName:Q,allowUnauthenticatedIdentities:Z=!1,cognitoIdentityProviders:U,supportedLoginProviders:W,samlProviderARNs:z,openIdConnectProviderARNs:G}=$,H=Q||f({slug:J,environment:Y,resourceType:"identity-pool"}),A=S(H);return{identityPool:{Type:"AWS::Cognito::IdentityPool",Properties:{IdentityPoolName:H,AllowUnauthenticatedIdentities:Z,CognitoIdentityProviders:U,SupportedLoginProviders:W,SamlProviderARNs:z,OpenIdConnectProviderARNs:G}},logicalId:A}}static createIdentityPoolRoleAttachment($,J){let{slug:Y,environment:Q,authenticatedRole:Z,unauthenticatedRole:U,roleMappings:W}=J,z=f({slug:Y,environment:Q,resourceType:"identity-pool-role-attachment"}),G=S(z),H={authenticated:Z};if(U)H.unauthenticated=U;return{attachment:{Type:"AWS::Cognito::IdentityPoolRoleAttachment",Properties:{IdentityPoolId:u.Ref($),Roles:H,RoleMappings:W}},logicalId:G}}static createAuthenticatedRole($){let{slug:J,environment:Y,identityPoolLogicalId:Q}=$,Z=f({slug:J,environment:Y,resourceType:"cognito-authenticated-role"}),U=S(Z);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:Z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Federated:"cognito-identity.amazonaws.com"},Action:"sts:AssumeRoleWithWebIdentity",Condition:{StringEquals:{"cognito-identity.amazonaws.com:aud":u.Ref(Q)},"ForAnyValue:StringLike":{"cognito-identity.amazonaws.com:amr":"authenticated"}}}]},Policies:[{PolicyName:"CognitoAuthenticatedPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["cognito-sync:*","cognito-identity:*"],Resource:"*"}]}}],Tags:[{Key:"Name",Value:Z},{Key:"Environment",Value:Y}]}},logicalId:U}}static createUnauthenticatedRole($){let{slug:J,environment:Y,identityPoolLogicalId:Q}=$,Z=f({slug:J,environment:Y,resourceType:"cognito-unauthenticated-role"}),U=S(Z);return{role:{Type:"AWS::IAM::Role",Properties:{RoleName:Z,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Federated:"cognito-identity.amazonaws.com"},Action:"sts:AssumeRoleWithWebIdentity",Condition:{StringEquals:{"cognito-identity.amazonaws.com:aud":u.Ref(Q)},"ForAnyValue:StringLike":{"cognito-identity.amazonaws.com:amr":"unauthenticated"}}}]},Policies:[{PolicyName:"CognitoUnauthenticatedPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["cognito-sync:*"],Resource:"*"}]}}],Tags:[{Key:"Name",Value:Z},{Key:"Environment",Value:Y}]}},logicalId:U}}static PasswordPolicies={relaxed:()=>({minimumLength:8,requireLowercase:!1,requireUppercase:!1,requireNumbers:!1,requireSymbols:!1,temporaryPasswordValidityDays:7}),standard:()=>({minimumLength:8,requireLowercase:!0,requireUppercase:!0,requireNumbers:!0,requireSymbols:!1,temporaryPasswordValidityDays:3}),strict:()=>({minimumLength:12,requireLowercase:!0,requireUppercase:!0,requireNumbers:!0,requireSymbols:!0,temporaryPasswordValidityDays:1})};static AuthFlows={standard:["ALLOW_USER_SRP_AUTH","ALLOW_REFRESH_TOKEN_AUTH"],admin:["ALLOW_ADMIN_USER_PASSWORD_AUTH","ALLOW_REFRESH_TOKEN_AUTH"],custom:["ALLOW_CUSTOM_AUTH","ALLOW_REFRESH_TOKEN_AUTH"],all:["ALLOW_USER_SRP_AUTH","ALLOW_USER_PASSWORD_AUTH","ALLOW_ADMIN_USER_PASSWORD_AUTH","ALLOW_CUSTOM_AUTH","ALLOW_REFRESH_TOKEN_AUTH"]};static OAuthScopes={basic:["openid","email","profile"],all:["openid","email","profile","phone","aws.cognito.signin.user.admin"]};static UseCases={webApp:($,J,Y)=>{let{userPool:Q,logicalId:Z}=n0.createUserPool({slug:$,environment:J,aliasAttributes:["email"],autoVerifiedAttributes:["email"],passwordPolicy:n0.PasswordPolicies.standard(),mfaConfiguration:"OPTIONAL"}),{client:U,logicalId:W}=n0.createUserPoolClient(Z,{slug:$,environment:J,explicitAuthFlows:[...n0.AuthFlows.standard],callbackURLs:[Y],allowedOAuthFlows:["code"],allowedOAuthScopes:[...n0.OAuthScopes.basic],allowedOAuthFlowsUserPoolClient:!0});return{userPool:Q,poolId:Z,client:U,clientId:W}},mobileApp:($,J)=>{let{userPool:Y,logicalId:Q}=n0.createUserPool({slug:$,environment:J,aliasAttributes:["email"],autoVerifiedAttributes:["email"],passwordPolicy:n0.PasswordPolicies.standard(),mfaConfiguration:"OPTIONAL"}),{client:Z,logicalId:U}=n0.createUserPoolClient(Q,{slug:$,environment:J,explicitAuthFlows:[...n0.AuthFlows.standard]}),{identityPool:W,logicalId:z}=n0.createIdentityPool({slug:$,environment:J,allowUnauthenticatedIdentities:!1,cognitoIdentityProviders:[{ClientId:u.Ref(U),ProviderName:u.GetAtt(Q,"ProviderName")}]}),{role:G,logicalId:H}=n0.createAuthenticatedRole({slug:$,environment:J,identityPoolLogicalId:z}),{attachment:A,logicalId:K}=n0.createIdentityPoolRoleAttachment(z,{slug:$,environment:J,authenticatedRole:u.GetAtt(H,"Arn")});return{userPool:Y,poolId:Q,client:Z,clientId:U,identityPool:W,identityPoolId:z,authRole:G,authRoleId:H,attachment:A,attachmentId:K}}}};a0=class a0{static createApplication($){let{slug:J,environment:Y,applicationName:Q,computePlatform:Z}=$,U=Q||f({slug:J,environment:Y,resourceType:"deploy-app"}),W=S(U);return{application:{Type:"AWS::CodeDeploy::Application",Properties:{ApplicationName:U,ComputePlatform:Z,Tags:[{Key:"Name",Value:U},{Key:"Environment",Value:Y}]}},logicalId:W}}static createDeploymentGroup($,J){let{slug:Y,environment:Q,deploymentGroupName:Z,serviceRoleArn:U,autoScalingGroups:W,ec2TagFilters:z,deploymentConfigName:G,autoRollbackConfiguration:H,alarmConfiguration:A,loadBalancerInfo:K,blueGreenDeploymentConfiguration:B}=J,j=Z||f({slug:Y,environment:Q,resourceType:"deploy-group"}),X=S(j);return{deploymentGroup:{Type:"AWS::CodeDeploy::DeploymentGroup",Properties:{ApplicationName:u.Ref($),DeploymentGroupName:j,ServiceRoleArn:U,AutoScalingGroups:W,Ec2TagFilters:z?.map((_)=>({Key:_.key,Value:_.value,Type:_.type})),DeploymentConfigName:G,AutoRollbackConfiguration:H?{Enabled:H.enabled,Events:H.events}:void 0,AlarmConfiguration:A?{Enabled:A.enabled,Alarms:A.alarms?.map((_)=>({Name:_.name})),IgnorePollAlarmFailure:A.ignorePollAlarmFailure}:void 0,LoadBalancerInfo:K?{TargetGroupInfoList:K.targetGroupInfoList?.map((_)=>({Name:_.name})),ElbInfoList:K.elbInfoList?.map((_)=>({Name:_.name}))}:void 0,BlueGreenDeploymentConfiguration:B?{TerminateBlueInstancesOnDeploymentSuccess:B.terminateBlueInstancesOnDeploymentSuccess?{Action:B.terminateBlueInstancesOnDeploymentSuccess.action,TerminationWaitTimeInMinutes:B.terminateBlueInstancesOnDeploymentSuccess.terminationWaitTimeInMinutes}:void 0,DeploymentReadyOption:B.deploymentReadyOption?{ActionOnTimeout:B.deploymentReadyOption.actionOnTimeout,WaitTimeInMinutes:B.deploymentReadyOption.waitTimeInMinutes}:void 0,GreenFleetProvisioningOption:B.greenFleetProvisioningOption?{Action:B.greenFleetProvisioningOption.action}:void 0}:void 0,Tags:[{Key:"Name",Value:j},{Key:"Environment",Value:Q}]}},logicalId:X}}static createDeploymentConfig($){let{slug:J,environment:Y,deploymentConfigName:Q,minimumHealthyHosts:Z,trafficRoutingConfig:U}=$,W=Q||f({slug:J,environment:Y,resourceType:"deploy-config"}),z=S(W);return{deploymentConfig:{Type:"AWS::CodeDeploy::DeploymentConfig",Properties:{DeploymentConfigName:W,MinimumHealthyHosts:Z?{Type:Z.type,Value:Z.value}:void 0,TrafficRoutingConfig:U?{Type:U.type,TimeBasedCanary:U.timeBasedCanary?{CanaryPercentage:U.timeBasedCanary.canaryPercentage,CanaryInterval:U.timeBasedCanary.canaryInterval}:void 0,TimeBasedLinear:U.timeBasedLinear?{LinearPercentage:U.timeBasedLinear.linearPercentage,LinearInterval:U.timeBasedLinear.linearInterval}:void 0}:void 0}},logicalId:z}}static DeploymentConfigs={allAtOnce:()=>({type:"FLEET_PERCENT",value:0}),halfAtATime:()=>({type:"FLEET_PERCENT",value:50}),oneAtATime:()=>({type:"HOST_COUNT",value:1}),custom:($,J)=>({type:$,value:J})};static TrafficRouting={allAtOnce:()=>({type:"AllAtOnce"}),canary:($,J)=>({type:"TimeBasedCanary",timeBasedCanary:{canaryPercentage:$,canaryInterval:J}}),linear:($,J)=>({type:"TimeBasedLinear",timeBasedLinear:{linearPercentage:$,linearInterval:J}})};static RollbackConfigs={onFailure:()=>({enabled:!0,events:["DEPLOYMENT_FAILURE"]}),onAlarmOrFailure:()=>({enabled:!0,events:["DEPLOYMENT_FAILURE","DEPLOYMENT_STOP_ON_ALARM"]}),onAllEvents:()=>({enabled:!0,events:["DEPLOYMENT_FAILURE","DEPLOYMENT_STOP_ON_ALARM","DEPLOYMENT_STOP_ON_REQUEST"]}),disabled:()=>({enabled:!1})};static BlueGreenConfigs={standard:()=>({terminateBlueInstancesOnDeploymentSuccess:{action:"TERMINATE",terminationWaitTimeInMinutes:5},deploymentReadyOption:{actionOnTimeout:"CONTINUE_DEPLOYMENT",waitTimeInMinutes:0},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}}),withDelay:($)=>({terminateBlueInstancesOnDeploymentSuccess:{action:"TERMINATE",terminationWaitTimeInMinutes:$},deploymentReadyOption:{actionOnTimeout:"CONTINUE_DEPLOYMENT",waitTimeInMinutes:0},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}}),withManualApproval:($)=>({terminateBlueInstancesOnDeploymentSuccess:{action:"TERMINATE",terminationWaitTimeInMinutes:5},deploymentReadyOption:{actionOnTimeout:"STOP_DEPLOYMENT",waitTimeInMinutes:$},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}}),keepBlue:()=>({terminateBlueInstancesOnDeploymentSuccess:{action:"KEEP_ALIVE"},deploymentReadyOption:{actionOnTimeout:"CONTINUE_DEPLOYMENT",waitTimeInMinutes:0},greenFleetProvisioningOption:{action:"COPY_AUTO_SCALING_GROUP"}})};static UseCases={ec2Deployment:($,J,Y,Q)=>{let{application:Z,logicalId:U}=a0.createApplication({slug:$,environment:J,computePlatform:"Server"}),{deploymentGroup:W,logicalId:z}=a0.createDeploymentGroup(U,{slug:$,environment:J,serviceRoleArn:Y,autoScalingGroups:Q,deploymentConfigName:"CodeDeployDefault.OneAtATime",autoRollbackConfiguration:a0.RollbackConfigs.onFailure()});return{application:Z,appId:U,deploymentGroup:W,groupId:z}},lambdaCanaryDeployment:($,J,Y,Q=10,Z=5)=>{let{application:U,logicalId:W}=a0.createApplication({slug:$,environment:J,computePlatform:"Lambda"}),{deploymentConfig:z,logicalId:G}=a0.createDeploymentConfig({slug:$,environment:J,trafficRoutingConfig:a0.TrafficRouting.canary(Q,Z)}),{deploymentGroup:H,logicalId:A}=a0.createDeploymentGroup(W,{slug:$,environment:J,serviceRoleArn:Y,deploymentConfigName:u.Ref(G),autoRollbackConfiguration:a0.RollbackConfigs.onAlarmOrFailure()});return{application:U,appId:W,deploymentConfig:z,configId:G,deploymentGroup:H,groupId:A}},ecsBlueGreenDeployment:($,J,Y,Q)=>{let{application:Z,logicalId:U}=a0.createApplication({slug:$,environment:J,computePlatform:"ECS"}),{deploymentGroup:W,logicalId:z}=a0.createDeploymentGroup(U,{slug:$,environment:J,serviceRoleArn:Y,loadBalancerInfo:{targetGroupInfoList:[{name:Q}]},blueGreenDeploymentConfiguration:a0.BlueGreenConfigs.standard(),autoRollbackConfiguration:a0.RollbackConfigs.onFailure()});return{application:Z,appId:U,deploymentGroup:W,groupId:z}}};static Strategies={rolling:($=25)=>({type:"rolling",batchPercentage:$}),blueGreen:()=>({type:"blue-green"}),canary:($=10,J=5)=>({type:"canary",canaryPercentage:$,canaryInterval:J}),allAtOnce:()=>({type:"all-at-once"})}};h0=class h0{static ContentTypes={".html":"text/html",".htm":"text/html",".css":"text/css",".js":"application/javascript",".mjs":"application/javascript",".json":"application/json",".xml":"application/xml",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".avif":"image/avif",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".map":"application/json"};static NoHashPatterns=[/^index\.html$/,/^favicon\.ico$/,/^robots\.txt$/,/^sitemap\.xml$/,/^manifest\.json$/,/^\.well-known\//,/^_redirects$/,/^_headers$/];static computeFileHash($,J="md5"){let Y=_9($);return L4(J).update(Y).digest("hex")}static computeShortHash($){return h0.computeFileHash($).slice(0,8)}static getContentType($){let J=zQ($).toLowerCase();return h0.ContentTypes[J]||"application/octet-stream"}static shouldHashFile($,J){return![...h0.NoHashPatterns,...J||[]].some((Q)=>Q.test($))}static generateHashedFilename($,J){let Y=zQ($),Q=D4($,Y),Z=WQ($);if(Z===".")return`${Q}.${J}${Y}`;return Z$(Z,`${Q}.${J}${Y}`)}static collectFiles($,J){let Y=[],Q=J||$;if(!U6($))return Y;let Z=M4($,{withFileTypes:!0});for(let U of Z){let W=Z$($,U.name);if(U.isDirectory())Y.push(...h0.collectFiles(W,Q));else if(U.isFile())Y.push(W)}return Y}static hashDirectory($){let{sourceDir:J,outputDir:Y,excludePatterns:Q=[],hashAlgorithm:Z="md5",copyUnhashed:U=!0}=$,W=h0.collectFiles(J),z=[],G={};for(let A of W){let K=A.replace(J,"").replace(/^[/\\]/,""),B=h0.shouldHashFile(K,Q),j=T4(A),X=B?h0.computeFileHash(A,Z).slice(0,8):"",O=B?h0.generateHashedFilename(K,X):K,_={originalPath:K,hashedPath:O,hash:X,size:j.size,contentType:h0.getContentType(A)};if(z.push(_),G[K]=O,Y){let w=Z$(Y,O),E=WQ(w);if(!U6(E)){let{mkdirSync:M}=cG("node:fs");M(E,{recursive:!0})}if(B||U)R4(A,w)}}let H={version:"1.0",timestamp:new Date().toISOString(),assets:z,hashMap:G};if(Y){let A=Z$(Y,"asset-manifest.json");q9(A,JSON.stringify(H,null,2))}return H}static getInvalidationPaths($,J){let Y=[];if(!$)return["/*"];let Q=$.hashMap,Z=J.hashMap;for(let[U,W]of Object.entries(Z)){let z=Q[U];if(!z||z!==W){if(Y.push(`/${U}`),z&&z!==W)Y.push(`/${z}`)}}for(let[U,W]of Object.entries(Q))if(!Z[U])Y.push(`/${U}`),Y.push(`/${W}`);if(Y.length>100)return["/*"];return[...new Set(Y)]}static updateHtmlReferences($){let{htmlDir:J,manifest:Y,basePath:Q=""}=$,Z=h0.collectFiles(J).filter((U)=>U.endsWith(".html")||U.endsWith(".htm"));for(let U of Z){let W=_9(U,"utf-8");for(let[z,G]of Object.entries(Y.hashMap)){if(z===G)continue;let H=[new RegExp(`(src|href)=["']${Q}/?${h0.escapeRegExp(z)}["']`,"g"),new RegExp(`url\\(["']?${Q}/?${h0.escapeRegExp(z)}["']?\\)`,"g")];for(let A of H)W=W.replace(A,(K)=>{return K.replace(z,G)})}q9(U,W)}}static updateCssReferences($){let{cssDir:J,manifest:Y,basePath:Q=""}=$,Z=h0.collectFiles(J).filter((U)=>U.endsWith(".css"));for(let U of Z){let W=_9(U,"utf-8");for(let[z,G]of Object.entries(Y.hashMap)){if(z===G)continue;let H=new RegExp(`url\\(["']?${Q}/?${h0.escapeRegExp(z)}["']?\\)`,"g");W=W.replace(H,`url(${Q}/${G})`)}q9(U,W)}}static escapeRegExp($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}static generateS3DeploymentManifest($){let{sourceDir:J,keyPrefix:Y="",excludePatterns:Q=[],cacheControl:Z={hashed:"public, max-age=31536000, immutable",unhashed:"public, max-age=3600",html:"public, max-age=0, must-revalidate"}}=$;return h0.hashDirectory({sourceDir:J,excludePatterns:Q}).assets.map((W)=>{let z=W.hash!=="",G=W.contentType==="text/html",H=Z.unhashed||"public, max-age=3600";if(G)H=Z.html||"public, max-age=0, must-revalidate";else if(z)H=Z.hashed||"public, max-age=31536000, immutable";return{localPath:Z$(J,W.originalPath),s3Key:Y?`${Y}/${W.hashedPath}`:W.hashedPath,contentType:W.contentType,cacheControl:H,hash:W.hash}})}static compareManifests($,J){let Y={added:[],removed:[],changed:[],unchanged:[]},Q=new Set(Object.keys($.hashMap)),Z=new Set(Object.keys(J.hashMap));for(let U of Z)if(!Q.has(U))Y.added.push(U);for(let U of Q)if(!Z.has(U))Y.removed.push(U);for(let U of Z)if(Q.has(U))if($.hashMap[U]!==J.hashMap[U])Y.changed.push(U);else Y.unchanged.push(U);return Y}static loadManifest($){if(!U6($))return null;try{let J=_9($,"utf-8");return JSON.parse(J)}catch{return null}}static saveManifest($,J){q9(J,JSON.stringify($,null,2))}};g2=class g2{static createSecret($){let{slug:J,environment:Y,secretName:Q,description:Z,secretString:U,kmsKeyId:W,tags:z}=$,G=Q||f({slug:J,environment:Y,resourceType:"secret"}),H=S(G),A={Type:"AWS::SecretsManager::Secret",Properties:{Name:G,Description:Z,SecretString:U,Tags:[{Key:"Name",Value:G},{Key:"Environment",Value:Y},...z?Object.entries(z).map(([K,B])=>({Key:K,Value:B})):[]]}};if(W)A.Properties.KmsKeyId=W;return{secret:A,logicalId:H}}static createGeneratedSecret($){let{slug:J,environment:Y,secretName:Q,description:Z,excludeCharacters:U,excludeLowercase:W,excludeNumbers:z,excludePunctuation:G,excludeUppercase:H,passwordLength:A,requireEachIncludedType:K,kmsKeyId:B,tags:j}=$,X=Q||f({slug:J,environment:Y,resourceType:"secret"}),O=S(X),_={Type:"AWS::SecretsManager::Secret",Properties:{Name:X,Description:Z,GenerateSecretString:{ExcludeCharacters:U,ExcludeLowercase:W,ExcludeNumbers:z,ExcludePunctuation:G,ExcludeUppercase:H,PasswordLength:A||32,RequireEachIncludedType:K!==!1},Tags:[{Key:"Name",Value:X},{Key:"Environment",Value:Y},...j?Object.entries(j).map(([w,E])=>({Key:w,Value:E})):[]]}};if(B)_.Properties.KmsKeyId=B;return{secret:_,logicalId:O}}static createDatabaseSecret($){let{slug:J,environment:Y,secretName:Q,username:Z,dbname:U,engine:W,host:z,port:G,kmsKeyId:H}=$,A=Q||f({slug:J,environment:Y,resourceType:"db-secret"}),K=S(A),B={username:Z};if(U)B.dbname=U;if(W)B.engine=W;if(z)B.host=z;if(G)B.port=G;let j={Type:"AWS::SecretsManager::Secret",Properties:{Name:A,Description:`Database credentials for ${Z}`,GenerateSecretString:{SecretStringTemplate:JSON.stringify(B),GenerateStringKey:"password",PasswordLength:32,ExcludeCharacters:'"@/\\',RequireEachIncludedType:!0},Tags:[{Key:"Name",Value:A},{Key:"Environment",Value:Y},{Key:"Type",Value:"database"}]}};if(H)j.Properties.KmsKeyId=H;return{secret:j,logicalId:K}}static attachToDatabase($){let{slug:J,environment:Y,secretId:Q,targetId:Z,targetType:U}=$,W=f({slug:J,environment:Y,resourceType:"secret-attachment"}),z=S(W);return{attachment:{Type:"AWS::SecretsManager::SecretTargetAttachment",Properties:{SecretId:Q,TargetId:Z,TargetType:U}},logicalId:z}}static enableRotation($){let{slug:J,environment:Y,secretId:Q,rotationLambdaArn:Z,automaticallyAfterDays:U,rotationType:W,kmsKeyArn:z,vpcSecurityGroupIds:G,vpcSubnetIds:H}=$,A=f({slug:J,environment:Y,resourceType:"secret-rotation"}),K=S(A),B={Type:"AWS::SecretsManager::RotationSchedule",Properties:{SecretId:Q,RotationRules:{AutomaticallyAfterDays:U||30}}};if(Z)B.Properties.RotationLambdaARN=Z;else if(W)B.Properties.HostedRotationLambda={RotationType:W,KmsKeyArn:z,VpcSecurityGroupIds:G,VpcSubnetIds:H};return{rotation:B,logicalId:K}}static SecretTypes={apiKey:($,J,Y)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-${Y}-api-key`,description:`API key for ${Y}`,passwordLength:32,excludePunctuation:!0,excludeLowercase:!1,excludeUppercase:!1,excludeNumbers:!1})},oauthClientSecret:($,J,Y)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-${Y}-oauth-secret`,description:`OAuth client secret for ${Y}`,passwordLength:64,excludeCharacters:"\"'`\\/@",requireEachIncludedType:!0})},jwtSecret:($,J)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-jwt-secret`,description:"JWT signing secret",passwordLength:64,excludePunctuation:!0})},encryptionKey:($,J)=>{return g2.createGeneratedSecret({slug:$,environment:J,secretName:`${$}-${J}-encryption-key`,description:"Data encryption key",passwordLength:64,excludeCharacters:"+/=",excludePunctuation:!0})}};static RotationTypes={MySQLSingleUser:"MySQLSingleUser",MySQLMultiUser:"MySQLMultiUser",PostgreSQLSingleUser:"PostgreSQLSingleUser",PostgreSQLMultiUser:"PostgreSQLMultiUser",OracleSingleUser:"OracleSingleUser",OracleMultiUser:"OracleMultiUser",MariaDBSingleUser:"MariaDBSingleUser",MariaDBMultiUser:"MariaDBMultiUser",SQLServerSingleUser:"SQLServerSingleUser",SQLServerMultiUser:"SQLServerMultiUser",RedshiftSingleUser:"RedshiftSingleUser",RedshiftMultiUser:"RedshiftMultiUser",MongoDBSingleUser:"MongoDBSingleUser",MongoDBMultiUser:"MongoDBMultiUser"}};D0=class D0{static createParameter($){let{slug:J,environment:Y,parameterName:Q,value:Z,type:U="String",description:W,tier:z="Standard",tags:G}=$,H=Q||f({slug:J,environment:Y,resourceType:"parameter"}),A=S(H);return{parameter:{Type:"AWS::SSM::Parameter",Properties:{Name:`/${J}/${Y}/${H}`,Type:U,Value:Z,Description:W,Tier:z,Tags:{Name:H,Environment:Y,...G}}},logicalId:A}}static createString($,J,Y,Q,Z){return D0.createParameter({slug:$,environment:J,parameterName:Y,value:Q,type:"String",description:Z})}static createSecureString($,J,Y,Q,Z){return D0.createParameter({slug:$,environment:J,parameterName:Y,value:Q,type:"SecureString",description:Z})}static createStringList($,J,Y,Q,Z){return D0.createParameter({slug:$,environment:J,parameterName:Y,value:Q.join(","),type:"StringList",description:Z})}static Parameters={databaseUrl:($,J,Y)=>{return D0.createSecureString($,J,"database-url",Y,"Database connection URL")},apiEndpoint:($,J,Y)=>{return D0.createString($,J,"api-endpoint",Y,"API endpoint URL")},appVersion:($,J,Y)=>{return D0.createString($,J,"app-version",Y,"Application version")},featureFlags:($,J,Y)=>{return D0.createStringList($,J,"feature-flags",Y,"Enabled feature flags")},apiKey:($,J,Y,Q)=>{return D0.createSecureString($,J,`${Y}-api-key`,Q,`API key for ${Y}`)},oauthCredentials:($,J,Y,Q)=>{let Z=D0.createString($,J,"oauth-client-id",Y,"OAuth client ID"),U=D0.createSecureString($,J,"oauth-client-secret",Q,"OAuth client secret");return{clientId:Z,clientSecret:U}},smtpCredentials:($,J,Y,Q,Z,U)=>{let W=D0.createString($,J,"smtp-username",Y,"SMTP username"),z=D0.createSecureString($,J,"smtp-password",Q,"SMTP password"),G=D0.createString($,J,"smtp-host",Z,"SMTP host"),H=D0.createString($,J,"smtp-port",U.toString(),"SMTP port");return{username:W,password:z,host:G,port:H}},redisUrl:($,J,Y)=>{return D0.createSecureString($,J,"redis-url",Y,"Redis connection URL")},s3Bucket:($,J,Y)=>{return D0.createString($,J,"s3-bucket",Y,"S3 bucket name")},cloudFrontDistribution:($,J,Y)=>{return D0.createString($,J,"cloudfront-distribution-id",Y,"CloudFront distribution ID")}}};Y2=class Y2{static createDomain($){let{slug:J,environment:Y,domainName:Q,engineVersion:Z="OpenSearch_2.11",instanceType:U="t3.small.search",instanceCount:W=1,volumeSize:z=10,volumeType:G="gp3",dedicatedMaster:H=!1,dedicatedMasterType:A,dedicatedMasterCount:K=3,multiAz:B=!1,availabilityZoneCount:j=2,vpc:X,encryption:O,enforceHttps:_=!0,tlsSecurityPolicy:w="Policy-Min-TLS-1-2-2019-07",advancedSecurity:E,autoSnapshotHour:M=0,autoTune:T=!0,tags:D={}}=$,N=Q||f({slug:J,environment:Y,resourceType:"search"}),x=S(N);return{domain:{Type:"AWS::OpenSearchService::Domain",Properties:{DomainName:N,EngineVersion:Z,ClusterConfig:{InstanceType:U,InstanceCount:W,DedicatedMasterEnabled:H,...H&&{DedicatedMasterType:A||U,DedicatedMasterCount:K},ZoneAwarenessEnabled:B,...B&&{ZoneAwarenessConfig:{AvailabilityZoneCount:j}}},EBSOptions:{EBSEnabled:!0,VolumeType:G,VolumeSize:z},DomainEndpointOptions:{EnforceHTTPS:_,TLSSecurityPolicy:w},SnapshotOptions:{AutomatedSnapshotStartHour:M},...X&&{VPCOptions:{SubnetIds:X.subnetIds,SecurityGroupIds:X.securityGroupIds}},...O&&{EncryptionAtRestOptions:{Enabled:O.atRest??!0,...O.kmsKeyId&&{KmsKeyId:O.kmsKeyId}},NodeToNodeEncryptionOptions:{Enabled:O.nodeToNode??!0}},...E&&{AdvancedSecurityOptions:{Enabled:E.enabled,InternalUserDatabaseEnabled:E.internalUserDatabase??!0,...E.masterUserName&&E.masterUserPassword&&{MasterUserOptions:{MasterUserName:E.masterUserName,MasterUserPassword:E.masterUserPassword}},...E.masterUserArn&&{MasterUserOptions:{MasterUserARN:E.masterUserArn}}}},...T&&{AutoTuneOptions:{DesiredState:"ENABLED"}},Tags:[{Key:"Name",Value:N},{Key:"Environment",Value:Y},...Object.entries(D).map(([I,b])=>({Key:I,Value:b}))]}},logicalId:x}}static createAccessPolicy($,J){let{ipAddresses:Y,iamPrincipalArns:Q,allowAll:Z,vpcEndpoint:U}=J;if(Z)return{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:$}]};let W=[];if(Q&&Q.length>0)W.push({Effect:"Allow",Principal:{AWS:Q},Action:"es:*",Resource:$});if(Y&&Y.length>0)W.push({Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:$,Condition:{IpAddress:{"aws:SourceIp":Y}}});if(U)return{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:"*"},Action:"es:*",Resource:$}]};return{Version:"2012-10-17",Statement:W}}static DomainPresets={development:($,J)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"t3.small.search",instanceCount:1,volumeSize:10,multiAz:!1,dedicatedMaster:!1,encryption:{atRest:!0,nodeToNode:!0},autoTune:!1})},production:($,J,Y)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"m6g.large.search",instanceCount:3,volumeSize:100,volumeType:"gp3",multiAz:!0,availabilityZoneCount:3,dedicatedMaster:!0,dedicatedMasterType:"m6g.large.search",dedicatedMasterCount:3,vpc:Y,encryption:{atRest:!0,nodeToNode:!0},advancedSecurity:{enabled:!0,internalUserDatabase:!0},autoTune:!0})},costOptimized:($,J)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"t3.medium.search",instanceCount:2,volumeSize:20,volumeType:"gp3",multiAz:!0,dedicatedMaster:!1,encryption:{atRest:!0,nodeToNode:!0},autoTune:!0})},highPerformance:($,J,Y)=>{return Y2.createDomain({slug:$,environment:J,instanceType:"r6g.2xlarge.search",instanceCount:6,volumeSize:500,volumeType:"gp3",multiAz:!0,availabilityZoneCount:3,dedicatedMaster:!0,dedicatedMasterType:"c6g.xlarge.search",dedicatedMasterCount:3,vpc:Y,encryption:{atRest:!0,nodeToNode:!0},advancedSecurity:{enabled:!0,internalUserDatabase:!1},autoTune:!0})}};static InstanceTypes={"t3.small.search":"t3.small.search","t3.medium.search":"t3.medium.search","m6g.large.search":"m6g.large.search","m6g.xlarge.search":"m6g.xlarge.search","m6g.2xlarge.search":"m6g.2xlarge.search","r6g.large.search":"r6g.large.search","r6g.xlarge.search":"r6g.xlarge.search","r6g.2xlarge.search":"r6g.2xlarge.search","r6g.4xlarge.search":"r6g.4xlarge.search","c6g.large.search":"c6g.large.search","c6g.xlarge.search":"c6g.xlarge.search","c6g.2xlarge.search":"c6g.2xlarge.search"};static EngineVersions={"OpenSearch_2.11":"OpenSearch_2.11","OpenSearch_2.9":"OpenSearch_2.9","OpenSearch_2.7":"OpenSearch_2.7","OpenSearch_1.3":"OpenSearch_1.3","Elasticsearch_7.10":"Elasticsearch_7.10"}};c1=class c1{static createDomainRedirectBucket($){let{slug:J,environment:Y,sourceDomain:Q,targetDomain:Z,protocol:U="https"}=$,W=f({slug:J,environment:Y,resourceType:"s3",suffix:"redirect"}),z=S(W),G=S(`${W}-policy`),H={Type:"AWS::S3::Bucket",Properties:{BucketName:Q,WebsiteConfiguration:{RedirectAllRequestsTo:{HostName:Z,Protocol:U}},PublicAccessBlockConfiguration:{BlockPublicAcls:!1,BlockPublicPolicy:!1,IgnorePublicAcls:!1,RestrictPublicBuckets:!1},Tags:[{Key:"Name",Value:W},{Key:"Environment",Value:Y},{Key:"Purpose",Value:"Domain Redirect"}]}},A={Type:"AWS::S3::BucketPolicy",Properties:{Bucket:u.Ref(z),PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"PublicReadForRedirect",Effect:"Allow",Principal:"*",Action:["s3:GetObject"],Resource:[u.Join("",[u.GetAtt(z,"Arn"),"/*"])]}]}}};return{bucket:H,bucketPolicy:A,logicalId:z,policyLogicalId:G}}static createPathRedirectFunction($){let{slug:J,environment:Y,rules:Q}=$,Z=f({slug:J,environment:Y,resourceType:"cf-redirect"}),U=S(Z),W=c1.generateRedirectFunctionCode(Q);return{function:{Type:"AWS::CloudFront::Function",Properties:{Name:Z,AutoPublish:!0,FunctionConfig:{Comment:`Path redirect function for ${J} (${Y})`,Runtime:"cloudfront-js-2.0"},FunctionCode:W}},logicalId:U,functionCode:W}}static generateRedirectFunctionCode($){return`function handler(event) {
5754
5754
  const request = event.request;
5755
5755
  const uri = request.uri;
5756
5756
  const querystring = request.querystring;
@@ -6900,20 +6900,20 @@ async function sendFallbackSms(to, message) {
6900
6900
  `)){let B=K.trim();if(!B||B.startsWith("#")||B.startsWith(";"))continue;let j=B.match(/^\[([^\]]+)\]$/);if(j){if(z===$&&G&&H)return{accessKeyId:G,secretAccessKey:H,sessionToken:A};z=j[1],G=void 0,H=void 0,A=void 0;continue}if(z===$){let[X,...O]=B.split("="),_=O.join("=").trim();switch(X.trim().toLowerCase()){case"aws_access_key_id":G=_;break;case"aws_secret_access_key":H=_;break;case"aws_session_token":A=_;break}}}if(z===$&&G&&H)return{accessKeyId:G,secretAccessKey:H,sessionToken:A};return null}var G5={};Z1(G5,{S3Client:()=>F0});import*as a from"node:crypto";import{readdir as UB}from"node:fs/promises";import{join as WB}from"node:path";import{readFileSync as kZ}from"node:fs";function hZ($){let{buffer:J,byteOffset:Y,byteLength:Q}=$;if(J instanceof ArrayBuffer)return J.slice(Y,Y+Q);let Z=new ArrayBuffer(Q);return new Uint8Array(Z).set(new Uint8Array($)),Z}class F0{client;region;explicitProfile;endpoint;forcePathStyle;explicitCredentials;constructor($="us-east-1",J,Y){this.region=$,this.explicitProfile=J,this.endpoint=Y?.endpoint,this.forcePathStyle=Y?.forcePathStyle,this.explicitCredentials=Y?.credentials,this.client=new t(Y?.credentials??E$(J),{endpoint:Y?.endpoint,forcePathStyle:Y?.forcePathStyle})}getCredentials(){if(this.explicitCredentials?.accessKeyId&&this.explicitCredentials.secretAccessKey)return this.explicitCredentials;let $=E$(this.explicitProfile);if($.accessKeyId&&$.secretAccessKey)return $;throw Error("S3 credentials not found. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (or pass explicit credentials/profile), or configure ~/.aws/credentials.")}s3BaseHost(){return this.endpoint||`s3.${this.region}.amazonaws.com`}s3VirtualHost($){return this.forcePathStyle?this.s3BaseHost():`${$}.${this.s3BaseHost()}`}async listBuckets(){let $=await this.client.request({service:"s3",region:this.region,method:"GET",path:"/"}),J=[],Q=($?.ListAllMyBucketsResult??$)?.Buckets?.Bucket;if(Q){let Z=Array.isArray(Q)?Q:[Q];for(let U of Z)J.push({Name:U.Name,CreationDate:U.CreationDate})}return{Buckets:J}}async createBucket($,J){let Y={};if(J?.acl)Y["x-amz-acl"]=J.acl;let Q;if(this.region!=="us-east-1"&&!this.endpoint)Q=`<?xml version="1.0" encoding="UTF-8"?>
6901
6901
  <CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
6902
6902
  <LocationConstraint>${this.region}</LocationConstraint>
6903
- </CreateBucketConfiguration>`,Y["Content-Type"]="application/xml";await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$}`,headers:Y,body:Q})}async deleteBucket($){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}`})}async emptyAndDeleteBucket($){let J=!0;while(J){let Y=await this.listAllObjects({bucket:$});if(Y.length===0){J=!1;break}let Q=Y.map((Z)=>Z.Key);for(let Z=0;Z<Q.length;Z+=1000){let U=Q.slice(Z,Z+1000);await this.deleteObjects($,U)}}await this.deleteBucket($)}async listAllObjects($){let J=[],Y;do{let Q={"list-type":"2","max-keys":"1000"};if($.prefix)Q.prefix=$.prefix;if(Y)Q["continuation-token"]=Y;let Z=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$.bucket}`,queryParams:Q}),U=Z?.ListBucketResult??Z,W=U?.Contents;if(W){let G=Array.isArray(W)?W:[W];for(let H of G)J.push({Key:H.Key,LastModified:H.LastModified||"",Size:Number.parseInt(H.Size||"0"),ETag:H.ETag})}let z=U?.IsTruncated;Y=z==="true"||z===!0?U?.NextContinuationToken:void 0}while(Y);return J}async list($){let J=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$.bucket}`}),Y=[],Z=(J?.ListBucketResult??J)?.Contents;if(Z){let U=Array.isArray(Z)?Z:[Z];for(let W of U){if($.prefix&&!W.Key?.startsWith($.prefix))continue;if(Y.push({Key:W.Key||"",LastModified:W.LastModified||"",Size:Number.parseInt(W.Size||"0"),ETag:W.ETag}),$.maxKeys&&Y.length>=$.maxKeys)break}}return Y}async putObject($){let J={};if($.acl)J["x-amz-acl"]=$.acl;if($.cacheControl)J["Cache-Control"]=$.cacheControl;if($.contentType)J["Content-Type"]=$.contentType;if($.metadata)for(let[Q,Z]of Object.entries($.metadata))J[`x-amz-meta-${Q}`]=Z;let Y=$.body instanceof Uint8Array&&!Buffer.isBuffer($.body)?Buffer.from($.body):$.body;if(Buffer.isBuffer(Y)||Y instanceof Uint8Array){let Q=Buffer.isBuffer(Y)?Y:Buffer.from(Y),{accessKeyId:Z,secretAccessKey:U,sessionToken:W}=this.getCredentials(),z=this.s3VirtualHost($.bucket),G=`https://${z}/${$.key}`,H=new Date,A=H.toISOString().replace(/[:-]|\.\d{3}/g,""),K=H.toISOString().slice(0,10).replace(/-/g,""),B=a.createHash("sha256").update(Q).digest("hex"),j={host:z,"x-amz-date":A,"x-amz-content-sha256":B,...J};if(W)j["x-amz-security-token"]=W;let X=Object.keys(j).sort().map((I)=>`${I.toLowerCase()}:${j[I].trim()}
6904
- `).join(""),O=Object.keys(j).sort().map((I)=>I.toLowerCase()).join(";"),_=["PUT",`/${$.key}`,"",X,O,B].join(`
6905
- `),w="AWS4-HMAC-SHA256",E=`${K}/${this.region}/s3/aws4_request`,M=[w,A,E,a.createHash("sha256").update(_).digest("hex")].join(`
6906
- `),T=a.createHmac("sha256",`AWS4${U}`).update(K).digest(),D=a.createHmac("sha256",T).update(this.region).digest(),N=a.createHmac("sha256",D).update("s3").digest(),x=a.createHmac("sha256",N).update("aws4_request").digest(),h=a.createHmac("sha256",x).update(M).digest("hex"),k=`${w} Credential=${Z}/${E}, SignedHeaders=${O}, Signature=${h}`,b=await fetch(G,{method:"PUT",headers:{...j,Authorization:k},body:hZ(Q)});if(!b.ok){let I=await b.text();throw Error(`S3 PUT failed: ${b.status} ${I}`)}return}await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$.key}`,bucket:$.bucket,headers:J,body:$.body})}async getObject($,J){return await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$}/${J}`,rawResponse:!0})}async copyObject($){let J={"x-amz-copy-source":`/${$.sourceBucket}/${$.sourceKey}`};if($.metadataDirective)J["x-amz-metadata-directive"]=$.metadataDirective;if($.contentType)J["Content-Type"]=$.contentType;if($.metadata)for(let[Y,Q]of Object.entries($.metadata))J[`x-amz-meta-${Y}`]=Q;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$.destinationBucket}/${$.destinationKey}`,headers:J})}async deleteObject($,J){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}/${J}`})}async deleteObjects($,J){let Y=`<?xml version="1.0" encoding="UTF-8"?>
6903
+ </CreateBucketConfiguration>`,Y["Content-Type"]="application/xml";await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$}`,headers:Y,body:Q})}async deleteBucket($){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}`})}async emptyAndDeleteBucket($){let J=!0;while(J){let Y=await this.listAllObjects({bucket:$});if(Y.length===0){J=!1;break}let Q=Y.map((Z)=>Z.Key);for(let Z=0;Z<Q.length;Z+=1000){let U=Q.slice(Z,Z+1000);await this.deleteObjects($,U)}}await this.deleteBucket($)}async listAllObjects($){let J=[],Y;do{let Q={"list-type":"2","max-keys":"1000"};if($.prefix)Q.prefix=$.prefix;if(Y)Q["continuation-token"]=Y;let Z=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$.bucket}`,queryParams:Q}),U=Z?.ListBucketResult??Z,W=U?.Contents;if(W){let G=Array.isArray(W)?W:[W];for(let H of G)J.push({Key:H.Key,LastModified:H.LastModified||"",Size:Number.parseInt(H.Size||"0"),ETag:H.ETag})}let z=U?.IsTruncated;Y=z==="true"||z===!0?U?.NextContinuationToken:void 0}while(Y);return J}async list($){let J=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$.bucket}`}),Y=[],Z=(J?.ListBucketResult??J)?.Contents;if(Z){let U=Array.isArray(Z)?Z:[Z];for(let W of U){if($.prefix&&!W.Key?.startsWith($.prefix))continue;if(Y.push({Key:W.Key||"",LastModified:W.LastModified||"",Size:Number.parseInt(W.Size||"0"),ETag:W.ETag}),$.maxKeys&&Y.length>=$.maxKeys)break}}return Y}async putObject($){let J={};if($.acl)J["x-amz-acl"]=$.acl;if($.cacheControl)J["Cache-Control"]=$.cacheControl;if($.contentType)J["Content-Type"]=$.contentType;if($.metadata)for(let[Z,U]of Object.entries($.metadata))J[`x-amz-meta-${Z}`]=U;let Y=$.key.split("/").map((Z)=>encodeURIComponent(Z)).join("/"),Q=$.body instanceof Uint8Array&&!Buffer.isBuffer($.body)?Buffer.from($.body):$.body;if(Buffer.isBuffer(Q)||Q instanceof Uint8Array){let Z=Buffer.isBuffer(Q)?Q:Buffer.from(Q),{accessKeyId:U,secretAccessKey:W,sessionToken:z}=this.getCredentials(),G=this.s3VirtualHost($.bucket),H=`https://${G}/${Y}`,A=new Date,K=A.toISOString().replace(/[:-]|\.\d{3}/g,""),B=A.toISOString().slice(0,10).replace(/-/g,""),j=a.createHash("sha256").update(Z).digest("hex"),X={host:G,"x-amz-date":K,"x-amz-content-sha256":j,...J};if(z)X["x-amz-security-token"]=z;let O=Object.keys(X).sort().map((y)=>`${y.toLowerCase()}:${X[y].trim()}
6904
+ `).join(""),_=Object.keys(X).sort().map((y)=>y.toLowerCase()).join(";"),w=["PUT",`/${Y}`,"",O,_,j].join(`
6905
+ `),E="AWS4-HMAC-SHA256",M=`${B}/${this.region}/s3/aws4_request`,T=[E,K,M,a.createHash("sha256").update(w).digest("hex")].join(`
6906
+ `),D=a.createHmac("sha256",`AWS4${W}`).update(B).digest(),N=a.createHmac("sha256",D).update(this.region).digest(),x=a.createHmac("sha256",N).update("s3").digest(),h=a.createHmac("sha256",x).update("aws4_request").digest(),I=a.createHmac("sha256",h).update(T).digest("hex"),b=`${E} Credential=${U}/${M}, SignedHeaders=${_}, Signature=${I}`,k=await fetch(H,{method:"PUT",headers:{...X,Authorization:b},body:hZ(Z)});if(!k.ok){let y=await k.text();throw Error(`S3 PUT failed: ${k.status} ${y}`)}return}await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${Y}`,bucket:$.bucket,headers:J,body:$.body})}async getObject($,J){let Y=J.split("/").map((Z)=>encodeURIComponent(Z)).join("/");return await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$}/${Y}`,rawResponse:!0})}async copyObject($){let J={"x-amz-copy-source":`/${$.sourceBucket}/${$.sourceKey}`};if($.metadataDirective)J["x-amz-metadata-directive"]=$.metadataDirective;if($.contentType)J["Content-Type"]=$.contentType;if($.metadata)for(let[Y,Q]of Object.entries($.metadata))J[`x-amz-meta-${Y}`]=Q;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$.destinationBucket}/${$.destinationKey}`,headers:J})}async deleteObject($,J){let Y=J.split("/").map((Q)=>encodeURIComponent(Q)).join("/");await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}/${Y}`})}async deleteObjects($,J){let Y=`<?xml version="1.0" encoding="UTF-8"?>
6907
6907
  <Delete>
6908
6908
  ${J.map((Z)=>`<Object><Key>${Z}</Key></Object>`).join(`
6909
6909
  `)}
6910
- </Delete>`,Q=a.createHash("md5").update(Y).digest("base64");await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${$}`,queryParams:{delete:""},body:Y,headers:{"Content-Type":"application/xml","Content-MD5":Q}})}async bucketExists($){try{return await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${$}`}),!0}catch{return!1}}async copy($){let J=kZ($.source);await this.putObject({bucket:$.bucket,key:$.key,body:J,acl:$.acl,cacheControl:$.cacheControl,contentType:$.contentType,metadata:$.metadata})}async sync($){let J=await this.listFilesRecursive($.source);for(let Y of J){if($.exclude&&$.exclude.some((U)=>Y.includes(U)))continue;if($.include&&!$.include.some((U)=>Y.includes(U)))continue;let Q=Y.substring($.source.length+1),Z=$.prefix?`${$.prefix}/${Q}`:Q;if(!$.dryRun){let U=kZ(Y);await this.putObject({bucket:$.bucket,key:Z,body:U,acl:$.acl,cacheControl:$.cacheControl,contentType:$.contentType,metadata:$.metadata})}}}async delete($,J){await this.deleteObject($,J)}async deletePrefix($,J){let Q=(await this.list({bucket:$,prefix:J})).map((Z)=>Z.Key);if(Q.length>0)await this.deleteObjects($,Q)}async getBucketSize($,J){return(await this.list({bucket:$,prefix:J})).reduce((Q,Z)=>Q+Z.Size,0)}async listFilesRecursive($){let J=[],Y=await UB($,{withFileTypes:!0});for(let Q of Y){let Z=WB($,Q.name);if(Q.isDirectory()){let U=await this.listFilesRecursive(Z);J.push(...U)}else J.push(Z)}return J}async putBucketPolicy($,J){let{accessKeyId:Y,secretAccessKey:Q,sessionToken:Z}=this.getCredentials(),U=this.s3BaseHost(),W=typeof J==="string"?J:JSON.stringify(J),z=new Date,G=z.toISOString().replace(/[:-]|\.\d{3}/g,""),H=z.toISOString().slice(0,10).replace(/-/g,""),A=a.createHash("sha256").update(W).digest("hex"),K="/"+$,B="policy=",j={host:U,"x-amz-date":G,"x-amz-content-sha256":A,"content-type":"application/json"};if(Z)j["x-amz-security-token"]=Z;let X=Object.keys(j).sort().map((f)=>`${f.toLowerCase()}:${j[f].trim()}
6911
- `).join(""),O=Object.keys(j).sort().map((f)=>f.toLowerCase()).join(";"),_=["PUT",K,"policy=",X,O,A].join(`
6910
+ </Delete>`,Q=a.createHash("md5").update(Y).digest("base64");await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${$}`,queryParams:{delete:""},body:Y,headers:{"Content-Type":"application/xml","Content-MD5":Q}})}async bucketExists($){try{return await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${$}`}),!0}catch{return!1}}async copy($){let J=kZ($.source);await this.putObject({bucket:$.bucket,key:$.key,body:J,acl:$.acl,cacheControl:$.cacheControl,contentType:$.contentType,metadata:$.metadata})}async sync($){let J=await this.listFilesRecursive($.source);for(let Y of J){if($.exclude&&$.exclude.some((U)=>Y.includes(U)))continue;if($.include&&!$.include.some((U)=>Y.includes(U)))continue;let Q=Y.substring($.source.length+1),Z=$.prefix?`${$.prefix}/${Q}`:Q;if(!$.dryRun){let U=kZ(Y);await this.putObject({bucket:$.bucket,key:Z,body:U,acl:$.acl,cacheControl:$.cacheControl,contentType:$.contentType,metadata:$.metadata})}}}async delete($,J){await this.deleteObject($,J)}async deletePrefix($,J){let Q=(await this.list({bucket:$,prefix:J})).map((Z)=>Z.Key);if(Q.length>0)await this.deleteObjects($,Q)}async getBucketSize($,J){return(await this.list({bucket:$,prefix:J})).reduce((Q,Z)=>Q+Z.Size,0)}async listFilesRecursive($){let J=[],Y=await UB($,{withFileTypes:!0});for(let Q of Y){let Z=WB($,Q.name);if(Q.isDirectory()){let U=await this.listFilesRecursive(Z);J.push(...U)}else J.push(Z)}return J}async putBucketPolicy($,J){let{accessKeyId:Y,secretAccessKey:Q,sessionToken:Z}=this.getCredentials(),U=this.s3BaseHost(),W=typeof J==="string"?J:JSON.stringify(J),z=new Date,G=z.toISOString().replace(/[:-]|\.\d{3}/g,""),H=z.toISOString().slice(0,10).replace(/-/g,""),A=a.createHash("sha256").update(W).digest("hex"),K="/"+$,B="policy=",j={host:U,"x-amz-date":G,"x-amz-content-sha256":A,"content-type":"application/json"};if(Z)j["x-amz-security-token"]=Z;let X=Object.keys(j).sort().map((y)=>`${y.toLowerCase()}:${j[y].trim()}
6911
+ `).join(""),O=Object.keys(j).sort().map((y)=>y.toLowerCase()).join(";"),_=["PUT",K,"policy=",X,O,A].join(`
6912
6912
  `),w="AWS4-HMAC-SHA256",E=`${H}/${this.region}/s3/aws4_request`,M=[w,G,E,a.createHash("sha256").update(_).digest("hex")].join(`
6913
- `),T=a.createHmac("sha256","AWS4"+Q).update(H).digest(),D=a.createHmac("sha256",T).update(this.region).digest(),N=a.createHmac("sha256",D).update("s3").digest(),x=a.createHmac("sha256",N).update("aws4_request").digest(),h=a.createHmac("sha256",x).update(M).digest("hex"),k=`${w} Credential=${Y}/${E}, SignedHeaders=${O}, Signature=${h}`,b=`https://${U}${K}?policy=`,I=await fetch(b,{method:"PUT",headers:{...j,Authorization:k},body:W});if(!I.ok){let f=await I.text();throw Error(`Failed to put bucket policy: ${I.status} ${f}`)}}async getBucketPolicy($){let{accessKeyId:J,secretAccessKey:Y,sessionToken:Q}=this.getCredentials(),Z=this.s3BaseHost(),U=new Date,W=U.toISOString().replace(/[:-]|\.\d{3}/g,""),z=U.toISOString().slice(0,10).replace(/-/g,""),G=a.createHash("sha256").update("").digest("hex"),H="/"+$,A="policy=",K={host:Z,"x-amz-date":W,"x-amz-content-sha256":G};if(Q)K["x-amz-security-token"]=Q;let B=Object.keys(K).sort().map((I)=>`${I.toLowerCase()}:${K[I].trim()}
6914
- `).join(""),j=Object.keys(K).sort().map((I)=>I.toLowerCase()).join(";"),X=["GET",H,"policy=",B,j,G].join(`
6913
+ `),T=a.createHmac("sha256","AWS4"+Q).update(H).digest(),D=a.createHmac("sha256",T).update(this.region).digest(),N=a.createHmac("sha256",D).update("s3").digest(),x=a.createHmac("sha256",N).update("aws4_request").digest(),h=a.createHmac("sha256",x).update(M).digest("hex"),I=`${w} Credential=${Y}/${E}, SignedHeaders=${O}, Signature=${h}`,b=`https://${U}${K}?policy=`,k=await fetch(b,{method:"PUT",headers:{...j,Authorization:I},body:W});if(!k.ok){let y=await k.text();throw Error(`Failed to put bucket policy: ${k.status} ${y}`)}}async getBucketPolicy($){let{accessKeyId:J,secretAccessKey:Y,sessionToken:Q}=this.getCredentials(),Z=this.s3BaseHost(),U=new Date,W=U.toISOString().replace(/[:-]|\.\d{3}/g,""),z=U.toISOString().slice(0,10).replace(/-/g,""),G=a.createHash("sha256").update("").digest("hex"),H="/"+$,A="policy=",K={host:Z,"x-amz-date":W,"x-amz-content-sha256":G};if(Q)K["x-amz-security-token"]=Q;let B=Object.keys(K).sort().map((k)=>`${k.toLowerCase()}:${K[k].trim()}
6914
+ `).join(""),j=Object.keys(K).sort().map((k)=>k.toLowerCase()).join(";"),X=["GET",H,"policy=",B,j,G].join(`
6915
6915
  `),O="AWS4-HMAC-SHA256",_=`${z}/${this.region}/s3/aws4_request`,w=[O,W,_,a.createHash("sha256").update(X).digest("hex")].join(`
6916
- `),E=a.createHmac("sha256","AWS4"+Y).update(z).digest(),M=a.createHmac("sha256",E).update(this.region).digest(),T=a.createHmac("sha256",M).update("s3").digest(),D=a.createHmac("sha256",T).update("aws4_request").digest(),N=a.createHmac("sha256",D).update(w).digest("hex"),x=`${O} Credential=${J}/${_}, SignedHeaders=${j}, Signature=${N}`,h=`https://${Z}${H}?policy=`,k=await fetch(h,{method:"GET",headers:{...K,Authorization:x}});if(k.status===404)return null;if(!k.ok){let I=await k.text();throw Error(`Failed to get bucket policy: ${k.status} ${I}`)}let b=await k.text();return JSON.parse(b)}async deleteBucketPolicy($){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}`,queryParams:{policy:""}})}async headBucket($){try{return{exists:!0,region:(await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${$}`,returnHeaders:!0}))?.headers?.["x-amz-bucket-region"]}}catch(J){if(J.statusCode===404)return{exists:!1};throw J}}async headObject($,J){try{let Y=await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${$}/${J}`,returnHeaders:!0});return{ContentLength:Y?.headers?.["content-length"]?parseInt(Y.headers["content-length"]):void 0,ContentType:Y?.headers?.["content-type"],ETag:Y?.headers?.etag,LastModified:Y?.headers?.["last-modified"]}}catch(Y){if(Y.statusCode===404)return null;throw Y}}async getObjectBuffer($,J){let Y=await this.getObject($,J);return Buffer.from(Y)}async getObjectJson($,J){let Y=await this.getObject($,J);return JSON.parse(Y)}async putObjectJson($,J,Y,Q){await this.putObject({bucket:$,key:J,body:JSON.stringify(Y),contentType:"application/json",...Q})}async getBucketVersioning($){return{Status:(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$}`,queryParams:{versioning:""}}))?.VersioningConfiguration?.Status}}async putBucketVersioning($,J){let Y=`<?xml version="1.0" encoding="UTF-8"?>
6916
+ `),E=a.createHmac("sha256","AWS4"+Y).update(z).digest(),M=a.createHmac("sha256",E).update(this.region).digest(),T=a.createHmac("sha256",M).update("s3").digest(),D=a.createHmac("sha256",T).update("aws4_request").digest(),N=a.createHmac("sha256",D).update(w).digest("hex"),x=`${O} Credential=${J}/${_}, SignedHeaders=${j}, Signature=${N}`,h=`https://${Z}${H}?policy=`,I=await fetch(h,{method:"GET",headers:{...K,Authorization:x}});if(I.status===404)return null;if(!I.ok){let k=await I.text();throw Error(`Failed to get bucket policy: ${I.status} ${k}`)}let b=await I.text();return JSON.parse(b)}async deleteBucketPolicy($){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}`,queryParams:{policy:""}})}async headBucket($){try{return{exists:!0,region:(await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${$}`,returnHeaders:!0}))?.headers?.["x-amz-bucket-region"]}}catch(J){if(J.statusCode===404)return{exists:!1};throw J}}async headObject($,J){try{let Y=await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${$}/${J}`,returnHeaders:!0});return{ContentLength:Y?.headers?.["content-length"]?parseInt(Y.headers["content-length"]):void 0,ContentType:Y?.headers?.["content-type"],ETag:Y?.headers?.etag,LastModified:Y?.headers?.["last-modified"]}}catch(Y){if(Y.statusCode===404)return null;throw Y}}async getObjectBuffer($,J){let Y=await this.getObject($,J);return Buffer.from(Y)}async getObjectJson($,J){let Y=await this.getObject($,J);return JSON.parse(Y)}async putObjectJson($,J,Y,Q){await this.putObject({bucket:$,key:J,body:JSON.stringify(Y),contentType:"application/json",...Q})}async getBucketVersioning($){return{Status:(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$}`,queryParams:{versioning:""}}))?.VersioningConfiguration?.Status}}async putBucketVersioning($,J){let Y=`<?xml version="1.0" encoding="UTF-8"?>
6917
6917
  <VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
6918
6918
  <Status>${J}</Status>
6919
6919
  </VersioningConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$}`,queryParams:{versioning:""},headers:{"Content-Type":"application/xml"},body:Y})}async getBucketLifecycleConfiguration($){try{return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$}`,queryParams:{lifecycle:""}}))?.LifecycleConfiguration}catch(J){if(J.statusCode===404)return null;throw J}}async putBucketLifecycleConfiguration($,J){let Q=`<?xml version="1.0" encoding="UTF-8"?>
@@ -6952,17 +6952,17 @@ async function sendFallbackSms(to, message) {
6952
6952
  <IgnorePublicAcls>${J.IgnorePublicAcls??!0}</IgnorePublicAcls>
6953
6953
  <BlockPublicPolicy>${J.BlockPublicPolicy??!0}</BlockPublicPolicy>
6954
6954
  <RestrictPublicBuckets>${J.RestrictPublicBuckets??!0}</RestrictPublicBuckets>
6955
- </PublicAccessBlockConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$}`,queryParams:{publicAccessBlock:""},headers:{"Content-Type":"application/xml"},body:Y})}async deletePublicAccessBlock($){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}`,queryParams:{publicAccessBlock:""}})}generatePresignedGetUrl($,J,Y=3600){let{accessKeyId:Q,secretAccessKey:Z}=this.getCredentials(),U=this.s3VirtualHost($),W=new Date,z=W.toISOString().replace(/[:-]|\.\d{3}/g,""),G=W.toISOString().slice(0,10).replace(/-/g,""),H=`${G}/${this.region}/s3/aws4_request`,A=`${Q}/${H}`,K=new URLSearchParams({"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":A,"X-Amz-Date":z,"X-Amz-Expires":Y.toString(),"X-Amz-SignedHeaders":"host"}),B=["GET",`/${J}`,K.toString(),`host:${U}
6955
+ </PublicAccessBlockConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${$}`,queryParams:{publicAccessBlock:""},headers:{"Content-Type":"application/xml"},body:Y})}async deletePublicAccessBlock($){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}`,queryParams:{publicAccessBlock:""}})}generatePresignedGetUrl($,J,Y=3600){let{accessKeyId:Q,secretAccessKey:Z}=this.getCredentials(),U=this.s3VirtualHost($),W=new Date,z=W.toISOString().replace(/[:-]|\.\d{3}/g,""),G=W.toISOString().slice(0,10).replace(/-/g,""),H=`${G}/${this.region}/s3/aws4_request`,A=`${Q}/${H}`,K=J.split("/").map((T)=>encodeURIComponent(T)).join("/"),B=new URLSearchParams({"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":A,"X-Amz-Date":z,"X-Amz-Expires":Y.toString(),"X-Amz-SignedHeaders":"host"}),j=["GET",`/${K}`,B.toString(),`host:${U}
6956
6956
  `,"host","UNSIGNED-PAYLOAD"].join(`
6957
- `),j=["AWS4-HMAC-SHA256",z,H,a.createHash("sha256").update(B).digest("hex")].join(`
6958
- `),X=a.createHmac("sha256",`AWS4${Z}`).update(G).digest(),O=a.createHmac("sha256",X).update(this.region).digest(),_=a.createHmac("sha256",O).update("s3").digest(),w=a.createHmac("sha256",_).update("aws4_request").digest(),E=a.createHmac("sha256",w).update(j).digest("hex");return K.append("X-Amz-Signature",E),`https://${U}/${J}?${K.toString()}`}generatePresignedPutUrl($,J,Y,Q=3600){let{accessKeyId:Z,secretAccessKey:U}=this.getCredentials(),W=this.s3VirtualHost($),z=new Date,G=z.toISOString().replace(/[:-]|\.\d{3}/g,""),H=z.toISOString().slice(0,10).replace(/-/g,""),A=`${H}/${this.region}/s3/aws4_request`,K=`${Z}/${A}`,B=new URLSearchParams({"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":K,"X-Amz-Date":G,"X-Amz-Expires":Q.toString(),"X-Amz-SignedHeaders":"content-type;host"}),j=["PUT",`/${J}`,B.toString(),`content-type:${Y}
6957
+ `),X=["AWS4-HMAC-SHA256",z,H,a.createHash("sha256").update(j).digest("hex")].join(`
6958
+ `),O=a.createHmac("sha256",`AWS4${Z}`).update(G).digest(),_=a.createHmac("sha256",O).update(this.region).digest(),w=a.createHmac("sha256",_).update("s3").digest(),E=a.createHmac("sha256",w).update("aws4_request").digest(),M=a.createHmac("sha256",E).update(X).digest("hex");return B.append("X-Amz-Signature",M),`https://${U}/${K}?${B.toString()}`}generatePresignedPutUrl($,J,Y,Q=3600){let{accessKeyId:Z,secretAccessKey:U}=this.getCredentials(),W=this.s3VirtualHost($),z=new Date,G=z.toISOString().replace(/[:-]|\.\d{3}/g,""),H=z.toISOString().slice(0,10).replace(/-/g,""),A=`${H}/${this.region}/s3/aws4_request`,K=`${Z}/${A}`,B=J.split("/").map((D)=>encodeURIComponent(D)).join("/"),j=new URLSearchParams({"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":K,"X-Amz-Date":G,"X-Amz-Expires":Q.toString(),"X-Amz-SignedHeaders":"content-type;host"}),X=["PUT",`/${B}`,j.toString(),`content-type:${Y}
6959
6959
  host:${W}
6960
6960
  `,"content-type;host","UNSIGNED-PAYLOAD"].join(`
6961
- `),X=["AWS4-HMAC-SHA256",G,A,a.createHash("sha256").update(j).digest("hex")].join(`
6962
- `),O=a.createHmac("sha256",`AWS4${U}`).update(H).digest(),_=a.createHmac("sha256",O).update(this.region).digest(),w=a.createHmac("sha256",_).update("s3").digest(),E=a.createHmac("sha256",w).update("aws4_request").digest(),M=a.createHmac("sha256",E).update(X).digest("hex");return B.append("X-Amz-Signature",M),`https://${W}/${J}?${B.toString()}`}async createMultipartUpload($,J,Y){let Q={};if(Y?.contentType)Q["Content-Type"]=Y.contentType;if(Y?.metadata)for(let[U,W]of Object.entries(Y.metadata))Q[`x-amz-meta-${U}`]=W;return{UploadId:(await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${$}/${J}`,queryParams:{uploads:""},headers:Q}))?.InitiateMultipartUploadResult?.UploadId}}async uploadPart($,J,Y,Q,Z){let{accessKeyId:U,secretAccessKey:W,sessionToken:z}=this.getCredentials(),G=this.s3VirtualHost($),H=`https://${G}/${J}?partNumber=${Q}&uploadId=${encodeURIComponent(Y)}`,A=new Date,K=A.toISOString().replace(/[:-]|\.\d{3}/g,""),B=A.toISOString().slice(0,10).replace(/-/g,""),j=a.createHash("sha256").update(Z).digest("hex"),X={host:G,"x-amz-date":K,"x-amz-content-sha256":j};if(z)X["x-amz-security-token"]=z;let O=Object.keys(X).sort().map((f)=>`${f.toLowerCase()}:${X[f].trim()}
6963
- `).join(""),_=Object.keys(X).sort().map((f)=>f.toLowerCase()).join(";"),w=["PUT",`/${J}`,`partNumber=${Q}&uploadId=${encodeURIComponent(Y)}`,O,_,j].join(`
6961
+ `),O=["AWS4-HMAC-SHA256",G,A,a.createHash("sha256").update(X).digest("hex")].join(`
6962
+ `),_=a.createHmac("sha256",`AWS4${U}`).update(H).digest(),w=a.createHmac("sha256",_).update(this.region).digest(),E=a.createHmac("sha256",w).update("s3").digest(),M=a.createHmac("sha256",E).update("aws4_request").digest(),T=a.createHmac("sha256",M).update(O).digest("hex");return j.append("X-Amz-Signature",T),`https://${W}/${B}?${j.toString()}`}async createMultipartUpload($,J,Y){let Q={};if(Y?.contentType)Q["Content-Type"]=Y.contentType;if(Y?.metadata)for(let[U,W]of Object.entries(Y.metadata))Q[`x-amz-meta-${U}`]=W;return{UploadId:(await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${$}/${J}`,queryParams:{uploads:""},headers:Q}))?.InitiateMultipartUploadResult?.UploadId}}async uploadPart($,J,Y,Q,Z){let{accessKeyId:U,secretAccessKey:W,sessionToken:z}=this.getCredentials(),G=this.s3VirtualHost($),H=`https://${G}/${J}?partNumber=${Q}&uploadId=${encodeURIComponent(Y)}`,A=new Date,K=A.toISOString().replace(/[:-]|\.\d{3}/g,""),B=A.toISOString().slice(0,10).replace(/-/g,""),j=a.createHash("sha256").update(Z).digest("hex"),X={host:G,"x-amz-date":K,"x-amz-content-sha256":j};if(z)X["x-amz-security-token"]=z;let O=Object.keys(X).sort().map((y)=>`${y.toLowerCase()}:${X[y].trim()}
6963
+ `).join(""),_=Object.keys(X).sort().map((y)=>y.toLowerCase()).join(";"),w=["PUT",`/${J}`,`partNumber=${Q}&uploadId=${encodeURIComponent(Y)}`,O,_,j].join(`
6964
6964
  `),E="AWS4-HMAC-SHA256",M=`${B}/${this.region}/s3/aws4_request`,T=[E,K,M,a.createHash("sha256").update(w).digest("hex")].join(`
6965
- `),D=a.createHmac("sha256",`AWS4${W}`).update(B).digest(),N=a.createHmac("sha256",D).update(this.region).digest(),x=a.createHmac("sha256",N).update("s3").digest(),h=a.createHmac("sha256",x).update("aws4_request").digest(),k=a.createHmac("sha256",h).update(T).digest("hex"),b=`${E} Credential=${U}/${M}, SignedHeaders=${_}, Signature=${k}`,I=await fetch(H,{method:"PUT",headers:{...X,Authorization:b},body:hZ(Z)});if(!I.ok){let f=await I.text();throw Error(`Upload part failed: ${I.status} ${f}`)}return{ETag:I.headers.get("etag")||""}}async completeMultipartUpload($,J,Y,Q){let U=`<?xml version="1.0" encoding="UTF-8"?>
6965
+ `),D=a.createHmac("sha256",`AWS4${W}`).update(B).digest(),N=a.createHmac("sha256",D).update(this.region).digest(),x=a.createHmac("sha256",N).update("s3").digest(),h=a.createHmac("sha256",x).update("aws4_request").digest(),I=a.createHmac("sha256",h).update(T).digest("hex"),b=`${E} Credential=${U}/${M}, SignedHeaders=${_}, Signature=${I}`,k=await fetch(H,{method:"PUT",headers:{...X,Authorization:b},body:hZ(Z)});if(!k.ok){let y=await k.text();throw Error(`Upload part failed: ${k.status} ${y}`)}return{ETag:k.headers.get("etag")||""}}async completeMultipartUpload($,J,Y,Q){let U=`<?xml version="1.0" encoding="UTF-8"?>
6966
6966
  <CompleteMultipartUpload>${Q.sort((W,z)=>W.PartNumber-z.PartNumber).map((W)=>`<Part><PartNumber>${W.PartNumber}</PartNumber><ETag>${W.ETag}</ETag></Part>`).join("")}</CompleteMultipartUpload>`;await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${$}/${J}`,queryParams:{uploadId:Y},headers:{"Content-Type":"application/xml"},body:U})}async abortMultipartUpload($,J,Y){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${$}/${J}`,queryParams:{uploadId:Y}})}async listMultipartUploads($){let Y=(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${$}`,queryParams:{uploads:""}}))?.ListMultipartUploadsResult?.Upload;if(!Y)return[];return(Array.isArray(Y)?Y:[Y]).map((Z)=>({Key:Z.Key,UploadId:Z.UploadId,Initiated:Z.Initiated}))}async restoreObject($,J,Y,Q="Standard"){let Z=`<?xml version="1.0" encoding="UTF-8"?>
6967
6967
  <RestoreRequest>
6968
6968
  <Days>${Y}</Days>
@@ -6975,10 +6975,10 @@ host:${W}
6975
6975
  <ExpressionType>SQL</ExpressionType>
6976
6976
  <InputSerialization>${U}</InputSerialization>
6977
6977
  <OutputSerialization>${W}</OutputSerialization>
6978
- </SelectObjectContentRequest>`;return await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${$}/${J}`,queryParams:{select:"","select-type":"2"},headers:{"Content-Type":"application/xml"},body:z,rawResponse:!0})}async getSignedUrl($){let{bucket:J,key:Y,expiresIn:Q=3600,operation:Z="getObject"}=$,{accessKeyId:U,secretAccessKey:W,sessionToken:z}=this.getCredentials(),G=new Date,H=G.toISOString().replace(/[:-]|\.\d{3}/g,""),A=G.toISOString().slice(0,10).replace(/-/g,""),K=this.s3VirtualHost(J),B=Z==="putObject"?"PUT":"GET",j="AWS4-HMAC-SHA256",X=`${A}/${this.region}/s3/aws4_request`,_={"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":`${U}/${X}`,"X-Amz-Date":H,"X-Amz-Expires":Q.toString(),"X-Amz-SignedHeaders":"host"};if(z)_["X-Amz-Security-Token"]=z;let E=Object.keys(_).sort().map((p)=>`${encodeURIComponent(p)}=${encodeURIComponent(_[p])}`).join("&"),M="/"+Y,T=`host:${K}
6978
+ </SelectObjectContentRequest>`;return await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${$}/${J}`,queryParams:{select:"","select-type":"2"},headers:{"Content-Type":"application/xml"},body:z,rawResponse:!0})}async getSignedUrl($){let{bucket:J,key:Y,expiresIn:Q=3600,operation:Z="getObject"}=$,{accessKeyId:U,secretAccessKey:W,sessionToken:z}=this.getCredentials(),G=new Date,H=G.toISOString().replace(/[:-]|\.\d{3}/g,""),A=G.toISOString().slice(0,10).replace(/-/g,""),K=this.s3VirtualHost(J),B=Z==="putObject"?"PUT":"GET",j="AWS4-HMAC-SHA256",X=`${A}/${this.region}/s3/aws4_request`,_={"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":`${U}/${X}`,"X-Amz-Date":H,"X-Amz-Expires":Q.toString(),"X-Amz-SignedHeaders":"host"};if(z)_["X-Amz-Security-Token"]=z;let E=Object.keys(_).sort().map((p)=>`${encodeURIComponent(p)}=${encodeURIComponent(_[p])}`).join("&"),M="/"+Y.split("/").map((p)=>encodeURIComponent(p)).join("/"),T=`host:${K}
6979
6979
  `,x=[B,M,E,T,"host","UNSIGNED-PAYLOAD"].join(`
6980
6980
  `),h=["AWS4-HMAC-SHA256",H,X,a.createHash("sha256").update(x).digest("hex")].join(`
6981
- `),k=a.createHmac("sha256",`AWS4${W}`).update(A).digest(),b=a.createHmac("sha256",k).update(this.region).digest(),I=a.createHmac("sha256",b).update("s3").digest(),f=a.createHmac("sha256",I).update("aws4_request").digest(),m=a.createHmac("sha256",f).update(h).digest("hex");return`https://${K}${M}?${E}&X-Amz-Signature=${m}`}async listObjects($){let{bucket:J,prefix:Y,maxKeys:Q=1000,continuationToken:Z}=$,U={"list-type":"2","max-keys":Q.toString()};if(Y)U.prefix=Y;if(Z)U["continuation-token"]=Z;let W=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${J}`,queryParams:U}),z=[],G=W?.ListBucketResult??W;if(G?.Contents){let H=Array.isArray(G.Contents)?G.Contents:[G.Contents];for(let A of H)z.push({Key:A.Key||"",LastModified:A.LastModified||"",Size:Number.parseInt(A.Size||"0"),ETag:A.ETag})}return{objects:z,nextContinuationToken:G?.NextContinuationToken}}async emptyBucket($){let J=0,Y=await this.listAllObjects({bucket:$});if(Y.length>0)for(let Q=0;Q<Y.length;Q+=1000){let U=Y.slice(Q,Q+1000).map((W)=>W.Key);await this.deleteObjects($,U),J+=U.length}try{let Q,Z;do{let U=await this.listObjectVersions({bucket:$,keyMarker:Q,versionIdMarker:Z,maxKeys:1000}),W=[];if(U.versions)for(let z of U.versions)W.push({Key:z.Key,VersionId:z.VersionId});if(U.deleteMarkers)for(let z of U.deleteMarkers)W.push({Key:z.Key,VersionId:z.VersionId});if(W.length>0)await this.deleteObjectVersions($,W),J+=W.length;Q=U.nextKeyMarker,Z=U.nextVersionIdMarker}while(Q)}catch{}return{deletedCount:J}}async listObjectVersions($){let{bucket:J,prefix:Y,keyMarker:Q,versionIdMarker:Z,maxKeys:U=1000}=$,W={versions:"","max-keys":U.toString()};if(Y)W.prefix=Y;if(Q)W["key-marker"]=Q;if(Z)W["version-id-marker"]=Z;let z=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${J}`,queryParams:W}),G=[],H=[];if(z.Version){let A=Array.isArray(z.Version)?z.Version:[z.Version];for(let K of A)G.push({Key:K.Key,VersionId:K.VersionId,IsLatest:K.IsLatest==="true"})}if(z.DeleteMarker){let A=Array.isArray(z.DeleteMarker)?z.DeleteMarker:[z.DeleteMarker];for(let K of A)H.push({Key:K.Key,VersionId:K.VersionId,IsLatest:K.IsLatest==="true"})}return{versions:G,deleteMarkers:H,nextKeyMarker:z.NextKeyMarker,nextVersionIdMarker:z.NextVersionIdMarker}}async deleteObjectVersions($,J){let Y=`<?xml version="1.0" encoding="UTF-8"?>
6981
+ `),I=a.createHmac("sha256",`AWS4${W}`).update(A).digest(),b=a.createHmac("sha256",I).update(this.region).digest(),k=a.createHmac("sha256",b).update("s3").digest(),y=a.createHmac("sha256",k).update("aws4_request").digest(),m=a.createHmac("sha256",y).update(h).digest("hex");return`https://${K}${M}?${E}&X-Amz-Signature=${m}`}async listObjects($){let{bucket:J,prefix:Y,maxKeys:Q=1000,continuationToken:Z}=$,U={"list-type":"2","max-keys":Q.toString()};if(Y)U.prefix=Y;if(Z)U["continuation-token"]=Z;let W=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${J}`,queryParams:U}),z=[],G=W?.ListBucketResult??W;if(G?.Contents){let H=Array.isArray(G.Contents)?G.Contents:[G.Contents];for(let A of H)z.push({Key:A.Key||"",LastModified:A.LastModified||"",Size:Number.parseInt(A.Size||"0"),ETag:A.ETag})}return{objects:z,nextContinuationToken:G?.NextContinuationToken}}async emptyBucket($){let J=0,Y=await this.listAllObjects({bucket:$});if(Y.length>0)for(let Q=0;Q<Y.length;Q+=1000){let U=Y.slice(Q,Q+1000).map((W)=>W.Key);await this.deleteObjects($,U),J+=U.length}try{let Q,Z;do{let U=await this.listObjectVersions({bucket:$,keyMarker:Q,versionIdMarker:Z,maxKeys:1000}),W=[];if(U.versions)for(let z of U.versions)W.push({Key:z.Key,VersionId:z.VersionId});if(U.deleteMarkers)for(let z of U.deleteMarkers)W.push({Key:z.Key,VersionId:z.VersionId});if(W.length>0)await this.deleteObjectVersions($,W),J+=W.length;Q=U.nextKeyMarker,Z=U.nextVersionIdMarker}while(Q)}catch{}return{deletedCount:J}}async listObjectVersions($){let{bucket:J,prefix:Y,keyMarker:Q,versionIdMarker:Z,maxKeys:U=1000}=$,W={versions:"","max-keys":U.toString()};if(Y)W.prefix=Y;if(Q)W["key-marker"]=Q;if(Z)W["version-id-marker"]=Z;let z=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${J}`,queryParams:W}),G=[],H=[];if(z.Version){let A=Array.isArray(z.Version)?z.Version:[z.Version];for(let K of A)G.push({Key:K.Key,VersionId:K.VersionId,IsLatest:K.IsLatest==="true"})}if(z.DeleteMarker){let A=Array.isArray(z.DeleteMarker)?z.DeleteMarker:[z.DeleteMarker];for(let K of A)H.push({Key:K.Key,VersionId:K.VersionId,IsLatest:K.IsLatest==="true"})}return{versions:G,deleteMarkers:H,nextKeyMarker:z.NextKeyMarker,nextVersionIdMarker:z.NextVersionIdMarker}}async deleteObjectVersions($,J){let Y=`<?xml version="1.0" encoding="UTF-8"?>
6982
6982
  <Delete>
6983
6983
  <Quiet>true</Quiet>
6984
6984
  ${J.map((Z)=>`<Object><Key>${Z.Key}</Key>${Z.VersionId?`<VersionId>${Z.VersionId}</VersionId>`:""}</Object>`).join(`
@@ -7131,7 +7131,7 @@ ${Object.entries($).filter(([U])=>!U.startsWith("@_")).map(([U,W])=>Z(U,W," ","
7131
7131
  }
7132
7132
 
7133
7133
  return request;
7134
- }`}};let H={Enabled:!0,DefaultRootObject:U,HttpVersion:"http2and3",IPV6Enabled:!0,PriceClass:"PriceClass_100",Origins:[{Id:`S3-${J}`,DomainName:{"Fn::GetAtt":["S3Bucket","RegionalDomainName"]},S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{"Fn::GetAtt":["CloudFrontOAC","Id"]}}],DefaultCacheBehavior:{TargetOriginId:`S3-${J}`,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":["UrlRewriteFunction","FunctionARN"]}}]},CustomErrorResponses:[{ErrorCode:403,ResponseCode:200,ResponsePagePath:`/${U}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${W}`,ErrorCachingMinTTL:300}]};if(Y&&Q)H.Aliases=[Y],H.ViewerCertificate={AcmCertificateArn:Q,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else H.ViewerCertificate={CloudFrontDefaultCertificate:!0};if(z.CloudFrontDistribution={Type:"AWS::CloudFront::Distribution",DependsOn:["S3Bucket","CloudFrontOAC","UrlRewriteFunction"],Properties:{DistributionConfig:H}},G.DistributionId={Description:"CloudFront Distribution ID",Value:{Ref:"CloudFrontDistribution"}},G.DistributionDomain={Description:"CloudFront Distribution Domain",Value:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]}},z.S3BucketPolicy={Type:"AWS::S3::BucketPolicy",DependsOn:["S3Bucket","CloudFrontDistribution"],Properties:{Bucket:{Ref:"S3Bucket"},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":"arn:aws:s3:::${S3Bucket}/*"},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":"arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"}}}}]}}},Y&&Z)z.DNSRecord={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:Z,Name:Y,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},z.DNSRecordIPv6={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:Z,Name:Y,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},G.SiteUrl={Description:"Site URL",Value:{"Fn::Sub":"https://${DNSRecord}"}};return{AWSTemplateFormatVersion:"2010-09-09",Description:`Static site infrastructure for ${Y||J}`,Resources:z,Outputs:G}}async function vZ($){if($.dnsProvider&&$.dnsProvider.provider!=="route53"){let N=$.domain||($.subdomain&&$.baseDomain?`${$.subdomain}.${$.baseDomain}`:void 0);if(!N)return{success:!1,stackName:$.stackName||`${$.siteName}-static-site`,bucket:$.bucket||`${$.siteName}-${Date.now()}`,message:"Domain is required when using external DNS provider"};return w5({siteName:$.siteName,region:$.region,domain:N,bucket:$.bucket,certificateArn:$.certificateArn,stackName:$.stackName,defaultRootObject:$.defaultRootObject,errorDocument:$.errorDocument,cacheControl:$.cacheControl,tags:$.tags,dnsProvider:$.dnsProvider})}let J=$.region||"us-east-1",Y="us-east-1",Q;if($.domain)Q=$.domain;else if($.subdomain&&$.baseDomain)Q=`${$.subdomain}.${$.baseDomain}`;let Z=$.bucket||(Q?Q.replace(/\./g,"-"):`${$.siteName}-${Date.now()}`),U=$.stackName||`${$.siteName}-static-site`,W=new O0(Y),z=new o0,G=new y0("us-east-1"),H=new X9("us-east-1"),A=$.hostedZoneId,K=$.certificateArn;if(Q&&!A){let N=await z.findHostedZoneForDomain(Q);if(N)A=N.Id.replace("/hostedzone/","");else return{success:!1,stackName:U,bucket:Z,message:`No Route53 hosted zone found for ${$.baseDomain||Q}. Please create one first.`}}if(Q&&!K&&A){let N=await G.findCertificateByDomain(Q);if(N&&N.Status==="ISSUED")K=N.CertificateArn;else K=(await H.requestAndValidate({domainName:Q,hostedZoneId:A,waitForValidation:!0,maxWaitMinutes:10})).certificateArn}let B=!1,j;try{let N=await W.describeStacks({stackName:U});if(N.Stacks.length>0){let x=N.Stacks[0],h=x.StackStatus;if(h==="DELETE_IN_PROGRESS")console.log("Previous stack is still being deleted, waiting..."),await W.waitForStack(U,"stack-delete-complete"),B=!1;else if(h==="DELETE_COMPLETE")B=!1;else B=!0,j=(x.Outputs||[]).find((b)=>b.OutputKey==="BucketName")?.OutputValue}}catch(N){if(N.message?.includes("does not exist")||N.code==="ValidationError")B=!1;else throw N}let X=j||Z;if(!B){let N=new F0(J),x=new _0,h=!1;if(Q){try{console.log(`Checking for existing CloudFront distribution for ${Q}...`);let k=await x.listDistributions();for(let b of k){let I=[];if(b.Aliases?.Items){if(Array.isArray(b.Aliases.Items))I=b.Aliases.Items;else if(typeof b.Aliases.Items==="object"){let f=b.Aliases.Items.CNAME;if(typeof f==="string")I=[f];else if(Array.isArray(f))I=f}}if(I.includes(Q)){h=!0,console.log(`Found existing CloudFront distribution ${b.Id} for ${Q}`);let m=(await x.getDistributionConfig(b.Id)).DistributionConfig?.Origins?.Items,l;if(m){let p=[];if(Array.isArray(m))p=m;else if(m.Origin)p=Array.isArray(m.Origin)?m.Origin:[m.Origin];else p=[m];for(let r of p){let o=(r.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(o){l=o[1];break}}}if(l){let p=Q.replace(/\./g,"-");if(!l.startsWith(p)&&!l.includes($.siteName)){console.log(`Warning: Found distribution with mismatched bucket ${l}, skipping...`);continue}if(console.log(`Using existing S3 bucket: ${l}`),A&&b.DomainName)try{console.log(`Ensuring Route53 records exist for ${Q}...`),await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"A",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:b.DomainName,EvaluateTargetHealth:!1}),await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"AAAA",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:b.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records ensured for ${Q}`)}catch(r){console.log(`Note: Could not update Route53 records: ${r.message}`)}return{success:!0,stackName:`existing-${b.Id}`,bucket:l,distributionId:b.Id,distributionDomain:b.DomainName,domain:Q,certificateArn:K,message:"Using existing CloudFront distribution"}}}}}catch{}if(A)try{let b=(await z.listResourceRecordSets({HostedZoneId:A})).ResourceRecordSets||[];for(let I of b)if(I.Name===`${Q}.`&&(I.Type==="A"||I.Type==="AAAA")){if(I.AliasTarget){console.log(`Found orphaned Route53 ${I.Type} record for ${Q}, cleaning up...`);try{await z.deleteRecord({HostedZoneId:A,RecordSet:I}),console.log(`Deleted orphaned Route53 ${I.Type} record for ${Q}`)}catch(f){console.log(`Note: Could not delete Route53 record: ${f.message}`)}}}}catch{}}if(!h)try{if((await N.headBucket(Z)).exists){console.log(`Found orphaned S3 bucket ${Z}, cleaning up...`);try{let b=N.emptyBucket(Z).then(()=>N.deleteBucket(Z)),I=new Promise((f,m)=>setTimeout(()=>m(Error("Bucket cleanup timeout")),30000));await Promise.race([b,I]),console.log(`Deleted orphaned S3 bucket ${Z}`)}catch(b){console.log(`Note: Could not clean up S3 bucket: ${b.message}`);let I=Date.now().toString(36);X=`${Z}-${I}`,console.log(`Using alternative bucket name: ${X}`)}}}catch{}}let O=yZ({bucketName:X,domain:Q,certificateArn:K,hostedZoneId:A,defaultRootObject:$.defaultRootObject,errorDocument:$.errorDocument}),_=Object.entries($.tags||{}).map(([N,x])=>({Key:N,Value:x}));_.push({Key:"ManagedBy",Value:"ts-cloud"}),_.push({Key:"Application",Value:$.siteName});let w,E=!1;if(B){E=!0,console.log(`Updating CloudFormation stack: ${U}`),console.log(`Using existing bucket: ${X}`),console.log(`Domain: ${Q||"not specified"}`),console.log(`Certificate ARN: ${K||"not specified"}`);try{w=(await W.updateStack({stackName:U,templateBody:JSON.stringify(O),capabilities:["CAPABILITY_IAM"],tags:_})).StackId,console.log(`Update initiated, stack ID: ${w}`)}catch(N){if(N.message?.includes("No updates are to be performed")){let x=await W.describeStacks({stackName:U});w=x.Stacks[0].StackId;let h=x.Stacks[0]?.Outputs||[],k=(b)=>h.find((I)=>I.OutputKey===b)?.OutputValue;return{success:!0,stackId:w,stackName:U,bucket:k("BucketName")||X,distributionId:k("DistributionId"),distributionDomain:k("DistributionDomain"),domain:Q,certificateArn:K,message:"Static site infrastructure is already up to date"}}else throw N}}else console.log(`Creating CloudFormation stack: ${U}`),console.log(`Bucket name: ${X}`),console.log(`Domain: ${Q||"not specified"}`),console.log(`Certificate ARN: ${K||"not specified"}`),console.log("Stack does not exist, creating..."),w=(await W.createStack({stackName:U,templateBody:JSON.stringify(O),capabilities:["CAPABILITY_IAM"],tags:_,onFailure:"DELETE"})).StackId,console.log(`Create initiated, stack ID: ${w}`);console.log(`Waiting for stack to reach ${E?"stack-update-complete":"stack-create-complete"}...`);try{await W.waitForStack(U,E?"stack-update-complete":"stack-create-complete"),console.log("Stack operation completed successfully!")}catch(N){if(N.message?.includes("must be verified")||N.message?.includes("Access denied for operation")||N.message?.includes("failed")){console.log("CloudFormation deployment failed, trying direct API creation...");let x=new _0;if(Q)try{let h=await x.listDistributions();for(let k of h){let b=[];if(k.Aliases?.Items){if(Array.isArray(k.Aliases.Items))b=k.Aliases.Items;else if(typeof k.Aliases.Items==="object"){let I=k.Aliases.Items.CNAME;if(typeof I==="string")b=[I];else if(Array.isArray(I))b=I}}if(b.includes(Q)){console.log(`Found existing CloudFront distribution ${k.Id} with alias ${Q}`);let f=(await x.getDistributionConfig(k.Id)).DistributionConfig?.Origins?.Items,m;if(f){let l=[];if(Array.isArray(f))l=f;else if(f.Origin)l=Array.isArray(f.Origin)?f.Origin:[f.Origin];else l=[f];for(let p of l){let s=(p.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(s){m=s[1];break}}}if(m)return console.log(`Using existing S3 bucket: ${m}`),{success:!0,stackName:`existing-${k.Id}`,bucket:m,distributionId:k.Id,distributionDomain:k.DomainName,domain:Q,certificateArn:K,message:"Using existing CloudFront distribution (account verification pending for new distributions)"}}}}catch{}console.log("No existing infrastructure found, creating via direct API calls...");try{let h=new F0(J);if((await h.headBucket(X)).exists)console.log(`Using existing S3 bucket: ${X}`);else console.log(`Creating S3 bucket: ${X}...`),await h.createBucket(X);await h.putBucketWebsite(X,{IndexDocument:$.defaultRootObject||"index.html",ErrorDocument:$.errorDocument||"404.html"}),await h.putPublicAccessBlock(X,{BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1}),console.log(`S3 bucket ${X} configured`);let b=`OAC-${X}`;console.log(`Creating Origin Access Control: ${b}...`);let I=await x.findOrCreateOriginAccessControl(b);console.log(`Origin Access Control ${I.Id} ready`),console.log("Creating CloudFront distribution...");let f=await x.createDistributionForS3({bucketName:X,bucketRegion:J,originAccessControlId:I.Id,aliases:Q?[Q]:[],certificateArn:K,defaultRootObject:$.defaultRootObject||"index.html",comment:`Distribution for ${Q||X}`});console.log(`CloudFront distribution ${f.Id} created`),console.log("Updating S3 bucket policy...");let m=_0.getS3BucketPolicyForCloudFront(X,f.ARN);if(await h.putBucketPolicy(X,m),console.log("S3 bucket policy updated"),Q&&A){console.log(`Creating Route53 records for ${Q}...`);try{await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"A",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:f.DomainName,EvaluateTargetHealth:!1}),await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"AAAA",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:f.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records created for ${Q}`)}catch(l){console.log(`Note: Could not create Route53 records: ${l.message}`)}}return{success:!0,stackName:`direct-${f.Id}`,bucket:X,distributionId:f.Id,distributionDomain:f.DomainName,domain:Q,certificateArn:K,message:"Static site infrastructure created via direct API calls"}}catch(h){return console.log(`Direct API creation failed: ${h.message}`),{success:!1,stackId:w,stackName:U,bucket:X,message:`Deployment failed: ${h.message}`}}}return{success:!1,stackId:w,stackName:U,bucket:X,message:`Stack deployment failed: ${N.message}`}}let T=(await W.describeStacks({stackName:U})).Stacks[0]?.Outputs||[],D=(N)=>T.find((x)=>x.OutputKey===N)?.OutputValue;return{success:!0,stackId:w,stackName:U,bucket:D("BucketName")||X,distributionId:D("DistributionId"),distributionDomain:D("DistributionDomain"),domain:Q,certificateArn:K,message:"Static site infrastructure deployed successfully"}}async function fZ($){let{sourceDir:J,bucket:Y,region:Q,cacheControl:Z="max-age=31536000, public",onProgress:U}=$,W=new F0(Q),{readdir:z}=await import("node:fs/promises"),{join:G,relative:H}=await import("node:path"),{createHash:A}=await import("node:crypto");async function K(T){let D=[],N=await z(T,{withFileTypes:!0});for(let x of N){let h=G(T,x.name);if(x.isDirectory())D.push(...await K(h));else D.push(h)}return D}function B(T){let D=T.split(".").pop()?.toLowerCase();return{html:"text/html; charset=utf-8",css:"text/css; charset=utf-8",js:"application/javascript; charset=utf-8",json:"application/json; charset=utf-8",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",xml:"application/xml",txt:"text/plain; charset=utf-8",sh:"text/plain; charset=utf-8",bash:"text/plain; charset=utf-8",ps1:"text/plain; charset=utf-8"}[D||""]||"application/octet-stream"}function j(T){return A("md5").update(T).digest("hex")}async function X(){let T=new Map,D;do{let N=await W.listObjects({bucket:Y,maxKeys:1000,continuationToken:D});for(let x of N.objects){let h=x.ETag?.replace(/"/g,"")||"";T.set(x.Key,h)}D=N.nextContinuationToken}while(D);return T}let O=await K(J),_=[],w=0,E=0,M=await X();for(let T of O){let D=H(J,T),N=B(T),x=T.endsWith(".html")?"max-age=3600, public":Z;try{let h=Buffer.from(await Bun.file(T).arrayBuffer()),k=j(h),b=M.get(D);if(b&&b===k){E++,U?.(w+E,O.length,D);continue}await W.putObject({bucket:Y,key:D,body:h,contentType:N,cacheControl:x}),w++,U?.(w+E,O.length,D)}catch(h){_.push(`Failed to upload ${D}: ${h.message}`)}}return{uploaded:w,skipped:E,errors:_}}async function gZ($){return{invalidationId:(await new _0().invalidateAll($)).Id}}async function FB($,J="us-east-1"){let Y=new O0(J);try{let W=((await Y.describeStacks({stackName:$})).Stacks[0]?.Outputs||[]).find((z)=>z.OutputKey==="BucketName")?.OutputValue;if(W)await new F0(J).emptyBucket(W)}catch{}await Y.deleteStack($);let Q=await Y.waitForStackComplete($,60,1e4);return{success:Q.success||Q.status==="DELETE_COMPLETE",message:Q.success?"Static site deleted successfully":`Deletion failed: ${Q.status}`}}async function AB($){let{sourceDir:J,cleanBucket:Y=!1,onProgress:Q,...Z}=$;Q?.("infrastructure","Deploying CloudFormation stack...");let U=await vZ(Z);if(!U.success)return U;if(Y){Q?.("clean","Cleaning old files from S3...");try{await new F0(Z.region||"us-east-1").emptyBucket(U.bucket)}catch(G){console.log(`Note: Could not clean bucket: ${G.message}`)}}Q?.("upload","Uploading files to S3...");let W=await fZ({sourceDir:J,bucket:U.bucket,region:Z.region||"us-east-1",cacheControl:Z.cacheControl,onProgress:(G,H,A)=>{Q?.("upload",`${G}/${H}: ${A}`)}});if(W.errors.length>0)return{...U,success:!1,message:`Upload errors: ${W.errors.join(", ")}`,filesUploaded:W.uploaded};if(U.distributionId&&W.uploaded>0)Q?.("invalidate","Invalidating CloudFront cache..."),await gZ(U.distributionId);Q?.("complete","Deployment complete!");let z=W.skipped>0?`Deployed ${W.uploaded} files (${W.skipped} unchanged)`:`Deployed ${W.uploaded} files successfully`;return{...U,filesUploaded:W.uploaded,filesSkipped:W.skipped,message:z}}var u9=S0(()=>{S1();P1();l1();B9();s1();V5()});function KB($){let{bucketName:J,domain:Y,aliases:Q,certificateArn:Z,defaultRootObject:U="index.html",errorDocument:W="404.html",passthroughUrls:z=!1,singlePageApp:G=!1,dynamicApp:H=!1,computeOriginDomain:A,computeOriginPort:K=3008,computeOriginId:B="app-compute",retainOnStackDelete:j=!1}=$,X=j?{DeletionPolicy:"Retain",UpdateReplacePolicy:"Retain"}:{},O=H&&!!A,_=O?["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"]:["GET","HEAD"],w=O?["GET","HEAD"]:["GET","HEAD"],E={},M={};E.S3Bucket={Type:"AWS::S3::Bucket",...X,Properties:{BucketName:J,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:U,ErrorDocument:W}}},M.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},M.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},E.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",...X,Properties:{OriginAccessControlConfig:{Name:`OAC-${J}`,Description:`OAC for ${J}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}};let T;if(z&&O)T="InstallRootRedirectFunction",E[T]={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-install-root-redirect"},AutoPublish:!0,FunctionConfig:{Comment:"Redirect curl pantry.dev | bash (GET /) to /install.sh on S3",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
7134
+ }`}};let H={Enabled:!0,DefaultRootObject:U,HttpVersion:"http2and3",IPV6Enabled:!0,PriceClass:"PriceClass_100",Origins:[{Id:`S3-${J}`,DomainName:{"Fn::GetAtt":["S3Bucket","RegionalDomainName"]},S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{"Fn::GetAtt":["CloudFrontOAC","Id"]}}],DefaultCacheBehavior:{TargetOriginId:`S3-${J}`,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":["UrlRewriteFunction","FunctionARN"]}}]},CustomErrorResponses:[{ErrorCode:403,ResponseCode:200,ResponsePagePath:`/${U}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${W}`,ErrorCachingMinTTL:300}]};if(Y&&Q)H.Aliases=[Y],H.ViewerCertificate={AcmCertificateArn:Q,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else H.ViewerCertificate={CloudFrontDefaultCertificate:!0};if(z.CloudFrontDistribution={Type:"AWS::CloudFront::Distribution",DependsOn:["S3Bucket","CloudFrontOAC","UrlRewriteFunction"],Properties:{DistributionConfig:H}},G.DistributionId={Description:"CloudFront Distribution ID",Value:{Ref:"CloudFrontDistribution"}},G.DistributionDomain={Description:"CloudFront Distribution Domain",Value:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]}},z.S3BucketPolicy={Type:"AWS::S3::BucketPolicy",DependsOn:["S3Bucket","CloudFrontDistribution"],Properties:{Bucket:{Ref:"S3Bucket"},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":"arn:aws:s3:::${S3Bucket}/*"},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":"arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"}}}}]}}},Y&&Z)z.DNSRecord={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:Z,Name:Y,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},z.DNSRecordIPv6={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:Z,Name:Y,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},G.SiteUrl={Description:"Site URL",Value:{"Fn::Sub":"https://${DNSRecord}"}};return{AWSTemplateFormatVersion:"2010-09-09",Description:`Static site infrastructure for ${Y||J}`,Resources:z,Outputs:G}}async function vZ($){if($.dnsProvider&&$.dnsProvider.provider!=="route53"){let N=$.domain||($.subdomain&&$.baseDomain?`${$.subdomain}.${$.baseDomain}`:void 0);if(!N)return{success:!1,stackName:$.stackName||`${$.siteName}-static-site`,bucket:$.bucket||`${$.siteName}-${Date.now()}`,message:"Domain is required when using external DNS provider"};return w5({siteName:$.siteName,region:$.region,domain:N,bucket:$.bucket,certificateArn:$.certificateArn,stackName:$.stackName,defaultRootObject:$.defaultRootObject,errorDocument:$.errorDocument,cacheControl:$.cacheControl,tags:$.tags,dnsProvider:$.dnsProvider})}let J=$.region||"us-east-1",Y="us-east-1",Q;if($.domain)Q=$.domain;else if($.subdomain&&$.baseDomain)Q=`${$.subdomain}.${$.baseDomain}`;let Z=$.bucket||(Q?Q.replace(/\./g,"-"):`${$.siteName}-${Date.now()}`),U=$.stackName||`${$.siteName}-static-site`,W=new O0(Y),z=new o0,G=new y0("us-east-1"),H=new X9("us-east-1"),A=$.hostedZoneId,K=$.certificateArn;if(Q&&!A){let N=await z.findHostedZoneForDomain(Q);if(N)A=N.Id.replace("/hostedzone/","");else return{success:!1,stackName:U,bucket:Z,message:`No Route53 hosted zone found for ${$.baseDomain||Q}. Please create one first.`}}if(Q&&!K&&A){let N=await G.findCertificateByDomain(Q);if(N&&N.Status==="ISSUED")K=N.CertificateArn;else K=(await H.requestAndValidate({domainName:Q,hostedZoneId:A,waitForValidation:!0,maxWaitMinutes:10})).certificateArn}let B=!1,j;try{let N=await W.describeStacks({stackName:U});if(N.Stacks.length>0){let x=N.Stacks[0],h=x.StackStatus;if(h==="DELETE_IN_PROGRESS")console.log("Previous stack is still being deleted, waiting..."),await W.waitForStack(U,"stack-delete-complete"),B=!1;else if(h==="DELETE_COMPLETE")B=!1;else B=!0,j=(x.Outputs||[]).find((b)=>b.OutputKey==="BucketName")?.OutputValue}}catch(N){if(N.message?.includes("does not exist")||N.code==="ValidationError")B=!1;else throw N}let X=j||Z;if(!B){let N=new F0(J),x=new _0,h=!1;if(Q){try{console.log(`Checking for existing CloudFront distribution for ${Q}...`);let I=await x.listDistributions();for(let b of I){let k=[];if(b.Aliases?.Items){if(Array.isArray(b.Aliases.Items))k=b.Aliases.Items;else if(typeof b.Aliases.Items==="object"){let y=b.Aliases.Items.CNAME;if(typeof y==="string")k=[y];else if(Array.isArray(y))k=y}}if(k.includes(Q)){h=!0,console.log(`Found existing CloudFront distribution ${b.Id} for ${Q}`);let m=(await x.getDistributionConfig(b.Id)).DistributionConfig?.Origins?.Items,l;if(m){let p=[];if(Array.isArray(m))p=m;else if(m.Origin)p=Array.isArray(m.Origin)?m.Origin:[m.Origin];else p=[m];for(let r of p){let o=(r.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(o){l=o[1];break}}}if(l){let p=Q.replace(/\./g,"-");if(!l.startsWith(p)&&!l.includes($.siteName)){console.log(`Warning: Found distribution with mismatched bucket ${l}, skipping...`);continue}if(console.log(`Using existing S3 bucket: ${l}`),A&&b.DomainName)try{console.log(`Ensuring Route53 records exist for ${Q}...`),await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"A",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:b.DomainName,EvaluateTargetHealth:!1}),await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"AAAA",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:b.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records ensured for ${Q}`)}catch(r){console.log(`Note: Could not update Route53 records: ${r.message}`)}return{success:!0,stackName:`existing-${b.Id}`,bucket:l,distributionId:b.Id,distributionDomain:b.DomainName,domain:Q,certificateArn:K,message:"Using existing CloudFront distribution"}}}}}catch{}if(A)try{let b=(await z.listResourceRecordSets({HostedZoneId:A})).ResourceRecordSets||[];for(let k of b)if(k.Name===`${Q}.`&&(k.Type==="A"||k.Type==="AAAA")){if(k.AliasTarget){console.log(`Found orphaned Route53 ${k.Type} record for ${Q}, cleaning up...`);try{await z.deleteRecord({HostedZoneId:A,RecordSet:k}),console.log(`Deleted orphaned Route53 ${k.Type} record for ${Q}`)}catch(y){console.log(`Note: Could not delete Route53 record: ${y.message}`)}}}}catch{}}if(!h)try{if((await N.headBucket(Z)).exists){console.log(`Found orphaned S3 bucket ${Z}, cleaning up...`);try{let b=N.emptyBucket(Z).then(()=>N.deleteBucket(Z)),k=new Promise((y,m)=>setTimeout(()=>m(Error("Bucket cleanup timeout")),30000));await Promise.race([b,k]),console.log(`Deleted orphaned S3 bucket ${Z}`)}catch(b){console.log(`Note: Could not clean up S3 bucket: ${b.message}`);let k=Date.now().toString(36);X=`${Z}-${k}`,console.log(`Using alternative bucket name: ${X}`)}}}catch{}}let O=yZ({bucketName:X,domain:Q,certificateArn:K,hostedZoneId:A,defaultRootObject:$.defaultRootObject,errorDocument:$.errorDocument}),_=Object.entries($.tags||{}).map(([N,x])=>({Key:N,Value:x}));_.push({Key:"ManagedBy",Value:"ts-cloud"}),_.push({Key:"Application",Value:$.siteName});let w,E=!1;if(B){E=!0,console.log(`Updating CloudFormation stack: ${U}`),console.log(`Using existing bucket: ${X}`),console.log(`Domain: ${Q||"not specified"}`),console.log(`Certificate ARN: ${K||"not specified"}`);try{w=(await W.updateStack({stackName:U,templateBody:JSON.stringify(O),capabilities:["CAPABILITY_IAM"],tags:_})).StackId,console.log(`Update initiated, stack ID: ${w}`)}catch(N){if(N.message?.includes("No updates are to be performed")){let x=await W.describeStacks({stackName:U});w=x.Stacks[0].StackId;let h=x.Stacks[0]?.Outputs||[],I=(b)=>h.find((k)=>k.OutputKey===b)?.OutputValue;return{success:!0,stackId:w,stackName:U,bucket:I("BucketName")||X,distributionId:I("DistributionId"),distributionDomain:I("DistributionDomain"),domain:Q,certificateArn:K,message:"Static site infrastructure is already up to date"}}else throw N}}else console.log(`Creating CloudFormation stack: ${U}`),console.log(`Bucket name: ${X}`),console.log(`Domain: ${Q||"not specified"}`),console.log(`Certificate ARN: ${K||"not specified"}`),console.log("Stack does not exist, creating..."),w=(await W.createStack({stackName:U,templateBody:JSON.stringify(O),capabilities:["CAPABILITY_IAM"],tags:_,onFailure:"DELETE"})).StackId,console.log(`Create initiated, stack ID: ${w}`);console.log(`Waiting for stack to reach ${E?"stack-update-complete":"stack-create-complete"}...`);try{await W.waitForStack(U,E?"stack-update-complete":"stack-create-complete"),console.log("Stack operation completed successfully!")}catch(N){if(N.message?.includes("must be verified")||N.message?.includes("Access denied for operation")||N.message?.includes("failed")){console.log("CloudFormation deployment failed, trying direct API creation...");let x=new _0;if(Q)try{let h=await x.listDistributions();for(let I of h){let b=[];if(I.Aliases?.Items){if(Array.isArray(I.Aliases.Items))b=I.Aliases.Items;else if(typeof I.Aliases.Items==="object"){let k=I.Aliases.Items.CNAME;if(typeof k==="string")b=[k];else if(Array.isArray(k))b=k}}if(b.includes(Q)){console.log(`Found existing CloudFront distribution ${I.Id} with alias ${Q}`);let y=(await x.getDistributionConfig(I.Id)).DistributionConfig?.Origins?.Items,m;if(y){let l=[];if(Array.isArray(y))l=y;else if(y.Origin)l=Array.isArray(y.Origin)?y.Origin:[y.Origin];else l=[y];for(let p of l){let s=(p.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(s){m=s[1];break}}}if(m)return console.log(`Using existing S3 bucket: ${m}`),{success:!0,stackName:`existing-${I.Id}`,bucket:m,distributionId:I.Id,distributionDomain:I.DomainName,domain:Q,certificateArn:K,message:"Using existing CloudFront distribution (account verification pending for new distributions)"}}}}catch{}console.log("No existing infrastructure found, creating via direct API calls...");try{let h=new F0(J);if((await h.headBucket(X)).exists)console.log(`Using existing S3 bucket: ${X}`);else console.log(`Creating S3 bucket: ${X}...`),await h.createBucket(X);await h.putBucketWebsite(X,{IndexDocument:$.defaultRootObject||"index.html",ErrorDocument:$.errorDocument||"404.html"}),await h.putPublicAccessBlock(X,{BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1}),console.log(`S3 bucket ${X} configured`);let b=`OAC-${X}`;console.log(`Creating Origin Access Control: ${b}...`);let k=await x.findOrCreateOriginAccessControl(b);console.log(`Origin Access Control ${k.Id} ready`),console.log("Creating CloudFront distribution...");let y=await x.createDistributionForS3({bucketName:X,bucketRegion:J,originAccessControlId:k.Id,aliases:Q?[Q]:[],certificateArn:K,defaultRootObject:$.defaultRootObject||"index.html",comment:`Distribution for ${Q||X}`});console.log(`CloudFront distribution ${y.Id} created`),console.log("Updating S3 bucket policy...");let m=_0.getS3BucketPolicyForCloudFront(X,y.ARN);if(await h.putBucketPolicy(X,m),console.log("S3 bucket policy updated"),Q&&A){console.log(`Creating Route53 records for ${Q}...`);try{await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"A",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:y.DomainName,EvaluateTargetHealth:!1}),await z.createAliasRecord({HostedZoneId:A,Name:Q,Type:"AAAA",TargetHostedZoneId:o0.CloudFrontHostedZoneId,TargetDNSName:y.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records created for ${Q}`)}catch(l){console.log(`Note: Could not create Route53 records: ${l.message}`)}}return{success:!0,stackName:`direct-${y.Id}`,bucket:X,distributionId:y.Id,distributionDomain:y.DomainName,domain:Q,certificateArn:K,message:"Static site infrastructure created via direct API calls"}}catch(h){return console.log(`Direct API creation failed: ${h.message}`),{success:!1,stackId:w,stackName:U,bucket:X,message:`Deployment failed: ${h.message}`}}}return{success:!1,stackId:w,stackName:U,bucket:X,message:`Stack deployment failed: ${N.message}`}}let T=(await W.describeStacks({stackName:U})).Stacks[0]?.Outputs||[],D=(N)=>T.find((x)=>x.OutputKey===N)?.OutputValue;return{success:!0,stackId:w,stackName:U,bucket:D("BucketName")||X,distributionId:D("DistributionId"),distributionDomain:D("DistributionDomain"),domain:Q,certificateArn:K,message:"Static site infrastructure deployed successfully"}}async function fZ($){let{sourceDir:J,bucket:Y,region:Q,cacheControl:Z="max-age=31536000, public",onProgress:U}=$,W=new F0(Q),{readdir:z}=await import("node:fs/promises"),{join:G,relative:H}=await import("node:path"),{createHash:A}=await import("node:crypto");async function K(T){let D=[],N=await z(T,{withFileTypes:!0});for(let x of N){let h=G(T,x.name);if(x.isDirectory())D.push(...await K(h));else D.push(h)}return D}function B(T){let D=T.split(".").pop()?.toLowerCase();return{html:"text/html; charset=utf-8",css:"text/css; charset=utf-8",js:"application/javascript; charset=utf-8",json:"application/json; charset=utf-8",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon",webp:"image/webp",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",xml:"application/xml",txt:"text/plain; charset=utf-8",sh:"text/plain; charset=utf-8",bash:"text/plain; charset=utf-8",ps1:"text/plain; charset=utf-8"}[D||""]||"application/octet-stream"}function j(T){return A("md5").update(T).digest("hex")}async function X(){let T=new Map,D;do{let N=await W.listObjects({bucket:Y,maxKeys:1000,continuationToken:D});for(let x of N.objects){let h=x.ETag?.replace(/"/g,"")||"";T.set(x.Key,h)}D=N.nextContinuationToken}while(D);return T}let O=await K(J),_=[],w=0,E=0,M=await X();for(let T of O){let D=H(J,T),N=B(T),x=T.endsWith(".html")?"max-age=3600, public":Z;try{let h=Buffer.from(await Bun.file(T).arrayBuffer()),I=j(h),b=M.get(D);if(b&&b===I){E++,U?.(w+E,O.length,D);continue}await W.putObject({bucket:Y,key:D,body:h,contentType:N,cacheControl:x}),w++,U?.(w+E,O.length,D)}catch(h){_.push(`Failed to upload ${D}: ${h.message}`)}}return{uploaded:w,skipped:E,errors:_}}async function gZ($){return{invalidationId:(await new _0().invalidateAll($)).Id}}async function FB($,J="us-east-1"){let Y=new O0(J);try{let W=((await Y.describeStacks({stackName:$})).Stacks[0]?.Outputs||[]).find((z)=>z.OutputKey==="BucketName")?.OutputValue;if(W)await new F0(J).emptyBucket(W)}catch{}await Y.deleteStack($);let Q=await Y.waitForStackComplete($,60,1e4);return{success:Q.success||Q.status==="DELETE_COMPLETE",message:Q.success?"Static site deleted successfully":`Deletion failed: ${Q.status}`}}async function AB($){let{sourceDir:J,cleanBucket:Y=!1,onProgress:Q,...Z}=$;Q?.("infrastructure","Deploying CloudFormation stack...");let U=await vZ(Z);if(!U.success)return U;if(Y){Q?.("clean","Cleaning old files from S3...");try{await new F0(Z.region||"us-east-1").emptyBucket(U.bucket)}catch(G){console.log(`Note: Could not clean bucket: ${G.message}`)}}Q?.("upload","Uploading files to S3...");let W=await fZ({sourceDir:J,bucket:U.bucket,region:Z.region||"us-east-1",cacheControl:Z.cacheControl,onProgress:(G,H,A)=>{Q?.("upload",`${G}/${H}: ${A}`)}});if(W.errors.length>0)return{...U,success:!1,message:`Upload errors: ${W.errors.join(", ")}`,filesUploaded:W.uploaded};if(U.distributionId&&W.uploaded>0)Q?.("invalidate","Invalidating CloudFront cache..."),await gZ(U.distributionId);Q?.("complete","Deployment complete!");let z=W.skipped>0?`Deployed ${W.uploaded} files (${W.skipped} unchanged)`:`Deployed ${W.uploaded} files successfully`;return{...U,filesUploaded:W.uploaded,filesSkipped:W.skipped,message:z}}var u9=S0(()=>{S1();P1();l1();B9();s1();V5()});function KB($){let{bucketName:J,domain:Y,aliases:Q,certificateArn:Z,defaultRootObject:U="index.html",errorDocument:W="404.html",passthroughUrls:z=!1,singlePageApp:G=!1,dynamicApp:H=!1,computeOriginDomain:A,computeOriginPort:K=3008,computeOriginId:B="app-compute",retainOnStackDelete:j=!1}=$,X=j?{DeletionPolicy:"Retain",UpdateReplacePolicy:"Retain"}:{},O=H&&!!A,_=O?["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"]:["GET","HEAD"],w=O?["GET","HEAD"]:["GET","HEAD"],E={},M={};E.S3Bucket={Type:"AWS::S3::Bucket",...X,Properties:{BucketName:J,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:U,ErrorDocument:W}}},M.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},M.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},E.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",...X,Properties:{OriginAccessControlConfig:{Name:`OAC-${J}`,Description:`OAC for ${J}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}};let T;if(z&&O)T="InstallRootRedirectFunction",E[T]={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-install-root-redirect"},AutoPublish:!0,FunctionConfig:{Comment:"Redirect curl pantry.dev | bash (GET /) to /install.sh on S3",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
7135
7135
  var request = event.request;
7136
7136
  if (request.uri === '/' || request.uri === '') {
7137
7137
  return {
@@ -7157,7 +7157,7 @@ ${Object.entries($).filter(([U])=>!U.startsWith("@_")).map(([U,W])=>Z(U,W," ","
7157
7157
  }
7158
7158
 
7159
7159
  return request;
7160
- }`}};let D={Id:`S3-${J}`,DomainName:{"Fn::GetAtt":["S3Bucket","RegionalDomainName"]},S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{"Fn::GetAtt":["CloudFrontOAC","Id"]}},N=O?{Id:B,DomainName:A,CustomOriginConfig:{HTTPPort:K,HTTPSPort:443,OriginProtocolPolicy:"http-only",OriginSSLProtocols:["TLSv1.2"]}}:null,x=O?B:`S3-${J}`,h={Enabled:!0,DefaultRootObject:U,HttpVersion:"http2and3",IPV6Enabled:!0,PriceClass:"PriceClass_100",Origins:N?[N,D]:[D],DefaultCacheBehavior:{TargetOriginId:x,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:_,CachedMethods:w,Compress:!0,...O?{CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",OriginRequestPolicyId:"b689b0a8-53d0-40ab-baf2-68738e2966ac",...z&&T?{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[T,"FunctionARN"]}}]}:{}}:{CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",...!z&&{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":["UrlRewriteFunction","FunctionARN"]}}]}}},...O&&z?{CacheBehaviors:[{PathPattern:"/install.sh",TargetOriginId:`S3-${J}`,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"}]}:{},CustomErrorResponses:G?[{ErrorCode:403,ResponseCode:200,ResponsePagePath:`/${U}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:200,ResponsePagePath:`/${U}`,ErrorCachingMinTTL:300}]:[{ErrorCode:403,ResponseCode:404,ResponsePagePath:`/${W}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${W}`,ErrorCachingMinTTL:300}]};if(Y&&Z)h.Aliases=Q&&Q.length>0?Q:[Y],h.ViewerCertificate={AcmCertificateArn:Z,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else h.ViewerCertificate={CloudFrontDefaultCertificate:!0};return E.CloudFrontDistribution={Type:"AWS::CloudFront::Distribution",...X,DependsOn:["S3Bucket","CloudFrontOAC",...z&&O&&T?[T]:[],...!z?["UrlRewriteFunction"]:[]],Properties:{DistributionConfig:h}},M.DistributionId={Description:"CloudFront Distribution ID",Value:{Ref:"CloudFrontDistribution"}},M.DistributionDomain={Description:"CloudFront Distribution Domain",Value:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]}},E.S3BucketPolicy={Type:"AWS::S3::BucketPolicy",...X,DependsOn:["S3Bucket","CloudFrontDistribution"],Properties:{Bucket:{Ref:"S3Bucket"},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":"arn:aws:s3:::${S3Bucket}/*"},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":"arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"}}}}]}}},M.SiteUrl={Description:"Site URL",Value:Y?`https://${Y}`:{"Fn::Sub":"https://${CloudFrontDistribution.DomainName}"}},{AWSTemplateFormatVersion:"2010-09-09",Description:`Static site infrastructure for ${Y||J} (External DNS)`,Resources:E,Outputs:M}}async function w5($){let J=$.region||"us-east-1",Y="us-east-1",Q=$.domain,Z=$.bucket||Q.replace(/\./g,"-"),U=$.stackName||`${$.siteName}-static-site`,W=new O0("us-east-1"),z=new y0("us-east-1"),G=null;if(!$.skipDnsVerification){G=e0($.dnsProvider),console.log(`Verifying DNS provider can manage ${Q}...`);let k=await G.listRecords(Q);if(!k.success){let b=k.message||"unknown error — check API credentials and domain ownership";return{success:!1,stackName:U,bucket:Z,message:`DNS provider '${G.name}' cannot manage domain ${Q}: ${b}`}}console.log(`DNS provider '${G.name}' verified for ${Q}`)}else console.log(`Skipping DNS verification for ${Q}`);let H=$.certificateArn,B=Q.split(".").length===2?`www.${Q}`:void 0;if(!H){console.log(`Checking for existing SSL certificate for ${Q}...`);let k=await z.findCertificateByDomain(Q),b=!1;if(k&&k.Status==="ISSUED"){if(B&&k.SubjectAlternativeNames)b=k.SubjectAlternativeNames.includes(B)||k.SubjectAlternativeNames.some((I)=>I===`*.${Q}`);else b=!0;if(b)H=k.CertificateArn,console.log(`Found existing certificate with www coverage: ${H}`);else console.log(`Existing certificate doesn't cover ${B}, requesting new one...`)}if(!H){if(!G)return{success:!1,stackName:U,bucket:Z,message:`No DNS provider available to validate SSL certificate for ${Q}. Provide a certificateArn or enable DNS verification.`};console.log(`Requesting new SSL certificate for ${Q}${B?` (including ${B})`:""}...`);let f=await new f2(G,"us-east-1").findOrCreateCertificate({domainName:Q,subjectAlternativeNames:B?[B]:void 0,waitForValidation:!0,maxWaitMinutes:10});if(f.status!=="issued")return{success:!1,stackName:U,bucket:Z,message:`SSL certificate validation failed. Status: ${f.status}`};H=f.certificateArn,console.log(`Certificate issued: ${H}`)}}let j=!1,X;try{let k=await W.describeStacks({stackName:U});if(k.Stacks.length>0){let b=k.Stacks[0],I=b.StackStatus;if(I==="DELETE_IN_PROGRESS")console.log("Previous stack is still being deleted, waiting..."),await W.waitForStack(U,"stack-delete-complete"),j=!1;else if(I==="DELETE_COMPLETE")j=!1;else j=!0,X=(b.Outputs||[]).find((m)=>m.OutputKey==="BucketName")?.OutputValue}}catch(k){if(k.message?.includes("does not exist")||k.code==="ValidationError")j=!1;else throw k}let O=X||Z;if(!j){let k=new F0(J),b=new _0,I=!1;if(Q)try{console.log(`Checking for existing CloudFront distributions with alias ${Q}...`);let f=await b.listDistributions();for(let m of f){let l=[];if(m.Aliases?.Items){if(Array.isArray(m.Aliases.Items))l=m.Aliases.Items;else if(typeof m.Aliases.Items==="object"){let p=m.Aliases.Items.CNAME;if(typeof p==="string")l=[p];else if(Array.isArray(p))l=p}}if(l.includes(Q)){I=!0,console.log(`Found existing CloudFront distribution ${m.Id} with alias ${Q}`),console.log("Reusing existing infrastructure for updates...");let r=(await b.getDistributionConfig(m.Id)).DistributionConfig?.Origins?.Items,s;if(r){let o=[];if(Array.isArray(r))o=r;else if(r.Origin)o=Array.isArray(r.Origin)?r.Origin:[r.Origin];else o=[r];for(let B0 of o){let x0=(B0.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(x0){s=x0[1];break}}}if(s)return console.log(`Using existing S3 bucket: ${s}`),{success:!0,stackName:`existing-${m.Id}`,bucket:s,distributionId:m.Id,distributionDomain:m.DomainName,domain:Q,certificateArn:H,message:"Using existing CloudFront distribution",_existingInfrastructure:!0}}}}catch{}if(!I)try{if((await k.headBucket(Z)).exists){console.log(`Found orphaned S3 bucket ${Z}, cleaning up...`);try{let m=k.emptyBucket(Z).then(()=>k.deleteBucket(Z)),l=new Promise((p,r)=>setTimeout(()=>r(Error("Bucket cleanup timeout")),30000));await Promise.race([m,l]),console.log(`Deleted orphaned S3 bucket ${Z}`)}catch(m){console.log(`Note: Could not clean up S3 bucket: ${m.message}`);let l=Date.now().toString(36);O=`${Z}-${l}`,console.log(`Using alternative bucket name: ${O}`)}}}catch{}}let w=KB({bucketName:O,domain:Q,aliases:B?[Q,B]:[Q],certificateArn:H,defaultRootObject:$.defaultRootObject,errorDocument:$.errorDocument,passthroughUrls:$.passthroughUrls,singlePageApp:$.singlePageApp,dynamicApp:$.dynamicApp,computeOriginDomain:$.computeOriginDomain,computeOriginPort:$.computeOriginPort,computeOriginId:$.computeOriginId}),E=Object.entries($.tags||{}).map(([k,b])=>({Key:k,Value:b}));if(E.push({Key:"ManagedBy",Value:"ts-cloud"}),E.push({Key:"Application",Value:$.siteName}),G)E.push({Key:"DnsProvider",Value:G.name});let M,T=!1;if(j){T=!0,console.log(`Updating CloudFormation stack: ${U}`);try{M=(await W.updateStack({stackName:U,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:E})).StackId,console.log(`Update initiated, stack ID: ${M}`)}catch(k){if(k.message?.includes("No updates are to be performed")){let b=await W.describeStacks({stackName:U});M=b.Stacks[0].StackId;let I=b.Stacks[0]?.Outputs||[],f=(l)=>I.find((p)=>p.OutputKey===l)?.OutputValue,m=f("DistributionDomain");if(m)await L5(G,Q,m);return{success:!0,stackId:M,stackName:U,bucket:f("BucketName")||O,distributionId:f("DistributionId"),distributionDomain:m,domain:Q,certificateArn:H,message:"Static site infrastructure is already up to date"}}else throw k}}else console.log(`Creating CloudFormation stack: ${U}`),console.log(`Bucket name: ${O}`),console.log(`Domain: ${Q}`),console.log(`Certificate ARN: ${H}`),M=(await W.createStack({stackName:U,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:E,onFailure:"DELETE"})).StackId,console.log(`Create initiated, stack ID: ${M}`);console.log(`Waiting for stack to reach ${T?"stack-update-complete":"stack-create-complete"}...`);try{await W.waitForStack(U,T?"stack-update-complete":"stack-create-complete"),console.log("Stack operation completed successfully!")}catch(k){if(k.message?.includes("must be verified")||k.message?.includes("Access denied for operation")){console.log("CloudFront account verification required - checking for existing infrastructure...");try{let I=new _0,f=await I.listDistributions();for(let m of f){let l=[];if(m.Aliases?.Items){if(Array.isArray(m.Aliases.Items))l=m.Aliases.Items;else if(typeof m.Aliases.Items==="object"){let p=m.Aliases.Items.CNAME;if(typeof p==="string")l=[p];else if(Array.isArray(p))l=p}}if(l.includes(Q)){console.log(`Found existing CloudFront distribution ${m.Id} with alias ${Q}`),console.log("Using existing infrastructure despite account verification requirement...");let r=(await I.getDistributionConfig(m.Id)).DistributionConfig?.Origins?.Items,s;if(r){let o=[];if(Array.isArray(r))o=r;else if(r.Origin)o=Array.isArray(r.Origin)?r.Origin:[r.Origin];else o=[r];for(let B0 of o){let x0=(B0.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(x0){s=x0[1];break}}}if(s){console.log(`Using existing S3 bucket: ${s}`);let o=m.DomainName;if(o)await L5(G,Q,o);return{success:!0,stackName:`existing-${m.Id}`,bucket:s,distributionId:m.Id,distributionDomain:m.DomainName,domain:Q,certificateArn:H,message:"Using existing CloudFront distribution (account verification pending for new distributions)"}}}}}catch{}return console.log(`
7160
+ }`}};let D={Id:`S3-${J}`,DomainName:{"Fn::GetAtt":["S3Bucket","RegionalDomainName"]},S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{"Fn::GetAtt":["CloudFrontOAC","Id"]}},N=O?{Id:B,DomainName:A,CustomOriginConfig:{HTTPPort:K,HTTPSPort:443,OriginProtocolPolicy:"http-only",OriginSSLProtocols:["TLSv1.2"]}}:null,x=O?B:`S3-${J}`,h={Enabled:!0,DefaultRootObject:U,HttpVersion:"http2and3",IPV6Enabled:!0,PriceClass:"PriceClass_100",Origins:N?[N,D]:[D],DefaultCacheBehavior:{TargetOriginId:x,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:_,CachedMethods:w,Compress:!0,...O?{CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",OriginRequestPolicyId:"b689b0a8-53d0-40ab-baf2-68738e2966ac",...z&&T?{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[T,"FunctionARN"]}}]}:{}}:{CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",...!z&&{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":["UrlRewriteFunction","FunctionARN"]}}]}}},...O&&z?{CacheBehaviors:[{PathPattern:"/install.sh",TargetOriginId:`S3-${J}`,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"}]}:{},CustomErrorResponses:G?[{ErrorCode:403,ResponseCode:200,ResponsePagePath:`/${U}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:200,ResponsePagePath:`/${U}`,ErrorCachingMinTTL:300}]:[{ErrorCode:403,ResponseCode:404,ResponsePagePath:`/${W}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${W}`,ErrorCachingMinTTL:300}]};if(Y&&Z)h.Aliases=Q&&Q.length>0?Q:[Y],h.ViewerCertificate={AcmCertificateArn:Z,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else h.ViewerCertificate={CloudFrontDefaultCertificate:!0};return E.CloudFrontDistribution={Type:"AWS::CloudFront::Distribution",...X,DependsOn:["S3Bucket","CloudFrontOAC",...z&&O&&T?[T]:[],...!z?["UrlRewriteFunction"]:[]],Properties:{DistributionConfig:h}},M.DistributionId={Description:"CloudFront Distribution ID",Value:{Ref:"CloudFrontDistribution"}},M.DistributionDomain={Description:"CloudFront Distribution Domain",Value:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]}},E.S3BucketPolicy={Type:"AWS::S3::BucketPolicy",...X,DependsOn:["S3Bucket","CloudFrontDistribution"],Properties:{Bucket:{Ref:"S3Bucket"},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":"arn:aws:s3:::${S3Bucket}/*"},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":"arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"}}}}]}}},M.SiteUrl={Description:"Site URL",Value:Y?`https://${Y}`:{"Fn::Sub":"https://${CloudFrontDistribution.DomainName}"}},{AWSTemplateFormatVersion:"2010-09-09",Description:`Static site infrastructure for ${Y||J} (External DNS)`,Resources:E,Outputs:M}}async function w5($){let J=$.region||"us-east-1",Y="us-east-1",Q=$.domain,Z=$.bucket||Q.replace(/\./g,"-"),U=$.stackName||`${$.siteName}-static-site`,W=new O0("us-east-1"),z=new y0("us-east-1"),G=null;if(!$.skipDnsVerification){G=e0($.dnsProvider),console.log(`Verifying DNS provider can manage ${Q}...`);let I=await G.listRecords(Q);if(!I.success){let b=I.message||"unknown error — check API credentials and domain ownership";return{success:!1,stackName:U,bucket:Z,message:`DNS provider '${G.name}' cannot manage domain ${Q}: ${b}`}}console.log(`DNS provider '${G.name}' verified for ${Q}`)}else console.log(`Skipping DNS verification for ${Q}`);let H=$.certificateArn,B=Q.split(".").length===2?`www.${Q}`:void 0;if(!H){console.log(`Checking for existing SSL certificate for ${Q}...`);let I=await z.findCertificateByDomain(Q),b=!1;if(I&&I.Status==="ISSUED"){if(B&&I.SubjectAlternativeNames)b=I.SubjectAlternativeNames.includes(B)||I.SubjectAlternativeNames.some((k)=>k===`*.${Q}`);else b=!0;if(b)H=I.CertificateArn,console.log(`Found existing certificate with www coverage: ${H}`);else console.log(`Existing certificate doesn't cover ${B}, requesting new one...`)}if(!H){if(!G)return{success:!1,stackName:U,bucket:Z,message:`No DNS provider available to validate SSL certificate for ${Q}. Provide a certificateArn or enable DNS verification.`};console.log(`Requesting new SSL certificate for ${Q}${B?` (including ${B})`:""}...`);let y=await new f2(G,"us-east-1").findOrCreateCertificate({domainName:Q,subjectAlternativeNames:B?[B]:void 0,waitForValidation:!0,maxWaitMinutes:10});if(y.status!=="issued")return{success:!1,stackName:U,bucket:Z,message:`SSL certificate validation failed. Status: ${y.status}`};H=y.certificateArn,console.log(`Certificate issued: ${H}`)}}let j=!1,X;try{let I=await W.describeStacks({stackName:U});if(I.Stacks.length>0){let b=I.Stacks[0],k=b.StackStatus;if(k==="DELETE_IN_PROGRESS")console.log("Previous stack is still being deleted, waiting..."),await W.waitForStack(U,"stack-delete-complete"),j=!1;else if(k==="DELETE_COMPLETE")j=!1;else j=!0,X=(b.Outputs||[]).find((m)=>m.OutputKey==="BucketName")?.OutputValue}}catch(I){if(I.message?.includes("does not exist")||I.code==="ValidationError")j=!1;else throw I}let O=X||Z;if(!j){let I=new F0(J),b=new _0,k=!1;if(Q)try{console.log(`Checking for existing CloudFront distributions with alias ${Q}...`);let y=await b.listDistributions();for(let m of y){let l=[];if(m.Aliases?.Items){if(Array.isArray(m.Aliases.Items))l=m.Aliases.Items;else if(typeof m.Aliases.Items==="object"){let p=m.Aliases.Items.CNAME;if(typeof p==="string")l=[p];else if(Array.isArray(p))l=p}}if(l.includes(Q)){k=!0,console.log(`Found existing CloudFront distribution ${m.Id} with alias ${Q}`),console.log("Reusing existing infrastructure for updates...");let r=(await b.getDistributionConfig(m.Id)).DistributionConfig?.Origins?.Items,s;if(r){let o=[];if(Array.isArray(r))o=r;else if(r.Origin)o=Array.isArray(r.Origin)?r.Origin:[r.Origin];else o=[r];for(let B0 of o){let x0=(B0.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(x0){s=x0[1];break}}}if(s)return console.log(`Using existing S3 bucket: ${s}`),{success:!0,stackName:`existing-${m.Id}`,bucket:s,distributionId:m.Id,distributionDomain:m.DomainName,domain:Q,certificateArn:H,message:"Using existing CloudFront distribution",_existingInfrastructure:!0}}}}catch{}if(!k)try{if((await I.headBucket(Z)).exists){console.log(`Found orphaned S3 bucket ${Z}, cleaning up...`);try{let m=I.emptyBucket(Z).then(()=>I.deleteBucket(Z)),l=new Promise((p,r)=>setTimeout(()=>r(Error("Bucket cleanup timeout")),30000));await Promise.race([m,l]),console.log(`Deleted orphaned S3 bucket ${Z}`)}catch(m){console.log(`Note: Could not clean up S3 bucket: ${m.message}`);let l=Date.now().toString(36);O=`${Z}-${l}`,console.log(`Using alternative bucket name: ${O}`)}}}catch{}}let w=KB({bucketName:O,domain:Q,aliases:B?[Q,B]:[Q],certificateArn:H,defaultRootObject:$.defaultRootObject,errorDocument:$.errorDocument,passthroughUrls:$.passthroughUrls,singlePageApp:$.singlePageApp,dynamicApp:$.dynamicApp,computeOriginDomain:$.computeOriginDomain,computeOriginPort:$.computeOriginPort,computeOriginId:$.computeOriginId}),E=Object.entries($.tags||{}).map(([I,b])=>({Key:I,Value:b}));if(E.push({Key:"ManagedBy",Value:"ts-cloud"}),E.push({Key:"Application",Value:$.siteName}),G)E.push({Key:"DnsProvider",Value:G.name});let M,T=!1;if(j){T=!0,console.log(`Updating CloudFormation stack: ${U}`);try{M=(await W.updateStack({stackName:U,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:E})).StackId,console.log(`Update initiated, stack ID: ${M}`)}catch(I){if(I.message?.includes("No updates are to be performed")){let b=await W.describeStacks({stackName:U});M=b.Stacks[0].StackId;let k=b.Stacks[0]?.Outputs||[],y=(l)=>k.find((p)=>p.OutputKey===l)?.OutputValue,m=y("DistributionDomain");if(m)await L5(G,Q,m);return{success:!0,stackId:M,stackName:U,bucket:y("BucketName")||O,distributionId:y("DistributionId"),distributionDomain:m,domain:Q,certificateArn:H,message:"Static site infrastructure is already up to date"}}else throw I}}else console.log(`Creating CloudFormation stack: ${U}`),console.log(`Bucket name: ${O}`),console.log(`Domain: ${Q}`),console.log(`Certificate ARN: ${H}`),M=(await W.createStack({stackName:U,templateBody:JSON.stringify(w),capabilities:["CAPABILITY_IAM"],tags:E,onFailure:"DELETE"})).StackId,console.log(`Create initiated, stack ID: ${M}`);console.log(`Waiting for stack to reach ${T?"stack-update-complete":"stack-create-complete"}...`);try{await W.waitForStack(U,T?"stack-update-complete":"stack-create-complete"),console.log("Stack operation completed successfully!")}catch(I){if(I.message?.includes("must be verified")||I.message?.includes("Access denied for operation")){console.log("CloudFront account verification required - checking for existing infrastructure...");try{let k=new _0,y=await k.listDistributions();for(let m of y){let l=[];if(m.Aliases?.Items){if(Array.isArray(m.Aliases.Items))l=m.Aliases.Items;else if(typeof m.Aliases.Items==="object"){let p=m.Aliases.Items.CNAME;if(typeof p==="string")l=[p];else if(Array.isArray(p))l=p}}if(l.includes(Q)){console.log(`Found existing CloudFront distribution ${m.Id} with alias ${Q}`),console.log("Using existing infrastructure despite account verification requirement...");let r=(await k.getDistributionConfig(m.Id)).DistributionConfig?.Origins?.Items,s;if(r){let o=[];if(Array.isArray(r))o=r;else if(r.Origin)o=Array.isArray(r.Origin)?r.Origin:[r.Origin];else o=[r];for(let B0 of o){let x0=(B0.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(x0){s=x0[1];break}}}if(s){console.log(`Using existing S3 bucket: ${s}`);let o=m.DomainName;if(o)await L5(G,Q,o);return{success:!0,stackName:`existing-${m.Id}`,bucket:s,distributionId:m.Id,distributionDomain:m.DomainName,domain:Q,certificateArn:H,message:"Using existing CloudFront distribution (account verification pending for new distributions)"}}}}}catch{}return console.log(`
7161
7161
  ┌─────────────────────────────────────────────────────────────────────────────┐
7162
7162
  │ AWS ACCOUNT VERIFICATION REQUIRED │
7163
7163
  ├─────────────────────────────────────────────────────────────────────────────┤
@@ -7175,7 +7175,7 @@ ${Object.entries($).filter(([U])=>!U.startsWith("@_")).map(([U,W])=>Z(U,W," ","
7175
7175
  │ │
7176
7176
  │ Verification typically takes 1-2 business days. │
7177
7177
  │ After verification, re-run: bunx bunpress deploy │
7178
- └─────────────────────────────────────────────────────────────────────────────┘`),{success:!1,stackId:M,stackName:U,bucket:O,message:"CloudFront account verification required. Please contact AWS Support."}}return{success:!1,stackId:M,stackName:U,bucket:O,message:`Stack deployment failed: ${k.message}`}}let N=(await W.describeStacks({stackName:U})).Stacks[0]?.Outputs||[],x=(k)=>N.find((b)=>b.OutputKey===k)?.OutputValue,h=x("DistributionDomain");if(h&&G)console.log(`Creating DNS records via ${G.name}...`),await L5(G,Q,h);else if(h&&!G)console.log("Skipping DNS record creation (DNS verification was skipped)");return{success:!0,stackId:M,stackName:U,bucket:x("BucketName")||O,distributionId:x("DistributionId"),distributionDomain:h,domain:Q,certificateArn:H,message:"Static site infrastructure deployed successfully with external DNS"}}async function L5($,J,Y){if(!$){console.log("Skipping DNS record creation (DNS verification was skipped)");return}if(J.split(".").length===2)if($ instanceof v2){console.log(`Creating Route53 alias record for apex domain ${J} -> ${Y}`);let U=await $.createCloudFrontAlias({domain:J,name:J,cloudFrontDomainName:Y});if(!U.success)console.warn(`Warning: Could not create Route53 alias record: ${U.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created Route53 alias record: ${J} -> ${Y}`);let W=`www.${J}`;console.log(`Creating Route53 alias record for ${W} -> ${Y}`);let z=await $.createCloudFrontAlias({domain:J,name:W,cloudFrontDomainName:Y});if(!z.success)console.warn(`Warning: Could not create www Route53 alias: ${z.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${W} -> ${Y}`);else console.log(`Created Route53 alias record: ${W} -> ${Y}`)}else{try{let G=await $.listRecords(J,"A");if(G.success)for(let H of G.records){let A=H.name.replace(/\.$/,"");if(A===J||A==="")console.log(`Removing existing root A record (${H.content}) to make room for ALIAS...`),await $.deleteRecord(J,{name:J,type:"A",content:H.content})}}catch(G){console.log(`Note: Could not check for conflicting A records: ${G instanceof Error?G.message:G}`)}console.log(`Creating ALIAS record for apex domain ${J} -> ${Y}`);let U=await $.upsertRecord(J,{name:J,type:"ALIAS",content:Y,ttl:600});if(!U.success)console.warn(`Warning: Could not create ALIAS record: ${U.message}`),console.warn("Please manually create an ALIAS record in your DNS provider:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created ALIAS record: ${J} -> ${Y}`);let W=`www.${J}`;console.log(`Creating CNAME record for ${W} -> ${Y}`);let z=await $.upsertRecord(J,{name:W,type:"CNAME",content:Y,ttl:600});if(!z.success)console.warn(`Warning: Could not create www DNS record: ${z.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${W} -> ${Y}`);else console.log(`Created CNAME record: ${W} -> ${Y}`)}else{console.log(`Creating CNAME record for ${J} -> ${Y}`);let U=await $.upsertRecord(J,{name:J,type:"CNAME",content:Y,ttl:600});if(!U.success)console.warn(`Warning: Could not create DNS record: ${U.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created CNAME record: ${J} -> ${Y}`)}}async function uZ($){let{sourceDir:J,cleanBucket:Y=!1,onProgress:Q,...Z}=$;Q?.("infrastructure","Deploying CloudFormation stack...");let U=await w5(Z);if(!U.success)return U;if(Y){Q?.("clean","Cleaning old files from S3...");try{await new F0(Z.region||"us-east-1").emptyBucket(U.bucket)}catch(H){console.log(`Note: Could not clean bucket: ${H.message}`)}}Q?.("upload","Uploading files to S3...");let{uploadStaticFiles:W}=await Promise.resolve().then(() => (u9(),g9)),z=await W({sourceDir:J,bucket:U.bucket,region:Z.region||"us-east-1",cacheControl:Z.cacheControl,onProgress:(H,A,K)=>{Q?.("upload",`${H}/${A}: ${K}`)}});if(z.errors.length>0)return{...U,success:!1,message:`Upload errors: ${z.errors.join(", ")}`,filesUploaded:z.uploaded};if(U.distributionId&&z.uploaded>0){Q?.("invalidate","Invalidating CloudFront cache...");let{invalidateCache:H}=await Promise.resolve().then(() => (u9(),g9));await H(U.distributionId)}Q?.("complete","Deployment complete!");let G=z.skipped>0?`Deployed ${z.uploaded} files (${z.skipped} unchanged) with external DNS`:`Deployed ${z.uploaded} files successfully with external DNS`;return{...U,filesUploaded:z.uploaded,filesSkipped:z.skipped,message:G}}var V5=S0(()=>{S1();P1();l1();s1();B2();j9();Q6()});var dZ={};Z1(dZ,{EC2Client:()=>m0});class m0{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}async describeInstances($){let J={Action:"DescribeInstances",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Z,U)=>{J[`InstanceId.${U+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,U)=>{J[`Filter.${U+1}.Name`]=Z.Name,Z.Values.forEach((W,z)=>{J[`Filter.${U+1}.Value.${z+1}`]=W})});if($?.MaxResults)J.MaxResults=String($.MaxResults);if($?.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeInstancesResponse||Y;return{Reservations:this.parseReservations(Q.reservationSet?.item),NextToken:Q.nextToken}}async getInstance($){return(await this.describeInstances({InstanceIds:[$]})).Reservations?.[0]?.Instances?.[0]}async getConsoleOutput($,J){let Y={Action:"GetConsoleOutput",Version:"2016-11-15",InstanceId:$};if(J)Y.Latest="true";let Q=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()}),Z=Q.GetConsoleOutputResponse||Q;return{InstanceId:Z.instanceId,Output:Z.output,Timestamp:Z.timestamp}}async getConsoleOutputDecoded($,J){let Y=await this.getConsoleOutput($,J?.latest);if(!Y.Output)return"No console output available yet";let Q=Buffer.from(Y.Output,"base64").toString("utf-8");if(J?.tailLines)return Q.split(`
7178
+ └─────────────────────────────────────────────────────────────────────────────┘`),{success:!1,stackId:M,stackName:U,bucket:O,message:"CloudFront account verification required. Please contact AWS Support."}}return{success:!1,stackId:M,stackName:U,bucket:O,message:`Stack deployment failed: ${I.message}`}}let N=(await W.describeStacks({stackName:U})).Stacks[0]?.Outputs||[],x=(I)=>N.find((b)=>b.OutputKey===I)?.OutputValue,h=x("DistributionDomain");if(h&&G)console.log(`Creating DNS records via ${G.name}...`),await L5(G,Q,h);else if(h&&!G)console.log("Skipping DNS record creation (DNS verification was skipped)");return{success:!0,stackId:M,stackName:U,bucket:x("BucketName")||O,distributionId:x("DistributionId"),distributionDomain:h,domain:Q,certificateArn:H,message:"Static site infrastructure deployed successfully with external DNS"}}async function L5($,J,Y){if(!$){console.log("Skipping DNS record creation (DNS verification was skipped)");return}if(J.split(".").length===2)if($ instanceof v2){console.log(`Creating Route53 alias record for apex domain ${J} -> ${Y}`);let U=await $.createCloudFrontAlias({domain:J,name:J,cloudFrontDomainName:Y});if(!U.success)console.warn(`Warning: Could not create Route53 alias record: ${U.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created Route53 alias record: ${J} -> ${Y}`);let W=`www.${J}`;console.log(`Creating Route53 alias record for ${W} -> ${Y}`);let z=await $.createCloudFrontAlias({domain:J,name:W,cloudFrontDomainName:Y});if(!z.success)console.warn(`Warning: Could not create www Route53 alias: ${z.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${W} -> ${Y}`);else console.log(`Created Route53 alias record: ${W} -> ${Y}`)}else{try{let G=await $.listRecords(J,"A");if(G.success)for(let H of G.records){let A=H.name.replace(/\.$/,"");if(A===J||A==="")console.log(`Removing existing root A record (${H.content}) to make room for ALIAS...`),await $.deleteRecord(J,{name:J,type:"A",content:H.content})}}catch(G){console.log(`Note: Could not check for conflicting A records: ${G instanceof Error?G.message:G}`)}console.log(`Creating ALIAS record for apex domain ${J} -> ${Y}`);let U=await $.upsertRecord(J,{name:J,type:"ALIAS",content:Y,ttl:600});if(!U.success)console.warn(`Warning: Could not create ALIAS record: ${U.message}`),console.warn("Please manually create an ALIAS record in your DNS provider:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created ALIAS record: ${J} -> ${Y}`);let W=`www.${J}`;console.log(`Creating CNAME record for ${W} -> ${Y}`);let z=await $.upsertRecord(J,{name:W,type:"CNAME",content:Y,ttl:600});if(!z.success)console.warn(`Warning: Could not create www DNS record: ${z.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${W} -> ${Y}`);else console.log(`Created CNAME record: ${W} -> ${Y}`)}else{console.log(`Creating CNAME record for ${J} -> ${Y}`);let U=await $.upsertRecord(J,{name:J,type:"CNAME",content:Y,ttl:600});if(!U.success)console.warn(`Warning: Could not create DNS record: ${U.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created CNAME record: ${J} -> ${Y}`)}}async function uZ($){let{sourceDir:J,cleanBucket:Y=!1,onProgress:Q,...Z}=$;Q?.("infrastructure","Deploying CloudFormation stack...");let U=await w5(Z);if(!U.success)return U;if(Y){Q?.("clean","Cleaning old files from S3...");try{await new F0(Z.region||"us-east-1").emptyBucket(U.bucket)}catch(H){console.log(`Note: Could not clean bucket: ${H.message}`)}}Q?.("upload","Uploading files to S3...");let{uploadStaticFiles:W}=await Promise.resolve().then(() => (u9(),g9)),z=await W({sourceDir:J,bucket:U.bucket,region:Z.region||"us-east-1",cacheControl:Z.cacheControl,onProgress:(H,A,K)=>{Q?.("upload",`${H}/${A}: ${K}`)}});if(z.errors.length>0)return{...U,success:!1,message:`Upload errors: ${z.errors.join(", ")}`,filesUploaded:z.uploaded};if(U.distributionId&&z.uploaded>0){Q?.("invalidate","Invalidating CloudFront cache...");let{invalidateCache:H}=await Promise.resolve().then(() => (u9(),g9));await H(U.distributionId)}Q?.("complete","Deployment complete!");let G=z.skipped>0?`Deployed ${z.uploaded} files (${z.skipped} unchanged) with external DNS`:`Deployed ${z.uploaded} files successfully with external DNS`;return{...U,filesUploaded:z.uploaded,filesSkipped:z.skipped,message:G}}var V5=S0(()=>{S1();P1();l1();s1();B2();j9();Q6()});var dZ={};Z1(dZ,{EC2Client:()=>m0});class m0{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}async describeInstances($){let J={Action:"DescribeInstances",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Z,U)=>{J[`InstanceId.${U+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,U)=>{J[`Filter.${U+1}.Name`]=Z.Name,Z.Values.forEach((W,z)=>{J[`Filter.${U+1}.Value.${z+1}`]=W})});if($?.MaxResults)J.MaxResults=String($.MaxResults);if($?.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeInstancesResponse||Y;return{Reservations:this.parseReservations(Q.reservationSet?.item),NextToken:Q.nextToken}}async getInstance($){return(await this.describeInstances({InstanceIds:[$]})).Reservations?.[0]?.Instances?.[0]}async getConsoleOutput($,J){let Y={Action:"GetConsoleOutput",Version:"2016-11-15",InstanceId:$};if(J)Y.Latest="true";let Q=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()}),Z=Q.GetConsoleOutputResponse||Q;return{InstanceId:Z.instanceId,Output:Z.output,Timestamp:Z.timestamp}}async getConsoleOutputDecoded($,J){let Y=await this.getConsoleOutput($,J?.latest);if(!Y.Output)return"No console output available yet";let Q=Buffer.from(Y.Output,"base64").toString("utf-8");if(J?.tailLines)return Q.split(`
7179
7179
  `).slice(-J.tailLines).join(`
7180
7180
  `);return Q}async describeInstanceStatus($){let J={Action:"DescribeInstanceStatus",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Q,Z)=>{J[`InstanceId.${Z+1}`]=Q});if($?.IncludeAllInstances)J.IncludeAllInstances="true";if($?.Filters)$.Filters.forEach((Q,Z)=>{J[`Filter.${Z+1}.Name`]=Q.Name,Q.Values.forEach((U,W)=>{J[`Filter.${Z+1}.Value.${W+1}`]=U})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InstanceStatuses:this.parseArray(Y.instanceStatusSet?.item).map((Q)=>({InstanceId:Q.instanceId,InstanceState:Q.instanceState?{Code:Number.parseInt(Q.instanceState.code),Name:Q.instanceState.name}:void 0,InstanceStatus:Q.instanceStatus?{Status:Q.instanceStatus.status,Details:this.parseArray(Q.instanceStatus.details?.item).map((Z)=>({Name:Z.name,Status:Z.status}))}:void 0,SystemStatus:Q.systemStatus?{Status:Q.systemStatus.status,Details:this.parseArray(Q.systemStatus.details?.item).map((Z)=>({Name:Z.name,Status:Z.status}))}:void 0}))}}async startInstances($){let J={Action:"StartInstances",Version:"2016-11-15"};$.forEach((Q,Z)=>{J[`InstanceId.${Z+1}`]=Q});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{StartingInstances:this.parseArray(Y.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async stopInstances($,J){let Y={Action:"StopInstances",Version:"2016-11-15"};if($.forEach((Z,U)=>{Y[`InstanceId.${U+1}`]=Z}),J)Y.Force="true";let Q=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()});return{StoppingInstances:this.parseArray(Q.instancesSet?.item).map((Z)=>({InstanceId:Z.instanceId,CurrentState:Z.currentState?{Name:Z.currentState.name}:void 0,PreviousState:Z.previousState?{Name:Z.previousState.name}:void 0}))}}async rebootInstances($){let J={Action:"RebootInstances",Version:"2016-11-15"};$.forEach((Y,Q)=>{J[`InstanceId.${Q+1}`]=Y}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async terminateInstances($){let J={Action:"TerminateInstances",Version:"2016-11-15"};$.forEach((Q,Z)=>{J[`InstanceId.${Z+1}`]=Q});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{TerminatingInstances:this.parseArray(Y.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async describeVpcs($){let J={Action:"DescribeVpcs",Version:"2016-11-15"};if($?.VpcIds)$.VpcIds.forEach((Q,Z)=>{J[`VpcId.${Z+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,Z)=>{J[`Filter.${Z+1}.Name`]=Q.Name,Q.Values.forEach((U,W)=>{J[`Filter.${Z+1}.Value.${W+1}`]=U})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Vpcs:this.parseArray(Y.vpcSet?.item).map((Q)=>({VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,State:Q.state,DhcpOptionsId:Q.dhcpOptionsId,InstanceTenancy:Q.instanceTenancy,IsDefault:Q.isDefault==="true",Tags:this.parseTags(Q.tagSet?.item)}))}}async describeSubnets($){let J={Action:"DescribeSubnets",Version:"2016-11-15"};if($?.SubnetIds)$.SubnetIds.forEach((Q,Z)=>{J[`SubnetId.${Z+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,Z)=>{J[`Filter.${Z+1}.Name`]=Q.Name,Q.Values.forEach((U,W)=>{J[`Filter.${Z+1}.Value.${W+1}`]=U})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Subnets:this.parseArray(Y.subnetSet?.item).map((Q)=>({SubnetId:Q.subnetId,VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,AvailabilityZone:Q.availabilityZone,AvailableIpAddressCount:Number.parseInt(Q.availableIpAddressCount),State:Q.state,MapPublicIpOnLaunch:Q.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Q.tagSet?.item)}))}}async describeSecurityGroups($){let J={Action:"DescribeSecurityGroups",Version:"2016-11-15"};if($?.GroupIds)$.GroupIds.forEach((Q,Z)=>{J[`GroupId.${Z+1}`]=Q});if($?.GroupNames)$.GroupNames.forEach((Q,Z)=>{J[`GroupName.${Z+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,Z)=>{J[`Filter.${Z+1}.Name`]=Q.Name,Q.Values.forEach((U,W)=>{J[`Filter.${Z+1}.Value.${W+1}`]=U})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{SecurityGroups:this.parseArray(Y.securityGroupInfo?.item).map((Q)=>({GroupId:Q.groupId,GroupName:Q.groupName,Description:Q.groupDescription,VpcId:Q.vpcId,IpPermissions:this.parseIpPermissions(Q.ipPermissions?.item),IpPermissionsEgress:this.parseIpPermissions(Q.ipPermissionsEgress?.item),Tags:this.parseTags(Q.tagSet?.item)}))}}async describeInternetGateways($){let J={Action:"DescribeInternetGateways",Version:"2016-11-15"};if($?.InternetGatewayIds)$.InternetGatewayIds.forEach((Q,Z)=>{J[`InternetGatewayId.${Z+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,Z)=>{J[`Filter.${Z+1}.Name`]=Q.Name,Q.Values.forEach((U,W)=>{J[`Filter.${Z+1}.Value.${W+1}`]=U})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InternetGateways:this.parseArray(Y.internetGatewaySet?.item).map((Q)=>({InternetGatewayId:Q.internetGatewayId,Attachments:this.parseArray(Q.attachmentSet?.item).map((Z)=>({VpcId:Z.vpcId,State:Z.state})),Tags:this.parseTags(Q.tagSet?.item)}))}}async describeAddresses($){let J={Action:"DescribeAddresses",Version:"2016-11-15"};if($?.AllocationIds)$.AllocationIds.forEach((Q,Z)=>{J[`AllocationId.${Z+1}`]=Q});if($?.PublicIps)$.PublicIps.forEach((Q,Z)=>{J[`PublicIp.${Z+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,Z)=>{J[`Filter.${Z+1}.Name`]=Q.Name,Q.Values.forEach((U,W)=>{J[`Filter.${Z+1}.Value.${W+1}`]=U})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Addresses:this.parseArray(Y.addressesSet?.item).map((Q)=>({PublicIp:Q.publicIp,AllocationId:Q.allocationId,AssociationId:Q.associationId,InstanceId:Q.instanceId,NetworkInterfaceId:Q.networkInterfaceId,PrivateIpAddress:Q.privateIpAddress,Domain:Q.domain,Tags:this.parseTags(Q.tagSet?.item)}))}}async allocateAddress($){let J={Action:"AllocateAddress",Version:"2016-11-15"};if($?.Domain)J.Domain=$.Domain;if($?.TagSpecifications)$.TagSpecifications.forEach((Q,Z)=>{J[`TagSpecification.${Z+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((U,W)=>{J[`TagSpecification.${Z+1}.Tag.${W+1}.Key`]=U.Key,J[`TagSpecification.${Z+1}.Tag.${W+1}.Value`]=U.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{AllocationId:Y.allocationId,PublicIp:Y.publicIp,Domain:Y.domain}}async associateAddress($){let J={Action:"AssociateAddress",Version:"2016-11-15"};if($.AllocationId)J.AllocationId=$.AllocationId;if($.PublicIp)J.PublicIp=$.PublicIp;if($.InstanceId)J.InstanceId=$.InstanceId;if($.NetworkInterfaceId)J.NetworkInterfaceId=$.NetworkInterfaceId;if($.PrivateIpAddress)J.PrivateIpAddress=$.PrivateIpAddress;if($.AllowReassociation)J.AllowReassociation="true";return{AssociationId:(await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})).associationId}}async createTags($){let J={Action:"CreateTags",Version:"2016-11-15"};$.Resources.forEach((Y,Q)=>{J[`ResourceId.${Q+1}`]=Y}),$.Tags.forEach((Y,Q)=>{J[`Tag.${Q+1}.Key`]=Y.Key,J[`Tag.${Q+1}.Value`]=Y.Value}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async waitForInstanceState($,J,Y){let Q=Y?.maxWaitMs||300000,Z=Y?.pollIntervalMs||5000,U=Date.now();while(Date.now()-U<Q){let W=await this.getInstance($);if(W?.State?.Name===J)return W;await new Promise((z)=>setTimeout(z,Z))}return}async createVpc($){let J={Action:"CreateVpc",Version:"2016-11-15",CidrBlock:$.CidrBlock};if($.InstanceTenancy)J.InstanceTenancy=$.InstanceTenancy;if($.TagSpecifications)$.TagSpecifications.forEach((U,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=U.ResourceType,U.Tags.forEach((z,G)=>{J[`TagSpecification.${W+1}.Tag.${G+1}.Key`]=z.Key,J[`TagSpecification.${W+1}.Tag.${G+1}.Value`]=z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=(Y.CreateVpcResponse||Y).vpc;return{Vpc:Z?{VpcId:Z.vpcId,CidrBlock:Z.cidrBlock,State:Z.state,DhcpOptionsId:Z.dhcpOptionsId,InstanceTenancy:Z.instanceTenancy,IsDefault:Z.isDefault==="true",Tags:this.parseTags(Z.tagSet?.item)}:void 0}}async createSubnet($){let J={Action:"CreateSubnet",Version:"2016-11-15",VpcId:$.VpcId,CidrBlock:$.CidrBlock};if($.AvailabilityZone)J.AvailabilityZone=$.AvailabilityZone;if($.TagSpecifications)$.TagSpecifications.forEach((U,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=U.ResourceType,U.Tags.forEach((z,G)=>{J[`TagSpecification.${W+1}.Tag.${G+1}.Key`]=z.Key,J[`TagSpecification.${W+1}.Tag.${G+1}.Value`]=z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=(Y.CreateSubnetResponse||Y).subnet;return{Subnet:Z?{SubnetId:Z.subnetId,VpcId:Z.vpcId,CidrBlock:Z.cidrBlock,AvailabilityZone:Z.availabilityZone,AvailableIpAddressCount:Z.availableIpAddressCount?Number.parseInt(Z.availableIpAddressCount):void 0,State:Z.state,MapPublicIpOnLaunch:Z.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Z.tagSet?.item)}:void 0}}async modifySubnetAttribute($){let J={Action:"ModifySubnetAttribute",Version:"2016-11-15",SubnetId:$.SubnetId};if($.MapPublicIpOnLaunch!==void 0)J["MapPublicIpOnLaunch.Value"]=String($.MapPublicIpOnLaunch.Value);await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async createSecurityGroup($){let J={Action:"CreateSecurityGroup",Version:"2016-11-15",GroupName:$.GroupName,GroupDescription:$.Description};if($.VpcId)J.VpcId=$.VpcId;if($.TagSpecifications)$.TagSpecifications.forEach((Z,U)=>{J[`TagSpecification.${U+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((W,z)=>{J[`TagSpecification.${U+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${U+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{GroupId:(Y.CreateSecurityGroupResponse||Y).groupId}}async authorizeSecurityGroupIngress($){let J={Action:"AuthorizeSecurityGroupIngress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async authorizeSecurityGroupEgress($){let J={Action:"AuthorizeSecurityGroupEgress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRouteTables($){let J={Action:"DescribeRouteTables",Version:"2016-11-15"};if($?.RouteTableIds)$.RouteTableIds.forEach((Z,U)=>{J[`RouteTableId.${U+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,U)=>{J[`Filter.${U+1}.Name`]=Z.Name,Z.Values.forEach((W,z)=>{J[`Filter.${U+1}.Value.${z+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeRouteTablesResponse||Y;return{RouteTables:this.parseArray(Q.routeTableSet?.item).map((Z)=>({RouteTableId:Z.routeTableId,VpcId:Z.vpcId,Routes:this.parseArray(Z.routeSet?.item).map((U)=>({DestinationCidrBlock:U.destinationCidrBlock,GatewayId:U.gatewayId,NatGatewayId:U.natGatewayId,State:U.state})),Associations:this.parseArray(Z.associationSet?.item).map((U)=>({RouteTableAssociationId:U.routeTableAssociationId,SubnetId:U.subnetId,Main:U.main==="true"||U.main===!0})),Tags:this.parseTags(Z.tagSet?.item)}))}}async deleteVpc($){let J={Action:"DeleteVpc",Version:"2016-11-15",VpcId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSubnet($){let J={Action:"DeleteSubnet",Version:"2016-11-15",SubnetId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeNetworkInterfaces($){let J={Action:"DescribeNetworkInterfaces",Version:"2016-11-15"};if($?.NetworkInterfaceIds)$.NetworkInterfaceIds.forEach((Z,U)=>{J[`NetworkInterfaceId.${U+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,U)=>{J[`Filter.${U+1}.Name`]=Z.Name,Z.Values.forEach((W,z)=>{J[`Filter.${U+1}.Value.${z+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.DescribeNetworkInterfacesResponse||Y;return{NetworkInterfaces:this.parseArray(Q.networkInterfaceSet?.item).map((Z)=>({NetworkInterfaceId:Z.networkInterfaceId,SubnetId:Z.subnetId,VpcId:Z.vpcId,Status:Z.status,Attachment:Z.attachment?{AttachmentId:Z.attachment.attachmentId,InstanceId:Z.attachment.instanceId,Status:Z.attachment.status}:void 0}))}}async detachNetworkInterface($,J){let Y={Action:"DetachNetworkInterface",Version:"2016-11-15",AttachmentId:$};if(J)Y.Force="true";await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()})}async deleteNetworkInterface($){let J={Action:"DeleteNetworkInterface",Version:"2016-11-15",NetworkInterfaceId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRegions(){let $={Action:"DescribeRegions",Version:"2016-11-15"},J=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams($).toString()}),Y=J.DescribeRegionsResponse||J;return{Regions:this.parseArray(Y.regionInfo?.item).map((Q)=>({RegionName:Q.regionName,Endpoint:Q.regionEndpoint}))}}async runInstances($){let J={Action:"RunInstances",Version:"2016-11-15",ImageId:$.ImageId,InstanceType:$.InstanceType,MinCount:String($.MinCount),MaxCount:String($.MaxCount)};if($.SecurityGroupIds)$.SecurityGroupIds.forEach((Z,U)=>{J[`SecurityGroupId.${U+1}`]=Z});if($.SubnetId)J.SubnetId=$.SubnetId;if($.UserData)J.UserData=$.UserData;if($.IamInstanceProfile){if($.IamInstanceProfile.Name)J["IamInstanceProfile.Name"]=$.IamInstanceProfile.Name;if($.IamInstanceProfile.Arn)J["IamInstanceProfile.Arn"]=$.IamInstanceProfile.Arn}if($.TagSpecifications)$.TagSpecifications.forEach((Z,U)=>{J[`TagSpecification.${U+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((W,z)=>{J[`TagSpecification.${U+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${U+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=Y.RunInstancesResponse||Y;return{Instances:this.parseInstances(Q.instancesSet?.item||Q.instancesSet)}}encodeIpPermissions($,J){J.forEach((Y,Q)=>{let Z=`IpPermissions.${Q+1}`;if(Y.IpProtocol!==void 0)$[`${Z}.IpProtocol`]=Y.IpProtocol;if(Y.FromPort!==void 0)$[`${Z}.FromPort`]=String(Y.FromPort);if(Y.ToPort!==void 0)$[`${Z}.ToPort`]=String(Y.ToPort);if(Y.IpRanges)Y.IpRanges.forEach((U,W)=>{if(U.CidrIp)$[`${Z}.IpRanges.${W+1}.CidrIp`]=U.CidrIp;if(U.Description)$[`${Z}.IpRanges.${W+1}.Description`]=U.Description});if(Y.Ipv6Ranges)Y.Ipv6Ranges.forEach((U,W)=>{if(U.CidrIpv6)$[`${Z}.Ipv6Ranges.${W+1}.CidrIpv6`]=U.CidrIpv6;if(U.Description)$[`${Z}.Ipv6Ranges.${W+1}.Description`]=U.Description});if(Y.UserIdGroupPairs)Y.UserIdGroupPairs.forEach((U,W)=>{if(U.GroupId)$[`${Z}.Groups.${W+1}.GroupId`]=U.GroupId;if(U.UserId)$[`${Z}.Groups.${W+1}.UserId`]=U.UserId;if(U.Description)$[`${Z}.Groups.${W+1}.Description`]=U.Description})})}parseArray($){if(!$)return[];return Array.isArray($)?$:[$]}parseTags($){return this.parseArray($).map((J)=>({Key:J.key,Value:J.value}))}parseReservations($){return this.parseArray($).map((J)=>({ReservationId:J.reservationId,Instances:this.parseInstances(J.instancesSet?.item||J.instancesSet)}))}parseInstances($){return this.parseArray($).map((J)=>({InstanceId:J.instanceId,ImageId:J.imageId,InstanceType:J.instanceType,State:J.instanceState?{Code:Number.parseInt(J.instanceState.code),Name:J.instanceState.name}:void 0,PrivateIpAddress:J.privateIpAddress,PublicIpAddress:J.ipAddress,SubnetId:J.subnetId,VpcId:J.vpcId,SecurityGroups:this.parseArray(J.groupSet?.item).map((Y)=>({GroupId:Y.groupId,GroupName:Y.groupName})),Tags:this.parseTags(J.tagSet?.item),LaunchTime:J.launchTime,Placement:J.placement?{AvailabilityZone:J.placement.availabilityZone,Tenancy:J.placement.tenancy}:void 0,Architecture:J.architecture,RootDeviceType:J.rootDeviceType,RootDeviceName:J.rootDeviceName,BlockDeviceMappings:this.parseArray(J.blockDeviceMapping?.item).map((Y)=>({DeviceName:Y.deviceName,Ebs:Y.ebs?{VolumeId:Y.ebs.volumeId,Status:Y.ebs.status,AttachTime:Y.ebs.attachTime,DeleteOnTermination:Y.ebs.deleteOnTermination==="true"}:void 0})),IamInstanceProfile:J.iamInstanceProfile?{Arn:J.iamInstanceProfile.arn,Id:J.iamInstanceProfile.id}:void 0}))}parseIpPermissions($){return this.parseArray($).map((J)=>({IpProtocol:J.ipProtocol,FromPort:J.fromPort?Number.parseInt(J.fromPort):void 0,ToPort:J.toPort?Number.parseInt(J.toPort):void 0,IpRanges:this.parseArray(J.ipRanges?.item).map((Y)=>({CidrIp:Y.cidrIp,Description:Y.description})),Ipv6Ranges:this.parseArray(J.ipv6Ranges?.item).map((Y)=>({CidrIpv6:Y.cidrIpv6,Description:Y.description})),UserIdGroupPairs:this.parseArray(J.groups?.item).map((Y)=>({GroupId:Y.groupId,UserId:Y.userId,Description:Y.description}))}))}}var d9=S0(()=>{z0()});var JU={};Z1(JU,{SQSClient:()=>x1});class x1{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t}async createQueue($){let Y={Action:"CreateQueue",QueueName:$.fifo&&!$.queueName.endsWith(".fifo")?`${$.queueName}.fifo`:$.queueName,Version:"2012-11-05"},Q=1;if($.visibilityTimeout!==void 0)Y[`Attribute.${Q}.Name`]="VisibilityTimeout",Y[`Attribute.${Q}.Value`]=$.visibilityTimeout.toString(),Q++;if($.messageRetentionPeriod!==void 0)Y[`Attribute.${Q}.Name`]="MessageRetentionPeriod",Y[`Attribute.${Q}.Value`]=$.messageRetentionPeriod.toString(),Q++;if($.delaySeconds!==void 0)Y[`Attribute.${Q}.Name`]="DelaySeconds",Y[`Attribute.${Q}.Value`]=$.delaySeconds.toString(),Q++;if($.maxMessageSize!==void 0)Y[`Attribute.${Q}.Name`]="MaximumMessageSize",Y[`Attribute.${Q}.Value`]=$.maxMessageSize.toString(),Q++;if($.receiveMessageWaitTime!==void 0)Y[`Attribute.${Q}.Name`]="ReceiveMessageWaitTimeSeconds",Y[`Attribute.${Q}.Value`]=$.receiveMessageWaitTime.toString(),Q++;if($.fifo){if(Y[`Attribute.${Q}.Name`]="FifoQueue",Y[`Attribute.${Q}.Value`]="true",Q++,$.contentBasedDeduplication)Y[`Attribute.${Q}.Name`]="ContentBasedDeduplication",Y[`Attribute.${Q}.Value`]="true",Q++}if($.deadLetterTargetArn&&$.maxReceiveCount)Y[`Attribute.${Q}.Name`]="RedrivePolicy",Y[`Attribute.${Q}.Value`]=JSON.stringify({deadLetterTargetArn:$.deadLetterTargetArn,maxReceiveCount:$.maxReceiveCount}),Q++;if($.tags&&Object.keys($.tags).length>0){let U=1;for(let[W,z]of Object.entries($.tags))Y[`Tag.${U}.Key`]=W,Y[`Tag.${U}.Value`]=z,U++}let Z=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(Y).toString()});return{QueueUrl:Z.QueueUrl||Z.CreateQueueResult?.QueueUrl}}async listQueues($){let J={Action:"ListQueues",Version:"2012-11-05"};if($)J.QueueNamePrefix=$;let Y=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()}),Q=[];if(Y.QueueUrl)Q.push(Y.QueueUrl);else if(Y.ListQueuesResult?.QueueUrl)if(Array.isArray(Y.ListQueuesResult.QueueUrl))Q.push(...Y.ListQueuesResult.QueueUrl);else Q.push(Y.ListQueuesResult.QueueUrl);return{QueueUrls:Q}}async getQueueAttributes($){let J={Action:"GetQueueAttributes",QueueUrl:$,Version:"2012-11-05","AttributeName.1":"All"},Y=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{Attributes:Y.Attributes||Y.GetQueueAttributesResult?.Attributes||{}}}async getQueueUrl($){let J={Action:"GetQueueUrl",QueueName:$,Version:"2012-11-05"},Y=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{QueueUrl:Y.QueueUrl||Y.GetQueueUrlResult?.QueueUrl}}async deleteQueue($){let J={Action:"DeleteQueue",QueueUrl:$,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()})}async purgeQueue($){let J={Action:"PurgeQueue",QueueUrl:$,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()})}async sendMessage($){let J={Action:"SendMessage",QueueUrl:$.queueUrl,MessageBody:$.messageBody,Version:"2012-11-05"};if($.delaySeconds!==void 0)J.DelaySeconds=$.delaySeconds;if($.messageGroupId)J.MessageGroupId=$.messageGroupId;if($.messageDeduplicationId)J.MessageDeduplicationId=$.messageDeduplicationId;let Y=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{MessageId:Y.MessageId||Y.SendMessageResult?.MessageId}}async receiveMessages($){let J={Action:"ReceiveMessage",QueueUrl:$.queueUrl,Version:"2012-11-05"};if($.maxMessages!==void 0)J.MaxNumberOfMessages=$.maxMessages;if($.visibilityTimeout!==void 0)J.VisibilityTimeout=$.visibilityTimeout;if($.waitTimeSeconds!==void 0)J.WaitTimeSeconds=$.waitTimeSeconds;let Y=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()}),Q=[],Z=Y.Message||Y.ReceiveMessageResult?.Message;if(Z)if(Array.isArray(Z))Q.push(...Z.map((U)=>({MessageId:U.MessageId,ReceiptHandle:U.ReceiptHandle,Body:U.Body})));else Q.push({MessageId:Z.MessageId,ReceiptHandle:Z.ReceiptHandle,Body:Z.Body});return{Messages:Q}}async deleteMessage($,J){let Y={Action:"DeleteMessage",QueueUrl:$,ReceiptHandle:J,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(Y).toString()})}}var p5=S0(()=>{z0()});var QU={};Z1(QU,{RDSClient:()=>YU});class YU{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}async describeDBInstances($){let J={Action:"DescribeDBInstances",Version:"2014-10-31"};if($?.DBInstanceIdentifier)J.DBInstanceIdentifier=$.DBInstanceIdentifier;if($?.MaxRecords)J.MaxRecords=$.MaxRecords;if($?.Marker)J.Marker=$.Marker;if($?.Filters)$.Filters.forEach((W,z)=>{J[`Filters.Filter.${z+1}.Name`]=W.Name,W.Values.forEach((G,H)=>{J[`Filters.Filter.${z+1}.Values.Value.${H+1}`]=G})});let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y}),Z=Q.DescribeDBInstancesResult||Q,U=Z.DBInstances?.DBInstance||[];if(!Array.isArray(U))U=U?[U]:[];return{DBInstances:U,Marker:Z.Marker}}async describeDBInstance($){return(await this.describeDBInstances({DBInstanceIdentifier:$})).DBInstances?.[0]}async describeDBClusters($){let J={Action:"DescribeDBClusters",Version:"2014-10-31"};if($?.DBClusterIdentifier)J.DBClusterIdentifier=$.DBClusterIdentifier;if($?.MaxRecords)J.MaxRecords=$.MaxRecords;if($?.Marker)J.Marker=$.Marker;if($?.Filters)$.Filters.forEach((W,z)=>{J[`Filters.Filter.${z+1}.Name`]=W.Name,W.Values.forEach((G,H)=>{J[`Filters.Filter.${z+1}.Values.Value.${H+1}`]=G})});let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y}),Z=Q.DescribeDBClustersResult||Q,U=Z.DBClusters?.DBCluster||[];if(!Array.isArray(U))U=U?[U]:[];return{DBClusters:U,Marker:Z.Marker}}async describeDBSnapshots($){let J={Action:"DescribeDBSnapshots",Version:"2014-10-31"};if($?.DBInstanceIdentifier)J.DBInstanceIdentifier=$.DBInstanceIdentifier;if($?.DBSnapshotIdentifier)J.DBSnapshotIdentifier=$.DBSnapshotIdentifier;if($?.SnapshotType)J.SnapshotType=$.SnapshotType;if($?.MaxRecords)J.MaxRecords=$.MaxRecords;if($?.Marker)J.Marker=$.Marker;let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y}),Z=Q.DescribeDBSnapshotsResult||Q,U=Z.DBSnapshots?.DBSnapshot||[];if(!Array.isArray(U))U=U?[U]:[];return{DBSnapshots:U,Marker:Z.Marker}}async describeDBSubnetGroups($){let J={Action:"DescribeDBSubnetGroups",Version:"2014-10-31"};if($?.DBSubnetGroupName)J.DBSubnetGroupName=$.DBSubnetGroupName;if($?.MaxRecords)J.MaxRecords=$.MaxRecords;if($?.Marker)J.Marker=$.Marker;let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y}),Z=Q.DescribeDBSubnetGroupsResult||Q,U=Z.DBSubnetGroups?.DBSubnetGroup||[];if(!Array.isArray(U))U=U?[U]:[];return{DBSubnetGroups:U,Marker:Z.Marker}}async createDBInstance($){let J={Action:"CreateDBInstance",Version:"2014-10-31",DBInstanceIdentifier:$.DBInstanceIdentifier,DBInstanceClass:$.DBInstanceClass,Engine:$.Engine};if($.MasterUsername)J.MasterUsername=$.MasterUsername;if($.MasterUserPassword)J.MasterUserPassword=$.MasterUserPassword;if($.DBName)J.DBName=$.DBName;if($.AllocatedStorage)J.AllocatedStorage=$.AllocatedStorage;if($.DBSubnetGroupName)J.DBSubnetGroupName=$.DBSubnetGroupName;if($.AvailabilityZone)J.AvailabilityZone=$.AvailabilityZone;if($.PreferredMaintenanceWindow)J.PreferredMaintenanceWindow=$.PreferredMaintenanceWindow;if($.PreferredBackupWindow)J.PreferredBackupWindow=$.PreferredBackupWindow;if($.BackupRetentionPeriod!==void 0)J.BackupRetentionPeriod=$.BackupRetentionPeriod;if($.MultiAZ!==void 0)J.MultiAZ=$.MultiAZ;if($.EngineVersion)J.EngineVersion=$.EngineVersion;if($.AutoMinorVersionUpgrade!==void 0)J.AutoMinorVersionUpgrade=$.AutoMinorVersionUpgrade;if($.LicenseModel)J.LicenseModel=$.LicenseModel;if($.PubliclyAccessible!==void 0)J.PubliclyAccessible=$.PubliclyAccessible;if($.StorageType)J.StorageType=$.StorageType;if($.StorageEncrypted!==void 0)J.StorageEncrypted=$.StorageEncrypted;if($.KmsKeyId)J.KmsKeyId=$.KmsKeyId;if($.DeletionProtection!==void 0)J.DeletionProtection=$.DeletionProtection;if($.VpcSecurityGroupIds)$.VpcSecurityGroupIds.forEach((U,W)=>{J[`VpcSecurityGroupIds.VpcSecurityGroupId.${W+1}`]=U});if($.Tags)$.Tags.forEach((U,W)=>{J[`Tags.Tag.${W+1}.Key`]=U.Key,J[`Tags.Tag.${W+1}.Value`]=U.Value});let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBInstance:(Q.CreateDBInstanceResult||Q).DBInstance}}async deleteDBInstance($){let J={Action:"DeleteDBInstance",Version:"2014-10-31",DBInstanceIdentifier:$.DBInstanceIdentifier};if($.SkipFinalSnapshot!==void 0)J.SkipFinalSnapshot=$.SkipFinalSnapshot;if($.FinalDBSnapshotIdentifier)J.FinalDBSnapshotIdentifier=$.FinalDBSnapshotIdentifier;if($.DeleteAutomatedBackups!==void 0)J.DeleteAutomatedBackups=$.DeleteAutomatedBackups;let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBInstance:(Q.DeleteDBInstanceResult||Q).DBInstance}}async modifyDBInstance($){let J={Action:"ModifyDBInstance",Version:"2014-10-31",DBInstanceIdentifier:$.DBInstanceIdentifier};if($.DBInstanceClass)J.DBInstanceClass=$.DBInstanceClass;if($.AllocatedStorage)J.AllocatedStorage=$.AllocatedStorage;if($.MasterUserPassword)J.MasterUserPassword=$.MasterUserPassword;if($.BackupRetentionPeriod!==void 0)J.BackupRetentionPeriod=$.BackupRetentionPeriod;if($.PreferredBackupWindow)J.PreferredBackupWindow=$.PreferredBackupWindow;if($.PreferredMaintenanceWindow)J.PreferredMaintenanceWindow=$.PreferredMaintenanceWindow;if($.MultiAZ!==void 0)J.MultiAZ=$.MultiAZ;if($.EngineVersion)J.EngineVersion=$.EngineVersion;if($.AutoMinorVersionUpgrade!==void 0)J.AutoMinorVersionUpgrade=$.AutoMinorVersionUpgrade;if($.PubliclyAccessible!==void 0)J.PubliclyAccessible=$.PubliclyAccessible;if($.ApplyImmediately!==void 0)J.ApplyImmediately=$.ApplyImmediately;if($.StorageType)J.StorageType=$.StorageType;if($.DeletionProtection!==void 0)J.DeletionProtection=$.DeletionProtection;if($.VpcSecurityGroupIds)$.VpcSecurityGroupIds.forEach((U,W)=>{J[`VpcSecurityGroupIds.VpcSecurityGroupId.${W+1}`]=U});let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBInstance:(Q.ModifyDBInstanceResult||Q).DBInstance}}async startDBInstance($){let Y=new URLSearchParams(g0({Action:"StartDBInstance",Version:"2014-10-31",DBInstanceIdentifier:$})).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBInstance:(Q.StartDBInstanceResult||Q).DBInstance}}async stopDBInstance($){let J={Action:"StopDBInstance",Version:"2014-10-31",DBInstanceIdentifier:$.DBInstanceIdentifier};if($.DBSnapshotIdentifier)J.DBSnapshotIdentifier=$.DBSnapshotIdentifier;let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBInstance:(Q.StopDBInstanceResult||Q).DBInstance}}async rebootDBInstance($){let J={Action:"RebootDBInstance",Version:"2014-10-31",DBInstanceIdentifier:$.DBInstanceIdentifier};if($.ForceFailover!==void 0)J.ForceFailover=$.ForceFailover;let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBInstance:(Q.RebootDBInstanceResult||Q).DBInstance}}async createDBSnapshot($){let J={Action:"CreateDBSnapshot",Version:"2014-10-31",DBInstanceIdentifier:$.DBInstanceIdentifier,DBSnapshotIdentifier:$.DBSnapshotIdentifier};if($.Tags)$.Tags.forEach((U,W)=>{J[`Tags.Tag.${W+1}.Key`]=U.Key,J[`Tags.Tag.${W+1}.Value`]=U.Value});let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBSnapshot:(Q.CreateDBSnapshotResult||Q).DBSnapshot}}async deleteDBSnapshot($){let Y=new URLSearchParams(g0({Action:"DeleteDBSnapshot",Version:"2014-10-31",DBSnapshotIdentifier:$})).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBSnapshot:(Q.DeleteDBSnapshotResult||Q).DBSnapshot}}async restoreDBInstanceFromDBSnapshot($){let J={Action:"RestoreDBInstanceFromDBSnapshot",Version:"2014-10-31",DBInstanceIdentifier:$.DBInstanceIdentifier,DBSnapshotIdentifier:$.DBSnapshotIdentifier};if($.DBInstanceClass)J.DBInstanceClass=$.DBInstanceClass;if($.Port)J.Port=$.Port;if($.AvailabilityZone)J.AvailabilityZone=$.AvailabilityZone;if($.DBSubnetGroupName)J.DBSubnetGroupName=$.DBSubnetGroupName;if($.MultiAZ!==void 0)J.MultiAZ=$.MultiAZ;if($.PubliclyAccessible!==void 0)J.PubliclyAccessible=$.PubliclyAccessible;if($.AutoMinorVersionUpgrade!==void 0)J.AutoMinorVersionUpgrade=$.AutoMinorVersionUpgrade;if($.StorageType)J.StorageType=$.StorageType;if($.DeletionProtection!==void 0)J.DeletionProtection=$.DeletionProtection;if($.VpcSecurityGroupIds)$.VpcSecurityGroupIds.forEach((U,W)=>{J[`VpcSecurityGroupIds.VpcSecurityGroupId.${W+1}`]=U});if($.Tags)$.Tags.forEach((U,W)=>{J[`Tags.Tag.${W+1}.Key`]=U.Key,J[`Tags.Tag.${W+1}.Value`]=U.Value});let Y=new URLSearchParams(g0(J)).toString(),Q=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:Y});return{DBInstance:(Q.RestoreDBInstanceFromDBSnapshotResult||Q).DBInstance}}async waitForDBInstanceAvailable($,J=60,Y=30000){for(let Q=0;Q<J;Q++){let Z=await this.describeDBInstance($);if(Z?.DBInstanceStatus==="available")return Z;if(["deleted","failed","incompatible-restore","incompatible-parameters"].includes(Z?.DBInstanceStatus||""))throw Error(`DB instance ${$} is in terminal state: ${Z?.DBInstanceStatus}`);await new Promise((U)=>setTimeout(U,Y))}throw Error(`Timeout waiting for DB instance ${$} to become available`)}async waitForDBInstanceDeleted($,J=60,Y=30000){for(let Q=0;Q<J;Q++)try{let Z=await this.describeDBInstance($);if(Z?.DBInstanceStatus==="deleting"){await new Promise((U)=>setTimeout(U,Y));continue}throw Error(`DB instance ${$} is in state: ${Z?.DBInstanceStatus}`)}catch(Z){if(Z.code==="DBInstanceNotFound"||Z.code==="DBInstanceNotFoundFault")return;throw Z}throw Error(`Timeout waiting for DB instance ${$} to be deleted`)}}var ZU=S0(()=>{z0()});var $J={};Z1($J,{LambdaClient:()=>WU});import{deflateRawSync as iB}from"zlib";function UU($,J){let Y=typeof J==="string"?Buffer.from(J,"utf-8"):J,Q=iB(Y),Z=tB(Y),U=new Date,W=(U.getHours()<<11|U.getMinutes()<<5|U.getSeconds()>>1)&65535,z=(U.getFullYear()-1980<<9|U.getMonth()+1<<5|U.getDate())&65535,G=Buffer.from($,"utf-8"),H=Buffer.alloc(30+G.length);H.writeUInt32LE(67324752,0),H.writeUInt16LE(20,4),H.writeUInt16LE(0,6),H.writeUInt16LE(8,8),H.writeUInt16LE(W,10),H.writeUInt16LE(z,12),H.writeUInt32LE(Z,14),H.writeUInt32LE(Q.length,18),H.writeUInt32LE(Y.length,22),H.writeUInt16LE(G.length,26),H.writeUInt16LE(0,28),G.copy(H,30);let A=Buffer.alloc(46+G.length);A.writeUInt32LE(33639248,0),A.writeUInt16LE(20,4),A.writeUInt16LE(20,6),A.writeUInt16LE(0,8),A.writeUInt16LE(8,10),A.writeUInt16LE(W,12),A.writeUInt16LE(z,14),A.writeUInt32LE(Z,16),A.writeUInt32LE(Q.length,20),A.writeUInt32LE(Y.length,24),A.writeUInt16LE(G.length,28),A.writeUInt16LE(0,30),A.writeUInt16LE(0,32),A.writeUInt16LE(0,34),A.writeUInt16LE(0,36),A.writeUInt32LE(0,38),A.writeUInt32LE(0,42),G.copy(A,46);let K=H.length+Q.length,B=A.length,j=Buffer.alloc(22);return j.writeUInt32LE(101010256,0),j.writeUInt16LE(0,4),j.writeUInt16LE(0,6),j.writeUInt16LE(1,8),j.writeUInt16LE(1,10),j.writeUInt32LE(B,12),j.writeUInt32LE(K,16),j.writeUInt16LE(0,20),Buffer.concat([H,Q,A,j])}function tB($){let J=[];for(let Q=0;Q<256;Q++){let Z=Q;for(let U=0;U<8;U++)Z=Z&1?3988292384^Z>>>1:Z>>>1;J[Q]=Z}let Y=4294967295;for(let Q=0;Q<$.length;Q++)Y=J[(Y^$[Q])&255]^Y>>>8;return(Y^4294967295)>>>0}class WU{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}async createFunction($){return await this.client.request({service:"lambda",region:this.region,method:"POST",path:"/2015-03-31/functions",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}async getFunction($){return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2015-03-31/functions/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async updateFunctionCode($){let{FunctionName:J,...Y}=$;return await this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(J)}/code`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)})}async updateFunctionCodeInline($,J,Y="index.js"){let Q=UU(Y,J);return this.updateFunctionCode({FunctionName:$,ZipFile:Q.toString("base64")})}async updateFunctionConfiguration($){let{FunctionName:J,...Y}=$;return await this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(J)}/configuration`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)})}async deleteFunction($){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2015-03-31/functions/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async invoke($){let{FunctionName:J,InvocationType:Y="RequestResponse",Payload:Q,LogType:Z}=$,U={"Content-Type":"application/json","X-Amz-Invocation-Type":Y};if(Z)U["X-Amz-Log-Type"]=Z;let W=Q?typeof Q==="string"?Q:JSON.stringify(Q):void 0,z=await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(J)}/invocations`,headers:U,body:W,returnHeaders:!0});return{StatusCode:z.statusCode||200,FunctionError:z.headers?.["x-amz-function-error"],LogResult:z.headers?.["x-amz-log-result"],Payload:typeof z.body==="string"?z.body:JSON.stringify(z.body),ExecutedVersion:z.headers?.["x-amz-executed-version"]}}async listFunctions($){let J={};if($?.MaxItems)J.MaxItems=String($.MaxItems);if($?.Marker)J.Marker=$.Marker;if($?.FunctionVersion)J.FunctionVersion=$.FunctionVersion;return await this.client.request({service:"lambda",region:this.region,method:"GET",path:"/2015-03-31/functions",queryParams:Object.keys(J).length>0?J:void 0,headers:{"Content-Type":"application/json"}})}async addPermission($){let{FunctionName:J,...Y}=$;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(J)}/policy`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)})}async removePermission($,J){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2015-03-31/functions/${encodeURIComponent($)}/policy/${encodeURIComponent(J)}`,headers:{"Content-Type":"application/json"}})}async publishVersion($){let{FunctionName:J,...Y}=$;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(J)}/versions`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)})}async createAlias($){let{FunctionName:J,...Y}=$;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(J)}/aliases`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)})}async waitForFunctionActive($,J=60){let Y=Date.now(),Q=J*1000;while(Date.now()-Y<Q)try{let Z=await this.getFunction($),U=Z.Configuration?.State;if(U==="Active")return Z.Configuration;if(U==="Failed")throw Error(`Function ${$} failed: ${Z.Configuration?.StateReason}`);await new Promise((W)=>setTimeout(W,2000))}catch(Z){if(Z.code==="ResourceNotFoundException"){await new Promise((U)=>setTimeout(U,2000));continue}throw Z}throw Error(`Timeout waiting for function ${$} to become active`)}async functionExists($){try{return await this.getFunction($),!0}catch(J){if(J.code==="ResourceNotFoundException"||J.statusCode===404)return!1;throw J}}async createFunctionUrl($){let{FunctionName:J,...Y}=$;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2021-10-31/functions/${encodeURIComponent(J)}/url`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)})}async getFunctionUrl($){try{return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2021-10-31/functions/${encodeURIComponent($)}/url`,headers:{"Content-Type":"application/json"}})}catch(J){if(J.statusCode===404)return null;throw J}}async deleteFunctionUrl($){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2021-10-31/functions/${encodeURIComponent($)}/url`,headers:{"Content-Type":"application/json"}})}async createFunctionWithCode($){let{Code:J,Filename:Y="index.js",...Q}=$,Z=UU(Y,J);return this.createFunction({...Q,Code:{ZipFile:Z.toString("base64")}})}async addFunctionUrlPermission($){return this.addPermission({FunctionName:$,StatementId:"FunctionURLAllowPublicAccess",Action:"lambda:InvokeFunctionUrl",Principal:"*",FunctionUrlAuthType:"NONE"})}async publishLayerVersion($){let{LayerName:J,...Y}=$;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2018-10-31/layers/${encodeURIComponent(J)}/versions`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)})}async listLayerVersions($,J){let Y={};if(J?.CompatibleRuntime)Y.CompatibleRuntime=J.CompatibleRuntime;if(J?.CompatibleArchitecture)Y.CompatibleArchitecture=J.CompatibleArchitecture;if(J?.MaxItems)Y.MaxItems=String(J.MaxItems);if(J?.Marker)Y.Marker=J.Marker;return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2018-10-31/layers/${encodeURIComponent($)}/versions`,queryParams:Object.keys(Y).length>0?Y:void 0,headers:{"Content-Type":"application/json"}})}async getLayerVersion($,J){return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2018-10-31/layers/${encodeURIComponent($)}/versions/${J}`,headers:{"Content-Type":"application/json"}})}async addLayerVersionPermission($){let{LayerName:J,VersionNumber:Y,...Q}=$;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2018-10-31/layers/${encodeURIComponent(J)}/versions/${Y}/policy`,headers:{"Content-Type":"application/json"},body:JSON.stringify(Q)})}async deleteLayerVersion($,J){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2018-10-31/layers/${encodeURIComponent($)}/versions/${J}`,headers:{"Content-Type":"application/json"}})}}var JJ=S0(()=>{z0()});import{existsSync as jU}from"node:fs";import i9 from"node:fs/promises";import WJ from"node:os";import t9 from"node:path";import H2 from"node:process";import{EventEmitter as XU}from"node:events";import r1 from"node:process";import zJ from"node:process";import $8 from"node:process";import M$ from"node:process";import a2 from"node:process";import FJ from"node:tty";import YW,{stdin as Oj,stdout as _j}from"node:process";import KJ,{stdin as UW,stdout as WW}from"node:process";import zW from"node:readline";class jJ{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let $=WJ.homedir(),J=t9.join($,".config","clapp");this.configPath=t9.join(J,"telemetry.json")}async isEnabled(){if(H2.env.DO_NOT_TRACK==="1"||H2.env.DO_NOT_TRACK==="true")return!1;if(H2.env.NO_TELEMETRY==="1"||H2.env.NO_TELEMETRY==="true")return!1;return(await this.loadConfig()).enabled}async enable(){let $=await this.loadConfig();if($.enabled=!0,!$.userId)$.userId=this.generateUserId();await this.saveConfig($)}async disable(){let $=await this.loadConfig();$.enabled=!1,await this.saveConfig($)}async track($,J){if(!await this.isEnabled())return;let Q={event:$,...J,timestamp:Date.now(),platform:WJ.platform(),nodeVersion:H2.version};if(this.events.push(Q),this.events.length>=10)await this.send()}async trackCommand($,J){await this.track("command",{command:$,duration:J})}async trackError($,J){await this.track("error",{error:$,command:J})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let J=await this.loadConfig();return J.lastSent=Date.now(),await this.saveConfig(J),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let J=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(J),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep($){return new Promise((J)=>setTimeout(J,$))}async status(){let $=await this.loadConfig();return{enabled:$.enabled,doNotTrack:H2.env.DO_NOT_TRACK==="1"||H2.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:$.lastSent}}async loadConfig(){if(this.config)return this.config;try{if(jU(this.configPath)){let $=await i9.readFile(this.configPath,"utf-8");return this.config=JSON.parse($),this.config}}catch{}return this.config={enabled:!1},this.config}async saveConfig($){this.config=$;try{let J=t9.dirname(this.configPath);await i9.mkdir(J,{recursive:!0}),await i9.writeFile(this.configPath,JSON.stringify($,null,2),"utf-8")}catch{}}generateUserId(){let $=Math.random().toString(36).substring(2,15),J=Date.now().toString(36);return`${$}-${J}`}}var Zj=new jJ;function OU($,J={}){let Y={_:[]},Q=J.alias||{},Z=new Set(J.boolean||[]),U={};for(let z of Object.keys(Q))for(let G of Q[z])U[G]=z;for(let z of Z)if(Q[z])for(let G of Q[z])Z.add(G);function W(z,G){let H=U[z]||z;if(Y[H]=G,Q[H])for(let A of Q[H])Y[A]=G;if(U[z]&&Q[U[z]])for(let A of Q[U[z]])Y[A]=G;Y[z]=G}for(let z=0;z<$.length;z++){let G=$[z];if(G==="--"){Y._.push(...$.slice(z+1));break}if(G.startsWith("--")){let H=G.indexOf("=");if(H!==-1){let A=G.slice(2,H),K=G.slice(H+1);W(A,K)}else{let A=G.slice(2);if(A.startsWith("no-")){let B=A.slice(3);W(B,!1);continue}let K=U[A]||A;if(Z.has(K)||Z.has(A))W(A,!0);else{let B=$[z+1];if(B!==void 0&&!B.startsWith("-"))W(A,B),z++;else W(A,!0)}}}else if(G.startsWith("-")&&G.length>1){let H=G.slice(1);for(let A=0;A<H.length;A++){let K=H[A],B=U[K]||K;if(A===H.length-1&&!Z.has(B)&&!Z.has(K)){let j=$[z+1];if(j!==void 0&&!j.startsWith("-"))W(K,j),z++;else W(K,!0)}else W(K,!0)}}else Y._.push(G)}return Y}function e9($){return $.replace(/[<[].+/,"").trim()}function _U($){let J=/<([^>]+)>/g,Y=/\[([^\]]+)\]/g,Q=[],Z=(z)=>{let G=!1,H=z[1];if(H.startsWith("..."))H=H.slice(3),G=!0;return{required:z[0].startsWith("<"),value:H,variadic:G}},U;while(U=J.exec($))Q.push(Z(U));let W;while(W=Y.exec($))Q.push(Z(W));return Q}function qU($){let J={alias:{},boolean:[]};for(let[Y,Q]of $.entries()){if(Q.names.length>1)J.alias[Q.names[0]]=Q.names.slice(1);if(Q.isBoolean)if(Q.negated){if(!$.some((U,W)=>{return W!==Y&&U.names.some((z)=>Q.names.includes(z))&&typeof U.required==="boolean"}))J.boolean.push(Q.names[0])}else J.boolean.push(Q.names[0])}return J}function GJ($){return $.reduce((J,Y)=>J.length>=Y.length?J:Y,"")}function s9($,J){return $.length>=J?$:`${$}${" ".repeat(J-$.length)}`}function EU($){return $.replace(/([a-z])-([a-z])/g,(J,Y,Q)=>{return Y+Q.toUpperCase()})}function wU($,J,Y){let Q=0,Z=J.length,U=$,W;for(;Q<Z;++Q)W=U[J[Q]],U=U[J[Q]]=Q===Z-1?Y:W!=null?W:!!~J[Q+1].indexOf(".")||!(+J[Q+1]>-1)?{}:[]}function VU($,J){for(let Y of Object.keys(J)){let Q=J[Y];if(Q.shouldTransform){if($[Y]=Array.prototype.concat.call([],$[Y]),typeof Q.transformFunction==="function")$[Y]=$[Y].map(Q.transformFunction)}}}function LU($){let J=/([^\\/]+)$/.exec($);return J?J[1]:""}function XJ($){return $.split(".").map((J,Y)=>{return Y===0?EU(J):J}).join(".")}class L$ extends Error{exitCode=2;isUsageError=!0;constructor($){super($);if(this.name=this.constructor.name,typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error($).stack}format($=!1){if($&&this.stack)return`${this.message}
7181
7181
 
@@ -7215,10 +7215,10 @@ Run \`${this.name??"cli"} --help\` for usage.`;r1.stderr.write(`${U}${Z}${W}
7215
7215
  `).length-1;this.output.write(h1.move(-999,$*-1))}render(){let $=BJ(this._render(this)??"",KJ.stdout.columns,{hard:!0,trim:!1});if($===this._prevFrame)return;if(this.state==="initial")this.output.write(h1.hide);else{let J=ZW(this._prevFrame,$);if(this.restoreCursor(),J&&J?.length===1){let Y=J[0];this.output.write(h1.move(0,Y)),this.output.write(o9.lines(1));let Q=$.split(`
7216
7216
  `);this.output.write(Q[Y]),this._prevFrame=$,this.output.write(h1.move(0,Q.length-Y-1));return}if(J&&J?.length>1){let Y=J[0];this.output.write(h1.move(0,Y)),this.output.write(o9.down());let Z=$.split(`
7217
7217
  `).slice(Y);this.output.write(Z.join(`
7218
- `)),this._prevFrame=$;return}this.output.write(o9.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function FW($,J){if($===void 0)return 0;if(J.length===0)return 0;let Q=J.findIndex((Z)=>Z.value===$);return Q!==-1?Q:0}function AW($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function KW($,J){if(!J)return;if($)return J;return J[0]}class BW extends Z8{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Q;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return T$.inverse(T$.hidden("_"));if(this._cursor>=this.userInput.length)return`${this.userInput}█`;let $=this.userInput.slice(0,this._cursor),[J,...Y]=this.userInput.slice(this._cursor);return`${$}${T$.inverse(J)}${Y.join("")}`}get options(){if(typeof this.#J==="function")return this.#J();return this.#J}constructor($){super($);this.#J=$.options;let J=this.options;this.filteredOptions=[...J],this.multiple=$.multiple===!0,this.#Q=$.filter??AW;let Y;if($.initialValue&&Array.isArray($.initialValue))if(this.multiple)Y=$.initialValue;else Y=$.initialValue.slice(0,1);else if(!this.multiple&&this.options.length>0)Y=[this.options[0].value];if(Y)for(let Q of Y){let Z=J.findIndex((U)=>U.value===Q);if(Z!==-1)this.toggleSelected(Q),this.#$=Z}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Q,Z)=>this.#Z(Q,Z)),this.on("userInput",(Q)=>this.#U(Q))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#Z($,J){let Y=J.name==="up",Q=J.name==="down",Z=J.name==="return";if(Y||Q){if(this.#$=Math.max(0,Math.min(this.#$+(Y?-1:1),this.filteredOptions.length-1)),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)this.selectedValues=[this.focusedValue];this.isNavigating=!0}else if(Z)this.value=KW(this.multiple,this.selectedValues);else if(this.multiple)if(this.focusedValue!==void 0&&(J.name==="tab"||this.isNavigating&&J.name==="space"))this.toggleSelected(this.focusedValue);else this.isNavigating=!1;else{if(this.focusedValue)this.selectedValues=[this.focusedValue];this.isNavigating=!1}}deselectAll(){this.selectedValues=[]}toggleSelected($){if(this.filteredOptions.length===0)return;if(this.multiple)if(this.selectedValues.includes($))this.selectedValues=this.selectedValues.filter((J)=>J!==$);else this.selectedValues=[...this.selectedValues,$];else this.selectedValues=[$]}#U($){if($!==this.#Y){this.#Y=$;let J=this.options;if($)this.filteredOptions=J.filter((Y)=>this.#Q($,Y));else this.filteredOptions=[...J];if(this.#$=FW(this.focusedValue,this.filteredOptions),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)if(this.focusedValue!==void 0)this.toggleSelected(this.focusedValue);else this.deselectAll()}}}class jW extends Z8{options;cursor=0;#$;getGroupItems($){return this.options.filter((J)=>J.group===$)}isGroupSelected($){let J=this.getGroupItems($),Y=this.value;if(Y===void 0)return!1;return J.every((Q)=>Y.includes(Q.value))}toggleValue(){let $=this.options[this.cursor];if(this.value===void 0)this.value=[];if($.group===!0){let J=$.value,Y=this.getGroupItems(J);if(this.isGroupSelected(J))this.value=this.value.filter((Q)=>Y.findIndex((Z)=>Z.value===Q)===-1);else this.value=[...this.value,...Y.map((Q)=>Q.value)];this.value=Array.from(new Set(this.value))}else{let J=this.value.includes($.value);this.value=J?this.value.filter((Y)=>Y!==$.value):[...this.value,$.value]}}constructor($){super($,!1);let{options:J}=$;this.#$=$.selectableGroups!==!1,this.options=Object.entries(J).flatMap(([Y,Q])=>[{value:Y,group:!0,label:Y},...Q.map((Z)=>({...Z,group:Y}))]),this.value=[...$.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:Y})=>Y===$.cursorAt),this.#$?0:1),this.on("cursor",(Y)=>{switch(Y){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var XW=MU();var j0=($,J)=>XW?$:J,Vj=j0("◆","*"),Lj=j0("■","x"),Mj=j0("▲","x"),Tj=j0("◇","o"),Rj=j0("┌","T"),OW=j0("│","|"),Dj=j0("└","—"),Nj=j0("●",">"),Sj=j0("○"," "),Pj=j0("◻","[•]"),xj=j0("◼","[+]"),Cj=j0("◻","[ ]"),Ij=j0("▪","•"),kj=j0("─","-"),hj=j0("╮","+"),bj=j0("├","+"),yj=j0("╯","+"),vj=j0("●","•"),fj=j0("◆","*"),gj=j0("▲","!"),uj=j0("■","x");var dj={light:j0("─","-"),heavy:j0("━","="),block:j0("█","#")};function _W(){return`${T$.gray(OW)} `}var mj=_W();var U8="0.2.17";import{existsSync as K8}from"node:fs";import{mkdir as NW,writeFile as hJ}from"node:fs/promises";var Y0={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",gray:"\x1B[90m"};function A2($,J){return`${Y0[J]}${$}${Y0.reset}`}function C($){console.log(`${Y0.green}✓${Y0.reset} ${$}`)}function R($){console.error(`${Y0.red}✗${Y0.reset} ${$}`)}function g($){console.warn(`${Y0.yellow}⚠${Y0.reset} ${$}`)}var L1=g;function F($){console.log(`${Y0.blue}ℹ${Y0.reset} ${$}`)}function i($){console.log(`${Y0.cyan}→${Y0.reset} ${$}`)}function V($){console.log(`
7218
+ `)),this._prevFrame=$;return}this.output.write(o9.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function FW($,J){if($===void 0)return 0;if(J.length===0)return 0;let Q=J.findIndex((Z)=>Z.value===$);return Q!==-1?Q:0}function AW($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function KW($,J){if(!J)return;if($)return J;return J[0]}class BW extends Z8{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Q;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return T$.inverse(T$.hidden("_"));if(this._cursor>=this.userInput.length)return`${this.userInput}█`;let $=this.userInput.slice(0,this._cursor),[J,...Y]=this.userInput.slice(this._cursor);return`${$}${T$.inverse(J)}${Y.join("")}`}get options(){if(typeof this.#J==="function")return this.#J();return this.#J}constructor($){super($);this.#J=$.options;let J=this.options;this.filteredOptions=[...J],this.multiple=$.multiple===!0,this.#Q=$.filter??AW;let Y;if($.initialValue&&Array.isArray($.initialValue))if(this.multiple)Y=$.initialValue;else Y=$.initialValue.slice(0,1);else if(!this.multiple&&this.options.length>0)Y=[this.options[0].value];if(Y)for(let Q of Y){let Z=J.findIndex((U)=>U.value===Q);if(Z!==-1)this.toggleSelected(Q),this.#$=Z}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Q,Z)=>this.#Z(Q,Z)),this.on("userInput",(Q)=>this.#U(Q))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#Z($,J){let Y=J.name==="up",Q=J.name==="down",Z=J.name==="return";if(Y||Q){if(this.#$=Math.max(0,Math.min(this.#$+(Y?-1:1),this.filteredOptions.length-1)),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)this.selectedValues=[this.focusedValue];this.isNavigating=!0}else if(Z)this.value=KW(this.multiple,this.selectedValues);else if(this.multiple)if(this.focusedValue!==void 0&&(J.name==="tab"||this.isNavigating&&J.name==="space"))this.toggleSelected(this.focusedValue);else this.isNavigating=!1;else{if(this.focusedValue)this.selectedValues=[this.focusedValue];this.isNavigating=!1}}deselectAll(){this.selectedValues=[]}toggleSelected($){if(this.filteredOptions.length===0)return;if(this.multiple)if(this.selectedValues.includes($))this.selectedValues=this.selectedValues.filter((J)=>J!==$);else this.selectedValues=[...this.selectedValues,$];else this.selectedValues=[$]}#U($){if($!==this.#Y){this.#Y=$;let J=this.options;if($)this.filteredOptions=J.filter((Y)=>this.#Q($,Y));else this.filteredOptions=[...J];if(this.#$=FW(this.focusedValue,this.filteredOptions),this.focusedValue=this.filteredOptions[this.#$]?.value,!this.multiple)if(this.focusedValue!==void 0)this.toggleSelected(this.focusedValue);else this.deselectAll()}}}class jW extends Z8{options;cursor=0;#$;getGroupItems($){return this.options.filter((J)=>J.group===$)}isGroupSelected($){let J=this.getGroupItems($),Y=this.value;if(Y===void 0)return!1;return J.every((Q)=>Y.includes(Q.value))}toggleValue(){let $=this.options[this.cursor];if(this.value===void 0)this.value=[];if($.group===!0){let J=$.value,Y=this.getGroupItems(J);if(this.isGroupSelected(J))this.value=this.value.filter((Q)=>Y.findIndex((Z)=>Z.value===Q)===-1);else this.value=[...this.value,...Y.map((Q)=>Q.value)];this.value=Array.from(new Set(this.value))}else{let J=this.value.includes($.value);this.value=J?this.value.filter((Y)=>Y!==$.value):[...this.value,$.value]}}constructor($){super($,!1);let{options:J}=$;this.#$=$.selectableGroups!==!1,this.options=Object.entries(J).flatMap(([Y,Q])=>[{value:Y,group:!0,label:Y},...Q.map((Z)=>({...Z,group:Y}))]),this.value=[...$.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:Y})=>Y===$.cursorAt),this.#$?0:1),this.on("cursor",(Y)=>{switch(Y){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let Q=this.options[this.cursor]?.group===!0;if(!this.#$&&Q)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var XW=MU();var j0=($,J)=>XW?$:J,Vj=j0("◆","*"),Lj=j0("■","x"),Mj=j0("▲","x"),Tj=j0("◇","o"),Rj=j0("┌","T"),OW=j0("│","|"),Dj=j0("└","—"),Nj=j0("●",">"),Sj=j0("○"," "),Pj=j0("◻","[•]"),xj=j0("◼","[+]"),Cj=j0("◻","[ ]"),Ij=j0("▪","•"),kj=j0("─","-"),hj=j0("╮","+"),bj=j0("├","+"),yj=j0("╯","+"),vj=j0("●","•"),fj=j0("◆","*"),gj=j0("▲","!"),uj=j0("■","x");var dj={light:j0("─","-"),heavy:j0("━","="),block:j0("█","#")};function _W(){return`${T$.gray(OW)} `}var mj=_W();var U8="0.2.19";import{existsSync as K8}from"node:fs";import{mkdir as NW,writeFile as hJ}from"node:fs/promises";var Y0={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",gray:"\x1B[90m"};function A2($,J){return`${Y0[J]}${$}${Y0.reset}`}function C($){console.log(`${Y0.green}✓${Y0.reset} ${$}`)}function R($){console.error(`${Y0.red}✗${Y0.reset} ${$}`)}function g($){console.warn(`${Y0.yellow}⚠${Y0.reset} ${$}`)}var L1=g;function F($){console.log(`${Y0.blue}ℹ${Y0.reset} ${$}`)}function i($){console.log(`${Y0.cyan}→${Y0.reset} ${$}`)}function V($){console.log(`
7219
7219
  ${Y0.bright}${Y0.cyan}${$}${Y0.reset}
7220
- `)}var F8=!!(process.env.CI||process.env.GITHUB_ACTIONS||process.env.BUILDKITE||process.env.CIRCLECI||process.env.GITLAB_CI);class L{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];interval=null;currentFrame=0;message;constructor($){this.message=$}get text(){return this.message}set text($){if(this.message=$,F8&&this.interval)console.log(` ${$}`)}start(){if(F8){console.log(` ${this.message}`),this.interval=!0;return}this.interval=setInterval(()=>{process.stdout.write(`\r${Y0.cyan}${this.frames[this.currentFrame]}${Y0.reset} ${this.message}`),this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}succeed($){this.stop(),C($||this.message)}fail($){this.stop(),R($||this.message)}warn($){this.stop(),L1($||this.message)}stop(){if(this.interval){if(!F8)process.stdout.write("\r");if(typeof this.interval==="object")clearInterval(this.interval);this.interval=null}}}async function A0($,J){let Q=(await import("node:readline")).createInterface({input:process.stdin,output:process.stdout});return new Promise((Z)=>{let U=J?`${Y0.cyan}?${Y0.reset} ${$} ${Y0.gray}(${J})${Y0.reset}: `:`${Y0.cyan}?${Y0.reset} ${$}: `;Q.question(U,(W)=>{Q.close(),Z(W||J||"")})})}async function y($,J=!1){let Y=await A0(`${$} (y/n)`,J?"y":"n");return Y.toLowerCase()==="y"||Y.toLowerCase()==="yes"}async function A8($,J){console.log(`${Y0.cyan}?${Y0.reset} ${$}`),J.forEach((Z,U)=>{console.log(` ${Y0.gray}${U+1}.${Y0.reset} ${Z}`)});let Y=await A0("Select","1"),Q=Number.parseInt(Y)-1;if(Q>=0&&Q<J.length)return J[Q];return J[0]}function d($,J){let Y=$.map((Z,U)=>{let W=Math.max(...J.map((z)=>(z[U]||"").length));return Math.max(Z.length,W)}),Q=$.map((Z,U)=>Z.padEnd(Y[U])).join(" ");console.log(A2(Q,"bright")),console.log(A2("─".repeat(Q.length),"gray")),J.forEach((Z)=>{let U=Z.map((W,z)=>(W||"").padEnd(Y[z])).join(" ");console.log(U)})}function M2($,J="cyan"){let Y=$.split(`
7221
- `),Q=Math.max(...Y.map((U)=>U.length)),Z="─".repeat(Q+2);console.log(A2(`┌${Z}┐`,J)),Y.forEach((U)=>{console.log(A2(`│ ${U.padEnd(Q)} │`,J))}),console.log(A2(`└${Z}┘`,J))}async function xJ(){return!0}async function CJ(){try{let{AWSClient:$}=await Promise.resolve().then(() => (z0(),F2));return await new $().request({service:"sts",region:"us-east-1",method:"POST",path:"/",body:new URLSearchParams({Action:"GetCallerIdentity",Version:"2011-06-15"}).toString()}),!0}catch{return!1}}async function IJ(){try{let{AWSClient:$}=await Promise.resolve().then(() => (z0(),F2)),Y=await new $().request({service:"sts",region:"us-east-1",method:"POST",path:"/",body:new URLSearchParams({Action:"GetCallerIdentity",Version:"2011-06-15"}).toString()});return Y.Account||Y.GetCallerIdentityResult?.Account||null}catch{return null}}async function kJ(){try{let{AWSClient:$}=await Promise.resolve().then(() => (z0(),F2)),Y=await new $().request({service:"ec2",region:"us-east-1",method:"POST",path:"/",body:new URLSearchParams({Action:"DescribeRegions",Version:"2016-11-15"}).toString()}),Q=[];if(Y.regionInfo){let Z=Array.isArray(Y.regionInfo)?Y.regionInfo:[Y.regionInfo];Q.push(...Z.map((U)=>U.regionName))}return Q.length>0?Q:PJ()}catch{return PJ()}}function PJ(){return["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1","ap-northeast-1"]}function B8($){$.command("init","Initialize a new ts-cloud project").option("--mode <mode>","Deployment mode: server, serverless, or hybrid").option("--name <name>","Project name").option("--region <region>","AWS Region").action(async(J)=>{if(V("Initializing ts-cloud Project"),K8("cloud.config.ts")){if(!await y("cloud.config.ts already exists. Overwrite?",!1)){F("Initialization cancelled");return}}let Y=J?.name||await A0("Project name","my-app"),Q=J?.mode||await A8("Select deployment mode",["serverless","server","hybrid"]),Z=J?.region||await A8("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),U=new L("Creating configuration file...");U.start();let W=`import { defineConfig } from '@ts-cloud/core'
7220
+ `)}var F8=!!(process.env.CI||process.env.GITHUB_ACTIONS||process.env.BUILDKITE||process.env.CIRCLECI||process.env.GITLAB_CI);class L{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];interval=null;currentFrame=0;message;constructor($){this.message=$}get text(){return this.message}set text($){if(this.message=$,F8&&this.interval)console.log(` ${$}`)}start(){if(F8){console.log(` ${this.message}`),this.interval=!0;return}this.interval=setInterval(()=>{process.stdout.write(`\r${Y0.cyan}${this.frames[this.currentFrame]}${Y0.reset} ${this.message}`),this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}succeed($){this.stop(),C($||this.message)}fail($){this.stop(),R($||this.message)}warn($){this.stop(),L1($||this.message)}stop(){if(this.interval){if(!F8)process.stdout.write("\r");if(typeof this.interval==="object")clearInterval(this.interval);this.interval=null}}}async function A0($,J){let Q=(await import("node:readline")).createInterface({input:process.stdin,output:process.stdout});return new Promise((Z)=>{let U=J?`${Y0.cyan}?${Y0.reset} ${$} ${Y0.gray}(${J})${Y0.reset}: `:`${Y0.cyan}?${Y0.reset} ${$}: `;Q.question(U,(W)=>{Q.close(),Z(W||J||"")})})}async function v($,J=!1){let Y=await A0(`${$} (y/n)`,J?"y":"n");return Y.toLowerCase()==="y"||Y.toLowerCase()==="yes"}async function A8($,J){console.log(`${Y0.cyan}?${Y0.reset} ${$}`),J.forEach((Z,U)=>{console.log(` ${Y0.gray}${U+1}.${Y0.reset} ${Z}`)});let Y=await A0("Select","1"),Q=Number.parseInt(Y)-1;if(Q>=0&&Q<J.length)return J[Q];return J[0]}function d($,J){let Y=$.map((Z,U)=>{let W=Math.max(...J.map((z)=>(z[U]||"").length));return Math.max(Z.length,W)}),Q=$.map((Z,U)=>Z.padEnd(Y[U])).join(" ");console.log(A2(Q,"bright")),console.log(A2("─".repeat(Q.length),"gray")),J.forEach((Z)=>{let U=Z.map((W,z)=>(W||"").padEnd(Y[z])).join(" ");console.log(U)})}function M2($,J="cyan"){let Y=$.split(`
7221
+ `),Q=Math.max(...Y.map((U)=>U.length)),Z="─".repeat(Q+2);console.log(A2(`┌${Z}┐`,J)),Y.forEach((U)=>{console.log(A2(`│ ${U.padEnd(Q)} │`,J))}),console.log(A2(`└${Z}┘`,J))}async function xJ(){return!0}async function CJ(){try{let{AWSClient:$}=await Promise.resolve().then(() => (z0(),F2));return await new $().request({service:"sts",region:"us-east-1",method:"POST",path:"/",body:new URLSearchParams({Action:"GetCallerIdentity",Version:"2011-06-15"}).toString()}),!0}catch{return!1}}async function IJ(){try{let{AWSClient:$}=await Promise.resolve().then(() => (z0(),F2)),Y=await new $().request({service:"sts",region:"us-east-1",method:"POST",path:"/",body:new URLSearchParams({Action:"GetCallerIdentity",Version:"2011-06-15"}).toString()});return Y.Account||Y.GetCallerIdentityResult?.Account||null}catch{return null}}async function kJ(){try{let{AWSClient:$}=await Promise.resolve().then(() => (z0(),F2)),Y=await new $().request({service:"ec2",region:"us-east-1",method:"POST",path:"/",body:new URLSearchParams({Action:"DescribeRegions",Version:"2016-11-15"}).toString()}),Q=[];if(Y.regionInfo){let Z=Array.isArray(Y.regionInfo)?Y.regionInfo:[Y.regionInfo];Q.push(...Z.map((U)=>U.regionName))}return Q.length>0?Q:PJ()}catch{return PJ()}}function PJ(){return["us-east-1","us-east-2","us-west-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1","ap-northeast-1"]}function B8($){$.command("init","Initialize a new ts-cloud project").option("--mode <mode>","Deployment mode: server, serverless, or hybrid").option("--name <name>","Project name").option("--region <region>","AWS Region").action(async(J)=>{if(V("Initializing ts-cloud Project"),K8("cloud.config.ts")){if(!await v("cloud.config.ts already exists. Overwrite?",!1)){F("Initialization cancelled");return}}let Y=J?.name||await A0("Project name","my-app"),Q=J?.mode||await A8("Select deployment mode",["serverless","server","hybrid"]),Z=J?.region||await A8("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),U=new L("Creating configuration file...");U.start();let W=`import { defineConfig } from '@ts-cloud/core'
7222
7222
 
7223
7223
  export default defineConfig({
7224
7224
  project: {
@@ -7313,7 +7313,7 @@ export type ConfigOf = Config
7313
7313
  `;Y+=`| Variable | Type | Description | Example |
7314
7314
  `,Y+=`|----------|------|-------------|----------|
7315
7315
  `;for(let Q of $)Y+=`| \`${Q.key}\` | ${Q.type} | ${Q.description} | \`${Q.example}\` |
7316
- `;return Y}}function SG($,J,Y={}){return sY($,J,Y,new WeakMap)}function sY($,J,Y,Q){let{arrayMergeMode:Z="replace",skipNullish:U=!1,customMerger:W}=Y;if(J===null||J===void 0)return U?$:J;if(W){let z=W($,J);if(z!==void 0)return z}if(Array.isArray(J)||Array.isArray($))return oY($,J,Z,Q);if(!G1(J)||!G1($))return J;return IG($,J,Y,Q)}function oY($,J,Y,Q){if(Array.isArray(J)&&!Array.isArray($))return J;if(Array.isArray($)&&!Array.isArray(J))return J;if(Array.isArray(J)&&Array.isArray($))switch(Y){case"replace":return J;case"concat":return PG($,J);case"smart":return xG($,J,Q);default:return J}return J}function PG($,J){let Y=[...J];for(let Q of $)if(!Y.some((Z)=>p8(Z,Q)))Y.push(Q);return Y}function xG($,J,Y){if(J.length===0)return $;if($.length===0)return J;if(G1(J[0])&&G1($[0]))return CG($,J,Y);if(J.every((Q)=>typeof Q==="string")&&$.every((Q)=>typeof Q==="string")){let Q=[...J];for(let Z of $)if(!Q.includes(Z))Q.push(Z);return Q}return J}function CG($,J,Y){let Q=[...J];for(let Z of $){if(!G1(Z)){Q.push(Z);continue}let U=["id","name","key","path","type"],W=!1;for(let z of U)if(z in Z){if(Q.find((H)=>G1(H)&&(z in H)&&H[z]===Z[z])){W=!0;break}}if(!W)Q.push(Z)}return Q}function IG($,J,Y,Q){let Z=J;if(G1(Z)&&Q.has(Z))return Q.get(Z);let U={...$};if(G1(Z))Q.set(Z,U);for(let W in Z){if(!Object.prototype.hasOwnProperty.call(Z,W))continue;let z=Z[W],G=U[W];if(Y.skipNullish&&(z===null||z===void 0))continue;if(z===null||z===void 0){U[W]=z;continue}if(G1(z)&&G1(G))U[W]=sY(G,z,Y,Q);else if(Array.isArray(z)||Array.isArray(G))U[W]=oY(G,z,Y.arrayMergeMode||"smart",Q);else U[W]=z}return U}function eY($,J,Y="replace"){return SG($,J,{arrayMergeMode:Y==="replace"?"replace":"smart",skipNullish:!0})}function p8($,J){if($===J)return!0;if(Array.isArray($)&&Array.isArray(J)){if($.length!==J.length)return!1;for(let Y=0;Y<$.length;Y++)if(!p8($[Y],J[Y]))return!1;return!0}if(G1($)&&G1(J)){let Y=Object.keys($),Q=Object.keys(J);if(Y.length!==Q.length)return!1;for(let Z of Y){if(!Object.prototype.hasOwnProperty.call(J,Z))return!1;if(!p8($[Z],J[Z]))return!1}return!0}return!1}function G1($){return Boolean($&&typeof $==="object"&&!Array.isArray($))}class $Q{extensions=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];async loadFromPath($,J,Y={}){let{arrayStrategy:Q="replace",useCache:Z=!0,cacheTtl:U,trackPerformance:W=!0,verbose:z=!1}=Y;if(Z){let H=r$.getWithFileCheck("file",$);if(H){if(z)console.log(`Configuration loaded from cache: ${$}`);return H}}let G=async()=>{if(!g$($))return null;try{let H=`?t=${Date.now()}`,A=await import($+H),K=A.default||A,B="default"in A,j=Object.keys(A).length>0;if(!B&&!j)throw new Z9($,Error("Configuration file is empty and exports nothing"),"unknown");if(typeof K!=="object"||K===null||Array.isArray(K))throw new Z9($,Error("Configuration must export a valid object"),"unknown");let _={config:eY(J,K,Q),source:{type:"file",path:$,priority:100,timestamp:new Date}};if(Z)r$.setWithFileCheck("file",_,$,U);return _}catch(H){throw H instanceof Error?y2.configLoad($,H):y2.configLoad($,Error(String(H)))}};if(W)return r8.track("loadFromPath",G,{path:$});return G()}async tryLoadFromPaths($,J,Y={}){for(let Q of $)try{let Z=await this.loadFromPath(Q,J,Y);if(Z)return Z}catch(Z){if(Z instanceof Error&&Z.name==="ConfigLoadError")throw Z;if(Y.verbose)console.warn(`Failed to load config from ${Q}:`,Z)}return null}generateConfigPaths($,J,Y){let Q=this.generateNamePatterns($,Y),Z=[];for(let U of Q)for(let W of this.extensions)Z.push(I8(J,`${U}${W}`));return Z}generateNamePatterns($,J){let Y=[];if(Y.push("config",".config"),$)Y.push($,`.${$}.config`,`${$}.config`,`.${$}`);let Q=J===void 0?[]:Array.isArray(J)?J:[J];for(let U of Q){if(!U)continue;if(Y.push(U,`.${U}.config`,`${U}.config`,`.${U}`),$)Y.push(`${$}.${U}.config`,`.${$}.${U}.config`)}let Z=new Set;return Y.filter((U)=>{if(!U||Z.has(U))return!1;return Z.add(U),!0})}checkFileAccess($){return NG(async()=>{return g$($)},{maxRetries:2,retryDelay:100,fallback:!1})}async discoverConfigFiles($,J,Y){let Q=[];if(!g$($))return Q;if(J||Y){let Z=this.generateNamePatterns(J||"",Y);for(let U of Z)for(let W of this.extensions){let z=I8($,`${U}${W}`);if(await this.checkFileAccess(z))Q.push(z)}}else try{let{readdirSync:Z}=await import("fs"),U=Z($);for(let W of U)if(this.looksLikeConfigFile(W)){let z=I8($,W);if(await this.checkFileAccess(z))Q.push(z)}}catch{return[]}return Q}looksLikeConfigFile($){return[/\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,/^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,/config\.(ts|js|mjs|cjs|json|mts|cts)$/].some((Y)=>Y.test($))}async validateConfigFile($){let J=[];try{if(!g$($))return J.push("Configuration file does not exist"),J;let Y=await import($),Q=Y.default||Y;if(Q===void 0)J.push("Configuration file must export a default value or named exports");else if(typeof Q!=="object"||Q===null)J.push("Configuration must be an object");else if(Array.isArray(Q))J.push("Configuration cannot be an array at the root level");if($.endsWith(".json"))try{let{readFileSync:Z}=await import("fs"),U=Z($,"utf8");JSON.parse(U)}catch(Z){J.push(`Invalid JSON syntax: ${Z}`)}}catch(Y){J.push(`Failed to load configuration file: ${Y}`)}return J}async getFileModificationTime($){try{let{statSync:J}=await import("fs");return J($).mtime}catch{return null}}async preloadConfigurations($,J={}){let Y=new Map;return await Promise.allSettled($.map(async(Q)=>{try{let Z=await this.loadFromPath(Q,{},J);if(Z)Y.set(Q,Z.config)}catch(Z){if(J.verbose)console.warn(`Failed to preload ${Q}:`,Z)}})),Y}}var hG=/^https?:\/\//;class JQ{async validateConfiguration($,J,Y={}){let{stopOnFirstError:Q=!1,validateRequired:Z=!0,validateTypes:U=!0,customRules:W=[],trackPerformance:z=!0,verbose:G=!1}=Y,H=async()=>{let A=[],K=[],B={stopOnFirstError:Q,validateRequired:Z,validateTypes:U,customRules:W,trackPerformance:z,verbose:G};try{if(typeof J==="string")return await this.validateWithSchemaFile($,J,B);else if(Array.isArray(J))return this.validateWithRules($,[...J,...W],B);else return this.validateWithJSONSchema($,J,B)}catch(j){return A.push({path:"",message:`Validation failed: ${j}`,rule:"system"}),{isValid:!1,errors:A,warnings:K}}};if(z)return await r8.track("validateConfiguration",H);return H()}async validateWithSchemaFile($,J,Y){try{if(!kG(J))throw new U9(J,[{path:"",message:"Schema file does not exist"}]);let Q=await import(J),Z=Q.default||Q;if(Array.isArray(Z))return this.validateWithRules($,Z,Y);else return this.validateWithJSONSchema($,Z,Y)}catch(Q){throw new U9(J,[{path:"",message:`Failed to load schema: ${Q}`}])}}validateWithJSONSchema($,J,Y){let Q=[],Z=[];return this.validateObjectAgainstSchema($,J,"",Q,Z,Y),{isValid:Q.length===0,errors:Q,warnings:Z}}validateObjectAgainstSchema($,J,Y,Q,Z,U){if(U.validateTypes&&J.type){let W=Array.isArray($)?"array":typeof $,z=Array.isArray(J.type)?J.type:[J.type];if(!z.includes(W)){if(Q.push({path:Y,message:`Expected type ${z.join(" or ")}, got ${W}`,expected:z.join(" or "),actual:W,rule:"type"}),U.stopOnFirstError)return}}if(J.enum&&!J.enum.includes($)){if(Q.push({path:Y,message:`Value must be one of: ${J.enum.join(", ")}`,expected:J.enum.join(", "),actual:$,rule:"enum"}),U.stopOnFirstError)return}if(typeof $==="string"){if(J.minLength!==void 0&&$.length<J.minLength)Q.push({path:Y,message:`String length must be at least ${J.minLength}`,expected:`>= ${J.minLength}`,actual:$.length,rule:"minLength"});if(J.maxLength!==void 0&&$.length>J.maxLength)Q.push({path:Y,message:`String length must not exceed ${J.maxLength}`,expected:`<= ${J.maxLength}`,actual:$.length,rule:"maxLength"});if(J.pattern){if(!new RegExp(J.pattern).test($))Q.push({path:Y,message:`String does not match pattern ${J.pattern}`,expected:J.pattern,actual:$,rule:"pattern"})}}if(typeof $==="number"){if(J.minimum!==void 0&&$<J.minimum)Q.push({path:Y,message:`Value must be at least ${J.minimum}`,expected:`>= ${J.minimum}`,actual:$,rule:"minimum"});if(J.maximum!==void 0&&$>J.maximum)Q.push({path:Y,message:`Value must not exceed ${J.maximum}`,expected:`<= ${J.maximum}`,actual:$,rule:"maximum"})}if(Array.isArray($)&&J.items)for(let W=0;W<$.length;W++){let z=Y?`${Y}[${W}]`:`[${W}]`;if(this.validateObjectAgainstSchema($[W],J.items,z,Q,Z,U),U.stopOnFirstError&&Q.length>0)return}if($&&typeof $==="object"&&!Array.isArray($)){let W=$;if(U.validateRequired&&J.required){for(let z of J.required)if(!(z in W)){if(Q.push({path:Y?`${Y}.${z}`:z,message:`Missing required property '${z}'`,expected:"required",rule:"required"}),U.stopOnFirstError)return}}if(J.properties){for(let[z,G]of Object.entries(J.properties))if(z in W){let H=Y?`${Y}.${z}`:z;if(this.validateObjectAgainstSchema(W[z],G,H,Q,Z,U),U.stopOnFirstError&&Q.length>0)return}}if(J.additionalProperties===!1){let z=new Set(Object.keys(J.properties||{}));for(let G of Object.keys(W))if(!z.has(G))Z.push({path:Y?`${Y}.${G}`:G,message:`Additional property '${G}' is not allowed`,rule:"additionalProperties"})}}}validateWithRules($,J,Y){let Q=[],Z=[];for(let U of J)try{let W=this.getValueByPath($,U.path),z=this.validateWithRule(W,U,U.path);if(Q.push(...z),Y.stopOnFirstError&&Q.length>0)break}catch(W){Q.push({path:U.path,message:`Rule validation failed: ${W}`,rule:"system"})}return{isValid:Q.length===0,errors:Q,warnings:Z}}validateWithRule($,J,Y){let Q=[];if(J.required&&($===void 0||$===null))return Q.push({path:Y,message:J.message||`Property '${Y}' is required`,expected:"required",rule:"required"}),Q;if($===void 0||$===null)return Q;if(J.type){let Z=Array.isArray($)?"array":typeof $;if(Z!==J.type)Q.push({path:Y,message:J.message||`Expected type ${J.type}, got ${Z}`,expected:J.type,actual:Z,rule:"type"})}if(J.min!==void 0){let Z=Array.isArray($)?$.length:typeof $==="string"?$.length:typeof $==="number"?$:0;if(Z<J.min)Q.push({path:Y,message:J.message||`Value must be at least ${J.min}`,expected:`>= ${J.min}`,actual:Z,rule:"min"})}if(J.max!==void 0){let Z=Array.isArray($)?$.length:typeof $==="string"?$.length:typeof $==="number"?$:0;if(Z>J.max)Q.push({path:Y,message:J.message||`Value must not exceed ${J.max}`,expected:`<= ${J.max}`,actual:Z,rule:"max"})}if(J.pattern&&typeof $==="string"){if(!J.pattern.test($))Q.push({path:Y,message:J.message||`Value does not match pattern ${J.pattern}`,expected:J.pattern.toString(),actual:$,rule:"pattern"})}if(J.enum&&!J.enum.includes($))Q.push({path:Y,message:J.message||`Value must be one of: ${J.enum.join(", ")}`,expected:J.enum.join(", "),actual:$,rule:"enum"});if(J.validator){let Z=J.validator($);if(Z)Q.push({path:Y,message:J.message||Z,rule:"custom"})}return Q}getValueByPath($,J){if(!J)return $;let Y=J.split("."),Q=$;for(let Z of Y)if(Q&&typeof Q==="object"&&Z in Q)Q=Q[Z];else return;return Q}generateRulesFromInterface($){let J=[],Y=$.matchAll(/(\w+)(\?)?:\s*(\w+)/g);for(let Q of Y){let[,Z,U,W]=Q;J.push({path:Z,required:!U,type:this.mapTypeScriptType(W)})}return J}mapTypeScriptType($){switch($.toLowerCase()){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return"array";case"object":return"object";default:return"object"}}static createCommonRules(){return{server:[{path:"port",required:!0,type:"number",min:1,max:65535},{path:"host",required:!0,type:"string",min:1},{path:"ssl",type:"boolean"}],database:[{path:"url",required:!0,type:"string",min:1},{path:"pool",type:"number",min:1,max:100},{path:"timeout",type:"number",min:0}],api:[{path:"baseUrl",required:!0,type:"string",pattern:hG},{path:"timeout",type:"number",min:0},{path:"retries",type:"number",min:0,max:10}]}}}var M1=new H9("bunfig",{showTags:!0});function bG($){if(!$)return"";let J=Array.isArray($)?$.filter(Boolean):[$];if(J.length===0)return"";if(J.length===1)return` or alias "${J[0]}"`;return` or aliases ${J.map((Y)=>`"${Y}"`).join(", ")}`}class YQ{fileLoader=new $Q;envProcessor=new J6;validator=new JQ;async loadConfig($){let J=Date.now(),{cache:Y,performance:Q,schema:Z,validate:U,...W}=$;try{if(Y?.enabled){let G=this.checkCache(W.name||"",W);if(G)return G}let z;try{z=await this.loadConfigurationStrategies(W,!0,Y)}catch(G){let H=W.__strictErrorHandling;if(G instanceof Error&&G.name==="ConfigNotFoundError"){if(H)throw G;z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`No configuration file found for "${W.name||"config"}", using defaults with environment variables`]}}else if(G instanceof Error&&G.name==="ConfigLoadError"){let A=G.message.includes("EACCES")||G.message.includes("EPERM")||G.message.includes("permission denied"),K=!A&&(G.message.includes("syntax")||G.message.includes("Expected")||G.message.includes("Unexpected")||G.message.includes("BuildMessage")||G.message.includes("errors building")),B=G.message.includes("Configuration must export a valid object")||G.message.includes("Configuration file is empty and exports nothing");if(H&&(B||A))throw G;if(K&&(!H||!B))z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:["Configuration file has syntax errors, using defaults with environment variables"]};else if(!H)z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading error, using defaults: ${G.message}`]};else throw G}else z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading failed, using defaults: ${G instanceof Error?G.message:String(G)}`]}}if(Z||U)await this.validateConfiguration(z.config,Z,U,W.name);if(Y?.enabled&&z)this.cacheResult(W.name||"",z,Y,W);if(Q?.enabled){let G={operation:"loadConfig",duration:Date.now()-J,configName:W.name,timestamp:new Date};if(Q.onMetrics)Q.onMetrics(G);if(Q.slowThreshold&&G.duration>Q.slowThreshold)M1.warn(`Slow configuration loading detected: ${G.duration}ms for ${W.name}`);z.metrics=G}return z}catch(z){if(z instanceof Error&&z.name==="ConfigNotFoundError")throw z;let G=Date.now()-J;throw M1.error(`Configuration loading failed after ${G}ms:`,[z instanceof Error?z:Error(String(z))]),z}}async loadConfigurationStrategies($,J=!1,Y){let{name:Q="",alias:Z,cwd:U,configDir:W,defaultConfig:z,checkEnv:G=!0,arrayStrategy:H="replace",verbose:A=!1}=$,K=U||W9.cwd(),B=[],j=await this.loadLocalConfiguration(Q,Z,K,W,z,H,A,G,Y);if(j)return B.push(...this.getLocalSearchPaths(Q,Z,K,W)),this.finalizeResult(j,B,G,Q,A);let X=await this.loadHomeConfiguration(Q,Z,z,H,A,G);if(X)return B.push(...this.getHomeSearchPaths(Q,Z)),this.finalizeResult(X,B,G,Q,A);let O=await this.loadPackageJsonConfiguration(Q,Z,K,z,H,A,G);if(O)return B.push(W1(K,"package.json")),this.finalizeResult(O,B,G,Q,A);if(B.push(...this.getAllSearchPaths(Q,Z,K,W)),J)throw y2.configNotFound(Q,B,Z);return{...await this.applyEnvironmentVariables(Q,z,G,A),warnings:[`No configuration file found for "${Q}"${bG(Z)}, using defaults with environment variables`]}}async loadLocalConfiguration($,J,Y,Q,Z,U,W,z,G){let H=z?u$($,Z,W):Z,A=this.getLocalDirectories(Y,Q);for(let K of A){if(W)M1.info(`Searching for configuration in: ${K}`);let B=this.fileLoader.generateConfigPaths($,K,J),j=await this.fileLoader.tryLoadFromPaths(B,H,{arrayStrategy:U,verbose:W,cacheTtl:G?.ttl,useCache:!G?.ttl||G.ttl>100});if(j){if(W)M1.success(`Configuration loaded from: ${j.source.path}`);return j}}return null}async loadHomeConfiguration($,J,Y,Q,Z,U){if(!$)return null;let W=U?u$($,Y,Z):Y,z=[W1(T2(),".config",$),W1(T2(),".config"),T2()];for(let G of z){if(Z)M1.info(`Checking home directory: ${G}`);let H=this.fileLoader.generateConfigPaths($,G,J),A=await this.fileLoader.tryLoadFromPaths(H,W,{arrayStrategy:Q,verbose:Z});if(A){if(Z)M1.success(`Configuration loaded from home directory: ${A.source.path}`);return A}}return null}async loadPackageJsonConfiguration($,J,Y,Q,Z,U,W){let z=W?u$($,Q,U):Q;try{let G=W1(Y,"package.json");if(!SW(G))return null;let H={};try{H=JSON.parse(PW(G,"utf8"))}catch(B){if(U)M1.warn("Failed to parse package.json:",[B instanceof Error?B:Error(String(B))]);return null}let A=H[$],K=$;if(!A&&J){let B=Array.isArray(J)?J:[J];for(let j of B){if(!j)continue;if(H[j]){A=H[j],K=j;break}}}if(A&&typeof A==="object"&&!Array.isArray(A)){if(U)M1.success(`Configuration loaded from package.json: ${K}`);return{config:eY(z,A,Z),source:{type:"package.json",path:G,priority:30,timestamp:new Date}}}}catch(G){if(U)M1.warn("Failed to load package.json:",[G instanceof Error?G:Error(String(G))])}return null}async applyEnvironmentVariables($,J,Y,Q){if(!Y||!$||typeof J!=="object"||J===null||Array.isArray(J))return{config:J,source:{type:"default",priority:10,timestamp:new Date}};return{config:u$($,J,Q),source:{type:"environment",priority:20,timestamp:new Date}}}async finalizeResult($,J,Y,Q,Z){return{config:$.config,source:$.source,path:$.source.path}}async validateConfiguration($,J,Y,Q){let Z=[];if(Y){let U=Y($);if(U)Z.push(...U)}if(J){let U=await this.validator.validateConfiguration($,J);if(!U.isValid)Z.push(...U.errors.map((W)=>W.path?`${W.path}: ${W.message}`:W.message))}if(Z.length>0)throw y2.configValidation(Q||"unknown",Z,Q)}checkCache($,J){let Y=this.generateCacheKey($,J);return r$.get(Y)||null}cacheResult($,J,Y,Q){let Z=this.generateCacheKey($,Q);r$.set(Z,J,void 0,Y.ttl)}generateCacheKey($,J){let Y=[$];if(J.alias){let Q=Array.isArray(J.alias)?J.alias.join(","):J.alias;Y.push(`alias:${Q}`)}if(J.cwd)Y.push(`cwd:${J.cwd}`);if(J.configDir)Y.push(`configDir:${J.configDir}`);if("checkEnv"in J)Y.push(`checkEnv:${J.checkEnv}`);return Y.join("|")}getLocalDirectories($,J){return Array.from(new Set([$,W1($,"config"),W1($,".config"),J?W1($,J):void 0].filter(Boolean)))}getAllSearchPaths($,J,Y,Q){let Z=[];return Z.push(...this.getLocalSearchPaths($,J,Y,Q)),Z.push(...this.getHomeSearchPaths($,J)),Z.push(W1(Y,"package.json")),Z}getLocalSearchPaths($,J,Y,Q){let Z=this.getLocalDirectories(Y,Q),U=[];for(let W of Z)U.push(...this.fileLoader.generateConfigPaths($,W,J));return U}getHomeSearchPaths($,J){if(!$)return[];let Y=[W1(T2(),".config",$),W1(T2(),".config"),T2()],Q=[];for(let Z of Y)Q.push(...this.fileLoader.generateConfigPaths($,Z,J));return Q}async loadConfigWithResult($){return this.loadConfig($)}}var k8=new YQ;async function QQ($){let J="defaultConfig"in $&&$.defaultConfig!==void 0?$.defaultConfig:{},Y="cache"in $||"performance"in $||"schema"in $||"validate"in $;try{let Q;if(Y)Q=await k8.loadConfig($);else Q=await k8.loadConfig({...$,defaultConfig:J,cache:{enabled:!0},performance:{enabled:!1}});return Q?.config??J}catch(Q){let Z=Q instanceof Error?Q.name:"UnknownError",U=Q instanceof Error?Q.message:String(Q);if(!(Z==="ConfigNotFoundError"||Z==="ConfigLoadError"||Z==="ConfigValidationError"||U.includes("config"))&&$.verbose)M1.warn("Unexpected error loading config, using defaults:",[Q instanceof Error?Q:Error(String(Q))]);let z=Y?{...$,defaultConfig:J}:{...$,defaultConfig:J,cache:{enabled:!0},performance:{enabled:!1}};if("checkEnv"in $?$.checkEnv!==!1:!0)return(await k8.applyEnvironmentVariables(z.name||"",J,!0,z.verbose||!1))?.config??J;return J}}function u$($,J,Y=!1){let Q=new J6,Z=$.toUpperCase().replace(/[^A-Z0-9]/g,"_");function U(W,z=[]){let G={...W};for(let[H,A]of Object.entries(W)){let K=[...z,H],B=[`${Z}_${K.join("_").toUpperCase()}`,`${Z}_${K.map((O)=>O.toUpperCase()).join("")}`,`${Z}_${K.map((O)=>O.replace(/([A-Z])/g,"_$1").toUpperCase()).join("")}`],j,X;for(let O of B)if(j=W9.env[O],j!==void 0){X=O;break}if(j!==void 0&&X)if(typeof A==="boolean")G[H]=["true","1","yes"].includes(j.toLowerCase());else if(typeof A==="number"){let O=Number(j);if(!Number.isNaN(O))G[H]=O}else if(Array.isArray(A))try{G[H]=JSON.parse(j)}catch{G[H]=j.split(",").map((O)=>O.trim())}else G[H]=j;else if(A&&typeof A==="object"&&!Array.isArray(A))G[H]=U(A,K)}return G}return U(J)}var hO=W1(W9.cwd(),"config"),bO=W1(W9.cwd(),"src/generated");var yG={project:{name:"my-project",slug:"my-project",region:"us-east-1"},environments:{production:{type:"production"}}},Y6=null;async function vG(){if(!Y6)Y6=await QQ({name:"cloud",defaultConfig:yG});return Y6}var ZQ=vG;B2();async function c(){let $=await ZQ();if(!$.project)throw Error("Missing required project configuration in cloud.config.ts");return $}function H1($){if($)switch($.toLowerCase()){case"porkbun":{let Q=process.env.PORKBUN_API_KEY,Z=process.env.PORKBUN_SECRET_KEY;if(!Q||!Z)throw Error("PORKBUN_API_KEY and PORKBUN_SECRET_KEY environment variables are required for Porkbun provider");return{provider:"porkbun",apiKey:Q,secretKey:Z}}case"godaddy":{let Q=process.env.GODADDY_API_KEY,Z=process.env.GODADDY_API_SECRET;if(!Q||!Z)throw Error("GODADDY_API_KEY and GODADDY_API_SECRET environment variables are required for GoDaddy provider");let U=process.env.GODADDY_ENVIRONMENT||"production";return{provider:"godaddy",apiKey:Q,apiSecret:Z,environment:U}}case"route53":{let Q=process.env.AWS_REGION||"us-east-1",Z=process.env.AWS_HOSTED_ZONE_ID;return{provider:"route53",region:Q,hostedZoneId:Z}}case"cloudflare":{let Q=process.env.CLOUDFLARE_API_TOKEN;if(!Q)throw Error("CLOUDFLARE_API_TOKEN environment variable is required for Cloudflare provider");return{provider:"cloudflare",apiToken:Q}}default:throw Error(`Unknown DNS provider: ${$}. Supported: porkbun, godaddy, route53, cloudflare`)}if(new O9().loadFromEnv().getAllProviders().length===0)return null;if(process.env.PORKBUN_API_KEY&&process.env.PORKBUN_SECRET_KEY)return{provider:"porkbun",apiKey:process.env.PORKBUN_API_KEY,secretKey:process.env.PORKBUN_SECRET_KEY};if(process.env.GODADDY_API_KEY&&process.env.GODADDY_API_SECRET)return{provider:"godaddy",apiKey:process.env.GODADDY_API_KEY,apiSecret:process.env.GODADDY_API_SECRET,environment:process.env.GODADDY_ENVIRONMENT||"production"};if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)return{provider:"route53",region:process.env.AWS_REGION||"us-east-1",hostedZoneId:process.env.AWS_HOSTED_ZONE_ID};if(process.env.CLOUDFLARE_API_TOKEN)return{provider:"cloudflare",apiToken:process.env.CLOUDFLARE_API_TOKEN};return null}function o1($){let J=H1($);if(!J)throw Error("No DNS provider configured. Set environment variables for Porkbun (PORKBUN_API_KEY, PORKBUN_SECRET_KEY), GoDaddy (GODADDY_API_KEY, GODADDY_API_SECRET), Cloudflare (CLOUDFLARE_API_TOKEN), or Route53 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)");return e0(J)}function Z6($){$.command("config","Show current configuration").action(async()=>{V("Configuration");try{let J=await c();console.log(JSON.stringify(J,null,2))}catch(J){R(`Failed to load configuration: ${J instanceof Error?J.message:"Unknown error"}`)}}),$.command("config:validate","Validate configuration file").action(async()=>{V("Validating Configuration");let J=new L("Validating cloud.config.ts...");J.start();try{let Y=await c();if(!Y.project?.name)throw Error("Missing project.name");if(!Y.project?.slug)throw Error("Missing project.slug");if(!Y.mode)throw Error("Missing deployment mode");J.succeed("Configuration is valid!"),F(`Project: ${Y.project.name}`),F(`Mode: ${Y.mode}`),F(`Region: ${Y.project.region||"us-east-1"}`)}catch(Y){J.fail("Configuration is invalid"),R(Y instanceof Error?Y.message:"Unknown error")}}),$.command("config:env","Manage environment variables").option("--list","List all environment variables").option("--set <key=value>","Set an environment variable").option("--unset <key>","Remove an environment variable").option("--environment <env>","Target environment (production, staging, development)").action(async(J)=>{V("Environment Variables");let Y=J?.environment||"production";if(J?.list)F(`Environment variables for ${Y}:`),d(["Key","Value","Last Modified"],[["NODE_ENV",Y,"2024-01-15"],["API_URL","https://api.example.com","2024-01-14"],["DEBUG","false","2024-01-10"]]);else if(J?.set){let[Q,...Z]=J.set.split("="),U=Z.join("=");if(!Q||!U){R("Invalid format. Use: --set KEY=VALUE");return}let W=new L(`Setting ${Q}=${U}...`);W.start(),await new Promise((z)=>setTimeout(z,1000)),W.succeed(`Environment variable ${Q} set for ${Y}`)}else if(J?.unset){if(!await y(`Remove ${J.unset} from ${Y} environment?`,!1)){F("Operation cancelled");return}let Z=new L(`Removing ${J.unset}...`);Z.start(),await new Promise((U)=>setTimeout(U,1000)),Z.succeed(`Environment variable ${J.unset} removed`)}else F("Use --list, --set KEY=VALUE, or --unset KEY")}),$.command("config:secrets","Manage secrets (AWS Secrets Manager)").option("--list","List all secrets").option("--create <name>","Create a new secret").option("--get <name>","Get secret value").option("--update <name>","Update secret value").option("--delete <name>","Delete a secret").option("--value <value>","Secret value (for create/update)").action(async(J)=>{if(V("Secrets Manager"),J?.list)F("Secrets in AWS Secrets Manager:"),d(["Name","Last Modified","Rotation Enabled"],[["db-password","2024-01-15","Yes"],["api-key","2024-01-14","No"],["jwt-secret","2024-01-10","Yes"]]);else if(J?.create){if(!J.value){let Q=await A0("Enter secret value","");J.value=Q}let Y=new L(`Creating secret ${J.create}...`);Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.succeed(`Secret ${J.create} created successfully`)}else if(J?.get){let Y=new L(`Fetching secret ${J.get}...`);Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.succeed("Secret retrieved"),F(`${J.get}: ******* (hidden for security)`),L1("Use --show-value to display the actual value")}else if(J?.update){if(!J.value){let Q=await A0("Enter new secret value","");J.value=Q}let Y=new L(`Updating secret ${J.update}...`);Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.succeed(`Secret ${J.update} updated successfully`)}else if(J?.delete){if(L1("This action is irreversible!"),!await y(`Delete secret ${J.delete}?`,!1)){F("Deletion cancelled");return}let Q=new L(`Deleting secret ${J.delete}...`);Q.start(),await new Promise((Z)=>setTimeout(Z,1000)),Q.succeed(`Secret ${J.delete} deleted`)}else F("Use --list, --create, --get, --update, or --delete")})}import{existsSync as cK}from"node:fs";import{mkdir as lK,writeFile as pK}from"node:fs/promises";import{join as rK}from"node:path";await Z2();class c2{builder;config;environment;mergedConfig;serverEipLogicalIds=new Map;constructor($){this.config=$.config,this.environment=$.environment,this.builder=new P9(`${this.config.project.name} - ${this.environment}`),this.mergedConfig=this.mergeEnvironmentConfig()}mergeEnvironmentConfig(){let J=this.config.environments[this.environment]?.infrastructure;if(!J)return this.config;return{...this.config,infrastructure:{...this.config.infrastructure,...J,compute:{...this.config.infrastructure?.compute,...J.compute},storage:{...this.config.infrastructure?.storage,...J.storage},functions:{...this.config.infrastructure?.functions,...J.functions},servers:{...this.config.infrastructure?.servers,...J.servers},databases:{...this.config.infrastructure?.databases,...J.databases},cdn:{...this.config.infrastructure?.cdn,...J.cdn},queues:{...this.config.infrastructure?.queues,...J.queues},redirects:{...this.config.infrastructure?.redirects,...J.redirects},realtime:{...this.config.infrastructure?.realtime,...J.realtime},cache:{...this.config.infrastructure?.cache,...J.cache},fileSystem:{...this.config.infrastructure?.fileSystem,...J.fileSystem},email:{...this.config.infrastructure?.email,...J.email},search:{...this.config.infrastructure?.search,...J.search},ai:{...this.config.infrastructure?.ai,...J.ai}}}}shouldDeploy($){if($.environments&&!$.environments.includes(this.environment))return!1;if($.requiresFeatures){let J=this.config.features||{};if(!$.requiresFeatures.every((Q)=>J[Q]===!0))return!1}if($.regions){let J=this.config.environments[this.environment]?.region||this.config.project.region;if(!$.regions.includes(J))return!1}if($.condition&&typeof $.condition==="function")return $.condition(this.config,this.environment);return!0}resolveApiOriginPort(){let $=this.mergedConfig.infrastructure?.api?.port??this.mergedConfig.ports?.api,J=Number($||3008);return Number.isFinite(J)&&J>0?J:3008}defaultComputeCachePathPatterns(){return["/api/*","/auth/*","/publisher/api/*","/publisher/*","/publish","/publish/*","/analytics/*","/packages/*","/npm/*","/zig/*","/php/*","/commits/*","/health","/dashboard/*","/search","/login","/logout","/signup","/account","/account/*"]}shouldRouteStorageBucketToCompute($,J){return $==="public"||J.routeCompute===!0}resolveComputeCachePathPatterns($){if($&&$.length>0)return $;return this.defaultComputeCachePathPatterns()}createComputeCacheBehavior($,J){return{PathPattern:$,TargetOriginId:J,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",OriginRequestPolicyId:"b689b0a8-53d0-40ab-baf2-68738e2966ac"}}appendComputeAppOrigin($,J,Y,Q,Z,U){let W=this.serverEipLogicalIds.get("app"),z=this.serverEipLogicalIds.get("appInstance");if(!W)return;let G=`EC2-${Q}-${Z}-api`,H=this.mergedConfig.infrastructure?.servers?.app?.region||this.mergedConfig.project?.region||"us-east-1",A=H==="us-east-1"?".compute-1.amazonaws.com":`.${H}.compute.amazonaws.com`,K={"Fn::Join":["",["ec2-",{"Fn::Join":["-",{"Fn::Split":[".",{Ref:W}]}]},A]]},B=this.resolveApiOriginPort();if($.push({Id:G,DomainName:K,CustomOriginConfig:{HTTPPort:B,HTTPSPort:443,OriginProtocolPolicy:"http-only",OriginSSLProtocols:["TLSv1.2"]}}),Y.push(W),z)Y.push(z);for(let j of U)J.push(this.createComputeCacheBehavior(j,G))}buildCaddyfile($){let J=$.filter(([,Z])=>typeof Z.domain==="string"&&Z.domain&&typeof Z.port==="number");if(J.length===0)return;let Y=new Map;for(let[,Z]of J){let U=Y.get(Z.domain)??[];U.push({port:Z.port,path:Z.path}),Y.set(Z.domain,U)}let Q=[];for(let[Z,U]of Y){let z=[...U].sort((G,H)=>{let A=!G.path||G.path==="/",K=!H.path||H.path==="/";if(A&&!K)return 1;if(!A&&K)return-1;return(H.path?.length??0)-(G.path?.length??0)}).map((G)=>{let H=!G.path||G.path==="/",A=`reverse_proxy localhost:${G.port}`;return H?` handle {
7316
+ `;return Y}}function SG($,J,Y={}){return sY($,J,Y,new WeakMap)}function sY($,J,Y,Q){let{arrayMergeMode:Z="replace",skipNullish:U=!1,customMerger:W}=Y;if(J===null||J===void 0)return U?$:J;if(W){let z=W($,J);if(z!==void 0)return z}if(Array.isArray(J)||Array.isArray($))return oY($,J,Z,Q);if(!G1(J)||!G1($))return J;return IG($,J,Y,Q)}function oY($,J,Y,Q){if(Array.isArray(J)&&!Array.isArray($))return J;if(Array.isArray($)&&!Array.isArray(J))return J;if(Array.isArray(J)&&Array.isArray($))switch(Y){case"replace":return J;case"concat":return PG($,J);case"smart":return xG($,J,Q);default:return J}return J}function PG($,J){let Y=[...J];for(let Q of $)if(!Y.some((Z)=>p8(Z,Q)))Y.push(Q);return Y}function xG($,J,Y){if(J.length===0)return $;if($.length===0)return J;if(G1(J[0])&&G1($[0]))return CG($,J,Y);if(J.every((Q)=>typeof Q==="string")&&$.every((Q)=>typeof Q==="string")){let Q=[...J];for(let Z of $)if(!Q.includes(Z))Q.push(Z);return Q}return J}function CG($,J,Y){let Q=[...J];for(let Z of $){if(!G1(Z)){Q.push(Z);continue}let U=["id","name","key","path","type"],W=!1;for(let z of U)if(z in Z){if(Q.find((H)=>G1(H)&&(z in H)&&H[z]===Z[z])){W=!0;break}}if(!W)Q.push(Z)}return Q}function IG($,J,Y,Q){let Z=J;if(G1(Z)&&Q.has(Z))return Q.get(Z);let U={...$};if(G1(Z))Q.set(Z,U);for(let W in Z){if(!Object.prototype.hasOwnProperty.call(Z,W))continue;let z=Z[W],G=U[W];if(Y.skipNullish&&(z===null||z===void 0))continue;if(z===null||z===void 0){U[W]=z;continue}if(G1(z)&&G1(G))U[W]=sY(G,z,Y,Q);else if(Array.isArray(z)||Array.isArray(G))U[W]=oY(G,z,Y.arrayMergeMode||"smart",Q);else U[W]=z}return U}function eY($,J,Y="replace"){return SG($,J,{arrayMergeMode:Y==="replace"?"replace":"smart",skipNullish:!0})}function p8($,J){if($===J)return!0;if(Array.isArray($)&&Array.isArray(J)){if($.length!==J.length)return!1;for(let Y=0;Y<$.length;Y++)if(!p8($[Y],J[Y]))return!1;return!0}if(G1($)&&G1(J)){let Y=Object.keys($),Q=Object.keys(J);if(Y.length!==Q.length)return!1;for(let Z of Y){if(!Object.prototype.hasOwnProperty.call(J,Z))return!1;if(!p8($[Z],J[Z]))return!1}return!0}return!1}function G1($){return Boolean($&&typeof $==="object"&&!Array.isArray($))}class $Q{extensions=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];async loadFromPath($,J,Y={}){let{arrayStrategy:Q="replace",useCache:Z=!0,cacheTtl:U,trackPerformance:W=!0,verbose:z=!1}=Y;if(Z){let H=r$.getWithFileCheck("file",$);if(H){if(z)console.log(`Configuration loaded from cache: ${$}`);return H}}let G=async()=>{if(!g$($))return null;try{let H=`?t=${Date.now()}`,A=await import($+H),K=A.default||A,B="default"in A,j=Object.keys(A).length>0;if(!B&&!j)throw new Z9($,Error("Configuration file is empty and exports nothing"),"unknown");if(typeof K!=="object"||K===null||Array.isArray(K))throw new Z9($,Error("Configuration must export a valid object"),"unknown");let _={config:eY(J,K,Q),source:{type:"file",path:$,priority:100,timestamp:new Date}};if(Z)r$.setWithFileCheck("file",_,$,U);return _}catch(H){throw H instanceof Error?y2.configLoad($,H):y2.configLoad($,Error(String(H)))}};if(W)return r8.track("loadFromPath",G,{path:$});return G()}async tryLoadFromPaths($,J,Y={}){for(let Q of $)try{let Z=await this.loadFromPath(Q,J,Y);if(Z)return Z}catch(Z){if(Z instanceof Error&&Z.name==="ConfigLoadError")throw Z;if(Y.verbose)console.warn(`Failed to load config from ${Q}:`,Z)}return null}generateConfigPaths($,J,Y){let Q=this.generateNamePatterns($,Y),Z=[];for(let U of Q)for(let W of this.extensions)Z.push(I8(J,`${U}${W}`));return Z}generateNamePatterns($,J){let Y=[];if(Y.push("config",".config"),$)Y.push($,`.${$}.config`,`${$}.config`,`.${$}`);let Q=J===void 0?[]:Array.isArray(J)?J:[J];for(let U of Q){if(!U)continue;if(Y.push(U,`.${U}.config`,`${U}.config`,`.${U}`),$)Y.push(`${$}.${U}.config`,`.${$}.${U}.config`)}let Z=new Set;return Y.filter((U)=>{if(!U||Z.has(U))return!1;return Z.add(U),!0})}checkFileAccess($){return NG(async()=>{return g$($)},{maxRetries:2,retryDelay:100,fallback:!1})}async discoverConfigFiles($,J,Y){let Q=[];if(!g$($))return Q;if(J||Y){let Z=this.generateNamePatterns(J||"",Y);for(let U of Z)for(let W of this.extensions){let z=I8($,`${U}${W}`);if(await this.checkFileAccess(z))Q.push(z)}}else try{let{readdirSync:Z}=await import("fs"),U=Z($);for(let W of U)if(this.looksLikeConfigFile(W)){let z=I8($,W);if(await this.checkFileAccess(z))Q.push(z)}}catch{return[]}return Q}looksLikeConfigFile($){return[/\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,/^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,/config\.(ts|js|mjs|cjs|json|mts|cts)$/].some((Y)=>Y.test($))}async validateConfigFile($){let J=[];try{if(!g$($))return J.push("Configuration file does not exist"),J;let Y=await import($),Q=Y.default||Y;if(Q===void 0)J.push("Configuration file must export a default value or named exports");else if(typeof Q!=="object"||Q===null)J.push("Configuration must be an object");else if(Array.isArray(Q))J.push("Configuration cannot be an array at the root level");if($.endsWith(".json"))try{let{readFileSync:Z}=await import("fs"),U=Z($,"utf8");JSON.parse(U)}catch(Z){J.push(`Invalid JSON syntax: ${Z}`)}}catch(Y){J.push(`Failed to load configuration file: ${Y}`)}return J}async getFileModificationTime($){try{let{statSync:J}=await import("fs");return J($).mtime}catch{return null}}async preloadConfigurations($,J={}){let Y=new Map;return await Promise.allSettled($.map(async(Q)=>{try{let Z=await this.loadFromPath(Q,{},J);if(Z)Y.set(Q,Z.config)}catch(Z){if(J.verbose)console.warn(`Failed to preload ${Q}:`,Z)}})),Y}}var hG=/^https?:\/\//;class JQ{async validateConfiguration($,J,Y={}){let{stopOnFirstError:Q=!1,validateRequired:Z=!0,validateTypes:U=!0,customRules:W=[],trackPerformance:z=!0,verbose:G=!1}=Y,H=async()=>{let A=[],K=[],B={stopOnFirstError:Q,validateRequired:Z,validateTypes:U,customRules:W,trackPerformance:z,verbose:G};try{if(typeof J==="string")return await this.validateWithSchemaFile($,J,B);else if(Array.isArray(J))return this.validateWithRules($,[...J,...W],B);else return this.validateWithJSONSchema($,J,B)}catch(j){return A.push({path:"",message:`Validation failed: ${j}`,rule:"system"}),{isValid:!1,errors:A,warnings:K}}};if(z)return await r8.track("validateConfiguration",H);return H()}async validateWithSchemaFile($,J,Y){try{if(!kG(J))throw new U9(J,[{path:"",message:"Schema file does not exist"}]);let Q=await import(J),Z=Q.default||Q;if(Array.isArray(Z))return this.validateWithRules($,Z,Y);else return this.validateWithJSONSchema($,Z,Y)}catch(Q){throw new U9(J,[{path:"",message:`Failed to load schema: ${Q}`}])}}validateWithJSONSchema($,J,Y){let Q=[],Z=[];return this.validateObjectAgainstSchema($,J,"",Q,Z,Y),{isValid:Q.length===0,errors:Q,warnings:Z}}validateObjectAgainstSchema($,J,Y,Q,Z,U){if(U.validateTypes&&J.type){let W=Array.isArray($)?"array":typeof $,z=Array.isArray(J.type)?J.type:[J.type];if(!z.includes(W)){if(Q.push({path:Y,message:`Expected type ${z.join(" or ")}, got ${W}`,expected:z.join(" or "),actual:W,rule:"type"}),U.stopOnFirstError)return}}if(J.enum&&!J.enum.includes($)){if(Q.push({path:Y,message:`Value must be one of: ${J.enum.join(", ")}`,expected:J.enum.join(", "),actual:$,rule:"enum"}),U.stopOnFirstError)return}if(typeof $==="string"){if(J.minLength!==void 0&&$.length<J.minLength)Q.push({path:Y,message:`String length must be at least ${J.minLength}`,expected:`>= ${J.minLength}`,actual:$.length,rule:"minLength"});if(J.maxLength!==void 0&&$.length>J.maxLength)Q.push({path:Y,message:`String length must not exceed ${J.maxLength}`,expected:`<= ${J.maxLength}`,actual:$.length,rule:"maxLength"});if(J.pattern){if(!new RegExp(J.pattern).test($))Q.push({path:Y,message:`String does not match pattern ${J.pattern}`,expected:J.pattern,actual:$,rule:"pattern"})}}if(typeof $==="number"){if(J.minimum!==void 0&&$<J.minimum)Q.push({path:Y,message:`Value must be at least ${J.minimum}`,expected:`>= ${J.minimum}`,actual:$,rule:"minimum"});if(J.maximum!==void 0&&$>J.maximum)Q.push({path:Y,message:`Value must not exceed ${J.maximum}`,expected:`<= ${J.maximum}`,actual:$,rule:"maximum"})}if(Array.isArray($)&&J.items)for(let W=0;W<$.length;W++){let z=Y?`${Y}[${W}]`:`[${W}]`;if(this.validateObjectAgainstSchema($[W],J.items,z,Q,Z,U),U.stopOnFirstError&&Q.length>0)return}if($&&typeof $==="object"&&!Array.isArray($)){let W=$;if(U.validateRequired&&J.required){for(let z of J.required)if(!(z in W)){if(Q.push({path:Y?`${Y}.${z}`:z,message:`Missing required property '${z}'`,expected:"required",rule:"required"}),U.stopOnFirstError)return}}if(J.properties){for(let[z,G]of Object.entries(J.properties))if(z in W){let H=Y?`${Y}.${z}`:z;if(this.validateObjectAgainstSchema(W[z],G,H,Q,Z,U),U.stopOnFirstError&&Q.length>0)return}}if(J.additionalProperties===!1){let z=new Set(Object.keys(J.properties||{}));for(let G of Object.keys(W))if(!z.has(G))Z.push({path:Y?`${Y}.${G}`:G,message:`Additional property '${G}' is not allowed`,rule:"additionalProperties"})}}}validateWithRules($,J,Y){let Q=[],Z=[];for(let U of J)try{let W=this.getValueByPath($,U.path),z=this.validateWithRule(W,U,U.path);if(Q.push(...z),Y.stopOnFirstError&&Q.length>0)break}catch(W){Q.push({path:U.path,message:`Rule validation failed: ${W}`,rule:"system"})}return{isValid:Q.length===0,errors:Q,warnings:Z}}validateWithRule($,J,Y){let Q=[];if(J.required&&($===void 0||$===null))return Q.push({path:Y,message:J.message||`Property '${Y}' is required`,expected:"required",rule:"required"}),Q;if($===void 0||$===null)return Q;if(J.type){let Z=Array.isArray($)?"array":typeof $;if(Z!==J.type)Q.push({path:Y,message:J.message||`Expected type ${J.type}, got ${Z}`,expected:J.type,actual:Z,rule:"type"})}if(J.min!==void 0){let Z=Array.isArray($)?$.length:typeof $==="string"?$.length:typeof $==="number"?$:0;if(Z<J.min)Q.push({path:Y,message:J.message||`Value must be at least ${J.min}`,expected:`>= ${J.min}`,actual:Z,rule:"min"})}if(J.max!==void 0){let Z=Array.isArray($)?$.length:typeof $==="string"?$.length:typeof $==="number"?$:0;if(Z>J.max)Q.push({path:Y,message:J.message||`Value must not exceed ${J.max}`,expected:`<= ${J.max}`,actual:Z,rule:"max"})}if(J.pattern&&typeof $==="string"){if(!J.pattern.test($))Q.push({path:Y,message:J.message||`Value does not match pattern ${J.pattern}`,expected:J.pattern.toString(),actual:$,rule:"pattern"})}if(J.enum&&!J.enum.includes($))Q.push({path:Y,message:J.message||`Value must be one of: ${J.enum.join(", ")}`,expected:J.enum.join(", "),actual:$,rule:"enum"});if(J.validator){let Z=J.validator($);if(Z)Q.push({path:Y,message:J.message||Z,rule:"custom"})}return Q}getValueByPath($,J){if(!J)return $;let Y=J.split("."),Q=$;for(let Z of Y)if(Q&&typeof Q==="object"&&Z in Q)Q=Q[Z];else return;return Q}generateRulesFromInterface($){let J=[],Y=$.matchAll(/(\w+)(\?)?:\s*(\w+)/g);for(let Q of Y){let[,Z,U,W]=Q;J.push({path:Z,required:!U,type:this.mapTypeScriptType(W)})}return J}mapTypeScriptType($){switch($.toLowerCase()){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return"array";case"object":return"object";default:return"object"}}static createCommonRules(){return{server:[{path:"port",required:!0,type:"number",min:1,max:65535},{path:"host",required:!0,type:"string",min:1},{path:"ssl",type:"boolean"}],database:[{path:"url",required:!0,type:"string",min:1},{path:"pool",type:"number",min:1,max:100},{path:"timeout",type:"number",min:0}],api:[{path:"baseUrl",required:!0,type:"string",pattern:hG},{path:"timeout",type:"number",min:0},{path:"retries",type:"number",min:0,max:10}]}}}var M1=new H9("bunfig",{showTags:!0});function bG($){if(!$)return"";let J=Array.isArray($)?$.filter(Boolean):[$];if(J.length===0)return"";if(J.length===1)return` or alias "${J[0]}"`;return` or aliases ${J.map((Y)=>`"${Y}"`).join(", ")}`}class YQ{fileLoader=new $Q;envProcessor=new J6;validator=new JQ;async loadConfig($){let J=Date.now(),{cache:Y,performance:Q,schema:Z,validate:U,...W}=$;try{if(Y?.enabled){let G=this.checkCache(W.name||"",W);if(G)return G}let z;try{z=await this.loadConfigurationStrategies(W,!0,Y)}catch(G){let H=W.__strictErrorHandling;if(G instanceof Error&&G.name==="ConfigNotFoundError"){if(H)throw G;z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`No configuration file found for "${W.name||"config"}", using defaults with environment variables`]}}else if(G instanceof Error&&G.name==="ConfigLoadError"){let A=G.message.includes("EACCES")||G.message.includes("EPERM")||G.message.includes("permission denied"),K=!A&&(G.message.includes("syntax")||G.message.includes("Expected")||G.message.includes("Unexpected")||G.message.includes("BuildMessage")||G.message.includes("errors building")),B=G.message.includes("Configuration must export a valid object")||G.message.includes("Configuration file is empty and exports nothing");if(H&&(B||A))throw G;if(K&&(!H||!B))z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:["Configuration file has syntax errors, using defaults with environment variables"]};else if(!H)z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading error, using defaults: ${G.message}`]};else throw G}else z={...await this.applyEnvironmentVariables(W.name||"",W.defaultConfig,W.checkEnv!==!1,W.verbose||!1),warnings:[`Configuration loading failed, using defaults: ${G instanceof Error?G.message:String(G)}`]}}if(Z||U)await this.validateConfiguration(z.config,Z,U,W.name);if(Y?.enabled&&z)this.cacheResult(W.name||"",z,Y,W);if(Q?.enabled){let G={operation:"loadConfig",duration:Date.now()-J,configName:W.name,timestamp:new Date};if(Q.onMetrics)Q.onMetrics(G);if(Q.slowThreshold&&G.duration>Q.slowThreshold)M1.warn(`Slow configuration loading detected: ${G.duration}ms for ${W.name}`);z.metrics=G}return z}catch(z){if(z instanceof Error&&z.name==="ConfigNotFoundError")throw z;let G=Date.now()-J;throw M1.error(`Configuration loading failed after ${G}ms:`,[z instanceof Error?z:Error(String(z))]),z}}async loadConfigurationStrategies($,J=!1,Y){let{name:Q="",alias:Z,cwd:U,configDir:W,defaultConfig:z,checkEnv:G=!0,arrayStrategy:H="replace",verbose:A=!1}=$,K=U||W9.cwd(),B=[],j=await this.loadLocalConfiguration(Q,Z,K,W,z,H,A,G,Y);if(j)return B.push(...this.getLocalSearchPaths(Q,Z,K,W)),this.finalizeResult(j,B,G,Q,A);let X=await this.loadHomeConfiguration(Q,Z,z,H,A,G);if(X)return B.push(...this.getHomeSearchPaths(Q,Z)),this.finalizeResult(X,B,G,Q,A);let O=await this.loadPackageJsonConfiguration(Q,Z,K,z,H,A,G);if(O)return B.push(W1(K,"package.json")),this.finalizeResult(O,B,G,Q,A);if(B.push(...this.getAllSearchPaths(Q,Z,K,W)),J)throw y2.configNotFound(Q,B,Z);return{...await this.applyEnvironmentVariables(Q,z,G,A),warnings:[`No configuration file found for "${Q}"${bG(Z)}, using defaults with environment variables`]}}async loadLocalConfiguration($,J,Y,Q,Z,U,W,z,G){let H=z?u$($,Z,W):Z,A=this.getLocalDirectories(Y,Q);for(let K of A){if(W)M1.info(`Searching for configuration in: ${K}`);let B=this.fileLoader.generateConfigPaths($,K,J),j=await this.fileLoader.tryLoadFromPaths(B,H,{arrayStrategy:U,verbose:W,cacheTtl:G?.ttl,useCache:!G?.ttl||G.ttl>100});if(j){if(W)M1.success(`Configuration loaded from: ${j.source.path}`);return j}}return null}async loadHomeConfiguration($,J,Y,Q,Z,U){if(!$)return null;let W=U?u$($,Y,Z):Y,z=[W1(T2(),".config",$),W1(T2(),".config"),T2()];for(let G of z){if(Z)M1.info(`Checking home directory: ${G}`);let H=this.fileLoader.generateConfigPaths($,G,J),A=await this.fileLoader.tryLoadFromPaths(H,W,{arrayStrategy:Q,verbose:Z});if(A){if(Z)M1.success(`Configuration loaded from home directory: ${A.source.path}`);return A}}return null}async loadPackageJsonConfiguration($,J,Y,Q,Z,U,W){let z=W?u$($,Q,U):Q;try{let G=W1(Y,"package.json");if(!SW(G))return null;let H={};try{H=JSON.parse(PW(G,"utf8"))}catch(B){if(U)M1.warn("Failed to parse package.json:",[B instanceof Error?B:Error(String(B))]);return null}let A=H[$],K=$;if(!A&&J){let B=Array.isArray(J)?J:[J];for(let j of B){if(!j)continue;if(H[j]){A=H[j],K=j;break}}}if(A&&typeof A==="object"&&!Array.isArray(A)){if(U)M1.success(`Configuration loaded from package.json: ${K}`);return{config:eY(z,A,Z),source:{type:"package.json",path:G,priority:30,timestamp:new Date}}}}catch(G){if(U)M1.warn("Failed to load package.json:",[G instanceof Error?G:Error(String(G))])}return null}async applyEnvironmentVariables($,J,Y,Q){if(!Y||!$||typeof J!=="object"||J===null||Array.isArray(J))return{config:J,source:{type:"default",priority:10,timestamp:new Date}};return{config:u$($,J,Q),source:{type:"environment",priority:20,timestamp:new Date}}}async finalizeResult($,J,Y,Q,Z){return{config:$.config,source:$.source,path:$.source.path}}async validateConfiguration($,J,Y,Q){let Z=[];if(Y){let U=Y($);if(U)Z.push(...U)}if(J){let U=await this.validator.validateConfiguration($,J);if(!U.isValid)Z.push(...U.errors.map((W)=>W.path?`${W.path}: ${W.message}`:W.message))}if(Z.length>0)throw y2.configValidation(Q||"unknown",Z,Q)}checkCache($,J){let Y=this.generateCacheKey($,J);return r$.get(Y)||null}cacheResult($,J,Y,Q){let Z=this.generateCacheKey($,Q);r$.set(Z,J,void 0,Y.ttl)}generateCacheKey($,J){let Y=[$];if(J.alias){let Q=Array.isArray(J.alias)?J.alias.join(","):J.alias;Y.push(`alias:${Q}`)}if(J.cwd)Y.push(`cwd:${J.cwd}`);if(J.configDir)Y.push(`configDir:${J.configDir}`);if("checkEnv"in J)Y.push(`checkEnv:${J.checkEnv}`);return Y.join("|")}getLocalDirectories($,J){return Array.from(new Set([$,W1($,"config"),W1($,".config"),J?W1($,J):void 0].filter(Boolean)))}getAllSearchPaths($,J,Y,Q){let Z=[];return Z.push(...this.getLocalSearchPaths($,J,Y,Q)),Z.push(...this.getHomeSearchPaths($,J)),Z.push(W1(Y,"package.json")),Z}getLocalSearchPaths($,J,Y,Q){let Z=this.getLocalDirectories(Y,Q),U=[];for(let W of Z)U.push(...this.fileLoader.generateConfigPaths($,W,J));return U}getHomeSearchPaths($,J){if(!$)return[];let Y=[W1(T2(),".config",$),W1(T2(),".config"),T2()],Q=[];for(let Z of Y)Q.push(...this.fileLoader.generateConfigPaths($,Z,J));return Q}async loadConfigWithResult($){return this.loadConfig($)}}var k8=new YQ;async function QQ($){let J="defaultConfig"in $&&$.defaultConfig!==void 0?$.defaultConfig:{},Y="cache"in $||"performance"in $||"schema"in $||"validate"in $;try{let Q;if(Y)Q=await k8.loadConfig($);else Q=await k8.loadConfig({...$,defaultConfig:J,cache:{enabled:!0},performance:{enabled:!1}});return Q?.config??J}catch(Q){let Z=Q instanceof Error?Q.name:"UnknownError",U=Q instanceof Error?Q.message:String(Q);if(!(Z==="ConfigNotFoundError"||Z==="ConfigLoadError"||Z==="ConfigValidationError"||U.includes("config"))&&$.verbose)M1.warn("Unexpected error loading config, using defaults:",[Q instanceof Error?Q:Error(String(Q))]);let z=Y?{...$,defaultConfig:J}:{...$,defaultConfig:J,cache:{enabled:!0},performance:{enabled:!1}};if("checkEnv"in $?$.checkEnv!==!1:!0)return(await k8.applyEnvironmentVariables(z.name||"",J,!0,z.verbose||!1))?.config??J;return J}}function u$($,J,Y=!1){let Q=new J6,Z=$.toUpperCase().replace(/[^A-Z0-9]/g,"_");function U(W,z=[]){let G={...W};for(let[H,A]of Object.entries(W)){let K=[...z,H],B=[`${Z}_${K.join("_").toUpperCase()}`,`${Z}_${K.map((O)=>O.toUpperCase()).join("")}`,`${Z}_${K.map((O)=>O.replace(/([A-Z])/g,"_$1").toUpperCase()).join("")}`],j,X;for(let O of B)if(j=W9.env[O],j!==void 0){X=O;break}if(j!==void 0&&X)if(typeof A==="boolean")G[H]=["true","1","yes"].includes(j.toLowerCase());else if(typeof A==="number"){let O=Number(j);if(!Number.isNaN(O))G[H]=O}else if(Array.isArray(A))try{G[H]=JSON.parse(j)}catch{G[H]=j.split(",").map((O)=>O.trim())}else G[H]=j;else if(A&&typeof A==="object"&&!Array.isArray(A))G[H]=U(A,K)}return G}return U(J)}var hO=W1(W9.cwd(),"config"),bO=W1(W9.cwd(),"src/generated");var yG={project:{name:"my-project",slug:"my-project",region:"us-east-1"},environments:{production:{type:"production"}}},Y6=null;async function vG(){if(!Y6)Y6=await QQ({name:"cloud",defaultConfig:yG});return Y6}var ZQ=vG;B2();async function c(){let $=await ZQ();if(!$.project)throw Error("Missing required project configuration in cloud.config.ts");return $}function H1($){if($)switch($.toLowerCase()){case"porkbun":{let Q=process.env.PORKBUN_API_KEY,Z=process.env.PORKBUN_SECRET_KEY;if(!Q||!Z)throw Error("PORKBUN_API_KEY and PORKBUN_SECRET_KEY environment variables are required for Porkbun provider");return{provider:"porkbun",apiKey:Q,secretKey:Z}}case"godaddy":{let Q=process.env.GODADDY_API_KEY,Z=process.env.GODADDY_API_SECRET;if(!Q||!Z)throw Error("GODADDY_API_KEY and GODADDY_API_SECRET environment variables are required for GoDaddy provider");let U=process.env.GODADDY_ENVIRONMENT||"production";return{provider:"godaddy",apiKey:Q,apiSecret:Z,environment:U}}case"route53":{let Q=process.env.AWS_REGION||"us-east-1",Z=process.env.AWS_HOSTED_ZONE_ID;return{provider:"route53",region:Q,hostedZoneId:Z}}case"cloudflare":{let Q=process.env.CLOUDFLARE_API_TOKEN;if(!Q)throw Error("CLOUDFLARE_API_TOKEN environment variable is required for Cloudflare provider");return{provider:"cloudflare",apiToken:Q}}default:throw Error(`Unknown DNS provider: ${$}. Supported: porkbun, godaddy, route53, cloudflare`)}if(new O9().loadFromEnv().getAllProviders().length===0)return null;if(process.env.PORKBUN_API_KEY&&process.env.PORKBUN_SECRET_KEY)return{provider:"porkbun",apiKey:process.env.PORKBUN_API_KEY,secretKey:process.env.PORKBUN_SECRET_KEY};if(process.env.GODADDY_API_KEY&&process.env.GODADDY_API_SECRET)return{provider:"godaddy",apiKey:process.env.GODADDY_API_KEY,apiSecret:process.env.GODADDY_API_SECRET,environment:process.env.GODADDY_ENVIRONMENT||"production"};if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)return{provider:"route53",region:process.env.AWS_REGION||"us-east-1",hostedZoneId:process.env.AWS_HOSTED_ZONE_ID};if(process.env.CLOUDFLARE_API_TOKEN)return{provider:"cloudflare",apiToken:process.env.CLOUDFLARE_API_TOKEN};return null}function o1($){let J=H1($);if(!J)throw Error("No DNS provider configured. Set environment variables for Porkbun (PORKBUN_API_KEY, PORKBUN_SECRET_KEY), GoDaddy (GODADDY_API_KEY, GODADDY_API_SECRET), Cloudflare (CLOUDFLARE_API_TOKEN), or Route53 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)");return e0(J)}function Z6($){$.command("config","Show current configuration").action(async()=>{V("Configuration");try{let J=await c();console.log(JSON.stringify(J,null,2))}catch(J){R(`Failed to load configuration: ${J instanceof Error?J.message:"Unknown error"}`)}}),$.command("config:validate","Validate configuration file").action(async()=>{V("Validating Configuration");let J=new L("Validating cloud.config.ts...");J.start();try{let Y=await c();if(!Y.project?.name)throw Error("Missing project.name");if(!Y.project?.slug)throw Error("Missing project.slug");if(!Y.mode)throw Error("Missing deployment mode");J.succeed("Configuration is valid!"),F(`Project: ${Y.project.name}`),F(`Mode: ${Y.mode}`),F(`Region: ${Y.project.region||"us-east-1"}`)}catch(Y){J.fail("Configuration is invalid"),R(Y instanceof Error?Y.message:"Unknown error")}}),$.command("config:env","Manage environment variables").option("--list","List all environment variables").option("--set <key=value>","Set an environment variable").option("--unset <key>","Remove an environment variable").option("--environment <env>","Target environment (production, staging, development)").action(async(J)=>{V("Environment Variables");let Y=J?.environment||"production";if(J?.list)F(`Environment variables for ${Y}:`),d(["Key","Value","Last Modified"],[["NODE_ENV",Y,"2024-01-15"],["API_URL","https://api.example.com","2024-01-14"],["DEBUG","false","2024-01-10"]]);else if(J?.set){let[Q,...Z]=J.set.split("="),U=Z.join("=");if(!Q||!U){R("Invalid format. Use: --set KEY=VALUE");return}let W=new L(`Setting ${Q}=${U}...`);W.start(),await new Promise((z)=>setTimeout(z,1000)),W.succeed(`Environment variable ${Q} set for ${Y}`)}else if(J?.unset){if(!await v(`Remove ${J.unset} from ${Y} environment?`,!1)){F("Operation cancelled");return}let Z=new L(`Removing ${J.unset}...`);Z.start(),await new Promise((U)=>setTimeout(U,1000)),Z.succeed(`Environment variable ${J.unset} removed`)}else F("Use --list, --set KEY=VALUE, or --unset KEY")}),$.command("config:secrets","Manage secrets (AWS Secrets Manager)").option("--list","List all secrets").option("--create <name>","Create a new secret").option("--get <name>","Get secret value").option("--update <name>","Update secret value").option("--delete <name>","Delete a secret").option("--value <value>","Secret value (for create/update)").action(async(J)=>{if(V("Secrets Manager"),J?.list)F("Secrets in AWS Secrets Manager:"),d(["Name","Last Modified","Rotation Enabled"],[["db-password","2024-01-15","Yes"],["api-key","2024-01-14","No"],["jwt-secret","2024-01-10","Yes"]]);else if(J?.create){if(!J.value){let Q=await A0("Enter secret value","");J.value=Q}let Y=new L(`Creating secret ${J.create}...`);Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.succeed(`Secret ${J.create} created successfully`)}else if(J?.get){let Y=new L(`Fetching secret ${J.get}...`);Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.succeed("Secret retrieved"),F(`${J.get}: ******* (hidden for security)`),L1("Use --show-value to display the actual value")}else if(J?.update){if(!J.value){let Q=await A0("Enter new secret value","");J.value=Q}let Y=new L(`Updating secret ${J.update}...`);Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.succeed(`Secret ${J.update} updated successfully`)}else if(J?.delete){if(L1("This action is irreversible!"),!await v(`Delete secret ${J.delete}?`,!1)){F("Deletion cancelled");return}let Q=new L(`Deleting secret ${J.delete}...`);Q.start(),await new Promise((Z)=>setTimeout(Z,1000)),Q.succeed(`Secret ${J.delete} deleted`)}else F("Use --list, --create, --get, --update, or --delete")})}import{existsSync as cK}from"node:fs";import{mkdir as lK,writeFile as pK}from"node:fs/promises";import{join as rK}from"node:path";await Z2();class c2{builder;config;environment;mergedConfig;serverEipLogicalIds=new Map;constructor($){this.config=$.config,this.environment=$.environment,this.builder=new P9(`${this.config.project.name} - ${this.environment}`),this.mergedConfig=this.mergeEnvironmentConfig()}mergeEnvironmentConfig(){let J=this.config.environments[this.environment]?.infrastructure;if(!J)return this.config;return{...this.config,infrastructure:{...this.config.infrastructure,...J,compute:{...this.config.infrastructure?.compute,...J.compute},storage:{...this.config.infrastructure?.storage,...J.storage},functions:{...this.config.infrastructure?.functions,...J.functions},servers:{...this.config.infrastructure?.servers,...J.servers},databases:{...this.config.infrastructure?.databases,...J.databases},cdn:{...this.config.infrastructure?.cdn,...J.cdn},queues:{...this.config.infrastructure?.queues,...J.queues},redirects:{...this.config.infrastructure?.redirects,...J.redirects},realtime:{...this.config.infrastructure?.realtime,...J.realtime},cache:{...this.config.infrastructure?.cache,...J.cache},fileSystem:{...this.config.infrastructure?.fileSystem,...J.fileSystem},email:{...this.config.infrastructure?.email,...J.email},search:{...this.config.infrastructure?.search,...J.search},ai:{...this.config.infrastructure?.ai,...J.ai}}}}shouldDeploy($){if($.environments&&!$.environments.includes(this.environment))return!1;if($.requiresFeatures){let J=this.config.features||{};if(!$.requiresFeatures.every((Q)=>J[Q]===!0))return!1}if($.regions){let J=this.config.environments[this.environment]?.region||this.config.project.region;if(!$.regions.includes(J))return!1}if($.condition&&typeof $.condition==="function")return $.condition(this.config,this.environment);return!0}resolveApiOriginPort(){let $=this.mergedConfig.infrastructure?.api?.port??this.mergedConfig.ports?.api,J=Number($||3008);return Number.isFinite(J)&&J>0?J:3008}defaultComputeCachePathPatterns(){return["/api/*","/auth/*","/publisher/api/*","/publisher/*","/publish","/publish/*","/analytics/*","/packages/*","/npm/*","/zig/*","/php/*","/commits/*","/health","/dashboard/*","/search","/login","/logout","/signup","/account","/account/*"]}shouldRouteStorageBucketToCompute($,J){return $==="public"||J.routeCompute===!0}resolveComputeCachePathPatterns($){if($&&$.length>0)return $;return this.defaultComputeCachePathPatterns()}createComputeCacheBehavior($,J){return{PathPattern:$,TargetOriginId:J,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],CachedMethods:["GET","HEAD"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",OriginRequestPolicyId:"b689b0a8-53d0-40ab-baf2-68738e2966ac"}}appendComputeAppOrigin($,J,Y,Q,Z,U){let W=this.serverEipLogicalIds.get("app"),z=this.serverEipLogicalIds.get("appInstance");if(!W)return;let G=`EC2-${Q}-${Z}-api`,H=this.mergedConfig.infrastructure?.servers?.app?.region||this.mergedConfig.project?.region||"us-east-1",A=H==="us-east-1"?".compute-1.amazonaws.com":`.${H}.compute.amazonaws.com`,K={"Fn::Join":["",["ec2-",{"Fn::Join":["-",{"Fn::Split":[".",{Ref:W}]}]},A]]},B=this.resolveApiOriginPort();if($.push({Id:G,DomainName:K,CustomOriginConfig:{HTTPPort:B,HTTPSPort:443,OriginProtocolPolicy:"http-only",OriginSSLProtocols:["TLSv1.2"]}}),Y.push(W),z)Y.push(z);for(let j of U)J.push(this.createComputeCacheBehavior(j,G))}buildCaddyfile($){let J=$.filter(([,Z])=>typeof Z.domain==="string"&&Z.domain&&typeof Z.port==="number");if(J.length===0)return;let Y=new Map;for(let[,Z]of J){let U=Y.get(Z.domain)??[];U.push({port:Z.port,path:Z.path}),Y.set(Z.domain,U)}let Q=[];for(let[Z,U]of Y){let z=[...U].sort((G,H)=>{let A=!G.path||G.path==="/",K=!H.path||H.path==="/";if(A&&!K)return 1;if(!A&&K)return-1;return(H.path?.length??0)-(G.path?.length??0)}).map((G)=>{let H=!G.path||G.path==="/",A=`reverse_proxy localhost:${G.port}`;return H?` handle {
7317
7317
  ${A}
7318
7318
  }`:` handle ${G.path} {
7319
7319
  ${A}
@@ -7322,8 +7322,8 @@ ${z.join(`
7322
7322
  `)}
7323
7323
  }`)}return Q.join(`
7324
7324
 
7325
- `)}normalizeMountPath($){let J=$?.mountPath||$?.path;if(!J||J==="/")return;let Y=`/${J}`.replace(/\/+/g,"/").replace(/\/$/,"");return Y==="/"?void 0:Y}storageBucketLogicalId($,J,Y){return`${$}-${J}-s3-${Y}`.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((Q)=>Q.charAt(0).toUpperCase()+Q.slice(1)).join("")}pathMountRewriteFunctionCode($,J="directory"){return`function handler(event) { var request = event.request; var prefix = ${JSON.stringify($)}; var rewriteStyle = ${JSON.stringify(J)}; var uri = request.uri; if (uri === prefix) { uri = '/'; } else if (uri.indexOf(prefix + '/') === 0) { uri = uri.substring(prefix.length); } if (uri === '' || uri === '/') { request.uri = '/index.html'; return request; } if (uri.endsWith('/')) { request.uri = uri + 'index.html'; return request; } var lastSegment = uri.substring(uri.lastIndexOf('/') + 1); if (lastSegment.indexOf('.') === -1) { request.uri = rewriteStyle === 'flat' ? uri + '.html' : uri + '/index.html'; return request; } request.uri = uri; return request; }`}generate(){let $=this.mergedConfig.project.slug,J=this.environment,Y=!!(this.mergedConfig.infrastructure?.functions&&Object.keys(this.mergedConfig.infrastructure.functions).length>0||this.mergedConfig.infrastructure?.api),Q=!!(this.mergedConfig.infrastructure?.servers&&Object.keys(this.mergedConfig.infrastructure.servers).length>0),Z=!!this.mergedConfig.infrastructure?.compute;if(!!((this.mergedConfig.mode||"server")==="serverless"&&this.mergedConfig.infrastructure?.containers&&Object.keys(this.mergedConfig.infrastructure.containers).length>0))this.generateNetworkInfrastructure($,J),this.generateContainerInfrastructure($,J);if(Y)this.generateServerless($,J);if(Q)this.generateServer($,J);if(Z)this.generateComputeApp($,J);if(this.mergedConfig.infrastructure?.jumpBox)this.generateJumpBox($,J);if(this.generateSharedInfrastructure($,J),this.config.tags)this.applyGlobalTags(this.config.tags);return this}applyGlobalTags($){}generateNetworkInfrastructure($,J){if(this.builder.hasResource("VPC"))return;let Q=this.mergedConfig.infrastructure?.network?.cidr||"10.0.0.0/16",{vpc:Z,logicalId:U}=E0.createVpc({slug:$,environment:J,cidr:Q,enableDnsHostnames:!0,enableDnsSupport:!0});this.builder.addResource("VPC",Z);let W=`${$}${J}IGW`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(W,{Type:"AWS::EC2::InternetGateway",Properties:{Tags:[{Key:"Name",Value:`${$}-${J}-igw`},{Key:"Environment",Value:J}]}});let z=`${$}${J}IGWAttach`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(z,{Type:"AWS::EC2::VPCGatewayAttachment",Properties:{VpcId:{Ref:"VPC"},InternetGatewayId:{Ref:W}}});let G=`${$}${J}PublicRT`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(G,{Type:"AWS::EC2::RouteTable",Properties:{VpcId:{Ref:"VPC"},Tags:[{Key:"Name",Value:`${$}-${J}-public-rt`},{Key:"Environment",Value:J}]}}),this.builder.addResource(`${$}${J}PublicRoute`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::EC2::Route",Properties:{RouteTableId:{Ref:G},DestinationCidrBlock:"0.0.0.0/0",GatewayId:{Ref:W}},DependsOn:z});let H=this.mergedConfig.environments[J]?.region||this.mergedConfig.project.region||"us-east-1",A=["a","b"];for(let K=0;K<2;K++){let B=`PublicSubnet${K+1}`;this.builder.addResource(B,{Type:"AWS::EC2::Subnet",Properties:{VpcId:{Ref:"VPC"},CidrBlock:`10.0.${K}.0/24`,AvailabilityZone:`${H}${A[K]}`,MapPublicIpOnLaunch:!0,Tags:[{Key:"Name",Value:`${$}-${J}-public-${A[K]}`},{Key:"Environment",Value:J}]}}),this.builder.addResource(`${B}RTAssoc`,{Type:"AWS::EC2::SubnetRouteTableAssociation",Properties:{SubnetId:{Ref:B},RouteTableId:{Ref:G}}})}}generateContainerInfrastructure($,J){let Y=this.mergedConfig.infrastructure?.containers;if(!Y)return;let Q=this.mergedConfig.infrastructure?.loadBalancer,Z=this.mergedConfig.infrastructure?.ssl,U=this.mergedConfig.infrastructure?.dns,W;if(Z?.enabled&&Z.domains?.length)if(Z.certificateArn);else{let A=Z.domains[0],K=Z.domains.slice(1).map((X)=>{if(X.includes(".")&&X.endsWith(A))return X.replace(`.${A}`,"");return X}),{certificate:B,logicalId:j}=L0.createCertificate({domain:A,subdomains:K,slug:$,environment:J,validationMethod:"DNS",hostedZoneId:U?.hostedZoneId});W=j,this.builder.addResource(j,B)}let z="ECSCluster";this.builder.addResource(z,{Type:"AWS::ECS::Cluster",Properties:{ClusterName:`${$}-${J}`,ClusterSettings:[{Name:"containerInsights",Value:"enabled"}],Tags:[{Key:"Name",Value:`${$}-${J}`},{Key:"Environment",Value:J}]}});let G=`${$}${J}ALBSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(G,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ALB security group for ${$}-${J}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:80,ToPort:80,CidrIp:"0.0.0.0/0",Description:"HTTP"},{IpProtocol:"tcp",FromPort:443,ToPort:443,CidrIp:"0.0.0.0/0",Description:"HTTPS"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${$}-${J}-alb-sg`},{Key:"Environment",Value:J}]}});let H=`${$}${J}ECSSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");for(let[A,K]of Object.entries(Y)){let B=K.port||3000;this.builder.addResource(H,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ECS tasks security group for ${$}-${J}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:B,ToPort:B,SourceSecurityGroupId:{Ref:G},Description:"Allow traffic from ALB"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${$}-${J}-ecs-sg`},{Key:"Environment",Value:J}]}});let j=`${$}${J}TaskExecRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(j,{Type:"AWS::IAM::Role",Properties:{RoleName:`${$}-${J}-ecs-exec-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"],Policies:[{PolicyName:"ECRPullPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"}]}}]}});let X=`${$}${J}TaskRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(X,{Type:"AWS::IAM::Role",Properties:{RoleName:`${$}-${J}-ecs-task-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"TaskPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:ListBucket"],Resource:"*"}]}}]}});let O=`${$}${J}${A}LogGroup`.replace(/[^a-zA-Z0-9]/g,""),_=`/ecs/${$}-${J}-${A}`;this.builder.addResource(O,{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:_,RetentionInDays:30}});let w=`${$}${J}${A}TaskDef`.replace(/[^a-zA-Z0-9]/g,""),E=String(K.cpu||512),M=String(K.memory||1024);this.builder.addResource(w,{Type:"AWS::ECS::TaskDefinition",Properties:{Family:`${$}-${J}-${A}`,NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:E,Memory:M,ExecutionRoleArn:{"Fn::GetAtt":[j,"Arn"]},TaskRoleArn:{"Fn::GetAtt":[X,"Arn"]},ContainerDefinitions:[{Name:A,Image:{"Fn::Sub":`\${AWS::AccountId}.dkr.ecr.\${AWS::Region}.amazonaws.com/${$}:latest`},Essential:!0,PortMappings:[{ContainerPort:B,Protocol:"tcp"}],LogConfiguration:{LogDriver:"awslogs",Options:{"awslogs-group":_,"awslogs-region":{Ref:"AWS::Region"},"awslogs-stream-prefix":A}},HealthCheck:{Command:["CMD-SHELL",`curl -f http://localhost:${B}${K.healthCheck||"/health"} || exit 1`],Interval:30,Timeout:5,Retries:3,StartPeriod:60}}],Tags:[{Key:"Name",Value:`${$}-${J}-${A}`},{Key:"Environment",Value:J}]},DependsOn:[j,X,O]});let T=`${$}${J}ALB`.replace(/[^a-zA-Z0-9]/g,"");if(Q?.enabled!==!1){this.builder.addResource(T,{Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:`${$}-${J}-alb`,Scheme:"internet-facing",Type:"application",Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],SecurityGroups:[{Ref:G}],Tags:[{Key:"Name",Value:`${$}-${J}-alb`},{Key:"Environment",Value:J}]}});let D=`${$}${J}TargetGroup`.replace(/[^a-zA-Z0-9]/g,""),N=Q?.healthCheck?.path||K.healthCheck||"/health";this.builder.addResource(D,{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:`${$}-${J}-tg`,Port:B,Protocol:"HTTP",VpcId:{Ref:"VPC"},TargetType:"ip",HealthCheckPath:N,HealthCheckIntervalSeconds:Q?.healthCheck?.interval||30,HealthyThresholdCount:Q?.healthCheck?.healthyThreshold||2,UnhealthyThresholdCount:Q?.healthCheck?.unhealthyThreshold||5,HealthCheckTimeoutSeconds:10,Tags:[{Key:"Name",Value:`${$}-${J}-tg`},{Key:"Environment",Value:J}]}});let x=`${$}${J}HTTPListener`.replace(/[^a-zA-Z0-9]/g,"");if(Z?.enabled&&Z?.redirectHttp)this.builder.addResource(x,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:T},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"redirect",RedirectConfig:{Protocol:"HTTPS",Port:"443",StatusCode:"HTTP_301"}}]}});else this.builder.addResource(x,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:T},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:D}}]}});if(Z?.enabled){let I=Z.certificateArn||(W?{Ref:W}:void 0);if(I){let f=`${$}${J}HTTPSListener`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(f,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:T},Port:443,Protocol:"HTTPS",Certificates:[{CertificateArn:I}],DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:D}}],SslPolicy:"ELBSecurityPolicy-TLS13-1-2-2021-06"}})}}let h=`${$}${J}${A}Service`.replace(/[^a-zA-Z0-9]/g,""),k=K.desiredCount||1;this.builder.addResource(h,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${$}-${J}-${A}`,Cluster:{Ref:z},TaskDefinition:{Ref:w},DesiredCount:k,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:H}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},LoadBalancers:[{ContainerName:A,ContainerPort:B,TargetGroupArn:{Ref:D}}],HealthCheckGracePeriodSeconds:120,Tags:[{Key:"Name",Value:`${$}-${J}-${A}`},{Key:"Environment",Value:J}]},DependsOn:[w,x,D]});let b=K.autoScaling;if(b){let I=`${$}${J}${A}ScalableTarget`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(I,{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{MaxCapacity:b.max||10,MinCapacity:b.min||1,ResourceId:{"Fn::Sub":`service/\${${z}}/${$}-${J}-${A}`},ScalableDimension:"ecs:service:DesiredCount",ServiceNamespace:"ecs",RoleARN:{"Fn::Sub":"arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"}},DependsOn:h}),b.targetCpuUtilization)this.builder.addResource(`${$}${J}${A}CPUScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${$}-${J}-${A}-cpu-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:I},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageCPUUtilization"},TargetValue:b.targetCpuUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}});if(b.targetMemoryUtilization)this.builder.addResource(`${$}${J}${A}MemoryScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${$}-${J}-${A}-memory-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:I},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageMemoryUtilization"},TargetValue:b.targetMemoryUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}})}if(U?.domain&&U?.hostedZoneId)this.builder.addResource(`${$}${J}ApiDnsRecord`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:U.hostedZoneId,Name:`api.${U.domain}`,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[T,"DNSName"]},HostedZoneId:{"Fn::GetAtt":[T,"CanonicalHostedZoneID"]}}}});this.builder.addOutput("ECSClusterArn",{Description:"ECS Cluster ARN",Value:{"Fn::GetAtt":[z,"Arn"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-cluster-arn"}}}),this.builder.addOutput("ECSServiceName",{Description:"ECS Service Name",Value:`${$}-${J}-${A}`,Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-service-name"}}}),this.builder.addOutput("LoadBalancerDNS",{Description:"Application Load Balancer DNS Name",Value:{"Fn::GetAtt":[T,"DNSName"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-alb-dns"}}})}else{let D=`${$}${J}${A}Service`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(D,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${$}-${J}-${A}`,Cluster:{Ref:z},TaskDefinition:{Ref:w},DesiredCount:K.desiredCount||1,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:H}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},Tags:[{Key:"Name",Value:`${$}-${J}-${A}`},{Key:"Environment",Value:J}]},DependsOn:[w]})}break}}generateServerless($,J){if(this.mergedConfig.infrastructure?.functions)for(let[Y,Q]of Object.entries(this.mergedConfig.infrastructure.functions)){if(!this.shouldDeploy(Q))continue;let{role:Z,logicalId:U}=Y1.createRole({slug:$,environment:J,roleName:`${$}-${J}-${Y}-role`,servicePrincipal:"lambda.amazonaws.com",managedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]});this.builder.addResource(U,Z);let{lambdaFunction:W,logicalId:z}=n.createLambdaFunction({slug:$,environment:J,functionName:`${$}-${J}-${Y}`,handler:Q.handler||"index.handler",runtime:Q.runtime||"nodejs20.x",code:{zipFile:Q.code||"export const handler = async () => ({ statusCode: 200 });"},role:U,timeout:Q.timeout,memorySize:Q.memorySize});this.builder.addResource(z,W)}if(this.mergedConfig.infrastructure?.api){let{restApi:Y,logicalId:Q}=x9.createRestApi({slug:$,environment:J,apiName:`${$}-${J}-api`});this.builder.addResource(Q,Y)}}generateServer($,J){if(!this.mergedConfig.infrastructure?.servers)return;let Y=this.mergedConfig.infrastructure.servers,Q=this.mergedConfig.infrastructure?.compute,Z=this.mergedConfig.infrastructure?.ssl;if(Object.values(Y).some((W)=>!W.privateNetwork||W.privateNetwork==="create"))this.generateNetworkInfrastructure($,J);for(let[W,z]of Object.entries(Y)){let G=z.instanceType||z.size||Q?.size,A=(G?n.InstanceSize.specs[G]:void 0)?.instanceType||G||"t3.micro",K=z.type||"app",B=z.userData||z.startupScript;if(!B)B=n.UserData.generateAppServerScript({runtime:"bun",runtimeVersion:z.bunVersion||"latest",webServer:"none",domain:z.domain,enableSsl:!!Z?.enabled,sslEmail:Z?.letsEncrypt?.email,installRedis:K==="cache",installDatabaseClients:!!z.database});let j=z.privateNetwork&&z.privateNetwork!=="create"?z.privateNetwork:{Ref:"VPC"},X=z.subnet||{Ref:"PublicSubnet1"},_=!!this.mergedConfig.infrastructure?.email?.server?.enabled,w=[22,80,443,this.resolveApiOriginPort()];if(_)w.push(25,465,587,143,993);let E=n.createServerModeStack({slug:`${$}-${W}`,environment:J,vpcId:j,subnetId:X,instanceType:A,keyName:z.keyName||`${$}-${J}`,domain:z.domain,userData:B,volumeSize:z.diskSize||20,imageId:z.image,allowedPorts:w});for(let[M,T]of Object.entries(E.resources))this.builder.addResource(M,T);this.serverEipLogicalIds.set(W,E.outputs.eipLogicalId),this.serverEipLogicalIds.set(`${W}Instance`,E.outputs.instanceLogicalId),this.builder.addOutput(`${W}InstanceId`,{Value:{Ref:E.outputs.instanceLogicalId},Description:`Instance ID for ${W} server`}),this.builder.addOutput(`${W}PublicIp`,{Value:{Ref:E.outputs.eipLogicalId},Description:`Public IP for ${W} server`})}}generateComputeApp($,J){let Y=this.mergedConfig.infrastructure?.compute;if(!Y)return;let Q=this.mergedConfig.sites||{},Z=Object.entries(Q),W=this.mergedConfig.infrastructure?.dns?.domain,z=this.mergedConfig.infrastructure?.database,G=Y.size,A=(G?n.InstanceSize.specs[G]:void 0)?.instanceType||"t3.micro";if(!this.builder.hasResource("VPC"))this.generateNetworkInfrastructure($,J);let K=this.buildCaddyfile(Z),B=n.UserData.generateBunAppScript({runtime:Y.runtime||"bun",runtimeVersion:Y.runtimeVersion||"latest",systemPackages:Y.systemPackages,database:z,caddyfile:K}),j=Z.map(([,T])=>T.port).filter((T)=>typeof T==="number"&&![80,443].includes(T)),X=this.resolveApiOriginPort(),O=`${$}${J}DeployBucket`.replace(/[^a-zA-Z0-9]/g,""),_=`${$}-${J}-deploy`;this.builder.addResource(O,{Type:"AWS::S3::Bucket",Properties:{BucketName:_,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"expire-old-releases",Status:"Enabled",ExpirationInDays:7,Prefix:"releases/"}]},Tags:[{Key:"Project",Value:$},{Key:"Environment",Value:J},{Key:"ManagedBy",Value:"ts-cloud"}]}});let w=n.createServerModeStack({slug:`${$}-app`,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},instanceType:A,keyName:`${$}-${J}`,domain:W,userData:B,volumeSize:Y.disk?.size||20,imageId:Y.image,allowedPorts:[...Y.allowSsh?[22]:[],80,443,X,...j]}),E=w.resources[w.outputs.instanceLogicalId];if(E?.Properties){let T=E.Properties.Tags||[];E.Properties.Tags=[...T,{Key:"Project",Value:$},{Key:"Environment",Value:J},{Key:"Role",Value:"app"},{Key:"ManagedBy",Value:"ts-cloud"}]}let M=w.resources[w.outputs.roleLogicalId];if(M?.Properties)M.Properties.Policies=M.Properties.Policies||[],M.Properties.Policies.push({PolicyName:"DeployBucketRead",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:GetObject","s3:ListBucket"],Resource:[`arn:aws:s3:::${_}`,`arn:aws:s3:::${_}/*`]}]}});for(let[T,D]of Object.entries(w.resources))this.builder.addResource(T,D);this.builder.addOutput("deployBucketName",{Value:{Ref:O},Description:"S3 bucket where release tarballs are uploaded"}),this.builder.addOutput("appInstanceId",{Value:{Ref:w.outputs.instanceLogicalId},Description:"EC2 instance ID for the app server"}),this.builder.addOutput("appPublicIp",{Value:{Ref:w.outputs.eipLogicalId},Description:"Public IP for the app server"}),this.serverEipLogicalIds.set("app",w.outputs.eipLogicalId),this.serverEipLogicalIds.set("appInstance",w.outputs.instanceLogicalId)}generateJumpBox($,J){let Y=this.mergedConfig.infrastructure?.jumpBox;if(!Y)return;let Q=Y===!0?{}:Y;if(Q.enabled===!1)return;this.generateNetworkInfrastructure($,J);let Z=Q.size||"micro",W=n.InstanceSize.specs[Z]?.instanceType||Z||"t3.micro",z;if(Q.mountEfs)z={fileSystemId:typeof Q.mountEfs==="string"?Q.mountEfs:{Ref:"FileSystem"},mountPath:Q.mountPath||"/mnt/efs"};let G;if(Q.databaseTools)G=n.JumpBox.withDatabaseTools({slug:$,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:Q.keyName||`${$}-${J}`,allowedCidrs:Q.allowedCidrs});else if(z)G=n.JumpBox.withEfsMount({slug:$,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:Q.keyName||`${$}-${J}`,fileSystemId:z.fileSystemId,mountPath:z.mountPath,allowedCidrs:Q.allowedCidrs});else G=n.createJumpBox({slug:$,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:Q.keyName||`${$}-${J}`,instanceType:W,allowedCidrs:Q.allowedCidrs,mountEfs:z});for(let[H,A]of Object.entries(G.resources))this.builder.addResource(H,A);this.builder.addOutput("JumpBoxInstanceId",{Value:{Ref:G.instanceLogicalId},Description:"The ID of the JumpBox EC2 instance (use with SSM Session Manager or SSH)"})}generateSharedInfrastructure($,J){let Y=this.mergedConfig.infrastructure?.ssl,Q=this.mergedConfig.infrastructure?.dns,Z=Q?.domain,U=Q?.hostedZoneId,W=[],z,G;if(Y?.certificateArn)G=Y.certificateArn;else if(Y?.enabled&&Z&&U){let O=Y.domains||[Z],_=O[0],w=O.slice(1).map((T)=>{if(T.includes(".")&&T.endsWith(_))return T.replace(`.${_}`,"");return T}),{certificate:E,logicalId:M}=L0.createCertificate({domain:_,subdomains:w,slug:$,environment:J,validationMethod:"DNS",hostedZoneId:U});z=M,this.builder.addResource(M,E)}if(this.mergedConfig.infrastructure?.storage){let O=Object.entries(this.mergedConfig.infrastructure.storage).some(([,E])=>E.website),_;if(O&&(z||G))_=`${$}${J}CloudFrontOAC`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(_,{Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${$}-${J}-s3-oac`,Description:`OAC for ${$} ${J} S3 website buckets`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}});let w=Object.entries(this.mergedConfig.infrastructure.storage).map(([E,M])=>({name:E,config:M,mountPath:this.normalizeMountPath(M),rewriteStyle:M.pathRewriteStyle||"directory",logicalId:this.storageBucketLogicalId($,J,E)})).filter((E)=>E.name!=="public"&&E.config.website&&E.mountPath);for(let[E,M]of Object.entries(this.mergedConfig.infrastructure.storage)){let T=!!(M.website&&_),D=M.bucket??`${$}-${J}-${E}`,{bucket:N,logicalId:x}=X1.createBucket({slug:$,name:E,environment:J,bucketName:D,versioning:M.versioning,encryption:M.encryption,public:T?!1:M.public});if(T&&N.Properties)N.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1};if(this.builder.addResource(x,N),M.website){let k=typeof M.website==="object"?M.website:{},b=X1.enableWebsiteHosting(N,k.indexDocument||"index.html",k.errorDocument);this.builder.addResource(x,b)}let h=this.normalizeMountPath(M);if(T&&_&&Z&&!(h&&E!=="public")){let k=`${$}${J}${E}CDN`.replace(/[^a-zA-Z0-9]/g,""),b=[];if(M.aliases&&M.aliases.length>0)b.push(...M.aliases);else if(E==="public"){if(b.push(Z),Y?.domains?.includes(`www.${Z}`))b.push(`www.${Z}`)}else if(E==="docs")b.push(`docs.${Z}`);else if(E==="blog")b.push(`blog.${Z}`);let I=typeof M.website==="object"?M.website:{},f=M.spa===!0,m=I.errorDocument||(f?"index.html":"404.html"),l=[];if(f)l.push({ErrorCode:403,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300});else l.push({ErrorCode:403,ResponseCode:404,ResponsePagePath:`/${m}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${m}`,ErrorCachingMinTTL:300});let p=G&&b.length>0?{AcmCertificateArn:G,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:z&&b.length>0?{AcmCertificateArn:{Ref:z},SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},r=`S3-${$}-${J}-${E}`,s=this.mergedConfig.project.region||"us-east-1",o;if(!f)o=`${$}${J}${E}UrlRewrite`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(o,{Type:"AWS::CloudFront::Function",Properties:{Name:`${$}-${J}-${E}-url-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`URL rewrite for ${$} ${J} ${E} - appends .html to extensionless paths`,Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) { var request = event.request; var uri = request.uri; if (uri.endsWith('/')) { request.uri += 'index.html'; }
7326
- else if (!uri.includes('.')) { request.uri += '.html'; } return request; }`}});let B0=[{Id:r,DomainName:{"Fn::Sub":`\${${x}}.s3.${s}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:_}}],c0=[],x0=[];if(this.shouldRouteStorageBucketToCompute(E,M)){this.appendComputeAppOrigin(B0,c0,x0,$,J,this.resolveComputeCachePathPatterns(M.computeRoutes));for(let N0 of w){let k1=`S3-${$}-${J}-${N0.name}`,p2=`${$}${J}${N0.name}PathMountRewrite`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(p2,{Type:"AWS::CloudFront::Function",Properties:{Name:`${$}-${J}-${N0.name}-path-mount-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`Path mount rewrite for ${$} ${J} ${N0.name} at ${N0.mountPath}`,Runtime:"cloudfront-js-2.0"},FunctionCode:this.pathMountRewriteFunctionCode(N0.mountPath,N0.rewriteStyle)}}),B0.push({Id:k1,DomainName:{"Fn::Sub":`\${${N0.logicalId}}.s3.${s}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:_}}),x0.push(N0.logicalId,p2);for(let a9 of[N0.mountPath,`${N0.mountPath}/*`])c0.push({PathPattern:a9,TargetOriginId:k1,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[p2,"FunctionARN"]}}]})}}let z2={Type:"AWS::CloudFront::Distribution",DependsOn:[x,_,...o?[o]:[],...x0],Properties:{DistributionConfig:{Enabled:!0,Comment:`${$} ${J} ${E} site`,DefaultRootObject:"index.html",Origins:B0,DefaultCacheBehavior:{TargetOriginId:r,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",...o?{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[o,"FunctionARN"]}}]}:{}},...c0.length>0?{CacheBehaviors:c0}:{},...b.length>0?{Aliases:b}:{},ViewerCertificate:p,PriceClass:"PriceClass_100",HttpVersion:"http2and3",IPV6Enabled:!0,CustomErrorResponses:l}}};if(z)z2.DependsOn.push(z);this.builder.addResource(k,z2);let G2=`${x}CloudFrontPolicy`;if(this.builder.addResource(G2,{Type:"AWS::S3::BucketPolicy",DependsOn:[x,k],Properties:{Bucket:{Ref:x},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${x}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${k}}`}}}}]}}}),this.shouldRouteStorageBucketToCompute(E,M))for(let N0 of w){let k1=`${N0.logicalId}CloudFrontPolicy`;this.builder.addResource(k1,{Type:"AWS::S3::BucketPolicy",DependsOn:[N0.logicalId,k],Properties:{Bucket:{Ref:N0.logicalId},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${N0.logicalId}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${k}}`}}}}]}}})}if(b.length>0)W.push({name:E,bucketLogicalId:x,distLogicalId:k,oacLogicalId:_,aliases:b});this.builder.addOutput(`${E}CloudFrontDomain`,{Value:{"Fn::GetAtt":[k,"DomainName"]},Description:`CloudFront domain for ${E}`}),this.builder.addOutput(`${E}CloudFrontDistributionId`,{Value:{Ref:k},Description:`CloudFront distribution ID for ${E}`})}if(this.builder.addOutput(`${E}BucketName`,{Value:{Ref:x},Description:`S3 bucket name for ${E}`}),E==="public")this.builder.addOutput("FrontendBucketName",{Value:{Ref:x},Description:"Frontend S3 bucket name"});if(E==="docs")this.builder.addOutput("DocsBucketName",{Value:{Ref:x},Description:"Documentation S3 bucket name"});if(E==="blog")this.builder.addOutput("BlogBucketName",{Value:{Ref:x},Description:"Blog S3 bucket name"})}}if(U&&W.length>0)for(let{name:O,distLogicalId:_,aliases:w}of W)for(let E of w){let M=E.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${M}ARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[_],Properties:{HostedZoneId:U,Name:E,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[_,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}}),this.builder.addResource(`${M}AAAARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[_],Properties:{HostedZoneId:U,Name:E,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":[_,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}})}if(this.mergedConfig.infrastructure?.databases){for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.databases))if(_.engine==="dynamodb"){let{table:w,logicalId:E}=Q2.createTable({slug:$,environment:J,tableName:`${$}-${J}-${O}`,partitionKey:_.partitionKey||{name:"id",type:"S"},sortKey:_.sortKey});this.builder.addResource(E,w)}else if(_.engine==="postgres"){let{dbInstance:w,logicalId:E}=Q2.createPostgres({slug:$,environment:J,dbInstanceIdentifier:`${$}-${J}-${O}`,masterUsername:_.username||"admin",masterUserPassword:_.password||"changeme123",allocatedStorage:_.storage||20,dbInstanceClass:_.instanceClass||"db.t3.micro"});this.builder.addResource(E,w)}else if(_.engine==="mysql"){let{dbInstance:w,logicalId:E}=Q2.createMysql({slug:$,environment:J,dbInstanceIdentifier:`${$}-${J}-${O}`,masterUsername:_.username||"admin",masterUserPassword:_.password||"changeme123",allocatedStorage:_.storage||20,dbInstanceClass:_.instanceClass||"db.t3.micro"});this.builder.addResource(E,w)}}if(this.mergedConfig.infrastructure?.cdn)for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.cdn)){if(!_.origin)continue;let w=typeof _.customDomain==="string"?_.customDomain:_.customDomain?.domain||_.domain,E=typeof _.customDomain==="object"?_.customDomain?.certificateArn:_.certificateArn,M=E||G,T=`${$}${J}${O}CDN`.replace(/[^a-zA-Z0-9]/g,""),D=`S3-${$}-${J}-${O}-cdn`,N=[{Id:D,DomainName:_.origin,OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""}}],x=[],h=[];if(_.routeCompute)this.appendComputeAppOrigin(N,x,h,$,J,this.resolveComputeCachePathPatterns(_.computeRoutes));let k=M&&w?{AcmCertificateArn:z&&!E?{Ref:z}:M,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},b=[...h];if(z&&!E&&w)b.push(z);let I={Type:"AWS::CloudFront::Distribution",...b.length>0?{DependsOn:b}:{},Properties:{DistributionConfig:{Enabled:!0,Comment:`${$} ${J} ${O} CDN`,DefaultRootObject:"index.html",Origins:N,DefaultCacheBehavior:{TargetOriginId:D,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:_.compress!==!1,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"},...x.length>0?{CacheBehaviors:x}:{},...w&&M?{Aliases:[w]}:{},ViewerCertificate:k,PriceClass:"PriceClass_100",HttpVersion:_.http3?"http2and3":"http2"}}};if(this.builder.addResource(T,I),U&&w&&M){let f=w.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${f}CdnARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[T,...z&&!E?[z]:[]],Properties:{HostedZoneId:U,Name:w,Type:"A",AliasTarget:{HostedZoneId:"Z2FDTNDATAQYW2",DNSName:{"Fn::GetAtt":[T,"DomainName"]}}}})}}if(this.mergedConfig.infrastructure?.queues)for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.queues)){if(!this.shouldDeploy(_))continue;let{queue:w,logicalId:E}=t0.createQueue({slug:$,environment:J,name:`${$}-${J}-${O}`,fifo:_.fifo,visibilityTimeout:_.visibilityTimeout,messageRetentionPeriod:_.messageRetentionPeriod,delaySeconds:_.delaySeconds,maxMessageSize:_.maxMessageSize,receiveMessageWaitTime:_.receiveMessageWaitTime,contentBasedDeduplication:_.contentBasedDeduplication,encrypted:_.encrypted,kmsKeyId:_.kmsKeyId});this.builder.addResource(E,w);let M;if(_.deadLetterQueue){let{deadLetterQueue:T,updatedSourceQueue:D,deadLetterLogicalId:N}=t0.createDeadLetterQueue(E,{slug:$,environment:J,maxReceiveCount:_.maxReceiveCount});M=N,this.builder.addResource(N,T);let h=this.builder.getResources()[E];if(h?.Properties)h.Properties.RedrivePolicy=D.Properties?.RedrivePolicy}if(_.trigger){let T=_.trigger,D=`${$}${J}${T.functionName}`.replace(/[^a-zA-Z0-9]/g,""),N={Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:{"Fn::GetAtt":[E,"Arn"]},FunctionName:{Ref:D},BatchSize:T.batchSize||10,MaximumBatchingWindowInSeconds:T.batchWindow||0,Enabled:!0,...T.reportBatchItemFailures!==!1&&{FunctionResponseTypes:["ReportBatchItemFailures"]},...T.maxConcurrency&&{ScalingConfig:{MaximumConcurrency:T.maxConcurrency}},...T.filterPattern&&{FilterCriteria:{Filters:[{Pattern:JSON.stringify(T.filterPattern)}]}}},DependsOn:[E,D]};this.builder.addResource(`${E}Trigger`,N)}if(_.alarms?.enabled){let T=_.alarms,D=T.notificationTopicArn;if(!D&&T.notificationEmails?.length){let h=`${E}AlarmTopic`;this.builder.addResource(h,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${$}-${J}-${O}-alarms`,DisplayName:`${O} Queue Alarms`}}),T.notificationEmails.forEach((k,b)=>{this.builder.addResource(`${h}Sub${b}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:h},Protocol:"email",Endpoint:k}})}),D={Ref:h}}let N=T.queueDepthThreshold||1000;this.builder.addResource(`${E}DepthAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-${O}-queue-depth`,AlarmDescription:`Queue ${O} depth exceeds ${N} messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:N,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[E,"QueueName"]}}],...D&&{AlarmActions:[D],OKActions:[D]}}});let x=T.messageAgeThreshold||3600;if(this.builder.addResource(`${E}AgeAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-${O}-message-age`,AlarmDescription:`Queue ${O} oldest message exceeds ${x} seconds`,MetricName:"ApproximateAgeOfOldestMessage",Namespace:"AWS/SQS",Statistic:"Maximum",Period:300,EvaluationPeriods:2,Threshold:x,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[E,"QueueName"]}}],...D&&{AlarmActions:[D],OKActions:[D]}}}),M&&T.dlqAlarm!==!1)this.builder.addResource(`${M}Alarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-${O}-dlq-messages`,AlarmDescription:`Dead letter queue for ${O} has messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Sum",Period:300,EvaluationPeriods:1,Threshold:0,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[M,"QueueName"]}}],...D&&{AlarmActions:[D]}}})}if(_.subscribe){let T=_.subscribe,D=T.topicArn;if(!D&&T.topicName)D={Ref:T.topicName};if(D){this.builder.addResource(`${E}SnsPolicy`,{Type:"AWS::SQS::QueuePolicy",Properties:{Queues:[{Ref:E}],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"sns.amazonaws.com"},Action:"sqs:SendMessage",Resource:{"Fn::GetAtt":[E,"Arn"]},Condition:{ArnEquals:{"aws:SourceArn":D}}}]}}});let N={TopicArn:D,Protocol:"sqs",Endpoint:{"Fn::GetAtt":[E,"Arn"]},RawMessageDelivery:T.rawMessageDelivery||!1};if(T.filterPolicy)N.FilterPolicy=T.filterPolicy,N.FilterPolicyScope=T.filterPolicyScope||"MessageAttributes";this.builder.addResource(`${E}SnsSub`,{Type:"AWS::SNS::Subscription",Properties:N,DependsOn:`${E}SnsPolicy`})}}}if(this.mergedConfig.infrastructure?.realtime?.enabled)if((this.mergedConfig.infrastructure.realtime.mode||"serverless")==="server")this.generateRealtimeServerResources($,J);else this.generateRealtimeResources($,J);let H=this.mergedConfig.infrastructure?.redirects;if(H){let O=H.target||this.mergedConfig.infrastructure?.dns?.domain||"",_=H.protocol||"https";if(H.domains?.length&&O)for(let w of H.domains){let{bucket:E,bucketPolicy:M,logicalId:T,policyLogicalId:D}=c1.createDomainRedirectBucket({slug:$,environment:J,sourceDomain:w,targetDomain:O,protocol:_});this.builder.addResource(T,E),this.builder.addResource(D,M)}if(H.paths&&Object.keys(H.paths).length>0){let w=c1.fromMapping(H.paths,{statusCode:H.statusCode||301}),{function:E,logicalId:M}=c1.createPathRedirectFunction({slug:$,environment:J,rules:w});this.builder.addResource(M,E)}}if(this.mergedConfig.infrastructure?.monitoring?.alarms)for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.monitoring.alarms)){let{alarm:w,logicalId:E}=_$.createAlarm({slug:$,environment:J,alarmName:`${$}-${J}-${O}`,metricName:_.metricName||"Errors",namespace:_.namespace||"AWS/Lambda",threshold:_.threshold||1,comparisonOperator:_.comparisonOperator||"GreaterThanThreshold"});this.builder.addResource(E,w)}let A=this.mergedConfig.infrastructure?.cache;if(A){let O=A.type||"redis";if(O==="redis"){this.generateNetworkInfrastructure($,J);let _=A.redis||{},{replicationGroup:w,subnetGroup:E,logicalId:M,subnetGroupId:T}=O$.createRedis({slug:$,environment:J,nodeType:_.nodeType||A.nodeType||"cache.t3.micro",engineVersion:_.engineVersion||"7.1",port:_.port||6379,numCacheClusters:_.numCacheNodes||2,automaticFailover:_.automaticFailoverEnabled!==!1,atRestEncryption:!0,transitEncryption:!0,snapshotRetentionDays:_.snapshotRetentionLimit||7,snapshotWindow:_.snapshotWindow,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(M,w),E&&T)this.builder.addResource(T,E);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[M,"PrimaryEndPoint.Address"]},Description:"Redis primary endpoint address"}),this.builder.addOutput("CachePort",{Value:{"Fn::GetAtt":[M,"PrimaryEndPoint.Port"]},Description:"Redis primary endpoint port"})}else if(O==="memcached"){this.generateNetworkInfrastructure($,J);let _=A.elasticache||{},{cluster:w,subnetGroup:E,logicalId:M,subnetGroupId:T}=O$.createMemcached({slug:$,environment:J,nodeType:_.nodeType||A.nodeType||"cache.t3.micro",engineVersion:_.engineVersion||"1.6.22",numCacheNodes:_.numCacheNodes||2,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(M,w),E&&T)this.builder.addResource(T,E);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[M,"ConfigurationEndpoint.Address"]},Description:"Memcached configuration endpoint address"})}}let K=this.mergedConfig.infrastructure?.email;if(K){let O=K.domain||this.mergedConfig.infrastructure?.dns?.domain;if(O){let{emailIdentity:_,logicalId:w}=H0.verifyDomain({domain:O,slug:$,environment:J,enableDkim:K.enableDkim!==!1,dkimKeyLength:K.dkimKeyLength||"RSA_2048_BIT"});if(this.builder.addResource(w,_),K.configurationSet!==!1){let{configurationSet:T,logicalId:D}=H0.createConfigurationSet({slug:$,environment:J});this.builder.addResource(D,T)}let E=K.hostedZoneId||this.mergedConfig.infrastructure?.dns?.hostedZoneId;if(E){if(K.enableDkim!==!1)for(let h=1;h<=3;h++){let k=`DkimRecord${h}${O.replace(/\./g,"")}`;this.builder.addResource(k,{Type:"AWS::Route53::RecordSet",DependsOn:[w],Properties:{HostedZoneId:E,Name:{"Fn::GetAtt":[w,`DkimDNSTokenName${h}`]},Type:"CNAME",TTL:1800,ResourceRecords:[{"Fn::GetAtt":[w,`DkimDNSTokenValue${h}`]}]}})}let{record:T,logicalId:D}=H0.createSpfRecord(O,E);this.builder.addResource(D,T);let{record:N,logicalId:x}=H0.createDmarcRecord(O,E,{policy:"none",reportingEmail:K.dmarcReportingEmail||`dmarc-reports@${O}`});this.builder.addResource(x,N)}this.builder.addOutput("EmailDomain",{Value:O,Description:"SES verified email domain"});let M=K.server;if(M?.enabled&&E){let T=this.mergedConfig.environments[J]?.region||this.mergedConfig.project.region||"us-east-1",D=`${$}-${J}-email`,{role:N,policy:x,roleLogicalId:h,policyLogicalId:k}=H0.createEmailLambdaRole({slug:$,environment:J,s3BucketArn:`arn:aws:s3:::${D}`,sesIdentityArn:`arn:aws:ses:${T}:*:identity/${O}`});this.builder.addResource(h,N),this.builder.addResource(k,x);let{function:b,permission:I,logicalId:f,permissionLogicalId:m}=H0.createInboundEmailLambda({slug:$,environment:J,roleArn:{"Fn::GetAtt":[h,"Arn"]},s3BucketName:D,organizedPrefix:"mailboxes/"});this.builder.addResource(f,b),this.builder.addResource(m,I);let l=H0.createInboundEmailSetup({slug:$,environment:J,domain:O,s3BucketName:D,s3KeyPrefix:"inbox/",region:T,hostedZoneId:E,lambdaFunctionArn:{"Fn::GetAtt":[f,"Arn"]}});for(let[r,s]of Object.entries(l.resources)){if(s.Type==="AWS::SES::ReceiptRule")s.DependsOn=[m,f];this.builder.addResource(r,s)}this.builder.addOutput("InboundEmailLambda",{Value:{Ref:f},Description:"Inbound email processing Lambda function"}),this.builder.addOutput("EmailBucket",{Value:D,Description:"S3 bucket for email storage"});let p=this.serverEipLogicalIds.get("app");if(p&&E){let s=`${M?.subdomain||"mail"}.${O}`,o=s.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${o}ARecord`,{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:E,Name:s,Type:"A",TTL:"300",ResourceRecords:[{Ref:p}]}})}this.builder.addOutput("MailHost",{Value:`mail.${O}`,Description:"Mail server hostname for SMTP/IMAP clients"})}}}let B=this.mergedConfig.infrastructure?.search;if(B){let O=B.vpc?{subnetIds:[{Ref:"PublicSubnet1"}],securityGroupIds:[]}:void 0;if(O)this.generateNetworkInfrastructure($,J);let{domain:_,logicalId:w}=Y2.createDomain({slug:$,environment:J,engineVersion:B.engineVersion||"OpenSearch_2.11",instanceType:B.instanceType||"t3.small.search",instanceCount:B.instanceCount||1,volumeSize:B.volumeSize||10,volumeType:B.volumeType||"gp3",dedicatedMaster:B.dedicatedMaster||!1,dedicatedMasterType:B.dedicatedMasterType,dedicatedMasterCount:B.dedicatedMasterCount||3,multiAz:B.multiAz||!1,encryption:B.encryption||{atRest:!0,nodeToNode:!0},advancedSecurity:B.advancedSecurity,autoTune:B.autoTune!==!1,vpc:O});this.builder.addResource(w,_),this.builder.addOutput("SearchDomainEndpoint",{Value:{"Fn::GetAtt":[w,"DomainEndpoint"]},Description:"OpenSearch domain endpoint"}),this.builder.addOutput("SearchDomainArn",{Value:{"Fn::GetAtt":[w,"Arn"]},Description:"OpenSearch domain ARN"})}let j=this.mergedConfig.infrastructure?.fileSystem;if(j&&Object.keys(j).length>0){this.generateNetworkInfrastructure($,J);for(let[O,_]of Object.entries(j)){let{fileSystem:w,logicalId:E}=D1.createFileSystem({slug:`${$}-${O}`,environment:J,encrypted:_.encrypted!==!1,performanceMode:_.performanceMode||"generalPurpose",throughputMode:_.throughputMode||"bursting",enableBackup:!0});this.builder.addResource(E,w);let{securityGroup:M,logicalId:T}=D1.createEfsSecurityGroup({slug:`${$}-${O}`,environment:J,vpcId:{Ref:"VPC"},sourceCidrBlocks:["10.0.0.0/16"]});this.builder.addResource(T,M);let{mountTargets:D,logicalIds:N}=D1.createMultiAzMountTargets(E,{slug:`${$}-${O}`,environment:J,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],securityGroupId:{Ref:T}});for(let x=0;x<D.length;x++)this.builder.addResource(N[x],D[x]);this.builder.addOutput(`${O}FileSystemId`,{Value:{Ref:E},Description:`EFS file system ID for ${O}`})}}let X=this.mergedConfig.infrastructure?.ai;if(X){let O=X.service||"ecs",_=X.models||["*"],w=X.allowStreaming!==!1,E;if(O==="ecs")E=O1.enableBedrockForEcs({slug:$,environment:J,models:_,allowStreaming:w});else if(O==="ec2")E=O1.enableBedrockForEc2({slug:$,environment:J,models:_,allowStreaming:w});else if(O==="lambda")E=O1.enableBedrockForLambda({slug:$,environment:J,models:_,allowStreaming:w});else E=O1.createBedrockRole(O,{slug:$,environment:J,models:_,allowStreaming:w});if(this.builder.addResource(E.logicalId,E.role),X.allowAsync){let{policy:M,logicalId:T}=O1.createBedrockPolicy({slug:$,environment:J,models:_,allowStreaming:w,allowAsync:!0});this.builder.addResource(T,M)}this.builder.addOutput("BedrockRoleArn",{Value:{"Fn::GetAtt":[E.logicalId,"Arn"]},Description:"IAM role ARN with Bedrock permissions"})}}generateRealtimeResources($,J){let Y=this.mergedConfig.infrastructure?.realtime;if(!Y)return;let Q=Y.name||`${$}-${J}-realtime`,Z=Y.scaling||{},U=Y.storage||{type:"dynamodb"},W=Z.handlerMemory||256,z=Z.handlerTimeout||30,G=`${$}${J}RealtimeConnections`.replace(/[^a-zA-Z0-9]/g,""),H=`${$}${J}RealtimeChannels`.replace(/[^a-zA-Z0-9]/g,"");if(U.type==="dynamodb"){let N=U.dynamodb||{},x=N.billingMode||"PAY_PER_REQUEST";this.builder.addResource(G,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$}-${J}-realtime-connections`,BillingMode:x,AttributeDefinitions:[{AttributeName:"connectionId",AttributeType:"S"},{AttributeName:"userId",AttributeType:"S"}],KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],GlobalSecondaryIndexes:[{IndexName:"userId-index",KeySchema:[{AttributeName:"userId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}},...N.pointInTimeRecovery&&{PointInTimeRecoverySpecification:{PointInTimeRecoveryEnabled:!0}},Tags:[{Key:"Name",Value:`${$}-${J}-realtime-connections`},{Key:"Environment",Value:J}]}}),this.builder.addResource(H,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$}-${J}-realtime-channels`,BillingMode:x,AttributeDefinitions:[{AttributeName:"channel",AttributeType:"S"},{AttributeName:"connectionId",AttributeType:"S"}],KeySchema:[{AttributeName:"channel",KeyType:"HASH"},{AttributeName:"connectionId",KeyType:"RANGE"}],GlobalSecondaryIndexes:[{IndexName:"connectionId-index",KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}},Tags:[{Key:"Name",Value:`${$}-${J}-realtime-channels`},{Key:"Environment",Value:J}]}})}let A=`${$}${J}RealtimeRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(A,{Type:"AWS::IAM::Role",Properties:{RoleName:`${$}-${J}-realtime-handler-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"RealtimeHandlerPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:GetItem","dynamodb:PutItem","dynamodb:DeleteItem","dynamodb:Query","dynamodb:Scan","dynamodb:UpdateItem"],Resource:[{"Fn::GetAtt":[G,"Arn"]},{"Fn::Sub":`\${${G}.Arn}/index/*`},{"Fn::GetAtt":[H,"Arn"]},{"Fn::Sub":`\${${H}.Arn}/index/*`}]},{Effect:"Allow",Action:"execute-api:ManageConnections",Resource:{"Fn::Sub":"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*"}}]}}]}});let K=`${$}${J}RealtimeConnect`.replace(/[^a-zA-Z0-9]/g,""),B=`${$}${J}RealtimeDisconnect`.replace(/[^a-zA-Z0-9]/g,""),j=`${$}${J}RealtimeMessage`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(K,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$}-${J}-realtime-connect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[A,"Arn"]},MemorySize:W,Timeout:z,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:G},CHANNELS_TABLE:{Ref:H},ENVIRONMENT:J}},Code:{ZipFile:this.generateConnectHandlerCode()}},DependsOn:[A,G]}),this.builder.addResource(B,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$}-${J}-realtime-disconnect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[A,"Arn"]},MemorySize:W,Timeout:z,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:G},CHANNELS_TABLE:{Ref:H},ENVIRONMENT:J}},Code:{ZipFile:this.generateDisconnectHandlerCode()}},DependsOn:[A,G,H]}),this.builder.addResource(j,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$}-${J}-realtime-message`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[A,"Arn"]},MemorySize:W,Timeout:z,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:G},CHANNELS_TABLE:{Ref:H},ENVIRONMENT:J}},Code:{ZipFile:this.generateMessageHandlerCode()}},DependsOn:[A,G,H]});let X=`${$}${J}RealtimeApi`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(X,{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:Q,ProtocolType:"WEBSOCKET",RouteSelectionExpression:"$request.body.action",Tags:{Name:Q,Environment:J}}});let O=`${K}Permission`,_=`${B}Permission`,w=`${j}Permission`;this.builder.addResource(O,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:K},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${X}}/*/$connect`}}}),this.builder.addResource(_,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:B},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${X}}/*/$disconnect`}}}),this.builder.addResource(w,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:j},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${X}}/*/$default`}}});let E=`${X}ConnectInteg`,M=`${X}DisconnectInteg`,T=`${X}MessageInteg`;this.builder.addResource(E,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:X},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${K}.Arn}/invocations`}}}),this.builder.addResource(M,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:X},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${B}.Arn}/invocations`}}}),this.builder.addResource(T,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:X},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${j}.Arn}/invocations`}}}),this.builder.addResource(`${X}ConnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:X},RouteKey:"$connect",AuthorizationType:"NONE",Target:{"Fn::Sub":`integrations/\${${E}}`}}}),this.builder.addResource(`${X}DisconnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:X},RouteKey:"$disconnect",Target:{"Fn::Sub":`integrations/\${${M}}`}}}),this.builder.addResource(`${X}DefaultRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:X},RouteKey:"$default",Target:{"Fn::Sub":`integrations/\${${T}}`}}});let D=`${X}Stage`;if(this.builder.addResource(D,{Type:"AWS::ApiGatewayV2::Stage",Properties:{ApiId:{Ref:X},StageName:J,AutoDeploy:!0,DefaultRouteSettings:{ThrottlingBurstLimit:Z.messagesPerSecond||1000,ThrottlingRateLimit:Z.messagesPerSecond||1000}}}),Y.monitoring?.enabled){let N=Y.monitoring,x=N.notificationTopicArn;if(!x&&N.notificationEmails?.length){let h=`${X}AlarmTopic`;this.builder.addResource(h,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${$}-${J}-realtime-alarms`,DisplayName:"Realtime WebSocket Alarms"}}),N.notificationEmails.forEach((k,b)=>{this.builder.addResource(`${h}Sub${b}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:h},Protocol:"email",Endpoint:k}})}),x={Ref:h}}if(N.connectionThreshold)this.builder.addResource(`${X}ConnectionAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-realtime-connections`,AlarmDescription:`WebSocket connections exceed ${N.connectionThreshold}`,MetricName:"ConnectCount",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:300,EvaluationPeriods:2,Threshold:N.connectionThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:X}}],...x&&{AlarmActions:[x]}}});if(N.errorThreshold)this.builder.addResource(`${X}ErrorAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-realtime-errors`,AlarmDescription:`WebSocket errors exceed ${N.errorThreshold}/min`,MetricName:"ExecutionError",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:60,EvaluationPeriods:3,Threshold:N.errorThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:X}}],...x&&{AlarmActions:[x]}}})}this.builder.addOutput(`${X}Endpoint`,{Description:"WebSocket API endpoint URL",Value:{"Fn::Sub":`wss://\${${X}}.execute-api.\${AWS::Region}.amazonaws.com/${J}`},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-endpoint"}}}),this.builder.addOutput(`${X}Id`,{Description:"WebSocket API ID",Value:{Ref:X},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-api-id"}}})}generateConnectHandlerCode(){return`
7325
+ `)}normalizeMountPath($){let J=$?.mountPath||$?.path;if(!J||J==="/")return;let Y=`/${J}`.replace(/\/+/g,"/").replace(/\/$/,"");return Y==="/"?void 0:Y}storageBucketLogicalId($,J,Y){return`${$}-${J}-s3-${Y}`.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((Q)=>Q.charAt(0).toUpperCase()+Q.slice(1)).join("")}pathMountRewriteFunctionCode($,J="directory"){return`function handler(event) { var request = event.request; var prefix = ${JSON.stringify($)}; var rewriteStyle = ${JSON.stringify(J)}; var uri = request.uri; if (uri === prefix) { uri = '/'; } else if (uri.indexOf(prefix + '/') === 0) { uri = uri.substring(prefix.length); } if (uri === '' || uri === '/') { request.uri = '/index.html'; return request; } if (uri.endsWith('/')) { request.uri = uri + 'index.html'; return request; } var lastSegment = uri.substring(uri.lastIndexOf('/') + 1); if (lastSegment.indexOf('.') === -1) { request.uri = rewriteStyle === 'flat' ? uri + '.html' : uri + '/index.html'; return request; } request.uri = uri; return request; }`}generate(){let $=this.mergedConfig.project.slug,J=this.environment,Y=!!(this.mergedConfig.infrastructure?.functions&&Object.keys(this.mergedConfig.infrastructure.functions).length>0||this.mergedConfig.infrastructure?.api),Q=!!(this.mergedConfig.infrastructure?.servers&&Object.keys(this.mergedConfig.infrastructure.servers).length>0),Z=!!this.mergedConfig.infrastructure?.compute;if(!!((this.mergedConfig.mode||"server")==="serverless"&&this.mergedConfig.infrastructure?.containers&&Object.keys(this.mergedConfig.infrastructure.containers).length>0))this.generateNetworkInfrastructure($,J),this.generateContainerInfrastructure($,J);if(Y)this.generateServerless($,J);if(Q)this.generateServer($,J);if(Z)this.generateComputeApp($,J);if(this.mergedConfig.infrastructure?.jumpBox)this.generateJumpBox($,J);if(this.generateSharedInfrastructure($,J),this.config.tags)this.applyGlobalTags(this.config.tags);return this}applyGlobalTags($){}generateNetworkInfrastructure($,J){if(this.builder.hasResource("VPC"))return;let Q=this.mergedConfig.infrastructure?.network?.cidr||"10.0.0.0/16",{vpc:Z,logicalId:U}=E0.createVpc({slug:$,environment:J,cidr:Q,enableDnsHostnames:!0,enableDnsSupport:!0});this.builder.addResource("VPC",Z);let W=`${$}${J}IGW`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(W,{Type:"AWS::EC2::InternetGateway",Properties:{Tags:[{Key:"Name",Value:`${$}-${J}-igw`},{Key:"Environment",Value:J}]}});let z=`${$}${J}IGWAttach`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(z,{Type:"AWS::EC2::VPCGatewayAttachment",Properties:{VpcId:{Ref:"VPC"},InternetGatewayId:{Ref:W}}});let G=`${$}${J}PublicRT`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(G,{Type:"AWS::EC2::RouteTable",Properties:{VpcId:{Ref:"VPC"},Tags:[{Key:"Name",Value:`${$}-${J}-public-rt`},{Key:"Environment",Value:J}]}}),this.builder.addResource(`${$}${J}PublicRoute`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::EC2::Route",Properties:{RouteTableId:{Ref:G},DestinationCidrBlock:"0.0.0.0/0",GatewayId:{Ref:W}},DependsOn:z});let H=this.mergedConfig.environments[J]?.region||this.mergedConfig.project.region||"us-east-1",A=["a","b"];for(let K=0;K<2;K++){let B=`PublicSubnet${K+1}`;this.builder.addResource(B,{Type:"AWS::EC2::Subnet",Properties:{VpcId:{Ref:"VPC"},CidrBlock:`10.0.${K}.0/24`,AvailabilityZone:`${H}${A[K]}`,MapPublicIpOnLaunch:!0,Tags:[{Key:"Name",Value:`${$}-${J}-public-${A[K]}`},{Key:"Environment",Value:J}]}}),this.builder.addResource(`${B}RTAssoc`,{Type:"AWS::EC2::SubnetRouteTableAssociation",Properties:{SubnetId:{Ref:B},RouteTableId:{Ref:G}}})}}generateContainerInfrastructure($,J){let Y=this.mergedConfig.infrastructure?.containers;if(!Y)return;let Q=this.mergedConfig.infrastructure?.loadBalancer,Z=this.mergedConfig.infrastructure?.ssl,U=this.mergedConfig.infrastructure?.dns,W;if(Z?.enabled&&Z.domains?.length)if(Z.certificateArn);else{let A=Z.domains[0],K=Z.domains.slice(1).map((X)=>{if(X.includes(".")&&X.endsWith(A))return X.replace(`.${A}`,"");return X}),{certificate:B,logicalId:j}=L0.createCertificate({domain:A,subdomains:K,slug:$,environment:J,validationMethod:"DNS",hostedZoneId:U?.hostedZoneId});W=j,this.builder.addResource(j,B)}let z="ECSCluster";this.builder.addResource(z,{Type:"AWS::ECS::Cluster",Properties:{ClusterName:`${$}-${J}`,ClusterSettings:[{Name:"containerInsights",Value:"enabled"}],Tags:[{Key:"Name",Value:`${$}-${J}`},{Key:"Environment",Value:J}]}});let G=`${$}${J}ALBSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(G,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ALB security group for ${$}-${J}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:80,ToPort:80,CidrIp:"0.0.0.0/0",Description:"HTTP"},{IpProtocol:"tcp",FromPort:443,ToPort:443,CidrIp:"0.0.0.0/0",Description:"HTTPS"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${$}-${J}-alb-sg`},{Key:"Environment",Value:J}]}});let H=`${$}${J}ECSSecurityGroup`.replace(/[^a-zA-Z0-9]/g,"");for(let[A,K]of Object.entries(Y)){let B=K.port||3000;this.builder.addResource(H,{Type:"AWS::EC2::SecurityGroup",Properties:{GroupDescription:`ECS tasks security group for ${$}-${J}`,VpcId:{Ref:"VPC"},SecurityGroupIngress:[{IpProtocol:"tcp",FromPort:B,ToPort:B,SourceSecurityGroupId:{Ref:G},Description:"Allow traffic from ALB"}],SecurityGroupEgress:[{IpProtocol:"-1",CidrIp:"0.0.0.0/0",Description:"Allow all outbound"}],Tags:[{Key:"Name",Value:`${$}-${J}-ecs-sg`},{Key:"Environment",Value:J}]}});let j=`${$}${J}TaskExecRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(j,{Type:"AWS::IAM::Role",Properties:{RoleName:`${$}-${J}-ecs-exec-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"],Policies:[{PolicyName:"ECRPullPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["ecr:GetAuthorizationToken","ecr:BatchCheckLayerAvailability","ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"}]}}]}});let X=`${$}${J}TaskRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(X,{Type:"AWS::IAM::Role",Properties:{RoleName:`${$}-${J}-ecs-task-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"ecs-tasks.amazonaws.com"},Action:"sts:AssumeRole"}]},Policies:[{PolicyName:"TaskPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["logs:CreateLogStream","logs:PutLogEvents"],Resource:"*"},{Effect:"Allow",Action:["s3:GetObject","s3:PutObject","s3:ListBucket"],Resource:"*"}]}}]}});let O=`${$}${J}${A}LogGroup`.replace(/[^a-zA-Z0-9]/g,""),_=`/ecs/${$}-${J}-${A}`;this.builder.addResource(O,{Type:"AWS::Logs::LogGroup",Properties:{LogGroupName:_,RetentionInDays:30}});let w=`${$}${J}${A}TaskDef`.replace(/[^a-zA-Z0-9]/g,""),E=String(K.cpu||512),M=String(K.memory||1024);this.builder.addResource(w,{Type:"AWS::ECS::TaskDefinition",Properties:{Family:`${$}-${J}-${A}`,NetworkMode:"awsvpc",RequiresCompatibilities:["FARGATE"],Cpu:E,Memory:M,ExecutionRoleArn:{"Fn::GetAtt":[j,"Arn"]},TaskRoleArn:{"Fn::GetAtt":[X,"Arn"]},ContainerDefinitions:[{Name:A,Image:{"Fn::Sub":`\${AWS::AccountId}.dkr.ecr.\${AWS::Region}.amazonaws.com/${$}:latest`},Essential:!0,PortMappings:[{ContainerPort:B,Protocol:"tcp"}],LogConfiguration:{LogDriver:"awslogs",Options:{"awslogs-group":_,"awslogs-region":{Ref:"AWS::Region"},"awslogs-stream-prefix":A}},HealthCheck:{Command:["CMD-SHELL",`curl -f http://localhost:${B}${K.healthCheck||"/health"} || exit 1`],Interval:30,Timeout:5,Retries:3,StartPeriod:60}}],Tags:[{Key:"Name",Value:`${$}-${J}-${A}`},{Key:"Environment",Value:J}]},DependsOn:[j,X,O]});let T=`${$}${J}ALB`.replace(/[^a-zA-Z0-9]/g,"");if(Q?.enabled!==!1){this.builder.addResource(T,{Type:"AWS::ElasticLoadBalancingV2::LoadBalancer",Properties:{Name:`${$}-${J}-alb`,Scheme:"internet-facing",Type:"application",Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],SecurityGroups:[{Ref:G}],Tags:[{Key:"Name",Value:`${$}-${J}-alb`},{Key:"Environment",Value:J}]}});let D=`${$}${J}TargetGroup`.replace(/[^a-zA-Z0-9]/g,""),N=Q?.healthCheck?.path||K.healthCheck||"/health";this.builder.addResource(D,{Type:"AWS::ElasticLoadBalancingV2::TargetGroup",Properties:{Name:`${$}-${J}-tg`,Port:B,Protocol:"HTTP",VpcId:{Ref:"VPC"},TargetType:"ip",HealthCheckPath:N,HealthCheckIntervalSeconds:Q?.healthCheck?.interval||30,HealthyThresholdCount:Q?.healthCheck?.healthyThreshold||2,UnhealthyThresholdCount:Q?.healthCheck?.unhealthyThreshold||5,HealthCheckTimeoutSeconds:10,Tags:[{Key:"Name",Value:`${$}-${J}-tg`},{Key:"Environment",Value:J}]}});let x=`${$}${J}HTTPListener`.replace(/[^a-zA-Z0-9]/g,"");if(Z?.enabled&&Z?.redirectHttp)this.builder.addResource(x,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:T},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"redirect",RedirectConfig:{Protocol:"HTTPS",Port:"443",StatusCode:"HTTP_301"}}]}});else this.builder.addResource(x,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:T},Port:80,Protocol:"HTTP",DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:D}}]}});if(Z?.enabled){let k=Z.certificateArn||(W?{Ref:W}:void 0);if(k){let y=`${$}${J}HTTPSListener`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(y,{Type:"AWS::ElasticLoadBalancingV2::Listener",Properties:{LoadBalancerArn:{Ref:T},Port:443,Protocol:"HTTPS",Certificates:[{CertificateArn:k}],DefaultActions:[{Type:"forward",TargetGroupArn:{Ref:D}}],SslPolicy:"ELBSecurityPolicy-TLS13-1-2-2021-06"}})}}let h=`${$}${J}${A}Service`.replace(/[^a-zA-Z0-9]/g,""),I=K.desiredCount||1;this.builder.addResource(h,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${$}-${J}-${A}`,Cluster:{Ref:z},TaskDefinition:{Ref:w},DesiredCount:I,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:H}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},LoadBalancers:[{ContainerName:A,ContainerPort:B,TargetGroupArn:{Ref:D}}],HealthCheckGracePeriodSeconds:120,Tags:[{Key:"Name",Value:`${$}-${J}-${A}`},{Key:"Environment",Value:J}]},DependsOn:[w,x,D]});let b=K.autoScaling;if(b){let k=`${$}${J}${A}ScalableTarget`.replace(/[^a-zA-Z0-9]/g,"");if(this.builder.addResource(k,{Type:"AWS::ApplicationAutoScaling::ScalableTarget",Properties:{MaxCapacity:b.max||10,MinCapacity:b.min||1,ResourceId:{"Fn::Sub":`service/\${${z}}/${$}-${J}-${A}`},ScalableDimension:"ecs:service:DesiredCount",ServiceNamespace:"ecs",RoleARN:{"Fn::Sub":"arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"}},DependsOn:h}),b.targetCpuUtilization)this.builder.addResource(`${$}${J}${A}CPUScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${$}-${J}-${A}-cpu-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:k},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageCPUUtilization"},TargetValue:b.targetCpuUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}});if(b.targetMemoryUtilization)this.builder.addResource(`${$}${J}${A}MemoryScaling`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::ApplicationAutoScaling::ScalingPolicy",Properties:{PolicyName:`${$}-${J}-${A}-memory-scaling`,PolicyType:"TargetTrackingScaling",ScalingTargetId:{Ref:k},TargetTrackingScalingPolicyConfiguration:{PredefinedMetricSpecification:{PredefinedMetricType:"ECSServiceAverageMemoryUtilization"},TargetValue:b.targetMemoryUtilization,ScaleInCooldown:300,ScaleOutCooldown:60}}})}if(U?.domain&&U?.hostedZoneId)this.builder.addResource(`${$}${J}ApiDnsRecord`.replace(/[^a-zA-Z0-9]/g,""),{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:U.hostedZoneId,Name:`api.${U.domain}`,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[T,"DNSName"]},HostedZoneId:{"Fn::GetAtt":[T,"CanonicalHostedZoneID"]}}}});this.builder.addOutput("ECSClusterArn",{Description:"ECS Cluster ARN",Value:{"Fn::GetAtt":[z,"Arn"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-cluster-arn"}}}),this.builder.addOutput("ECSServiceName",{Description:"ECS Service Name",Value:`${$}-${J}-${A}`,Export:{Name:{"Fn::Sub":"${AWS::StackName}-ecs-service-name"}}}),this.builder.addOutput("LoadBalancerDNS",{Description:"Application Load Balancer DNS Name",Value:{"Fn::GetAtt":[T,"DNSName"]},Export:{Name:{"Fn::Sub":"${AWS::StackName}-alb-dns"}}})}else{let D=`${$}${J}${A}Service`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(D,{Type:"AWS::ECS::Service",Properties:{ServiceName:`${$}-${J}-${A}`,Cluster:{Ref:z},TaskDefinition:{Ref:w},DesiredCount:K.desiredCount||1,LaunchType:"FARGATE",NetworkConfiguration:{AwsvpcConfiguration:{AssignPublicIp:"ENABLED",SecurityGroups:[{Ref:H}],Subnets:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]}},Tags:[{Key:"Name",Value:`${$}-${J}-${A}`},{Key:"Environment",Value:J}]},DependsOn:[w]})}break}}generateServerless($,J){if(this.mergedConfig.infrastructure?.functions)for(let[Y,Q]of Object.entries(this.mergedConfig.infrastructure.functions)){if(!this.shouldDeploy(Q))continue;let{role:Z,logicalId:U}=Y1.createRole({slug:$,environment:J,roleName:`${$}-${J}-${Y}-role`,servicePrincipal:"lambda.amazonaws.com",managedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]});this.builder.addResource(U,Z);let{lambdaFunction:W,logicalId:z}=n.createLambdaFunction({slug:$,environment:J,functionName:`${$}-${J}-${Y}`,handler:Q.handler||"index.handler",runtime:Q.runtime||"nodejs20.x",code:{zipFile:Q.code||"export const handler = async () => ({ statusCode: 200 });"},role:U,timeout:Q.timeout,memorySize:Q.memorySize});this.builder.addResource(z,W)}if(this.mergedConfig.infrastructure?.api){let{restApi:Y,logicalId:Q}=x9.createRestApi({slug:$,environment:J,apiName:`${$}-${J}-api`});this.builder.addResource(Q,Y)}}generateServer($,J){if(!this.mergedConfig.infrastructure?.servers)return;let Y=this.mergedConfig.infrastructure.servers,Q=this.mergedConfig.infrastructure?.compute,Z=this.mergedConfig.infrastructure?.ssl;if(Object.values(Y).some((W)=>!W.privateNetwork||W.privateNetwork==="create"))this.generateNetworkInfrastructure($,J);for(let[W,z]of Object.entries(Y)){let G=z.instanceType||z.size||Q?.size,A=(G?n.InstanceSize.specs[G]:void 0)?.instanceType||G||"t3.micro",K=z.type||"app",B=z.userData||z.startupScript;if(!B)B=n.UserData.generateAppServerScript({runtime:"bun",runtimeVersion:z.bunVersion||"latest",webServer:"none",domain:z.domain,enableSsl:!!Z?.enabled,sslEmail:Z?.letsEncrypt?.email,installRedis:K==="cache",installDatabaseClients:!!z.database});let j=z.privateNetwork&&z.privateNetwork!=="create"?z.privateNetwork:{Ref:"VPC"},X=z.subnet||{Ref:"PublicSubnet1"},_=!!this.mergedConfig.infrastructure?.email?.server?.enabled,w=[22,80,443,this.resolveApiOriginPort()];if(_)w.push(25,465,587,143,993);let E=n.createServerModeStack({slug:`${$}-${W}`,environment:J,vpcId:j,subnetId:X,instanceType:A,keyName:z.keyName||`${$}-${J}`,domain:z.domain,userData:B,volumeSize:z.diskSize||20,imageId:z.image,allowedPorts:w});for(let[M,T]of Object.entries(E.resources))this.builder.addResource(M,T);this.serverEipLogicalIds.set(W,E.outputs.eipLogicalId),this.serverEipLogicalIds.set(`${W}Instance`,E.outputs.instanceLogicalId),this.builder.addOutput(`${W}InstanceId`,{Value:{Ref:E.outputs.instanceLogicalId},Description:`Instance ID for ${W} server`}),this.builder.addOutput(`${W}PublicIp`,{Value:{Ref:E.outputs.eipLogicalId},Description:`Public IP for ${W} server`})}}generateComputeApp($,J){let Y=this.mergedConfig.infrastructure?.compute;if(!Y)return;let Q=this.mergedConfig.sites||{},Z=Object.entries(Q),W=this.mergedConfig.infrastructure?.dns?.domain,z=this.mergedConfig.infrastructure?.database,G=Y.size,A=(G?n.InstanceSize.specs[G]:void 0)?.instanceType||"t3.micro";if(!this.builder.hasResource("VPC"))this.generateNetworkInfrastructure($,J);let K=this.buildCaddyfile(Z),B=n.UserData.generateBunAppScript({runtime:Y.runtime||"bun",runtimeVersion:Y.runtimeVersion||"latest",systemPackages:Y.systemPackages,database:z,caddyfile:K}),j=Z.map(([,T])=>T.port).filter((T)=>typeof T==="number"&&![80,443].includes(T)),X=this.resolveApiOriginPort(),O=`${$}${J}DeployBucket`.replace(/[^a-zA-Z0-9]/g,""),_=`${$}-${J}-deploy`;this.builder.addResource(O,{Type:"AWS::S3::Bucket",Properties:{BucketName:_,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0},LifecycleConfiguration:{Rules:[{Id:"expire-old-releases",Status:"Enabled",ExpirationInDays:7,Prefix:"releases/"}]},Tags:[{Key:"Project",Value:$},{Key:"Environment",Value:J},{Key:"ManagedBy",Value:"ts-cloud"}]}});let w=n.createServerModeStack({slug:`${$}-app`,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},instanceType:A,keyName:`${$}-${J}`,domain:W,userData:B,volumeSize:Y.disk?.size||20,imageId:Y.image,allowedPorts:[...Y.allowSsh?[22]:[],80,443,X,...j]}),E=w.resources[w.outputs.instanceLogicalId];if(E?.Properties){let T=E.Properties.Tags||[];E.Properties.Tags=[...T,{Key:"Project",Value:$},{Key:"Environment",Value:J},{Key:"Role",Value:"app"},{Key:"ManagedBy",Value:"ts-cloud"}]}let M=w.resources[w.outputs.roleLogicalId];if(M?.Properties)M.Properties.Policies=M.Properties.Policies||[],M.Properties.Policies.push({PolicyName:"DeployBucketRead",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["s3:GetObject","s3:ListBucket"],Resource:[`arn:aws:s3:::${_}`,`arn:aws:s3:::${_}/*`]}]}});for(let[T,D]of Object.entries(w.resources))this.builder.addResource(T,D);this.builder.addOutput("deployBucketName",{Value:{Ref:O},Description:"S3 bucket where release tarballs are uploaded"}),this.builder.addOutput("appInstanceId",{Value:{Ref:w.outputs.instanceLogicalId},Description:"EC2 instance ID for the app server"}),this.builder.addOutput("appPublicIp",{Value:{Ref:w.outputs.eipLogicalId},Description:"Public IP for the app server"}),this.serverEipLogicalIds.set("app",w.outputs.eipLogicalId),this.serverEipLogicalIds.set("appInstance",w.outputs.instanceLogicalId)}generateJumpBox($,J){let Y=this.mergedConfig.infrastructure?.jumpBox;if(!Y)return;let Q=Y===!0?{}:Y;if(Q.enabled===!1)return;this.generateNetworkInfrastructure($,J);let Z=Q.size||"micro",W=n.InstanceSize.specs[Z]?.instanceType||Z||"t3.micro",z;if(Q.mountEfs)z={fileSystemId:typeof Q.mountEfs==="string"?Q.mountEfs:{Ref:"FileSystem"},mountPath:Q.mountPath||"/mnt/efs"};let G;if(Q.databaseTools)G=n.JumpBox.withDatabaseTools({slug:$,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:Q.keyName||`${$}-${J}`,allowedCidrs:Q.allowedCidrs});else if(z)G=n.JumpBox.withEfsMount({slug:$,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:Q.keyName||`${$}-${J}`,fileSystemId:z.fileSystemId,mountPath:z.mountPath,allowedCidrs:Q.allowedCidrs});else G=n.createJumpBox({slug:$,environment:J,vpcId:{Ref:"VPC"},subnetId:{Ref:"PublicSubnet1"},keyName:Q.keyName||`${$}-${J}`,instanceType:W,allowedCidrs:Q.allowedCidrs,mountEfs:z});for(let[H,A]of Object.entries(G.resources))this.builder.addResource(H,A);this.builder.addOutput("JumpBoxInstanceId",{Value:{Ref:G.instanceLogicalId},Description:"The ID of the JumpBox EC2 instance (use with SSM Session Manager or SSH)"})}generateSharedInfrastructure($,J){let Y=this.mergedConfig.infrastructure?.ssl,Q=this.mergedConfig.infrastructure?.dns,Z=Q?.domain,U=Q?.hostedZoneId,W=[],z,G;if(Y?.certificateArn)G=Y.certificateArn;else if(Y?.enabled&&Z&&U){let O=Y.domains||[Z],_=O[0],w=O.slice(1).map((T)=>{if(T.includes(".")&&T.endsWith(_))return T.replace(`.${_}`,"");return T}),{certificate:E,logicalId:M}=L0.createCertificate({domain:_,subdomains:w,slug:$,environment:J,validationMethod:"DNS",hostedZoneId:U});z=M,this.builder.addResource(M,E)}if(this.mergedConfig.infrastructure?.storage){let O=Object.entries(this.mergedConfig.infrastructure.storage).some(([,E])=>E.website),_;if(O&&(z||G))_=`${$}${J}CloudFrontOAC`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(_,{Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${$}-${J}-s3-oac`,Description:`OAC for ${$} ${J} S3 website buckets`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}});let w=Object.entries(this.mergedConfig.infrastructure.storage).map(([E,M])=>({name:E,config:M,mountPath:this.normalizeMountPath(M),rewriteStyle:M.pathRewriteStyle||"directory",logicalId:this.storageBucketLogicalId($,J,E)})).filter((E)=>E.name!=="public"&&E.config.website&&E.mountPath);for(let[E,M]of Object.entries(this.mergedConfig.infrastructure.storage)){let T=!!(M.website&&_),D=M.bucket??`${$}-${J}-${E}`,{bucket:N,logicalId:x}=X1.createBucket({slug:$,name:E,environment:J,bucketName:D,versioning:M.versioning,encryption:M.encryption,public:T?!1:M.public});if(T&&N.Properties)N.Properties.PublicAccessBlockConfiguration={BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1};if(this.builder.addResource(x,N),M.website){let I=typeof M.website==="object"?M.website:{},b=X1.enableWebsiteHosting(N,I.indexDocument||"index.html",I.errorDocument);this.builder.addResource(x,b)}let h=this.normalizeMountPath(M);if(T&&_&&Z&&!(h&&E!=="public")){let I=`${$}${J}${E}CDN`.replace(/[^a-zA-Z0-9]/g,""),b=[];if(M.aliases&&M.aliases.length>0)b.push(...M.aliases);else if(E==="public"){if(b.push(Z),Y?.domains?.includes(`www.${Z}`))b.push(`www.${Z}`)}else if(E==="docs")b.push(`docs.${Z}`);else if(E==="blog")b.push(`blog.${Z}`);let k=typeof M.website==="object"?M.website:{},y=M.spa===!0,m=k.errorDocument||(y?"index.html":"404.html"),l=[];if(y)l.push({ErrorCode:403,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:200,ResponsePagePath:"/index.html",ErrorCachingMinTTL:300});else l.push({ErrorCode:403,ResponseCode:404,ResponsePagePath:`/${m}`,ErrorCachingMinTTL:300},{ErrorCode:404,ResponseCode:404,ResponsePagePath:`/${m}`,ErrorCachingMinTTL:300});let p=G&&b.length>0?{AcmCertificateArn:G,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:z&&b.length>0?{AcmCertificateArn:{Ref:z},SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},r=`S3-${$}-${J}-${E}`,s=this.mergedConfig.project.region||"us-east-1",o;if(!y)o=`${$}${J}${E}UrlRewrite`.replace(/[^a-zA-Z0-9]/g,""),this.builder.addResource(o,{Type:"AWS::CloudFront::Function",Properties:{Name:`${$}-${J}-${E}-url-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`URL rewrite for ${$} ${J} ${E} - appends .html to extensionless paths`,Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) { var request = event.request; var uri = request.uri; if (uri.endsWith('/')) { request.uri += 'index.html'; }
7326
+ else if (!uri.includes('.')) { request.uri += '.html'; } return request; }`}});let B0=[{Id:r,DomainName:{"Fn::Sub":`\${${x}}.s3.${s}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:_}}],c0=[],x0=[];if(this.shouldRouteStorageBucketToCompute(E,M)){this.appendComputeAppOrigin(B0,c0,x0,$,J,this.resolveComputeCachePathPatterns(M.computeRoutes));for(let N0 of w){let k1=`S3-${$}-${J}-${N0.name}`,p2=`${$}${J}${N0.name}PathMountRewrite`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(p2,{Type:"AWS::CloudFront::Function",Properties:{Name:`${$}-${J}-${N0.name}-path-mount-rewrite`,AutoPublish:!0,FunctionConfig:{Comment:`Path mount rewrite for ${$} ${J} ${N0.name} at ${N0.mountPath}`,Runtime:"cloudfront-js-2.0"},FunctionCode:this.pathMountRewriteFunctionCode(N0.mountPath,N0.rewriteStyle)}}),B0.push({Id:k1,DomainName:{"Fn::Sub":`\${${N0.logicalId}}.s3.${s}.amazonaws.com`},OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""},OriginAccessControlId:{Ref:_}}),x0.push(N0.logicalId,p2);for(let a9 of[N0.mountPath,`${N0.mountPath}/*`])c0.push({PathPattern:a9,TargetOriginId:k1,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[p2,"FunctionARN"]}}]})}}let z2={Type:"AWS::CloudFront::Distribution",DependsOn:[x,_,...o?[o]:[],...x0],Properties:{DistributionConfig:{Enabled:!0,Comment:`${$} ${J} ${E} site`,DefaultRootObject:"index.html",Origins:B0,DefaultCacheBehavior:{TargetOriginId:r,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6",...o?{FunctionAssociations:[{EventType:"viewer-request",FunctionARN:{"Fn::GetAtt":[o,"FunctionARN"]}}]}:{}},...c0.length>0?{CacheBehaviors:c0}:{},...b.length>0?{Aliases:b}:{},ViewerCertificate:p,PriceClass:"PriceClass_100",HttpVersion:"http2and3",IPV6Enabled:!0,CustomErrorResponses:l}}};if(z)z2.DependsOn.push(z);this.builder.addResource(I,z2);let G2=`${x}CloudFrontPolicy`;if(this.builder.addResource(G2,{Type:"AWS::S3::BucketPolicy",DependsOn:[x,I],Properties:{Bucket:{Ref:x},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${x}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${I}}`}}}}]}}}),this.shouldRouteStorageBucketToCompute(E,M))for(let N0 of w){let k1=`${N0.logicalId}CloudFrontPolicy`;this.builder.addResource(k1,{Type:"AWS::S3::BucketPolicy",DependsOn:[N0.logicalId,I],Properties:{Bucket:{Ref:N0.logicalId},PolicyDocument:{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:{"Fn::Sub":`arn:aws:s3:::\${${N0.logicalId}}/*`},Condition:{StringEquals:{"AWS:SourceArn":{"Fn::Sub":`arn:aws:cloudfront::\${AWS::AccountId}:distribution/\${${I}}`}}}}]}}})}if(b.length>0)W.push({name:E,bucketLogicalId:x,distLogicalId:I,oacLogicalId:_,aliases:b});this.builder.addOutput(`${E}CloudFrontDomain`,{Value:{"Fn::GetAtt":[I,"DomainName"]},Description:`CloudFront domain for ${E}`}),this.builder.addOutput(`${E}CloudFrontDistributionId`,{Value:{Ref:I},Description:`CloudFront distribution ID for ${E}`})}if(this.builder.addOutput(`${E}BucketName`,{Value:{Ref:x},Description:`S3 bucket name for ${E}`}),E==="public")this.builder.addOutput("FrontendBucketName",{Value:{Ref:x},Description:"Frontend S3 bucket name"});if(E==="docs")this.builder.addOutput("DocsBucketName",{Value:{Ref:x},Description:"Documentation S3 bucket name"});if(E==="blog")this.builder.addOutput("BlogBucketName",{Value:{Ref:x},Description:"Blog S3 bucket name"})}}if(U&&W.length>0)for(let{name:O,distLogicalId:_,aliases:w}of W)for(let E of w){let M=E.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${M}ARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[_],Properties:{HostedZoneId:U,Name:E,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":[_,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}}),this.builder.addResource(`${M}AAAARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[_],Properties:{HostedZoneId:U,Name:E,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":[_,"DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}})}if(this.mergedConfig.infrastructure?.databases){for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.databases))if(_.engine==="dynamodb"){let{table:w,logicalId:E}=Q2.createTable({slug:$,environment:J,tableName:`${$}-${J}-${O}`,partitionKey:_.partitionKey||{name:"id",type:"S"},sortKey:_.sortKey});this.builder.addResource(E,w)}else if(_.engine==="postgres"){let{dbInstance:w,logicalId:E}=Q2.createPostgres({slug:$,environment:J,dbInstanceIdentifier:`${$}-${J}-${O}`,masterUsername:_.username||"admin",masterUserPassword:_.password||"changeme123",allocatedStorage:_.storage||20,dbInstanceClass:_.instanceClass||"db.t3.micro"});this.builder.addResource(E,w)}else if(_.engine==="mysql"){let{dbInstance:w,logicalId:E}=Q2.createMysql({slug:$,environment:J,dbInstanceIdentifier:`${$}-${J}-${O}`,masterUsername:_.username||"admin",masterUserPassword:_.password||"changeme123",allocatedStorage:_.storage||20,dbInstanceClass:_.instanceClass||"db.t3.micro"});this.builder.addResource(E,w)}}if(this.mergedConfig.infrastructure?.cdn)for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.cdn)){if(!_.origin)continue;let w=typeof _.customDomain==="string"?_.customDomain:_.customDomain?.domain||_.domain,E=typeof _.customDomain==="object"?_.customDomain?.certificateArn:_.certificateArn,M=E||G,T=`${$}${J}${O}CDN`.replace(/[^a-zA-Z0-9]/g,""),D=`S3-${$}-${J}-${O}-cdn`,N=[{Id:D,DomainName:_.origin,OriginPath:"",S3OriginConfig:{OriginAccessIdentity:""}}],x=[],h=[];if(_.routeCompute)this.appendComputeAppOrigin(N,x,h,$,J,this.resolveComputeCachePathPatterns(_.computeRoutes));let I=M&&w?{AcmCertificateArn:z&&!E?{Ref:z}:M,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"}:{CloudFrontDefaultCertificate:!0},b=[...h];if(z&&!E&&w)b.push(z);let k={Type:"AWS::CloudFront::Distribution",...b.length>0?{DependsOn:b}:{},Properties:{DistributionConfig:{Enabled:!0,Comment:`${$} ${J} ${O} CDN`,DefaultRootObject:"index.html",Origins:N,DefaultCacheBehavior:{TargetOriginId:D,ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:_.compress!==!1,CachePolicyId:"658327ea-f89d-4fab-a63d-7e88639e58f6"},...x.length>0?{CacheBehaviors:x}:{},...w&&M?{Aliases:[w]}:{},ViewerCertificate:I,PriceClass:"PriceClass_100",HttpVersion:_.http3?"http2and3":"http2"}}};if(this.builder.addResource(T,k),U&&w&&M){let y=w.replace(/\./g,"").replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${y}CdnARecord`,{Type:"AWS::Route53::RecordSet",DependsOn:[T,...z&&!E?[z]:[]],Properties:{HostedZoneId:U,Name:w,Type:"A",AliasTarget:{HostedZoneId:"Z2FDTNDATAQYW2",DNSName:{"Fn::GetAtt":[T,"DomainName"]}}}})}}if(this.mergedConfig.infrastructure?.queues)for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.queues)){if(!this.shouldDeploy(_))continue;let{queue:w,logicalId:E}=t0.createQueue({slug:$,environment:J,name:`${$}-${J}-${O}`,fifo:_.fifo,visibilityTimeout:_.visibilityTimeout,messageRetentionPeriod:_.messageRetentionPeriod,delaySeconds:_.delaySeconds,maxMessageSize:_.maxMessageSize,receiveMessageWaitTime:_.receiveMessageWaitTime,contentBasedDeduplication:_.contentBasedDeduplication,encrypted:_.encrypted,kmsKeyId:_.kmsKeyId});this.builder.addResource(E,w);let M;if(_.deadLetterQueue){let{deadLetterQueue:T,updatedSourceQueue:D,deadLetterLogicalId:N}=t0.createDeadLetterQueue(E,{slug:$,environment:J,maxReceiveCount:_.maxReceiveCount});M=N,this.builder.addResource(N,T);let h=this.builder.getResources()[E];if(h?.Properties)h.Properties.RedrivePolicy=D.Properties?.RedrivePolicy}if(_.trigger){let T=_.trigger,D=`${$}${J}${T.functionName}`.replace(/[^a-zA-Z0-9]/g,""),N={Type:"AWS::Lambda::EventSourceMapping",Properties:{EventSourceArn:{"Fn::GetAtt":[E,"Arn"]},FunctionName:{Ref:D},BatchSize:T.batchSize||10,MaximumBatchingWindowInSeconds:T.batchWindow||0,Enabled:!0,...T.reportBatchItemFailures!==!1&&{FunctionResponseTypes:["ReportBatchItemFailures"]},...T.maxConcurrency&&{ScalingConfig:{MaximumConcurrency:T.maxConcurrency}},...T.filterPattern&&{FilterCriteria:{Filters:[{Pattern:JSON.stringify(T.filterPattern)}]}}},DependsOn:[E,D]};this.builder.addResource(`${E}Trigger`,N)}if(_.alarms?.enabled){let T=_.alarms,D=T.notificationTopicArn;if(!D&&T.notificationEmails?.length){let h=`${E}AlarmTopic`;this.builder.addResource(h,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${$}-${J}-${O}-alarms`,DisplayName:`${O} Queue Alarms`}}),T.notificationEmails.forEach((I,b)=>{this.builder.addResource(`${h}Sub${b}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:h},Protocol:"email",Endpoint:I}})}),D={Ref:h}}let N=T.queueDepthThreshold||1000;this.builder.addResource(`${E}DepthAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-${O}-queue-depth`,AlarmDescription:`Queue ${O} depth exceeds ${N} messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Average",Period:300,EvaluationPeriods:2,Threshold:N,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[E,"QueueName"]}}],...D&&{AlarmActions:[D],OKActions:[D]}}});let x=T.messageAgeThreshold||3600;if(this.builder.addResource(`${E}AgeAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-${O}-message-age`,AlarmDescription:`Queue ${O} oldest message exceeds ${x} seconds`,MetricName:"ApproximateAgeOfOldestMessage",Namespace:"AWS/SQS",Statistic:"Maximum",Period:300,EvaluationPeriods:2,Threshold:x,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[E,"QueueName"]}}],...D&&{AlarmActions:[D],OKActions:[D]}}}),M&&T.dlqAlarm!==!1)this.builder.addResource(`${M}Alarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-${O}-dlq-messages`,AlarmDescription:`Dead letter queue for ${O} has messages`,MetricName:"ApproximateNumberOfMessagesVisible",Namespace:"AWS/SQS",Statistic:"Sum",Period:300,EvaluationPeriods:1,Threshold:0,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"QueueName",Value:{"Fn::GetAtt":[M,"QueueName"]}}],...D&&{AlarmActions:[D]}}})}if(_.subscribe){let T=_.subscribe,D=T.topicArn;if(!D&&T.topicName)D={Ref:T.topicName};if(D){this.builder.addResource(`${E}SnsPolicy`,{Type:"AWS::SQS::QueuePolicy",Properties:{Queues:[{Ref:E}],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"sns.amazonaws.com"},Action:"sqs:SendMessage",Resource:{"Fn::GetAtt":[E,"Arn"]},Condition:{ArnEquals:{"aws:SourceArn":D}}}]}}});let N={TopicArn:D,Protocol:"sqs",Endpoint:{"Fn::GetAtt":[E,"Arn"]},RawMessageDelivery:T.rawMessageDelivery||!1};if(T.filterPolicy)N.FilterPolicy=T.filterPolicy,N.FilterPolicyScope=T.filterPolicyScope||"MessageAttributes";this.builder.addResource(`${E}SnsSub`,{Type:"AWS::SNS::Subscription",Properties:N,DependsOn:`${E}SnsPolicy`})}}}if(this.mergedConfig.infrastructure?.realtime?.enabled)if((this.mergedConfig.infrastructure.realtime.mode||"serverless")==="server")this.generateRealtimeServerResources($,J);else this.generateRealtimeResources($,J);let H=this.mergedConfig.infrastructure?.redirects;if(H){let O=H.target||this.mergedConfig.infrastructure?.dns?.domain||"",_=H.protocol||"https";if(H.domains?.length&&O)for(let w of H.domains){let{bucket:E,bucketPolicy:M,logicalId:T,policyLogicalId:D}=c1.createDomainRedirectBucket({slug:$,environment:J,sourceDomain:w,targetDomain:O,protocol:_});this.builder.addResource(T,E),this.builder.addResource(D,M)}if(H.paths&&Object.keys(H.paths).length>0){let w=c1.fromMapping(H.paths,{statusCode:H.statusCode||301}),{function:E,logicalId:M}=c1.createPathRedirectFunction({slug:$,environment:J,rules:w});this.builder.addResource(M,E)}}if(this.mergedConfig.infrastructure?.monitoring?.alarms)for(let[O,_]of Object.entries(this.mergedConfig.infrastructure.monitoring.alarms)){let{alarm:w,logicalId:E}=_$.createAlarm({slug:$,environment:J,alarmName:`${$}-${J}-${O}`,metricName:_.metricName||"Errors",namespace:_.namespace||"AWS/Lambda",threshold:_.threshold||1,comparisonOperator:_.comparisonOperator||"GreaterThanThreshold"});this.builder.addResource(E,w)}let A=this.mergedConfig.infrastructure?.cache;if(A){let O=A.type||"redis";if(O==="redis"){this.generateNetworkInfrastructure($,J);let _=A.redis||{},{replicationGroup:w,subnetGroup:E,logicalId:M,subnetGroupId:T}=O$.createRedis({slug:$,environment:J,nodeType:_.nodeType||A.nodeType||"cache.t3.micro",engineVersion:_.engineVersion||"7.1",port:_.port||6379,numCacheClusters:_.numCacheNodes||2,automaticFailover:_.automaticFailoverEnabled!==!1,atRestEncryption:!0,transitEncryption:!0,snapshotRetentionDays:_.snapshotRetentionLimit||7,snapshotWindow:_.snapshotWindow,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(M,w),E&&T)this.builder.addResource(T,E);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[M,"PrimaryEndPoint.Address"]},Description:"Redis primary endpoint address"}),this.builder.addOutput("CachePort",{Value:{"Fn::GetAtt":[M,"PrimaryEndPoint.Port"]},Description:"Redis primary endpoint port"})}else if(O==="memcached"){this.generateNetworkInfrastructure($,J);let _=A.elasticache||{},{cluster:w,subnetGroup:E,logicalId:M,subnetGroupId:T}=O$.createMemcached({slug:$,environment:J,nodeType:_.nodeType||A.nodeType||"cache.t3.micro",engineVersion:_.engineVersion||"1.6.22",numCacheNodes:_.numCacheNodes||2,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}]});if(this.builder.addResource(M,w),E&&T)this.builder.addResource(T,E);this.builder.addOutput("CacheEndpoint",{Value:{"Fn::GetAtt":[M,"ConfigurationEndpoint.Address"]},Description:"Memcached configuration endpoint address"})}}let K=this.mergedConfig.infrastructure?.email;if(K){let O=K.domain||this.mergedConfig.infrastructure?.dns?.domain;if(O){let{emailIdentity:_,logicalId:w}=H0.verifyDomain({domain:O,slug:$,environment:J,enableDkim:K.enableDkim!==!1,dkimKeyLength:K.dkimKeyLength||"RSA_2048_BIT"});if(this.builder.addResource(w,_),K.configurationSet!==!1){let{configurationSet:T,logicalId:D}=H0.createConfigurationSet({slug:$,environment:J});this.builder.addResource(D,T)}let E=K.hostedZoneId||this.mergedConfig.infrastructure?.dns?.hostedZoneId;if(E){if(K.enableDkim!==!1)for(let h=1;h<=3;h++){let I=`DkimRecord${h}${O.replace(/\./g,"")}`;this.builder.addResource(I,{Type:"AWS::Route53::RecordSet",DependsOn:[w],Properties:{HostedZoneId:E,Name:{"Fn::GetAtt":[w,`DkimDNSTokenName${h}`]},Type:"CNAME",TTL:1800,ResourceRecords:[{"Fn::GetAtt":[w,`DkimDNSTokenValue${h}`]}]}})}let{record:T,logicalId:D}=H0.createSpfRecord(O,E);this.builder.addResource(D,T);let{record:N,logicalId:x}=H0.createDmarcRecord(O,E,{policy:"none",reportingEmail:K.dmarcReportingEmail||`dmarc-reports@${O}`});this.builder.addResource(x,N)}this.builder.addOutput("EmailDomain",{Value:O,Description:"SES verified email domain"});let M=K.server;if(M?.enabled&&E){let T=this.mergedConfig.environments[J]?.region||this.mergedConfig.project.region||"us-east-1",D=`${$}-${J}-email`,{role:N,policy:x,roleLogicalId:h,policyLogicalId:I}=H0.createEmailLambdaRole({slug:$,environment:J,s3BucketArn:`arn:aws:s3:::${D}`,sesIdentityArn:`arn:aws:ses:${T}:*:identity/${O}`});this.builder.addResource(h,N),this.builder.addResource(I,x);let{function:b,permission:k,logicalId:y,permissionLogicalId:m}=H0.createInboundEmailLambda({slug:$,environment:J,roleArn:{"Fn::GetAtt":[h,"Arn"]},s3BucketName:D,organizedPrefix:"mailboxes/"});this.builder.addResource(y,b),this.builder.addResource(m,k);let l=H0.createInboundEmailSetup({slug:$,environment:J,domain:O,s3BucketName:D,s3KeyPrefix:"inbox/",region:T,hostedZoneId:E,lambdaFunctionArn:{"Fn::GetAtt":[y,"Arn"]}});for(let[r,s]of Object.entries(l.resources)){if(s.Type==="AWS::SES::ReceiptRule")s.DependsOn=[m,y];this.builder.addResource(r,s)}this.builder.addOutput("InboundEmailLambda",{Value:{Ref:y},Description:"Inbound email processing Lambda function"}),this.builder.addOutput("EmailBucket",{Value:D,Description:"S3 bucket for email storage"});let p=this.serverEipLogicalIds.get("app");if(p&&E){let s=`${M?.subdomain||"mail"}.${O}`,o=s.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(`${o}ARecord`,{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:E,Name:s,Type:"A",TTL:"300",ResourceRecords:[{Ref:p}]}})}this.builder.addOutput("MailHost",{Value:`mail.${O}`,Description:"Mail server hostname for SMTP/IMAP clients"})}}}let B=this.mergedConfig.infrastructure?.search;if(B){let O=B.vpc?{subnetIds:[{Ref:"PublicSubnet1"}],securityGroupIds:[]}:void 0;if(O)this.generateNetworkInfrastructure($,J);let{domain:_,logicalId:w}=Y2.createDomain({slug:$,environment:J,engineVersion:B.engineVersion||"OpenSearch_2.11",instanceType:B.instanceType||"t3.small.search",instanceCount:B.instanceCount||1,volumeSize:B.volumeSize||10,volumeType:B.volumeType||"gp3",dedicatedMaster:B.dedicatedMaster||!1,dedicatedMasterType:B.dedicatedMasterType,dedicatedMasterCount:B.dedicatedMasterCount||3,multiAz:B.multiAz||!1,encryption:B.encryption||{atRest:!0,nodeToNode:!0},advancedSecurity:B.advancedSecurity,autoTune:B.autoTune!==!1,vpc:O});this.builder.addResource(w,_),this.builder.addOutput("SearchDomainEndpoint",{Value:{"Fn::GetAtt":[w,"DomainEndpoint"]},Description:"OpenSearch domain endpoint"}),this.builder.addOutput("SearchDomainArn",{Value:{"Fn::GetAtt":[w,"Arn"]},Description:"OpenSearch domain ARN"})}let j=this.mergedConfig.infrastructure?.fileSystem;if(j&&Object.keys(j).length>0){this.generateNetworkInfrastructure($,J);for(let[O,_]of Object.entries(j)){let{fileSystem:w,logicalId:E}=D1.createFileSystem({slug:`${$}-${O}`,environment:J,encrypted:_.encrypted!==!1,performanceMode:_.performanceMode||"generalPurpose",throughputMode:_.throughputMode||"bursting",enableBackup:!0});this.builder.addResource(E,w);let{securityGroup:M,logicalId:T}=D1.createEfsSecurityGroup({slug:`${$}-${O}`,environment:J,vpcId:{Ref:"VPC"},sourceCidrBlocks:["10.0.0.0/16"]});this.builder.addResource(T,M);let{mountTargets:D,logicalIds:N}=D1.createMultiAzMountTargets(E,{slug:`${$}-${O}`,environment:J,subnetIds:[{Ref:"PublicSubnet1"},{Ref:"PublicSubnet2"}],securityGroupId:{Ref:T}});for(let x=0;x<D.length;x++)this.builder.addResource(N[x],D[x]);this.builder.addOutput(`${O}FileSystemId`,{Value:{Ref:E},Description:`EFS file system ID for ${O}`})}}let X=this.mergedConfig.infrastructure?.ai;if(X){let O=X.service||"ecs",_=X.models||["*"],w=X.allowStreaming!==!1,E;if(O==="ecs")E=O1.enableBedrockForEcs({slug:$,environment:J,models:_,allowStreaming:w});else if(O==="ec2")E=O1.enableBedrockForEc2({slug:$,environment:J,models:_,allowStreaming:w});else if(O==="lambda")E=O1.enableBedrockForLambda({slug:$,environment:J,models:_,allowStreaming:w});else E=O1.createBedrockRole(O,{slug:$,environment:J,models:_,allowStreaming:w});if(this.builder.addResource(E.logicalId,E.role),X.allowAsync){let{policy:M,logicalId:T}=O1.createBedrockPolicy({slug:$,environment:J,models:_,allowStreaming:w,allowAsync:!0});this.builder.addResource(T,M)}this.builder.addOutput("BedrockRoleArn",{Value:{"Fn::GetAtt":[E.logicalId,"Arn"]},Description:"IAM role ARN with Bedrock permissions"})}}generateRealtimeResources($,J){let Y=this.mergedConfig.infrastructure?.realtime;if(!Y)return;let Q=Y.name||`${$}-${J}-realtime`,Z=Y.scaling||{},U=Y.storage||{type:"dynamodb"},W=Z.handlerMemory||256,z=Z.handlerTimeout||30,G=`${$}${J}RealtimeConnections`.replace(/[^a-zA-Z0-9]/g,""),H=`${$}${J}RealtimeChannels`.replace(/[^a-zA-Z0-9]/g,"");if(U.type==="dynamodb"){let N=U.dynamodb||{},x=N.billingMode||"PAY_PER_REQUEST";this.builder.addResource(G,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$}-${J}-realtime-connections`,BillingMode:x,AttributeDefinitions:[{AttributeName:"connectionId",AttributeType:"S"},{AttributeName:"userId",AttributeType:"S"}],KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],GlobalSecondaryIndexes:[{IndexName:"userId-index",KeySchema:[{AttributeName:"userId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}},...N.pointInTimeRecovery&&{PointInTimeRecoverySpecification:{PointInTimeRecoveryEnabled:!0}},Tags:[{Key:"Name",Value:`${$}-${J}-realtime-connections`},{Key:"Environment",Value:J}]}}),this.builder.addResource(H,{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${$}-${J}-realtime-channels`,BillingMode:x,AttributeDefinitions:[{AttributeName:"channel",AttributeType:"S"},{AttributeName:"connectionId",AttributeType:"S"}],KeySchema:[{AttributeName:"channel",KeyType:"HASH"},{AttributeName:"connectionId",KeyType:"RANGE"}],GlobalSecondaryIndexes:[{IndexName:"connectionId-index",KeySchema:[{AttributeName:"connectionId",KeyType:"HASH"}],Projection:{ProjectionType:"ALL"},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}}}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0},...x==="PROVISIONED"&&{ProvisionedThroughput:{ReadCapacityUnits:N.readCapacity||5,WriteCapacityUnits:N.writeCapacity||5}},Tags:[{Key:"Name",Value:`${$}-${J}-realtime-channels`},{Key:"Environment",Value:J}]}})}let A=`${$}${J}RealtimeRole`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(A,{Type:"AWS::IAM::Role",Properties:{RoleName:`${$}-${J}-realtime-handler-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:"lambda.amazonaws.com"},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],Policies:[{PolicyName:"RealtimeHandlerPolicy",PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:["dynamodb:GetItem","dynamodb:PutItem","dynamodb:DeleteItem","dynamodb:Query","dynamodb:Scan","dynamodb:UpdateItem"],Resource:[{"Fn::GetAtt":[G,"Arn"]},{"Fn::Sub":`\${${G}.Arn}/index/*`},{"Fn::GetAtt":[H,"Arn"]},{"Fn::Sub":`\${${H}.Arn}/index/*`}]},{Effect:"Allow",Action:"execute-api:ManageConnections",Resource:{"Fn::Sub":"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*"}}]}}]}});let K=`${$}${J}RealtimeConnect`.replace(/[^a-zA-Z0-9]/g,""),B=`${$}${J}RealtimeDisconnect`.replace(/[^a-zA-Z0-9]/g,""),j=`${$}${J}RealtimeMessage`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(K,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$}-${J}-realtime-connect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[A,"Arn"]},MemorySize:W,Timeout:z,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:G},CHANNELS_TABLE:{Ref:H},ENVIRONMENT:J}},Code:{ZipFile:this.generateConnectHandlerCode()}},DependsOn:[A,G]}),this.builder.addResource(B,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$}-${J}-realtime-disconnect`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[A,"Arn"]},MemorySize:W,Timeout:z,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:G},CHANNELS_TABLE:{Ref:H},ENVIRONMENT:J}},Code:{ZipFile:this.generateDisconnectHandlerCode()}},DependsOn:[A,G,H]}),this.builder.addResource(j,{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${$}-${J}-realtime-message`,Runtime:"nodejs20.x",Handler:"index.handler",Role:{"Fn::GetAtt":[A,"Arn"]},MemorySize:W,Timeout:z,Environment:{Variables:{CONNECTIONS_TABLE:{Ref:G},CHANNELS_TABLE:{Ref:H},ENVIRONMENT:J}},Code:{ZipFile:this.generateMessageHandlerCode()}},DependsOn:[A,G,H]});let X=`${$}${J}RealtimeApi`.replace(/[^a-zA-Z0-9]/g,"");this.builder.addResource(X,{Type:"AWS::ApiGatewayV2::Api",Properties:{Name:Q,ProtocolType:"WEBSOCKET",RouteSelectionExpression:"$request.body.action",Tags:{Name:Q,Environment:J}}});let O=`${K}Permission`,_=`${B}Permission`,w=`${j}Permission`;this.builder.addResource(O,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:K},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${X}}/*/$connect`}}}),this.builder.addResource(_,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:B},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${X}}/*/$disconnect`}}}),this.builder.addResource(w,{Type:"AWS::Lambda::Permission",Properties:{FunctionName:{Ref:j},Action:"lambda:InvokeFunction",Principal:"apigateway.amazonaws.com",SourceArn:{"Fn::Sub":`arn:aws:execute-api:\${AWS::Region}:\${AWS::AccountId}:\${${X}}/*/$default`}}});let E=`${X}ConnectInteg`,M=`${X}DisconnectInteg`,T=`${X}MessageInteg`;this.builder.addResource(E,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:X},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${K}.Arn}/invocations`}}}),this.builder.addResource(M,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:X},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${B}.Arn}/invocations`}}}),this.builder.addResource(T,{Type:"AWS::ApiGatewayV2::Integration",Properties:{ApiId:{Ref:X},IntegrationType:"AWS_PROXY",IntegrationUri:{"Fn::Sub":`arn:aws:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/\${${j}.Arn}/invocations`}}}),this.builder.addResource(`${X}ConnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:X},RouteKey:"$connect",AuthorizationType:"NONE",Target:{"Fn::Sub":`integrations/\${${E}}`}}}),this.builder.addResource(`${X}DisconnectRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:X},RouteKey:"$disconnect",Target:{"Fn::Sub":`integrations/\${${M}}`}}}),this.builder.addResource(`${X}DefaultRoute`,{Type:"AWS::ApiGatewayV2::Route",Properties:{ApiId:{Ref:X},RouteKey:"$default",Target:{"Fn::Sub":`integrations/\${${T}}`}}});let D=`${X}Stage`;if(this.builder.addResource(D,{Type:"AWS::ApiGatewayV2::Stage",Properties:{ApiId:{Ref:X},StageName:J,AutoDeploy:!0,DefaultRouteSettings:{ThrottlingBurstLimit:Z.messagesPerSecond||1000,ThrottlingRateLimit:Z.messagesPerSecond||1000}}}),Y.monitoring?.enabled){let N=Y.monitoring,x=N.notificationTopicArn;if(!x&&N.notificationEmails?.length){let h=`${X}AlarmTopic`;this.builder.addResource(h,{Type:"AWS::SNS::Topic",Properties:{TopicName:`${$}-${J}-realtime-alarms`,DisplayName:"Realtime WebSocket Alarms"}}),N.notificationEmails.forEach((I,b)=>{this.builder.addResource(`${h}Sub${b}`,{Type:"AWS::SNS::Subscription",Properties:{TopicArn:{Ref:h},Protocol:"email",Endpoint:I}})}),x={Ref:h}}if(N.connectionThreshold)this.builder.addResource(`${X}ConnectionAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-realtime-connections`,AlarmDescription:`WebSocket connections exceed ${N.connectionThreshold}`,MetricName:"ConnectCount",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:300,EvaluationPeriods:2,Threshold:N.connectionThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:X}}],...x&&{AlarmActions:[x]}}});if(N.errorThreshold)this.builder.addResource(`${X}ErrorAlarm`,{Type:"AWS::CloudWatch::Alarm",Properties:{AlarmName:`${$}-${J}-realtime-errors`,AlarmDescription:`WebSocket errors exceed ${N.errorThreshold}/min`,MetricName:"ExecutionError",Namespace:"AWS/ApiGateway",Statistic:"Sum",Period:60,EvaluationPeriods:3,Threshold:N.errorThreshold,ComparisonOperator:"GreaterThanThreshold",Dimensions:[{Name:"ApiId",Value:{Ref:X}}],...x&&{AlarmActions:[x]}}})}this.builder.addOutput(`${X}Endpoint`,{Description:"WebSocket API endpoint URL",Value:{"Fn::Sub":`wss://\${${X}}.execute-api.\${AWS::Region}.amazonaws.com/${J}`},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-endpoint"}}}),this.builder.addOutput(`${X}Id`,{Description:"WebSocket API ID",Value:{Ref:X},Export:{Name:{"Fn::Sub":"${AWS::StackName}-realtime-api-id"}}})}generateConnectHandlerCode(){return`
7327
7327
  const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
7328
7328
  const { DynamoDBDocumentClient, PutCommand } = require('@aws-sdk/lib-dynamodb');
7329
7329
 
@@ -7537,25 +7537,25 @@ Next steps:
7537
7537
  1. Review the generated templates in ${Z}/
7538
7538
  2. Run 'cloud deploy' to deploy your infrastructure`)}catch(Q){Y.fail("Failed to generate templates"),R(Q instanceof Error?Q.message:"Unknown error")}}),$.command("generate:preview","Preview what will be generated").action(async()=>{V("Template Preview"),F("This command will show a preview of generated templates")}),$.command("diff","Show diff between local config and deployed stack").alias("generate:diff").option("--stack <name>","Stack name to compare against").option("--env <environment>","Environment (production, staging, development)").action(async(J)=>{V("Infrastructure Diff");try{let Y=await c(),Q=J?.env||"production",{resolveProjectStackName:Z}=await Z2().then(() => MZ),U=J?.stack||Z(Y,Q),W=Y.project.region||"us-east-1";F(`Stack: ${U}`),F(`Region: ${W}`),F(`Environment: ${Q}`),i("Generating template from configuration...");let z=new c2({config:Y,environment:Q});z.generate();let G=z.toJSON(),H=JSON.parse(G);i("Fetching deployed template...");let A=new O0(W),K=null;try{let M=await A.getTemplate(U);if(M.TemplateBody)K=JSON.parse(M.TemplateBody)}catch(M){if(M.message?.includes("does not exist")){g(`Stack "${U}" does not exist yet`),F(`
7539
7539
  This will be a new deployment with the following resources:`);let T=Object.keys(H.Resources||{}).length;F(`
7540
- Resources to create: ${T}`);let D={};for(let N of Object.values(H.Resources||{})){let x=N.Type;D[x]=(D[x]||0)+1}for(let[N,x]of Object.entries(D).sort((h,k)=>k[1]-h[1]))F(` + ${N}: ${x}`);F("\nRun `cloud deploy` to create this stack");return}throw M}i("Comparing templates...");let B=K.Resources||{},j=H.Resources||{},X=new Set(Object.keys(B)),O=new Set(Object.keys(j)),_=[];for(let M of O)if(!X.has(M))_.push(M);let w=[];for(let M of X)if(!O.has(M))w.push(M);let E=[];for(let M of O)if(X.has(M)){let T=JSON.stringify(B[M]),D=JSON.stringify(j[M]);if(T!==D)E.push(M)}if(_.length===0&&w.length===0&&E.length===0){C(`
7540
+ Resources to create: ${T}`);let D={};for(let N of Object.values(H.Resources||{})){let x=N.Type;D[x]=(D[x]||0)+1}for(let[N,x]of Object.entries(D).sort((h,I)=>I[1]-h[1]))F(` + ${N}: ${x}`);F("\nRun `cloud deploy` to create this stack");return}throw M}i("Comparing templates...");let B=K.Resources||{},j=H.Resources||{},X=new Set(Object.keys(B)),O=new Set(Object.keys(j)),_=[];for(let M of O)if(!X.has(M))_.push(M);let w=[];for(let M of X)if(!O.has(M))w.push(M);let E=[];for(let M of O)if(X.has(M)){let T=JSON.stringify(B[M]),D=JSON.stringify(j[M]);if(T!==D)E.push(M)}if(_.length===0&&w.length===0&&E.length===0){C(`
7541
7541
  No changes detected - infrastructure is up to date`);return}if(F(`
7542
7542
  Changes detected:
7543
- `),_.length>0){C(`Resources to add (${_.length}):`);for(let M of _){let T=j[M].Type;F(` + ${M} (${T})`)}console.log()}if(w.length>0){R(`Resources to remove (${w.length}):`);for(let M of w){let T=B[M].Type;F(` - ${M} (${T})`)}console.log()}if(E.length>0){g(`Resources to modify (${E.length}):`);for(let M of E){let T=j[M].Type;F(` ~ ${M} (${T})`)}console.log()}F("Summary:"),F(` - Add: ${_.length}`),F(` - Remove: ${w.length}`),F(` - Modify: ${E.length}`),F("\nRun `cloud deploy` to apply these changes")}catch(Y){R(`Diff failed: ${Y.message}`)}})}function s7($){$.command("server:list","List all servers").action(async()=>{V("Listing Servers"),d(["Name","Instance ID","Type","Status","AZ"],[["web-1","i-1234567890abcdef0","t3.micro","running","us-east-1a"],["web-2","i-0987654321fedcba0","t3.micro","running","us-east-1b"]])}),$.command("server:create <name>","Create a new server").option("--type <type>","Instance type (e.g., t3.micro)",{default:"t3.micro"}).option("--ami <ami>","AMI ID").action(async(J,Y)=>{V(`Creating Server: ${J}`);let Q=new L(`Creating server ${J}...`);Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed(`Server ${J} created successfully`),F(`Instance type: ${Y?.type||"t3.micro"}`)}),$.command("server:ssh <name>","SSH into a server").action(async(J)=>{i(`Connecting to ${J}...`)}),$.command("server:logs <name>","View server logs").option("--tail","Tail logs in real-time").action(async(J)=>{V(`Logs for ${J}`)}),$.command("server:deploy <name>","Deploy app to server").option("--strategy <strategy>","Deployment strategy: git, rsync, or scp").action(async(J)=>{V(`Deploying to ${J}`)}),$.command("server:resize <name> <type>","Change server instance type").action(async(J,Y)=>{if(V(`Resizing Server: ${J}`),!await y(`This will stop and restart ${J}. Continue?`,!1)){F("Resize cancelled");return}let Z=new L(`Resizing ${J} to ${Y}...`);Z.start();try{await new Promise((U)=>setTimeout(U,2000)),Z.succeed(`Server ${J} resized to ${Y}`),C(`Instance type changed from t3.micro to ${Y}`)}catch(U){Z.fail("Resize failed"),R(U.message)}}),$.command("server:reboot <name>","Reboot a server").option("--force","Force reboot without confirmation").action(async(J,Y)=>{if(V(`Rebooting Server: ${J}`),!Y?.force){if(!await y(`Are you sure you want to reboot ${J}?`,!1)){F("Reboot cancelled");return}}let Q=new L(`Rebooting ${J}...`);Q.start();try{await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed(`Server ${J} rebooted successfully`),F("Server will be available in a few moments")}catch(Z){Q.fail("Reboot failed"),R(Z.message)}}),$.command("server:destroy <name>","Terminate a server").option("--force","Skip confirmation prompt").action(async(J,Y)=>{if(V(`Destroying Server: ${J}`),L1("This action is irreversible!"),!Y?.force){if(!await y(`Are you absolutely sure you want to terminate ${J}?`,!1)){F("Termination cancelled");return}if(!await y(`Type the server name to confirm: ${J}`,!1)){F("Termination cancelled");return}}let Q=new L(`Terminating ${J}...`);Q.start();try{await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed(`Server ${J} terminated successfully`),C("All resources have been cleaned up")}catch(Z){Q.fail("Termination failed"),R(Z.message)}}),$.command("server:recipe <name> <recipe>","Install software recipe").action(async(J,Y)=>{V(`Installing Recipe: ${Y}`);let Q=["lamp","lemp","nodejs","python","ruby","docker"];if(!Q.includes(Y.toLowerCase()))g(`Unknown recipe. Common recipes: ${Q.join(", ")}`);if(F(`Server: ${J}`),F(`Recipe: ${Y}`),!await y(`
7543
+ `),_.length>0){C(`Resources to add (${_.length}):`);for(let M of _){let T=j[M].Type;F(` + ${M} (${T})`)}console.log()}if(w.length>0){R(`Resources to remove (${w.length}):`);for(let M of w){let T=B[M].Type;F(` - ${M} (${T})`)}console.log()}if(E.length>0){g(`Resources to modify (${E.length}):`);for(let M of E){let T=j[M].Type;F(` ~ ${M} (${T})`)}console.log()}F("Summary:"),F(` - Add: ${_.length}`),F(` - Remove: ${w.length}`),F(` - Modify: ${E.length}`),F("\nRun `cloud deploy` to apply these changes")}catch(Y){R(`Diff failed: ${Y.message}`)}})}function s7($){$.command("server:list","List all servers").action(async()=>{V("Listing Servers"),d(["Name","Instance ID","Type","Status","AZ"],[["web-1","i-1234567890abcdef0","t3.micro","running","us-east-1a"],["web-2","i-0987654321fedcba0","t3.micro","running","us-east-1b"]])}),$.command("server:create <name>","Create a new server").option("--type <type>","Instance type (e.g., t3.micro)",{default:"t3.micro"}).option("--ami <ami>","AMI ID").action(async(J,Y)=>{V(`Creating Server: ${J}`);let Q=new L(`Creating server ${J}...`);Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed(`Server ${J} created successfully`),F(`Instance type: ${Y?.type||"t3.micro"}`)}),$.command("server:ssh <name>","SSH into a server").action(async(J)=>{i(`Connecting to ${J}...`)}),$.command("server:logs <name>","View server logs").option("--tail","Tail logs in real-time").action(async(J)=>{V(`Logs for ${J}`)}),$.command("server:deploy <name>","Deploy app to server").option("--strategy <strategy>","Deployment strategy: git, rsync, or scp").action(async(J)=>{V(`Deploying to ${J}`)}),$.command("server:resize <name> <type>","Change server instance type").action(async(J,Y)=>{if(V(`Resizing Server: ${J}`),!await v(`This will stop and restart ${J}. Continue?`,!1)){F("Resize cancelled");return}let Z=new L(`Resizing ${J} to ${Y}...`);Z.start();try{await new Promise((U)=>setTimeout(U,2000)),Z.succeed(`Server ${J} resized to ${Y}`),C(`Instance type changed from t3.micro to ${Y}`)}catch(U){Z.fail("Resize failed"),R(U.message)}}),$.command("server:reboot <name>","Reboot a server").option("--force","Force reboot without confirmation").action(async(J,Y)=>{if(V(`Rebooting Server: ${J}`),!Y?.force){if(!await v(`Are you sure you want to reboot ${J}?`,!1)){F("Reboot cancelled");return}}let Q=new L(`Rebooting ${J}...`);Q.start();try{await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed(`Server ${J} rebooted successfully`),F("Server will be available in a few moments")}catch(Z){Q.fail("Reboot failed"),R(Z.message)}}),$.command("server:destroy <name>","Terminate a server").option("--force","Skip confirmation prompt").action(async(J,Y)=>{if(V(`Destroying Server: ${J}`),L1("This action is irreversible!"),!Y?.force){if(!await v(`Are you absolutely sure you want to terminate ${J}?`,!1)){F("Termination cancelled");return}if(!await v(`Type the server name to confirm: ${J}`,!1)){F("Termination cancelled");return}}let Q=new L(`Terminating ${J}...`);Q.start();try{await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed(`Server ${J} terminated successfully`),C("All resources have been cleaned up")}catch(Z){Q.fail("Termination failed"),R(Z.message)}}),$.command("server:recipe <name> <recipe>","Install software recipe").action(async(J,Y)=>{V(`Installing Recipe: ${Y}`);let Q=["lamp","lemp","nodejs","python","ruby","docker"];if(!Q.includes(Y.toLowerCase()))g(`Unknown recipe. Common recipes: ${Q.join(", ")}`);if(F(`Server: ${J}`),F(`Recipe: ${Y}`),!await v(`
7544
7544
  Install this recipe?`,!0)){F("Operation cancelled");return}let U=new L(`Installing ${Y} stack...`);U.start(),await new Promise((W)=>setTimeout(W,5000)),U.succeed("Recipe installed successfully"),C(`
7545
- Software stack installed!`),F(`Server ${J} is now running ${Y}`)}),$.command("server:cron:add <name> <schedule> <command>","Add cron job to server").action(async(J,Y,Q)=>{if(V("Adding Cron Job"),F(`Server: ${J}`),F(`Schedule: ${Y}`),F(`Command: ${Q}`),!await y(`
7545
+ Software stack installed!`),F(`Server ${J} is now running ${Y}`)}),$.command("server:cron:add <name> <schedule> <command>","Add cron job to server").action(async(J,Y,Q)=>{if(V("Adding Cron Job"),F(`Server: ${J}`),F(`Schedule: ${Y}`),F(`Command: ${Q}`),!await v(`
7546
7546
  Add this cron job?`,!0)){F("Operation cancelled");return}let U=new L("Adding cron job...");U.start(),await new Promise((W)=>setTimeout(W,2000)),U.succeed("Cron job added"),C(`
7547
- Cron job created!`),F("Job ID: cron-abc123")}),$.command("server:cron:list <name>","List cron jobs on server").action(async(J)=>{V(`Cron Jobs on ${J}`);let Y=new L("Fetching cron jobs...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["ID","Schedule","Command","Last Run","Status"],[["cron-1","0 2 * * *","backup-db.sh","2h ago","Success"],["cron-2","*/15 * * * *","sync-files.sh","10m ago","Success"],["cron-3","0 0 * * 0","weekly-report.sh","2d ago","Success"]])}),$.command("server:cron:remove <name> <id>","Remove cron job").action(async(J,Y)=>{if(V("Removing Cron Job"),F(`Server: ${J}`),F(`Job ID: ${Y}`),!await y(`
7547
+ Cron job created!`),F("Job ID: cron-abc123")}),$.command("server:cron:list <name>","List cron jobs on server").action(async(J)=>{V(`Cron Jobs on ${J}`);let Y=new L("Fetching cron jobs...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["ID","Schedule","Command","Last Run","Status"],[["cron-1","0 2 * * *","backup-db.sh","2h ago","Success"],["cron-2","*/15 * * * *","sync-files.sh","10m ago","Success"],["cron-3","0 0 * * 0","weekly-report.sh","2d ago","Success"]])}),$.command("server:cron:remove <name> <id>","Remove cron job").action(async(J,Y)=>{if(V("Removing Cron Job"),F(`Server: ${J}`),F(`Job ID: ${Y}`),!await v(`
7548
7548
  Remove this cron job?`,!0)){F("Operation cancelled");return}let Z=new L("Removing cron job...");Z.start(),await new Promise((U)=>setTimeout(U,1500)),Z.succeed("Cron job removed"),C(`
7549
- Cron job deleted!`)}),$.command("server:worker:add <name> <queue>","Add background worker").option("--processes <count>","Number of worker processes",{default:"1"}).action(async(J,Y,Q)=>{let Z=Q?.processes||"1";if(V("Adding Background Worker"),F(`Server: ${J}`),F(`Queue: ${Y}`),F(`Processes: ${Z}`),!await y(`
7549
+ Cron job deleted!`)}),$.command("server:worker:add <name> <queue>","Add background worker").option("--processes <count>","Number of worker processes",{default:"1"}).action(async(J,Y,Q)=>{let Z=Q?.processes||"1";if(V("Adding Background Worker"),F(`Server: ${J}`),F(`Queue: ${Y}`),F(`Processes: ${Z}`),!await v(`
7550
7550
  Add this worker?`,!0)){F("Operation cancelled");return}let W=new L("Configuring worker process...");W.start(),await new Promise((z)=>setTimeout(z,2000)),W.succeed("Worker configured"),C(`
7551
7551
  Background worker added!`),F("Worker ID: worker-abc123")}),$.command("server:worker:list <name>","List workers on server").action(async(J)=>{V(`Workers on ${J}`);let Y=new L("Fetching workers...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["ID","Queue","Processes","Status","Uptime"],[["worker-1","emails","2","Running","5d 3h"],["worker-2","images","4","Running","2d 8h"],["worker-3","reports","1","Stopped","-"]])}),$.command("server:worker:restart <name> <id>","Restart worker").action(async(J,Y)=>{V("Restarting Worker"),F(`Server: ${J}`),F(`Worker ID: ${Y}`);let Q=new L("Restarting worker process...");Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed("Worker restarted"),C(`
7552
- Worker restarted successfully!`)}),$.command("server:worker:remove <name> <id>","Remove worker").action(async(J,Y)=>{if(V("Removing Worker"),F(`Server: ${J}`),F(`Worker ID: ${Y}`),!await y(`
7552
+ Worker restarted successfully!`)}),$.command("server:worker:remove <name> <id>","Remove worker").action(async(J,Y)=>{if(V("Removing Worker"),F(`Server: ${J}`),F(`Worker ID: ${Y}`),!await v(`
7553
7553
  Remove this worker?`,!0)){F("Operation cancelled");return}let Z=new L("Removing worker...");Z.start(),await new Promise((U)=>setTimeout(U,1500)),Z.succeed("Worker removed"),C(`
7554
- Worker deleted!`)}),$.command("server:firewall:add <name> <rule>","Add firewall rule").action(async(J,Y)=>{if(V("Adding Firewall Rule"),F(`Server: ${J}`),F(`Rule: ${Y}`),!await y(`
7554
+ Worker deleted!`)}),$.command("server:firewall:add <name> <rule>","Add firewall rule").action(async(J,Y)=>{if(V("Adding Firewall Rule"),F(`Server: ${J}`),F(`Rule: ${Y}`),!await v(`
7555
7555
  Add this firewall rule?`,!0)){F("Operation cancelled");return}let Z=new L("Updating firewall rules (ufw)...");Z.start(),await new Promise((U)=>setTimeout(U,2000)),Z.succeed("Firewall rule added"),C(`
7556
- Firewall rule configured!`)}),$.command("server:firewall:list <name>","List firewall rules").action(async(J)=>{V(`Firewall Rules on ${J}`);let Y=new L("Fetching firewall rules...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["#","Action","From","To","Port","Protocol"],[["1","ALLOW","Anywhere","22/tcp","22","TCP"],["2","ALLOW","Anywhere","80/tcp","80","TCP"],["3","ALLOW","Anywhere","443/tcp","443","TCP"],["4","DENY","192.168.1.0/24","Any","Any","Any"]])}),$.command("server:firewall:remove <name> <rule>","Remove firewall rule").action(async(J,Y)=>{if(V("Removing Firewall Rule"),F(`Server: ${J}`),F(`Rule: ${Y}`),!await y(`
7556
+ Firewall rule configured!`)}),$.command("server:firewall:list <name>","List firewall rules").action(async(J)=>{V(`Firewall Rules on ${J}`);let Y=new L("Fetching firewall rules...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["#","Action","From","To","Port","Protocol"],[["1","ALLOW","Anywhere","22/tcp","22","TCP"],["2","ALLOW","Anywhere","80/tcp","80","TCP"],["3","ALLOW","Anywhere","443/tcp","443","TCP"],["4","DENY","192.168.1.0/24","Any","Any","Any"]])}),$.command("server:firewall:remove <name> <rule>","Remove firewall rule").action(async(J,Y)=>{if(V("Removing Firewall Rule"),F(`Server: ${J}`),F(`Rule: ${Y}`),!await v(`
7557
7557
  Remove this firewall rule?`,!0)){F("Operation cancelled");return}let Z=new L("Updating firewall rules...");Z.start(),await new Promise((U)=>setTimeout(U,1500)),Z.succeed("Firewall rule removed"),C(`
7558
- Firewall rule deleted!`)}),$.command("server:ssl:install <domain>","Install Let's Encrypt certificate").action(async(J)=>{if(V(`Installing SSL Certificate for ${J}`),!await y(`
7558
+ Firewall rule deleted!`)}),$.command("server:ssl:install <domain>","Install Let's Encrypt certificate").action(async(J)=>{if(V(`Installing SSL Certificate for ${J}`),!await v(`
7559
7559
  Install Let's Encrypt certificate?`,!0)){F("Operation cancelled");return}let Q=new L("Installing certbot and obtaining certificate...");Q.start(),await new Promise((Z)=>setTimeout(Z,3000)),Q.succeed("SSL certificate installed"),C(`
7560
7560
  SSL certificate active!`),F(`HTTPS enabled for ${J}`),F("Auto-renewal configured via cron")}),$.command("server:ssl:renew <domain>","Renew SSL certificate").action(async(J)=>{V(`Renewing SSL Certificate for ${J}`);let Y=new L("Renewing certificate...");Y.start(),await new Promise((Q)=>setTimeout(Q,2000)),Y.succeed("Certificate renewed"),C(`
7561
7561
  SSL certificate renewed!`),F(`Valid until: ${new Date(Date.now()+7776000000).toLocaleDateString()}`)}),$.command("server:monitoring <name>","Show server metrics").action(async(J)=>{V(`Server Metrics: ${J}`);let Y=new L("Fetching metrics from CloudWatch...");Y.start(),await new Promise((Q)=>setTimeout(Q,2000)),Y.stop(),F(`
@@ -7563,13 +7563,13 @@ Current Metrics:
7563
7563
  `),F("CPU Usage:"),F(" - Current: 23.5%"),F(" - Average (1h): 18.2%"),F(" - Peak (24h): 67.3%"),F(`
7564
7564
  Memory Usage:`),F(" - Used: 2.1 GB / 4 GB (52.5%)"),F(" - Available: 1.9 GB"),F(" - Swap: 0 GB"),F(`
7565
7565
  Disk Usage:`),F(" - /: 15.2 GB / 30 GB (50.7%)"),F(" - /data: 45.8 GB / 100 GB (45.8%)"),F(`
7566
- Network:`),F(" - In: 125 MB/s"),F(" - Out: 87 MB/s")}),$.command("server:snapshot <name>","Create server snapshot").action(async(J)=>{if(V(`Creating Snapshot of ${J}`),!await y(`
7566
+ Network:`),F(" - In: 125 MB/s"),F(" - Out: 87 MB/s")}),$.command("server:snapshot <name>","Create server snapshot").action(async(J)=>{if(V(`Creating Snapshot of ${J}`),!await v(`
7567
7567
  Create snapshot? This may take several minutes.`,!0)){F("Operation cancelled");return}let Q=new L("Creating EBS snapshot...");Q.start(),await new Promise((Z)=>setTimeout(Z,3000)),Q.succeed("Snapshot created"),C(`
7568
7568
  Server snapshot created!`),F("Snapshot ID: snap-abc123"),F("Use `cloud server:snapshot:restore` to restore from this snapshot")}),$.command("server:snapshot:restore <name> <snapshot-id>","Restore from snapshot").action(async(J,Y)=>{if(V("Restoring from Snapshot"),F(`Server: ${J}`),F(`Snapshot: ${Y}`),g(`
7569
- This will replace the current server data`),!await y("Proceed with restore?",!1)){F("Operation cancelled");return}let Z=new L("Restoring from snapshot...");Z.start(),await new Promise((U)=>setTimeout(U,4000)),Z.succeed("Restore complete"),C(`
7570
- Server restored from snapshot!`),g("Reboot required to complete restoration")}),$.command("server:update <name>","Update server packages").action(async(J)=>{if(V(`Updating Packages on ${J}`),!await y(`
7569
+ This will replace the current server data`),!await v("Proceed with restore?",!1)){F("Operation cancelled");return}let Z=new L("Restoring from snapshot...");Z.start(),await new Promise((U)=>setTimeout(U,4000)),Z.succeed("Restore complete"),C(`
7570
+ Server restored from snapshot!`),g("Reboot required to complete restoration")}),$.command("server:update <name>","Update server packages").action(async(J)=>{if(V(`Updating Packages on ${J}`),!await v(`
7571
7571
  Update all packages?`,!0)){F("Operation cancelled");return}let Q=new L("Running apt update && apt upgrade...");Q.start(),await new Promise((Z)=>setTimeout(Z,5000)),Q.succeed("Packages updated"),C(`
7572
- Server packages updated!`),F("Updated: 45 packages"),g("Reboot recommended")}),$.command("server:secure <name>","Run security hardening script").action(async(J)=>{if(V(`Securing Server: ${J}`),!await y(`
7572
+ Server packages updated!`),F("Updated: 45 packages"),g("Reboot recommended")}),$.command("server:secure <name>","Run security hardening script").action(async(J)=>{if(V(`Securing Server: ${J}`),!await v(`
7573
7573
  Run security hardening? This will:
7574
7574
  - Configure firewall
7575
7575
  - Disable root login
@@ -7596,25 +7596,25 @@ Verification details:`),F(` - Provider: ${Z}`),F(` - DNS records found: ${G.le
7596
7596
  Record summary:`);for(let[j,X]of B)F(` - ${j}: ${X}`)}}catch(Q){R(`Failed to verify domain: ${Q instanceof Error?Q.message:String(Q)}`)}}),$.command("dns:records <domain>","List DNS records for a domain").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").option("--type <type>","Filter by record type (A, AAAA, CNAME, TXT, MX, etc.)").action(async(J,Y)=>{V(`DNS Records for ${J}`);try{let Q=o1(Y?.provider),Z=H1(Y?.provider)?.provider||"unknown",U=new L(`Fetching records from ${Z}...`);U.start();let z=(await Q.listRecords(J)).records||[];if(U.succeed(`Found ${z.length} record(s)`),Y?.type){let H=Y.type.toUpperCase();z=z.filter((A)=>A.type.toUpperCase()===H),F(`Filtered to ${z.length} ${H} record(s)`)}if(z.length===0){F("No records found");return}let G=z.map((H)=>[H.type,H.name||"@",H.content.length>50?`${H.content.substring(0,47)}...`:H.content,String(H.ttl||300)]);d(["Type","Name","Value","TTL"],G)}catch(Q){R(`Failed to list records: ${Q instanceof Error?Q.message:String(Q)}`)}}),$.command("dns:add <domain> <type> <value>","Add DNS record").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").option("--name <name>","Record name (subdomain)",{default:"@"}).option("--ttl <seconds>","Time to live in seconds",{default:"300"}).action(async(J,Y,Q,Z)=>{V("Adding DNS Record");try{let U=o1(Z?.provider),W=H1(Z?.provider)?.provider||"unknown",z=Z?.name||"@",G=Number.parseInt(Z?.ttl||"300",10),H=Y.toUpperCase();F(`Provider: ${W}`),F(`Domain: ${J}`),F(`Type: ${H}`),F(`Name: ${z}`),F(`Value: ${Q}`),F(`TTL: ${G}`);let A=new L(`Adding record via ${W}...`);A.start(),await U.createRecord(J,{type:H,name:z==="@"?"":z,content:Q,ttl:G}),A.succeed("DNS record added successfully"),C(`
7597
7597
  Record created!`),F(`
7598
7598
  Note: DNS changes may take a few minutes to propagate`)}catch(U){R(`Failed to add record: ${U instanceof Error?U.message:String(U)}`)}}),$.command("dns:delete <domain> <type>","Delete DNS record").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").option("--name <name>","Record name (subdomain)",{default:"@"}).option("--value <value>","Record value (required for multi-value records)").action(async(J,Y,Q)=>{V("Deleting DNS Record");try{let Z=o1(Q?.provider),U=H1(Q?.provider)?.provider||"unknown",W=Q?.name||"@",z=Y.toUpperCase();F(`Provider: ${U}`),F(`Domain: ${J}`),F(`Type: ${z}`),F(`Name: ${W}`);let G=new L("Finding record...");G.start();let K=((await Z.listRecords(J)).records||[]).filter((X)=>X.type.toUpperCase()===z&&(X.name===W||X.name===""&&W==="@"));if(K.length===0){G.fail("No matching record found");return}if(K.length>1&&!Q?.value){G.warn("Multiple records found"),F(`
7599
- Please specify --value to identify which record to delete:`);for(let X of K)F(` - ${X.content}`);return}let B=Q?.value?K.find((X)=>X.content===Q.value)||K[0]:K[0];if(F(`Value: ${B.content}`),!await y("Delete this record?",!1)){F("Deletion cancelled");return}G.text=`Deleting record via ${U}...`,G.start(),await Z.deleteRecord(J,B),G.succeed("DNS record deleted successfully"),C(`
7599
+ Please specify --value to identify which record to delete:`);for(let X of K)F(` - ${X.content}`);return}let B=Q?.value?K.find((X)=>X.content===Q.value)||K[0]:K[0];if(F(`Value: ${B.content}`),!await v("Delete this record?",!1)){F("Deletion cancelled");return}G.text=`Deleting record via ${U}...`,G.start(),await Z.deleteRecord(J,B),G.succeed("DNS record deleted successfully"),C(`
7600
7600
  Record deleted!`)}catch(Z){R(`Failed to delete record: ${Z instanceof Error?Z.message:String(Z)}`)}})}function J5($){$.command("db:list","List all databases").action(async()=>{V("Databases"),d(["Name","Engine","Instance Type","Status","Storage"],[["production-db","PostgreSQL 15","db.t3.micro","available","20 GB"],["staging-db","PostgreSQL 15","db.t3.micro","available","20 GB"]])}),$.command("db:create <name>","Create a new database").option("--engine <engine>","Database engine: postgres, mysql, or dynamodb").option("--size <size>","Instance size (e.g., db.t3.micro)").action(async(J,Y)=>{V(`Creating Database: ${J}`);let Q=Y?.engine||"postgres",Z=Y?.size||"db.t3.micro",U=new L(`Creating ${Q} database...`);U.start(),await new Promise((W)=>setTimeout(W,3000)),U.succeed(`Database ${J} created successfully`),F(`Engine: ${Q}`),F(`Size: ${Z}`)}),$.command("db:backup <name>","Create database backup").action(async(J)=>{V(`Backing up ${J}`);let Y=new L("Creating snapshot...");Y.start(),await new Promise((Q)=>setTimeout(Q,2000)),Y.succeed("Backup created successfully")}),$.command("db:connect <name>","Get connection details").action(async(J)=>{V(`Connection Details for ${J}`),F("Host: my-db.xxxxx.us-east-1.rds.amazonaws.com"),F("Port: 5432"),F("Database: postgres"),g("Get password from AWS Secrets Manager")}),$.command("db:restore <name> <backup-id>","Restore database from backup").option("--new-name <name>","Name for restored database").action(async(J,Y,Q)=>{V(`Restoring Database: ${J}`);let Z=Q?.newName||`${J}-restored-${Date.now()}`;if(F(`Source: ${J}`),F(`Backup ID: ${Y}`),F(`Target: ${Z}`),L1(`
7601
- This will create a new database instance from the backup.`),!await y("Continue with restore?",!1)){F("Restore cancelled");return}let W=new L("Restoring from snapshot...");W.start(),await new Promise((z)=>setTimeout(z,3000)),W.succeed("Database restore initiated"),C(`
7601
+ This will create a new database instance from the backup.`),!await v("Continue with restore?",!1)){F("Restore cancelled");return}let W=new L("Restoring from snapshot...");W.start(),await new Promise((z)=>setTimeout(z,3000)),W.succeed("Database restore initiated"),C(`
7602
7602
  Restore started!`),F(`
7603
7603
  The new database will be available in a few minutes`),F(`New instance: ${Z}`)}),$.command("db:tunnel <name>","Create SSH tunnel to database").option("--local-port <port>","Local port for tunnel",{default:"5432"}).action(async(J,Y)=>{V(`Creating SSH Tunnel to ${J}`);let Q=Y?.localPort||"5432";F(`Database: ${J}`),F(`Local port: ${Q}`);let Z=new L("Establishing SSH tunnel...");Z.start(),await new Promise((U)=>setTimeout(U,2000)),Z.succeed("SSH tunnel established"),C(`
7604
7604
  Tunnel active!`),F(`
7605
7605
  Connection details:`),F(" Host: localhost"),F(` Port: ${Q}`),F(" Database: postgres"),F(`
7606
- Press Ctrl+C to close the tunnel`)}),$.command("db:migrations:run <name>","Run database migrations").action(async(J)=>{if(V(`Running Migrations for ${J}`),!await y(`
7606
+ Press Ctrl+C to close the tunnel`)}),$.command("db:migrations:run <name>","Run database migrations").action(async(J)=>{if(V(`Running Migrations for ${J}`),!await v(`
7607
7607
  Run pending migrations?`,!0)){F("Operation cancelled");return}let Q=new L("Running migrations...");Q.start(),await new Promise((Z)=>setTimeout(Z,3000)),Q.succeed("Migrations complete"),C(`
7608
7608
  Migrations applied!`),F("Executed: 3 migrations"),F(" - 20241101_add_users_table"),F(" - 20241102_add_email_column"),F(" - 20241103_create_indexes")}),$.command("db:migrations:rollback <name>","Rollback last migration").action(async(J)=>{if(V(`Rolling Back Migration for ${J}`),g(`
7609
- This will revert the last migration`),!await y("Rollback last migration?",!1)){F("Operation cancelled");return}let Q=new L("Rolling back migration...");Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed("Rollback complete"),C(`
7609
+ This will revert the last migration`),!await v("Rollback last migration?",!1)){F("Operation cancelled");return}let Q=new L("Rolling back migration...");Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed("Rollback complete"),C(`
7610
7610
  Migration rolled back!`),F("Reverted: 20241103_create_indexes")}),$.command("db:migrations:status <name>","Show migration status").action(async(J)=>{V(`Migration Status for ${J}`);let Y=new L("Fetching migration status...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["Migration","Status","Executed"],[["20241101_add_users_table","Applied","2024-11-01 10:30"],["20241102_add_email_column","Applied","2024-11-02 15:45"],["20241103_create_indexes","Applied","2024-11-03 09:15"],["20241104_add_timestamps","Pending","-"]]),F(`
7611
7611
  Summary: 3 applied, 1 pending`)}),$.command("db:seed <name>","Seed database with test data").action(async(J)=>{if(V(`Seeding Database: ${J}`),g(`
7612
- This will add test/sample data`),!await y("Seed database?",!0)){F("Operation cancelled");return}let Q=new L("Running database seeders...");Q.start(),await new Promise((Z)=>setTimeout(Z,3000)),Q.succeed("Seeding complete"),C(`
7613
- Database seeded!`),F("Added:"),F(" - 100 users"),F(" - 500 products"),F(" - 1,000 orders")}),$.command("db:snapshot <name>","Create database snapshot").action(async(J)=>{if(V(`Creating Snapshot of ${J}`),!await y(`
7612
+ This will add test/sample data`),!await v("Seed database?",!0)){F("Operation cancelled");return}let Q=new L("Running database seeders...");Q.start(),await new Promise((Z)=>setTimeout(Z,3000)),Q.succeed("Seeding complete"),C(`
7613
+ Database seeded!`),F("Added:"),F(" - 100 users"),F(" - 500 products"),F(" - 1,000 orders")}),$.command("db:snapshot <name>","Create database snapshot").action(async(J)=>{if(V(`Creating Snapshot of ${J}`),!await v(`
7614
7614
  Create snapshot?`,!0)){F("Operation cancelled");return}let Q=new L("Creating RDS snapshot...");Q.start(),await new Promise((Z)=>setTimeout(Z,3000)),Q.succeed("Snapshot created"),C(`
7615
- Database snapshot created!`),F("Snapshot ID: snap-db-abc123")}),$.command("db:snapshot:list <name>","List snapshots").action(async(J)=>{V(`Snapshots for ${J}`);let Y=new L("Fetching snapshots...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["Snapshot ID","Created","Size","Status"],[["snap-db-001","2024-11-15 02:00","12.5 GB","Available"],["snap-db-002","2024-11-14 02:00","12.3 GB","Available"],["snap-db-003","2024-11-13 02:00","12.1 GB","Available"]])}),$.command("db:snapshot:restore <name> <snapshot-id>","Restore from snapshot").option("--new-name <name>","Name for restored database").action(async(J,Y,Q)=>{let Z=Q?.newName||`${J}-restored`;if(V("Restoring from Snapshot"),F(`Source: ${J}`),F(`Snapshot: ${Y}`),F(`New database: ${Z}`),!await y(`
7615
+ Database snapshot created!`),F("Snapshot ID: snap-db-abc123")}),$.command("db:snapshot:list <name>","List snapshots").action(async(J)=>{V(`Snapshots for ${J}`);let Y=new L("Fetching snapshots...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["Snapshot ID","Created","Size","Status"],[["snap-db-001","2024-11-15 02:00","12.5 GB","Available"],["snap-db-002","2024-11-14 02:00","12.3 GB","Available"],["snap-db-003","2024-11-13 02:00","12.1 GB","Available"]])}),$.command("db:snapshot:restore <name> <snapshot-id>","Restore from snapshot").option("--new-name <name>","Name for restored database").action(async(J,Y,Q)=>{let Z=Q?.newName||`${J}-restored`;if(V("Restoring from Snapshot"),F(`Source: ${J}`),F(`Snapshot: ${Y}`),F(`New database: ${Z}`),!await v(`
7616
7616
  Restore from snapshot?`,!0)){F("Operation cancelled");return}let W=new L("Restoring database from snapshot...");W.start(),await new Promise((z)=>setTimeout(z,8000)),W.succeed("Restore complete"),C(`
7617
- Database restored!`),F(`New database: ${Z}`)}),$.command("db:users:add <name> <user>","Create database user").option("--password <password>","User password").option("--readonly","Create readonly user").action(async(J,Y,Q)=>{let Z=Q?.readonly||!1;if(V("Creating Database User"),F(`Database: ${J}`),F(`Username: ${Y}`),F(`Permissions: ${Z?"Read-only":"Read-write"}`),!await y(`
7617
+ Database restored!`),F(`New database: ${Z}`)}),$.command("db:users:add <name> <user>","Create database user").option("--password <password>","User password").option("--readonly","Create readonly user").action(async(J,Y,Q)=>{let Z=Q?.readonly||!1;if(V("Creating Database User"),F(`Database: ${J}`),F(`Username: ${Y}`),F(`Permissions: ${Z?"Read-only":"Read-write"}`),!await v(`
7618
7618
  Create this user?`,!0)){F("Operation cancelled");return}let W=new L("Creating database user...");W.start(),await new Promise((z)=>setTimeout(z,2000)),W.succeed("User created"),C(`
7619
7619
  Database user created!`),F(`Username: ${Y}`),F("Password: ************"),g(`
7620
7620
  Save credentials securely!`)}),$.command("db:users:list <name>","List database users").action(async(J)=>{V(`Users for ${J}`);let Y=new L("Fetching database users...");Y.start(),await new Promise((Q)=>setTimeout(Q,1500)),Y.stop(),d(["Username","Permissions","Created","Last Login"],[["admin","Superuser","2024-01-01","2h ago"],["app_user","Read-write","2024-01-15","5m ago"],["readonly","Read-only","2024-02-01","1d ago"],["backup","Read-only","2024-01-10","Never"]])}),$.command("db:slow-queries <name>","Show slow query log").option("--limit <count>","Number of queries to show",{default:"10"}).action(async(J,Y)=>{let Q=Y?.limit||"10";V(`Slow Queries for ${J}`);let Z=new L("Analyzing slow query log...");Z.start(),await new Promise((U)=>setTimeout(U,2000)),Z.stop(),F(`
@@ -7629,14 +7629,14 @@ Alarm is now active!`),F(`
7629
7629
  You will be notified when the condition is met`)})}function Q5($){$.command("secrets:list","List all secrets").action(async()=>{V("Secrets"),d(["Name","Status"],[["database-password","Last rotated 30 days ago"],["api-key","Last rotated 15 days ago"]])}),$.command("secrets:set <key> <value>","Set a secret").action(async(J,Y)=>{V("Setting Secret");let Q=new L(`Storing secret ${J}...`);Q.start(),await new Promise((Z)=>setTimeout(Z,1000)),Q.succeed(`Secret ${J} stored successfully`),g("Secret value is encrypted and stored in AWS Secrets Manager")}),$.command("secrets:get <key>","Get secret value").action(async(J)=>{V("Getting Secret");let Y=new L(`Retrieving secret ${J}...`);Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.stop(),C(`
7630
7630
  Secret: ${J}`),F("Value: ************"),g(`
7631
7631
  Secret values are hidden for security`),F("To view the actual value, use AWS Console or AWS CLI with --query")})}function Z5($){$.command("firewall:rules","List WAF rules").option("--env <environment>","Environment (production, staging, development)").action(async(J)=>{V("WAF Rules");let Y=J?.env||"production";F(`Environment: ${Y}
7632
- `),d(["Rule","Priority","Action","Requests Blocked"],[["Rate Limit","1","Block","1,234"],["Geo Block (CN, RU)","2","Block","567"],["SQL Injection","3","Block","89"],["XSS Prevention","4","Block","23"]])}),$.command("firewall:block <ip>","Block an IP address").option("--reason <reason>","Reason for blocking").action(async(J,Y)=>{V("Blocking IP Address");let Q=Y?.reason||"Manual block";if(F(`IP: ${J}`),F(`Reason: ${Q}`),!await y(`
7632
+ `),d(["Rule","Priority","Action","Requests Blocked"],[["Rate Limit","1","Block","1,234"],["Geo Block (CN, RU)","2","Block","567"],["SQL Injection","3","Block","89"],["XSS Prevention","4","Block","23"]])}),$.command("firewall:block <ip>","Block an IP address").option("--reason <reason>","Reason for blocking").action(async(J,Y)=>{V("Blocking IP Address");let Q=Y?.reason||"Manual block";if(F(`IP: ${J}`),F(`Reason: ${Q}`),!await v(`
7633
7633
  Block this IP address?`,!0)){F("Operation cancelled");return}let U=new L("Adding IP to WAF block list...");U.start(),await new Promise((W)=>setTimeout(W,2000)),U.succeed(`IP ${J} blocked successfully`),C(`
7634
- IP blocked!`),F("The IP address will be blocked within 60 seconds")}),$.command("firewall:unblock <ip>","Unblock an IP address").action(async(J)=>{if(V("Unblocking IP Address"),F(`IP: ${J}`),!await y(`
7634
+ IP blocked!`),F("The IP address will be blocked within 60 seconds")}),$.command("firewall:unblock <ip>","Unblock an IP address").action(async(J)=>{if(V("Unblocking IP Address"),F(`IP: ${J}`),!await v(`
7635
7635
  Unblock this IP address?`,!0)){F("Operation cancelled");return}let Q=new L("Removing IP from WAF block list...");Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed(`IP ${J} unblocked successfully`),C(`
7636
7636
  IP unblocked!`)}),$.command("firewall:countries","Manage geo-blocking").option("--add <countries>","Comma-separated country codes to block (e.g., CN,RU)").option("--remove <countries>","Comma-separated country codes to unblock").option("--list","List currently blocked countries").action(async(J)=>{if(V("Geo-Blocking Management"),J?.list)F(`Currently blocked countries:
7637
- `),d(["Country Code","Country Name","Blocked Since"],[["CN","China","2024-01-15"],["RU","Russia","2024-01-15"],["KP","North Korea","2024-01-10"]]);else if(J?.add){let Y=J.add.split(",").map((U)=>U.trim().toUpperCase());if(F(`Countries to block: ${Y.join(", ")}`),!await y(`
7637
+ `),d(["Country Code","Country Name","Blocked Since"],[["CN","China","2024-01-15"],["RU","Russia","2024-01-15"],["KP","North Korea","2024-01-10"]]);else if(J?.add){let Y=J.add.split(",").map((U)=>U.trim().toUpperCase());if(F(`Countries to block: ${Y.join(", ")}`),!await v(`
7638
7638
  Block these countries?`,!0)){F("Operation cancelled");return}let Z=new L("Updating geo-blocking rules...");Z.start(),await new Promise((U)=>setTimeout(U,2000)),Z.succeed("Geo-blocking rules updated"),C(`
7639
- Countries blocked!`)}else if(J?.remove){let Y=J.remove.split(",").map((U)=>U.trim().toUpperCase());if(F(`Countries to unblock: ${Y.join(", ")}`),!await y(`
7639
+ Countries blocked!`)}else if(J?.remove){let Y=J.remove.split(",").map((U)=>U.trim().toUpperCase());if(F(`Countries to unblock: ${Y.join(", ")}`),!await v(`
7640
7640
  Unblock these countries?`,!0)){F("Operation cancelled");return}let Z=new L("Updating geo-blocking rules...");Z.start(),await new Promise((U)=>setTimeout(U,2000)),Z.succeed("Geo-blocking rules updated"),C(`
7641
7641
  Countries unblocked!`)}else F("Use --list, --add, or --remove options"),F("Example: cloud firewall:countries --add CN,RU")})}s1();function U5($){$.command("ssl:list","List all SSL certificates").option("--region <region>","AWS region (default: us-east-1)").action(async(J)=>{V("SSL Certificates");let Y=J?.region||"us-east-1",Q=new L("Fetching certificates from ACM...");Q.start();try{let Z=new y0(Y),U=await Z.listCertificates();if(U.CertificateSummaryList.length===0){Q.succeed("No certificates found"),F(`
7642
7642
  No SSL certificates found in region ${Y}`),F("Use 'cloud domain:ssl <domain>' to request a new certificate");return}let W=await Promise.all(U.CertificateSummaryList.map(async(H)=>{return await Z.describeCertificate({CertificateArn:H.CertificateArn})}));Q.succeed(`Found ${W.length} certificate(s)`);let z=(H)=>{if(!H)return"N/A";let A=typeof H==="string"?Number.parseFloat(H):H,K=A<1000000000000?A*1000:A;return new Date(K).toISOString().split("T")[0]},G=W.map((H)=>{let A=z(H.NotAfter),K=H.Type==="AMAZON_ISSUED"?"Amazon Issued":H.Type||"Unknown",B=H.Status==="ISSUED"?"Available":H.Status||"Unknown";return[H.DomainName,H.Status||"Unknown",A,K,B]});d(["Domain","Status","Expiry","Type","State"],G),F(`
@@ -7659,39 +7659,39 @@ ${A}
7659
7659
  This command needs the ce:GetCostAndUsage IAM permission.`);return}let A=null,K=!1;if(H.some((O)=>O.service===H5))try{A=(await new F0("us-east-1",Y).listBuckets()).Buckets?.length??0}catch{K=!0}if(z.stop(),H.length===0){F("No billed services in this period.");return}let B=H.reduce((O,_)=>O+_.amount,0),j=H.map((O)=>{let _="-";if(O.service===H5){if(K)_="unknown (no s3:ListAllMyBuckets)";else if(A!==null)_=`${A} bucket${A===1?"":"s"}`}let w=B>0?`${(O.amount/B*100).toFixed(1)}%`:"—";return[O.service,_,F5(O.amount),w]});if(d(["Service","Resources","Cost","% of Total"],j),F(`
7660
7660
  Total: ${F5(B)} across ${H.length} service${H.length===1?"":"s"}`),G.lastCacheAgeSeconds!==null)F(`(cached, ${G.lastCacheAgeSeconds}s old — pass --no-cache to refresh)`);if((H.find((O)=>O.service===H5)?.amount??0)>1&&A===0)g(`
7661
7661
  S3 has spend but listBuckets returned 0. The buckets are likely owned by a different account in your AWS Organization (consolidated billing rolls up to the payer account, but ListBuckets only shows buckets owned by the calling account).`);if(J?.output){let O=`${process.cwd()}/aws.md`;await Bun.write(O,GB({label:W,profile:Y,rows:j,total:B,count:H.length})),C(`
7662
- Wrote ${O}`)}}),$.command("cost:cache:clear","Wipe the local Cost Explorer response cache").option("--all","Wipe entries for every profile (default: just the current profile)").action(async(J)=>{let Y=J?.all?void 0:J?.profile,Q=CZ(Y),Z=xZ(Y);F(`Cleared ${Z.deletedFiles} cached response${Z.deletedFiles===1?"":"s"} for ${Z.scope}`),F(`(${Q})`)}),$.command("cost","Show estimated monthly cost").option("--env <environment>","Environment (production, staging, development)").action(()=>{g("`cost` is not yet implemented against real AWS data. Use `cost:analyze` for real numbers."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/108")}),$.command("cost:breakdown","Cost breakdown by service").option("--env <environment>","Environment (production, staging, development)").option("--days <days>","Number of days to analyze",{default:"30"}).action(()=>{g("`cost:breakdown` is not yet implemented against real AWS data. Use `cost:analyze` for the latest full month."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/109")}),$.command("resources","List all resources").option("--env <environment>","Environment (production, staging, development)").option("--type <type>","Resource type (ec2, rds, s3, lambda, etc.)").action(()=>{g("`resources` is not yet implemented against real AWS data."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/110")}),$.command("resources:unused","Find unused resources").option("--env <environment>","Environment (production, staging, development)").action(()=>{g("`resources:unused` is not yet implemented against real AWS data."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/111")}),$.command("optimize","Suggest cost optimizations").option("--env <environment>","Environment (production, staging, development)").action(()=>{g("`optimize` is not yet implemented against real AWS data."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/112")})}function K5($){$.command("git:add <repo>","Connect git repository").option("--branch <branch>","Default branch to deploy",{default:"main"}).action(async(J,Y)=>{let Q=Y?.branch||"main";if(V("Connecting Git Repository"),F(`Repository: ${J}`),F(`Default branch: ${Q}`),!await y(`
7662
+ Wrote ${O}`)}}),$.command("cost:cache:clear","Wipe the local Cost Explorer response cache").option("--all","Wipe entries for every profile (default: just the current profile)").action(async(J)=>{let Y=J?.all?void 0:J?.profile,Q=CZ(Y),Z=xZ(Y);F(`Cleared ${Z.deletedFiles} cached response${Z.deletedFiles===1?"":"s"} for ${Z.scope}`),F(`(${Q})`)}),$.command("cost","Show estimated monthly cost").option("--env <environment>","Environment (production, staging, development)").action(()=>{g("`cost` is not yet implemented against real AWS data. Use `cost:analyze` for real numbers."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/108")}),$.command("cost:breakdown","Cost breakdown by service").option("--env <environment>","Environment (production, staging, development)").option("--days <days>","Number of days to analyze",{default:"30"}).action(()=>{g("`cost:breakdown` is not yet implemented against real AWS data. Use `cost:analyze` for the latest full month."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/109")}),$.command("resources","List all resources").option("--env <environment>","Environment (production, staging, development)").option("--type <type>","Resource type (ec2, rds, s3, lambda, etc.)").action(()=>{g("`resources` is not yet implemented against real AWS data."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/110")}),$.command("resources:unused","Find unused resources").option("--env <environment>","Environment (production, staging, development)").action(()=>{g("`resources:unused` is not yet implemented against real AWS data."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/111")}),$.command("optimize","Suggest cost optimizations").option("--env <environment>","Environment (production, staging, development)").action(()=>{g("`optimize` is not yet implemented against real AWS data."),F("Tracking: https://github.com/stacksjs/ts-cloud/issues/112")})}function K5($){$.command("git:add <repo>","Connect git repository").option("--branch <branch>","Default branch to deploy",{default:"main"}).action(async(J,Y)=>{let Q=Y?.branch||"main";if(V("Connecting Git Repository"),F(`Repository: ${J}`),F(`Default branch: ${Q}`),!await v(`
7663
7663
  Connect this repository?`,!0)){F("Operation cancelled");return}let U=new L("Setting up git integration...");U.start(),await new Promise((W)=>setTimeout(W,2000)),U.succeed("Repository connected"),C(`
7664
7664
  Git repository connected!`),F(`
7665
- Next steps:`),F(" - Deploy: cloud git:deploy main"),F(" - Add webhook: cloud git:webhook:add")}),$.command("git:deploy <branch>","Deploy from git branch").option("--env <environment>","Target environment").action(async(J,Y)=>{let Q=Y?.env||"production";if(V(`Deploying from Git: ${J}`),F(`Branch: ${J}`),F(`Environment: ${Q}`),!await y(`
7665
+ Next steps:`),F(" - Deploy: cloud git:deploy main"),F(" - Add webhook: cloud git:webhook:add")}),$.command("git:deploy <branch>","Deploy from git branch").option("--env <environment>","Target environment").action(async(J,Y)=>{let Q=Y?.env||"production";if(V(`Deploying from Git: ${J}`),F(`Branch: ${J}`),F(`Environment: ${Q}`),!await v(`
7666
7666
  Deploy this branch?`,!0)){F("Operation cancelled");return}let U=new L("Pulling latest changes and deploying...");U.start(),await new Promise((W)=>setTimeout(W,4000)),U.succeed("Deployment complete"),C(`
7667
7667
  Deployed successfully!`),F(`Branch ${J} is now live on ${Q}`)}),$.command("git:webhook:add <repo>","Add webhook for auto-deploy").action(async(J)=>{V("Adding Deploy Webhook"),F(`Repository: ${J}`);let Y=new L("Creating webhook endpoint...");Y.start(),await new Promise((Q)=>setTimeout(Q,2000)),Y.succeed("Webhook created"),C(`
7668
7668
  Webhook endpoint created!`),F(`
7669
7669
  Webhook URL:`),F(" https://api.example.com/webhooks/deploy/abc123"),F(`
7670
- Add this webhook to your repository:`),F(" - GitHub: Settings > Webhooks > Add webhook"),F(" - GitLab: Settings > Webhooks > Add webhook"),F(" - Event: Push events")}),$.command("git:webhook:remove <repo>","Remove webhook").action(async(J)=>{if(V("Removing Deploy Webhook"),F(`Repository: ${J}`),!await y(`
7670
+ Add this webhook to your repository:`),F(" - GitHub: Settings > Webhooks > Add webhook"),F(" - GitLab: Settings > Webhooks > Add webhook"),F(" - Event: Push events")}),$.command("git:webhook:remove <repo>","Remove webhook").action(async(J)=>{if(V("Removing Deploy Webhook"),F(`Repository: ${J}`),!await v(`
7671
7671
  Remove this webhook?`,!0)){F("Operation cancelled");return}let Q=new L("Removing webhook...");Q.start(),await new Promise((Z)=>setTimeout(Z,1500)),Q.succeed("Webhook removed"),C(`
7672
- Webhook deleted!`)}),$.command("git:branches","List deployable branches").action(async()=>{V("Deployable Branches");let J=new L("Fetching branches...");J.start(),await new Promise((Y)=>setTimeout(Y,1500)),J.stop(),d(["Branch","Last Commit","Author","Deployed To"],[["main","2h ago","john@example.com","production"],["develop","30m ago","jane@example.com","staging"],["feature/new-ui","1d ago","bob@example.com","-"],["hotfix/bug-123","5h ago","alice@example.com","-"]]),F("\nTip: Deploy a branch with `cloud git:deploy <branch>`")})}function B5($){$.command("env:create <name>","Create new environment").option("--clone <source>","Clone from existing environment").action(async(J,Y)=>{V(`Creating Environment: ${J}`);let Q=["production","staging","development","preview","test"];if(!Q.includes(J.toLowerCase()))g("Warning: Creating non-standard environment name"),F(`Standard names: ${Q.join(", ")}`);if(Y?.clone)F(`Cloning from: ${Y.clone}`);if(!await y(`
7672
+ Webhook deleted!`)}),$.command("git:branches","List deployable branches").action(async()=>{V("Deployable Branches");let J=new L("Fetching branches...");J.start(),await new Promise((Y)=>setTimeout(Y,1500)),J.stop(),d(["Branch","Last Commit","Author","Deployed To"],[["main","2h ago","john@example.com","production"],["develop","30m ago","jane@example.com","staging"],["feature/new-ui","1d ago","bob@example.com","-"],["hotfix/bug-123","5h ago","alice@example.com","-"]]),F("\nTip: Deploy a branch with `cloud git:deploy <branch>`")})}function B5($){$.command("env:create <name>","Create new environment").option("--clone <source>","Clone from existing environment").action(async(J,Y)=>{V(`Creating Environment: ${J}`);let Q=["production","staging","development","preview","test"];if(!Q.includes(J.toLowerCase()))g("Warning: Creating non-standard environment name"),F(`Standard names: ${Q.join(", ")}`);if(Y?.clone)F(`Cloning from: ${Y.clone}`);if(!await v(`
7673
7673
  Create this environment?`,!0)){F("Operation cancelled");return}let U=new L("Creating environment infrastructure...");U.start(),await new Promise((W)=>setTimeout(W,3000)),U.succeed("Environment created successfully"),C(`
7674
7674
  Environment created!`),F(`Environment ${J} is now available`),F(`
7675
7675
  Next steps:`),F(` - Deploy to environment: cloud deploy --env ${J}`),F(` - Switch to environment: cloud env:switch ${J}`)}),$.command("env:list","List environments").action(async()=>{V("Environments");let J=new L("Fetching environments...");J.start(),await new Promise((Y)=>setTimeout(Y,1500)),J.stop(),d(["Environment","Status","Region","Last Deployed","Active"],[["production","Active","us-east-1","2 hours ago",""],["staging","Active","us-east-1","1 day ago","*"],["development","Active","us-west-2","3 days ago",""],["preview-pr-123","Active","us-east-1","5 hours ago",""]]),F("\nTip: Use `cloud env:switch NAME` to switch active environment"),F("Tip: Use `cloud env:create NAME` to create new environment")}),$.command("env:switch <name>","Switch active environment").action(async(J)=>{V(`Switching to Environment: ${J}`),F(`Switching to: ${J}`);let Y=new L("Updating environment configuration...");Y.start(),await new Promise((Q)=>setTimeout(Q,1000)),Y.succeed("Environment switched successfully"),C(`
7676
7676
  Now using environment: ${J}`),F(`All commands will now target the ${J} environment`),F(`
7677
7677
  Environment details:`),F(" - Region: us-east-1"),F(" - Status: Active"),F(" - Last deployed: 1 day ago")}),$.command("env:clone <source> <target>","Clone environment").action(async(J,Y)=>{if(V("Cloning Environment"),F(`Source: ${J}`),F(`Target: ${Y}`),g(`
7678
- This will copy:`),F(" - Infrastructure configuration"),F(" - Environment variables"),F(" - Database schema (not data)"),!await y(`
7678
+ This will copy:`),F(" - Infrastructure configuration"),F(" - Environment variables"),F(" - Database schema (not data)"),!await v(`
7679
7679
  Clone environment?`,!0)){F("Operation cancelled");return}let Z=new L("Cloning environment...");Z.start(),await new Promise((U)=>setTimeout(U,5000)),Z.succeed("Environment cloned"),C(`
7680
7680
  Environment ${Y} created from ${J}!`),F("Deploy with: cloud deploy --env "+Y)}),$.command("env:promote <source> <target>","Promote environment").action(async(J,Y)=>{if(V("Promoting Environment"),F(`From: ${J}`),F(`To: ${Y}`),g(`
7681
- This will:`),F(" - Deploy code from source to target"),F(" - Update target configuration"),F(" - Run database migrations if any"),!await y(`
7681
+ This will:`),F(" - Deploy code from source to target"),F(" - Update target configuration"),F(" - Run database migrations if any"),!await v(`
7682
7682
  Promote to `+Y+"?",!1)){F("Operation cancelled");return}let Z=new L("Promoting environment...");Z.start(),await new Promise((U)=>setTimeout(U,6000)),Z.succeed("Promotion complete"),C(`
7683
7683
  ${J} promoted to ${Y}!`)}),$.command("env:compare <env1> <env2>","Compare configurations").action(async(J,Y)=>{V("Comparing Environments"),F(`Environment 1: ${J}`),F(`Environment 2: ${Y}`);let Q=new L("Analyzing configurations...");Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.stop(),F(`
7684
7684
  Configuration Differences:
7685
7685
  `),d(["Setting",J,Y,"Match"],[["Instance Type","t3.medium","t3.small","X"],["Database Size","db.t3.medium","db.t3.micro","X"],["Auto Scaling","Enabled","Disabled","X"],["Region","us-east-1","us-east-1","*"],["Node Version","20.x","20.x","*"]]),F(`
7686
7686
  Found 3 differences`)}),$.command("env:sync <source> <target>","Sync configuration").action(async(J,Y)=>{if(V("Syncing Configuration"),F(`Source: ${J}`),F(`Target: ${Y}`),g(`
7687
- This will sync configuration (not resources or data)`),!await y(`
7687
+ This will sync configuration (not resources or data)`),!await v(`
7688
7688
  Sync configuration?`,!0)){F("Operation cancelled");return}let Z=new L("Syncing configuration...");Z.start(),await new Promise((U)=>setTimeout(U,2000)),Z.succeed("Configuration synced"),C(`
7689
- Configuration synchronized!`)}),$.command("env:preview <branch>","Create preview environment from branch").action(async(J)=>{V(`Creating Preview Environment for ${J}`);let Y=`preview-${J.replace(/[^a-z0-9]/gi,"-").toLowerCase()}`;if(F(`Environment name: ${Y}`),F(`Branch: ${J}`),!await y(`
7689
+ Configuration synchronized!`)}),$.command("env:preview <branch>","Create preview environment from branch").action(async(J)=>{V(`Creating Preview Environment for ${J}`);let Y=`preview-${J.replace(/[^a-z0-9]/gi,"-").toLowerCase()}`;if(F(`Environment name: ${Y}`),F(`Branch: ${J}`),!await v(`
7690
7690
  Create preview environment?`,!0)){F("Operation cancelled");return}let Z=new L("Creating preview environment...");Z.start(),await new Promise((U)=>setTimeout(U,8000)),Z.succeed("Preview environment created"),C(`
7691
7691
  Preview environment ready!`),F(`URL: https://${Y}.preview.example.com`),F(`
7692
7692
  This environment will auto-delete after 7 days`)}),$.command("env:cleanup","Remove stale preview environments").action(async()=>{V("Cleaning Up Preview Environments");let J=new L("Finding stale preview environments...");if(J.start(),await new Promise((Z)=>setTimeout(Z,2000)),J.stop(),F(`
7693
7693
  Found 3 stale preview environments:
7694
- `),d(["Environment","Created","Age","Status"],[["preview-feature-123","2024-10-15","30 days","Inactive"],["preview-bugfix-456","2024-10-20","25 days","Inactive"],["preview-test-789","2024-11-01","14 days","Inactive"]]),!await y(`
7694
+ `),d(["Environment","Created","Age","Status"],[["preview-feature-123","2024-10-15","30 days","Inactive"],["preview-bugfix-456","2024-10-20","25 days","Inactive"],["preview-test-789","2024-11-01","14 days","Inactive"]]),!await v(`
7695
7695
  Delete these environments?`,!0)){F("Operation cancelled");return}let Q=new L("Deleting stale environments...");Q.start(),await new Promise((Z)=>setTimeout(Z,4000)),Q.succeed("Cleanup complete"),C(`
7696
7696
  3 preview environments deleted!`),F("Estimated monthly savings: $87")})}import{existsSync as HB}from"node:fs";P1();l1();function X5($){$.command("assets:build","Build assets").option("--minify","Minify output").option("--compress","Compress output").action(async(J)=>{V("Building Assets");let Y=J?.minify||!1,Q=J?.compress||!1;F("Build configuration:"),F(` - Minify: ${Y?"Yes":"No"}`),F(` - Compress: ${Q?"Yes":"No"}`);let Z=new L("Building assets...");Z.start(),await new Promise((U)=>setTimeout(U,4000)),Z.succeed("Assets built successfully"),C(`
7697
7697
  Build complete!`),F(`
@@ -7700,17 +7700,17 @@ Build directory: ./dist`)}),$.command("assets:optimize:images","Optimize images"
7700
7700
  Optimization complete!`),F(`
7701
7701
  Results:`),F(" - Processed: 127 images"),F(" - Original: 15.2 MB"),F(" - Optimized: 8.9 MB"),F(" - Savings: 6.3 MB (41%)")}),$.command("images:optimize","Optimize and compress images").option("--dir <directory>","Directory to optimize",{default:"./public/images"}).action(async(J)=>{let Y=J?.dir||"./public/images";V("Optimizing Images"),F(`Directory: ${Y}`);let Q=new L("Optimizing images...");Q.start(),await new Promise((Z)=>setTimeout(Z,3000)),Q.succeed("Images optimized"),C(`
7702
7702
  Optimization complete!`),F(`
7703
- Results:`),F(" - PNG: 45 files, 3.2 MB > 1.8 MB (44% savings)"),F(" - JPG: 82 files, 12.0 MB > 7.1 MB (41% savings)"),F(" - Total savings: 6.3 MB")}),$.command("assets:deploy","Deploy static assets to S3").option("--source <path>","Source directory",{default:"dist"}).option("--bucket <name>","S3 bucket name").option("--prefix <prefix>","S3 prefix/folder").option("--delete","Delete files not in source").option("--cache-control <value>","Cache-Control header",{default:"public, max-age=31536000"}).action(async(J)=>{V("Deploying Assets to S3");try{let Q=(await c()).project.region||"us-east-1",Z=J?.source||"dist",U=J?.bucket,W=J?.prefix,z=J?.delete||!1,G=J?.cacheControl||"public, max-age=31536000";if(!U){R("--bucket is required");return}if(!HB(Z)){R(`Source directory not found: ${Z}`);return}if(F(`Source: ${Z}`),F(`Bucket: s3://${U}${W?`/${W}`:""}`),F(`Cache-Control: ${G}`),z)g("Delete mode enabled - files not in source will be removed");if(!await y(`
7703
+ Results:`),F(" - PNG: 45 files, 3.2 MB > 1.8 MB (44% savings)"),F(" - JPG: 82 files, 12.0 MB > 7.1 MB (41% savings)"),F(" - Total savings: 6.3 MB")}),$.command("assets:deploy","Deploy static assets to S3").option("--source <path>","Source directory",{default:"dist"}).option("--bucket <name>","S3 bucket name").option("--prefix <prefix>","S3 prefix/folder").option("--delete","Delete files not in source").option("--cache-control <value>","Cache-Control header",{default:"public, max-age=31536000"}).action(async(J)=>{V("Deploying Assets to S3");try{let Q=(await c()).project.region||"us-east-1",Z=J?.source||"dist",U=J?.bucket,W=J?.prefix,z=J?.delete||!1,G=J?.cacheControl||"public, max-age=31536000";if(!U){R("--bucket is required");return}if(!HB(Z)){R(`Source directory not found: ${Z}`);return}if(F(`Source: ${Z}`),F(`Bucket: s3://${U}${W?`/${W}`:""}`),F(`Cache-Control: ${G}`),z)g("Delete mode enabled - files not in source will be removed");if(!await v(`
7704
7704
  Deploy assets now?`,!0)){F("Deployment cancelled");return}let A=new F0(Q),K=new L("Uploading assets to S3...");K.start(),await A.sync({source:Z,bucket:U,prefix:W,delete:z,cacheControl:G,acl:"public-read"}),K.succeed("Assets deployed successfully!");let j=(await A.getBucketSize(U,W)/1024/1024).toFixed(2);C(`
7705
7705
  Deployment complete!`),F(`Total size: ${j} MB`),F(`
7706
- Assets URL: https://${U}.s3.${Q}.amazonaws.com${W?`/${W}`:""}`)}catch(Y){R(`Deployment failed: ${Y.message}`)}}),$.command("assets:invalidate","Invalidate CloudFront cache").option("--distribution <id>","CloudFront distribution ID").option("--paths <paths>","Paths to invalidate (comma-separated)",{default:"/*"}).option("--wait","Wait for invalidation to complete").action(async(J)=>{V("Invalidating CloudFront Cache");try{let Y=J?.distribution;if(!Y){R("--distribution is required");return}let Z=(J?.paths||"/*").split(",").map((A)=>A.trim()),U=J?.wait||!1;if(F(`Distribution: ${Y}`),F(`Paths: ${Z.join(", ")}`),!await y(`
7706
+ Assets URL: https://${U}.s3.${Q}.amazonaws.com${W?`/${W}`:""}`)}catch(Y){R(`Deployment failed: ${Y.message}`)}}),$.command("assets:invalidate","Invalidate CloudFront cache").option("--distribution <id>","CloudFront distribution ID").option("--paths <paths>","Paths to invalidate (comma-separated)",{default:"/*"}).option("--wait","Wait for invalidation to complete").action(async(J)=>{V("Invalidating CloudFront Cache");try{let Y=J?.distribution;if(!Y){R("--distribution is required");return}let Z=(J?.paths||"/*").split(",").map((A)=>A.trim()),U=J?.wait||!1;if(F(`Distribution: ${Y}`),F(`Paths: ${Z.join(", ")}`),!await v(`
7707
7707
  Invalidate cache now?`,!0)){F("Invalidation cancelled");return}let z=new _0,G=new L("Creating invalidation...");G.start();let H=await z.invalidatePaths(Y,Z);if(G.succeed("Invalidation created"),C(`
7708
7708
  Invalidation ID: ${H.Id}`),F(`Status: ${H.Status}`),F(`Created: ${new Date(H.CreateTime).toLocaleString()}`),U){let A=new L("Waiting for invalidation to complete...");A.start(),await z.waitForInvalidation(Y,H.Id),A.succeed("Invalidation completed!")}else F(`
7709
- Invalidation is in progress. Use --wait to wait for completion.`)}catch(Y){R(`Invalidation failed: ${Y.message}`)}})}function O5($){$.command("team:add <email> <role>","Add team member").action(async(J,Y)=>{V("Adding Team Member"),F(`Email: ${J}`),F(`Role: ${Y}`);let Q=["admin","developer","viewer"];if(!Q.includes(Y.toLowerCase())){R(`Invalid role. Must be one of: ${Q.join(", ")}`);return}if(!await y(`
7709
+ Invalidation is in progress. Use --wait to wait for completion.`)}catch(Y){R(`Invalidation failed: ${Y.message}`)}})}function O5($){$.command("team:add <email> <role>","Add team member").action(async(J,Y)=>{V("Adding Team Member"),F(`Email: ${J}`),F(`Role: ${Y}`);let Q=["admin","developer","viewer"];if(!Q.includes(Y.toLowerCase())){R(`Invalid role. Must be one of: ${Q.join(", ")}`);return}if(!await v(`
7710
7710
  Add this team member?`,!0)){F("Operation cancelled");return}let U=new L("Creating IAM user and sending invitation...");U.start(),await new Promise((W)=>setTimeout(W,2000)),U.succeed("Team member added successfully"),C(`
7711
7711
  Team member added!`),F("An invitation email has been sent with access credentials"),F(`
7712
7712
  Access Details:`),F(` - Email: ${J}`),F(` - Role: ${Y}`),F(" - Status: Pending")}),$.command("team:list","List team members").action(async()=>{V("Team Members");let J=new L("Fetching team members...");J.start(),await new Promise((Y)=>setTimeout(Y,1500)),J.stop(),d(["Email","Role","Status","Added","Last Login"],[["admin@example.com","Admin","Active","2024-01-01","2 hours ago"],["dev@example.com","Developer","Active","2024-01-15","1 day ago"],["viewer@example.com","Viewer","Active","2024-02-01","3 days ago"],["new@example.com","Developer","Pending","2024-11-10","Never"]]),F("\nTip: Use `cloud team:add` to add new team members"),F("Tip: Use `cloud team:remove` to remove team members")}),$.command("team:remove <email>","Remove team member").action(async(J)=>{if(V("Removing Team Member"),F(`Email: ${J}`),g(`
7713
- This will revoke all access for this team member`),!await y("Remove this team member?",!1)){F("Operation cancelled");return}let Q=new L("Removing IAM user and access...");Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed("Team member removed successfully"),C(`
7713
+ This will revoke all access for this team member`),!await v("Remove this team member?",!1)){F("Operation cancelled");return}let Q=new L("Removing IAM user and access...");Q.start(),await new Promise((Z)=>setTimeout(Z,2000)),Q.succeed("Team member removed successfully"),C(`
7714
7714
  Team member removed!`),F("All access credentials have been revoked")})}import{existsSync as q1,copyFileSync as w$,readFileSync as $U}from"node:fs";S1();P1();l1();z0();class _5{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t}async createRepository($){let J={repositoryName:$.repositoryName};if($.imageTagMutability)J.imageTagMutability=$.imageTagMutability;if($.imageScanningConfiguration)J.imageScanningConfiguration=$.imageScanningConfiguration;if($.encryptionConfiguration)J.encryptionConfiguration=$.encryptionConfiguration;if($.tags&&$.tags.length>0)J.tags=$.tags;let Y=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(J)});return{repository:Y.repository?this.parseRepository(Y.repository):void 0}}async describeRepositories($){let J={};if($?.repositoryNames&&$.repositoryNames.length>0)J.repositoryNames=$.repositoryNames;if($?.registryId)J.registryId=$.registryId;if($?.maxResults)J.maxResults=$.maxResults;if($?.nextToken)J.nextToken=$.nextToken;let Y=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(J)});return{repositories:Y.repositories?.map((Q)=>this.parseRepository(Q)),nextToken:Y.nextToken}}async getAuthorizationToken($){let J={};if($&&$.length>0)J.registryIds=$;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(J)})).authorizationData?.map((Q)=>({authorizationToken:Q.authorizationToken,expiresAt:Q.expiresAt,proxyEndpoint:Q.proxyEndpoint}))}}async deleteRepository($){let J={repositoryName:$.repositoryName};if($.registryId)J.registryId=$.registryId;if($.force!==void 0)J.force=$.force;let Y=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(J)});return{repository:Y.repository?this.parseRepository(Y.repository):void 0}}async describeImages($){let J={repositoryName:$.repositoryName};if($.registryId)J.registryId=$.registryId;if($.imageIds&&$.imageIds.length>0)J.imageIds=$.imageIds;if($.filter)J.filter=$.filter;if($.maxResults)J.maxResults=$.maxResults;if($.nextToken)J.nextToken=$.nextToken;let Y=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(J)});return{imageDetails:Y.imageDetails?.map((Q)=>this.parseImageDetail(Q)),nextToken:Y.nextToken}}async batchDeleteImage($){let J={repositoryName:$.repositoryName,imageIds:$.imageIds};if($.registryId)J.registryId=$.registryId;let Y=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(J)});return{imageIds:Y.imageIds,failures:Y.failures}}async putLifecyclePolicy($){let J={repositoryName:$.repositoryName,lifecyclePolicyText:$.lifecyclePolicyText};if($.registryId)J.registryId=$.registryId;let Y=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(J)});return{registryId:Y.registryId,repositoryName:Y.repositoryName,lifecyclePolicyText:Y.lifecyclePolicyText}}async getLifecyclePolicy($){let J={repositoryName:$.repositoryName};if($.registryId)J.registryId=$.registryId;let Y=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(J)});return{registryId:Y.registryId,repositoryName:Y.repositoryName,lifecyclePolicyText:Y.lifecyclePolicyText,lastEvaluatedAt:Y.lastEvaluatedAt}}async setRepositoryPolicy($){let J={repositoryName:$.repositoryName,policyText:$.policyText};if($.registryId)J.registryId=$.registryId;if($.force!==void 0)J.force=$.force;let Y=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(J)});return{registryId:Y.registryId,repositoryName:Y.repositoryName,policyText:Y.policyText}}async getRepositoryPolicy($){let J={repositoryName:$.repositoryName};if($.registryId)J.registryId=$.registryId;let Y=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(J)});return{registryId:Y.registryId,repositoryName:Y.repositoryName,policyText:Y.policyText}}async tagResource($){let J={resourceArn:$.resourceArn,tags:$.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(J)})}async listTagsForResource($){let J={resourceArn:$};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(J)})).tags}}createLifecyclePolicyText($){return JSON.stringify({rules:$.map((J)=>({rulePriority:J.rulePriority,description:J.description,selection:J.selection,action:J.action}))})}async getDockerLoginCommand(){let $=await this.getAuthorizationToken();if(!$.authorizationData?.[0])throw Error("Failed to get authorization token");let J=$.authorizationData[0],Y=J.authorizationToken||"",Q=J.proxyEndpoint||"";return`echo "${Buffer.from(Y,"base64").toString("utf8").split(":")[1]}" | docker login --username AWS --password-stdin ${Q}`}getRegistryUri($){return`${$}.dkr.ecr.${this.region}.amazonaws.com`}parseRepository($){return{repositoryArn:$.repositoryArn,registryId:$.registryId,repositoryName:$.repositoryName,repositoryUri:$.repositoryUri,createdAt:$.createdAt,imageTagMutability:$.imageTagMutability,imageScanningConfiguration:$.imageScanningConfiguration,encryptionConfiguration:$.encryptionConfiguration}}parseImageDetail($){return{registryId:$.registryId,repositoryName:$.repositoryName,imageDigest:$.imageDigest,imageTags:$.imageTags,imageSizeInBytes:$.imageSizeInBytes,imagePushedAt:$.imagePushedAt,imageScanStatus:$.imageScanStatus,imageScanFindingsSummary:$.imageScanFindingsSummary}}}z0();class q5{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t}async describeServices($){let J={cluster:$.cluster,services:$.services};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async listServices($){let J={cluster:$};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async listTasks($,J){let Y={cluster:$};if(J)Y.serviceName=J;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(Y)})}async describeTasks($,J){let Y={cluster:$,tasks:J};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(Y)})}async updateService($){let J={cluster:$.cluster,service:$.service};if($.forceNewDeployment!==void 0)J.forceNewDeployment=$.forceNewDeployment;if($.desiredCount!==void 0)J.desiredCount=$.desiredCount;if($.taskDefinition)J.taskDefinition=$.taskDefinition;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.UpdateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async createService($){let J={cluster:$.cluster,serviceName:$.serviceName,taskDefinition:$.taskDefinition,desiredCount:$.desiredCount};if($.launchType)J.launchType=$.launchType;if($.networkConfiguration)J.networkConfiguration=$.networkConfiguration;if($.loadBalancers)J.loadBalancers=$.loadBalancers;if($.healthCheckGracePeriodSeconds!==void 0)J.healthCheckGracePeriodSeconds=$.healthCheckGracePeriodSeconds;if($.deploymentConfiguration)J.deploymentConfiguration=$.deploymentConfiguration;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.CreateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async deleteService($){let J={cluster:$.cluster,service:$.service};if($.force!==void 0)J.force=$.force;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeleteService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async listClusters(){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({})})}async describeClusters($){let J={clusters:$,include:["ATTACHMENTS","CONFIGURATIONS","SETTINGS","STATISTICS","TAGS"]};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async stopTask($){let J={cluster:$.cluster,task:$.task};if($.reason)J.reason=$.reason;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.StopTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async runTask($){let J={cluster:$.cluster,taskDefinition:$.taskDefinition};if($.count!==void 0)J.count=$.count;if($.launchType)J.launchType=$.launchType;if($.networkConfiguration)J.networkConfiguration=$.networkConfiguration;if($.overrides)J.overrides=$.overrides;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RunTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async registerTaskDefinition($){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RegisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify($)})}async deregisterTaskDefinition($){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeregisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:$})})}async describeTaskDefinition($){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:$,include:["TAGS"]})})}async listTaskDefinitionFamilies($){let J={};if($?.familyPrefix)J.familyPrefix=$.familyPrefix;if($?.status)J.status=$.status;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTaskDefinitionFamilies","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async waitForServiceStable($,J,Y=40,Q=15000){for(let Z=0;Z<Y;Z++){let W=(await this.describeServices({cluster:$,services:[J]})).services?.[0];if(W){let z=W.deployments?.find((G)=>G.status==="PRIMARY");if(z&&z.runningCount===z.desiredCount&&W.deployments?.length===1)return!0}await new Promise((z)=>setTimeout(z,Q))}return!1}async forceNewDeployment($,J){return this.updateService({cluster:$,service:J,forceNewDeployment:!0})}async scaleService($,J,Y){return this.updateService({cluster:$,service:J,desiredCount:Y})}}E5();z0();import{execSync as v5}from"node:child_process";import{tmpdir as IB}from"node:os";import{join as kB}from"node:path";V5();B2();import{existsSync as BB,readdirSync as jB,readFileSync as XB,statSync as OB}from"node:fs";import{join as _B,relative as qB,extname as EB}from"node:path";var wB=[{name:"AWS Access Key ID",pattern:/(?:^|[^A-Z0-9])((AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16})(?:[^A-Z0-9]|$)/g,severity:"critical",description:"AWS Access Key ID detected"},{name:"AWS Secret Access Key",pattern:/(?:aws_secret_access_key|aws_secret_key|secret_access_key|secretAccessKey)\s*[=:]\s*['"]?([A-Za-z0-9/+=]{40})['"]?/gi,severity:"critical",description:"AWS Secret Access Key detected"},{name:"AWS Secret Key (Generic)",pattern:/(?:^|['"`:=\s])([A-Za-z0-9/+=]{40})(?:['"`\s]|$)/g,severity:"high",description:"Potential AWS Secret Key (40-char base64)"},{name:"Generic API Key",pattern:/(?:api[_-]?key|apikey|api[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9_\-]{20,})['"]?/gi,severity:"high",description:"Generic API key detected"},{name:"RSA Private Key",pattern:/-----BEGIN RSA PRIVATE KEY-----/g,severity:"critical",description:"RSA private key detected"},{name:"OpenSSH Private Key",pattern:/-----BEGIN OPENSSH PRIVATE KEY-----/g,severity:"critical",description:"OpenSSH private key detected"},{name:"EC Private Key",pattern:/-----BEGIN EC PRIVATE KEY-----/g,severity:"critical",description:"EC private key detected"},{name:"PGP Private Key",pattern:/-----BEGIN PGP PRIVATE KEY BLOCK-----/g,severity:"critical",description:"PGP private key detected"},{name:"GitHub Token",pattern:/(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}/g,severity:"critical",description:"GitHub personal access token detected"},{name:"GitHub OAuth",pattern:/github[_-]?oauth[_-]?token\s*[=:]\s*['"]?([A-Za-z0-9_]{40})['"]?/gi,severity:"critical",description:"GitHub OAuth token detected"},{name:"Slack Token",pattern:/xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*/g,severity:"critical",description:"Slack token detected"},{name:"Slack Webhook",pattern:/https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/g,severity:"high",description:"Slack webhook URL detected"},{name:"Discord Webhook",pattern:/https:\/\/discord(?:app)?\.com\/api\/webhooks\/[0-9]+\/[A-Za-z0-9_-]+/g,severity:"high",description:"Discord webhook URL detected"},{name:"JWT Token",pattern:/eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*/g,severity:"high",description:"JWT token detected"},{name:"Google API Key",pattern:/AIza[0-9A-Za-z_-]{35}/g,severity:"critical",description:"Google API key detected"},{name:"Google OAuth ID",pattern:/[0-9]+-[A-Za-z0-9_]{32}\.apps\.googleusercontent\.com/g,severity:"high",description:"Google OAuth client ID detected"},{name:"Firebase API Key",pattern:/(?:firebase[_-]?api[_-]?key)\s*[=:]\s*['"]?([A-Za-z0-9_-]{39})['"]?/gi,severity:"critical",description:"Firebase API key detected"},{name:"Cloudflare API Token",pattern:/(?:cloudflare[_-]?api[_-]?token|cf[_-]?api[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{40})['"]?/gi,severity:"critical",description:"Cloudflare API token detected"},{name:"Azure Client Secret",pattern:/(?:azure[_-]?client[_-]?secret|client[_-]?secret)\s*[=:]\s*['"]?([A-Za-z0-9~._-]{34,})['"]?/gi,severity:"critical",description:"Azure client secret detected"},{name:"Heroku API Key",pattern:/(?:heroku[_-]?api[_-]?key)\s*[=:]\s*['"]?([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})['"]?/gi,severity:"critical",description:"Heroku API key detected"},{name:"Database Connection String",pattern:/(?:mysql|postgres|postgresql|mongodb|redis|mongodb\+srv):\/\/[^:]+:[^@]+@[^/\s]+/gi,severity:"critical",description:"Database connection string with credentials detected"},{name:"Database Password",pattern:/(?:db[_-]?password|database[_-]?password|mysql[_-]?password|postgres[_-]?password)\s*[=:]\s*['"]?([^'"\s]{8,})['"]?/gi,severity:"critical",description:"Database password detected"},{name:"Stripe API Key",pattern:/(?:sk|pk)_(?:test|live)_[0-9a-zA-Z]{24,}/g,severity:"critical",description:"Stripe API key detected"},{name:"PayPal Client ID",pattern:/(?:paypal[_-]?client[_-]?id)\s*[=:]\s*['"]?([A-Za-z0-9_-]{80})['"]?/gi,severity:"high",description:"PayPal client ID detected"},{name:"Square Access Token",pattern:/sq0[a-z]{3}-[0-9A-Za-z_-]{22,}/g,severity:"critical",description:"Square access token detected"},{name:"Twilio API Key",pattern:/SK[a-f0-9]{32}/g,severity:"critical",description:"Twilio API key detected"},{name:"SendGrid API Key",pattern:/SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}/g,severity:"critical",description:"SendGrid API key detected"},{name:"Mailgun API Key",pattern:/key-[0-9a-zA-Z]{32}/g,severity:"critical",description:"Mailgun API key detected"},{name:"Password in Code",pattern:/(?:password|passwd|pwd)\s*[=:]\s*['"]([^'"]{8,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded password detected"},{name:"Secret/Token Assignment",pattern:/(?:secret|token|auth[_-]?token|access[_-]?token)\s*[=:]\s*['"]([A-Za-z0-9_\-/+=]{16,})['"](?!\s*[,\]])/gi,severity:"high",description:"Hardcoded secret or token detected"},{name:"NPM Token",pattern:/(?:npm[_-]?token)\s*[=:]\s*['"]?([A-Za-z0-9_-]{36})['"]?/gi,severity:"critical",description:"NPM token detected"},{name:"SSH Private Key Path Exposed",pattern:/~\/\.ssh\/id_[a-z]+|\/home\/[^/]+\/\.ssh\/id_[a-z]+/g,severity:"medium",description:"SSH private key path exposed"},{name:"Env Variable with Secret",pattern:/(?:process\.env\.)((?=[A-Z_]*(?:SECRET|KEY|TOKEN|PASSWORD|CREDENTIAL|AUTH))[A-Z_]+)\s*(?:===?\s*['"]([^'"]+)['"])?/g,severity:"medium",description:"Environment variable containing secret may be exposed"}],VB=[".js",".jsx",".ts",".tsx",".mjs",".cjs",".vue",".svelte",".html",".htm",".css",".scss",".less",".json",".yaml",".yml",".toml",".xml",".env",".config",".conf"],LB=["node_modules",".git",".svn",".hg","dist","build","coverage",".nyc_output","__pycache__",".pytest_cache","vendor",".idea",".vscode",".turbo",".next",".nuxt"],MB=["package-lock.json","yarn.lock","pnpm-lock.yaml","bun.lockb","*.min.js","*.min.css","*.map"];class M5{patterns;excludeDirs;excludeFiles;maxFileSize;constructor($){this.patterns=[...wB,...$?.customPatterns||[]],this.excludeDirs=[...LB,...$?.excludeDirs||[]],this.excludeFiles=[...MB,...$?.excludeFiles||[]],this.maxFileSize=$?.maxFileSize||1048576}async scan($){let J=Date.now(),Y=[],Q=0,{directory:Z,exclude:U=[],include:W,skipPatterns:z=[]}=$,G=$.failOnSeverity||"critical";if(!BB(Z))throw Error(`Directory not found: ${Z}`);let H=this.getFilesToScan(Z,[...this.excludeDirs,...U],W);for(let X of H){let O=qB(Z,X);if(this.shouldExcludeFile(O))continue;try{if(OB(X).size>this.maxFileSize)continue;let w=XB(X,"utf-8"),E=this.scanContent(w,O,z);Y.push(...E),Q++}catch{continue}}let A={critical:Y.filter((X)=>X.pattern.severity==="critical").length,high:Y.filter((X)=>X.pattern.severity==="high").length,medium:Y.filter((X)=>X.pattern.severity==="medium").length,low:Y.filter((X)=>X.pattern.severity==="low").length},K=["low","medium","high","critical"],B=K.indexOf(G),j=!0;for(let X=B;X<K.length;X++)if(A[K[X]]>0){j=!1;break}return{passed:j,findings:Y,scannedFiles:Q,duration:Date.now()-J,summary:A}}scanContent($,J,Y){let Q=[],Z=$.split(`
7715
7715
  `);for(let U of this.patterns){if(Y.includes(U.name))continue;U.pattern.lastIndex=0;let W;while((W=U.pattern.exec($))!==null){let z=$.substring(0,W.index),G=z.split(`
7716
7716
  `).length,H=z.lastIndexOf(`
@@ -7808,13 +7808,13 @@ Findings:`);let U=Y.filter((A)=>A.pattern.severity==="critical"),W=Y.filter((A)=
7808
7808
  ${A2(`[${K}]`,B)}`);for(let j of A.slice(0,10))F(` ${j.pattern.name}`),F(` File: ${j.file}:${j.line}`),F(` Match: ${j.match}`);if(A.length>10)F(` ... and ${A.length-10} more ${K.toLowerCase()} findings`)}};H(U,"CRITICAL","red"),H(W,"HIGH","yellow"),H(z,"MEDIUM","blue"),H(G,"LOW","gray")}}function f5($){$.command("deploy:security-scan","Run pre-deployment security scan").option("--source <path>","Source directory to scan",{default:"."}).option("--fail-on <severity>","Fail on severity level (critical, high, medium, low)",{default:"critical"}).option("--skip-patterns <patterns>","Comma-separated list of pattern names to skip").action(async(J)=>{V("Pre-Deployment Security Scan");try{let Y=J?.source||".",Q=J?.failOn||"critical",Z=J?.skipPatterns?.split(",").map((z)=>z.trim())||[];if(!q1(Y)){R(`Source directory not found: ${Y}`);return}F(`Source: ${Y}`),F(`Fail on: ${Q} or higher severity`);let{passed:U,result:W}=await r9({sourceDir:Y,failOnSeverity:Q,skipPatterns:Z});if(n9(W),U)C(`
7809
7809
  ✓ Security scan passed - no blocking issues found`);else R(`
7810
7810
  ✗ Security scan failed - blocking issues detected`),F(`
7811
- Recommendations:`),F(" 1. Remove any hardcoded credentials from your code"),F(" 2. Use environment variables or AWS Secrets Manager"),F(" 3. Add sensitive files to .gitignore"),F(" 4. Use --skip-patterns to ignore false positives"),process.exit(1)}catch(Y){R(`Security scan failed: ${Y.message}`),process.exit(1)}}),$.command("deploy","Deploy infrastructure").option("--stack <name>","Stack name").option("--env <environment>","Environment to deploy to").option("--site <name>","Deploy specific site only").option("--skip-security-scan","Skip pre-deployment security scan").option("--skip-dns-verification","Skip DNS provider verification and record creation (use when DNS is already configured)").option("--security-fail-on <severity>","Security scan fail threshold (critical, high, medium, low)",{default:"critical"}).option("--yes","Skip confirmation prompts (non-interactive / CI)").action(async(J)=>{V("Deploying Infrastructure");let Y=J?.yes===!0||process.env.CI==="true",Q=J?.env||"staging",Z=null;Z=await vB(Q);try{let U=await c(),W=U.project?.region||"us-east-1";if(await hB(W),!J?.skipSecurityScan){let I=process.cwd(),{passed:f,result:m}=await r9({sourceDir:I,failOnSeverity:J?.securityFailOn||"critical"});if(n9(m),!f){R(`
7811
+ Recommendations:`),F(" 1. Remove any hardcoded credentials from your code"),F(" 2. Use environment variables or AWS Secrets Manager"),F(" 3. Add sensitive files to .gitignore"),F(" 4. Use --skip-patterns to ignore false positives"),process.exit(1)}catch(Y){R(`Security scan failed: ${Y.message}`),process.exit(1)}}),$.command("deploy","Deploy infrastructure").option("--stack <name>","Stack name").option("--env <environment>","Environment to deploy to").option("--site <name>","Deploy specific site only").option("--skip-security-scan","Skip pre-deployment security scan").option("--skip-dns-verification","Skip DNS provider verification and record creation (use when DNS is already configured)").option("--security-fail-on <severity>","Security scan fail threshold (critical, high, medium, low)",{default:"critical"}).option("--yes","Skip confirmation prompts (non-interactive / CI)").action(async(J)=>{V("Deploying Infrastructure");let Y=J?.yes===!0||process.env.CI==="true",Q=J?.env||"staging",Z=null;Z=await vB(Q);try{let U=await c(),W=U.project?.region||"us-east-1";if(await hB(W),!J?.skipSecurityScan){let k=process.cwd(),{passed:y,result:m}=await r9({sourceDir:k,failOnSeverity:J?.securityFailOn||"critical"});if(n9(m),!y){R(`
7812
7812
  ✗ Security scan failed - deployment blocked`),F(`
7813
7813
  To proceed anyway, use --skip-security-scan flag`),F("To change sensitivity, use --security-fail-on <severity>");return}C(`✓ Security scan passed
7814
7814
  `)}else g(`Security scan skipped (--skip-security-scan)
7815
- `);let z=J?.stack||A1(U,Q),G=U.project.region||"us-east-1",H=U.infrastructure?.deployStack!==!1,A=U.sites&&Object.keys(U.sites).length>0,K=U.infrastructure?.dns?.provider;if(A&&K){if(await fB(U,J?.site,K,G,J?.skipDnsVerification,Q,Y),!H){if(U.infrastructure?.compute){let I=Object.values(U.sites).map((f)=>f.domain).filter((f)=>!!f);if(I.length>0)i("Syncing CloudFront dynamic HTTP methods for app domains..."),await T5(I)}return}}if(!H){F("Infrastructure stack deployment disabled (infrastructure.deployStack: false)");return}let B=w2(U);if(F(`Cloud provider: ${B}`),F(`Stack: ${z}`),F(`Region: ${G}`),F(`Environment: ${Q}`),B==="hetzner"&&U.infrastructure?.compute){i("Provisioning Hetzner compute infrastructure...");let I=p9({config:U,provider:"hetzner"});if(!I.provisionComputeInfrastructure){R("Hetzner driver does not support compute provisioning");return}let f=await I.provisionComputeInfrastructure({config:U,environment:Q});if(C("Hetzner compute infrastructure ready"),f.appPublicIp)F(`App server: ${f.appPublicIp}`);if(f.appInstanceId)F(`Server ID: ${f.appInstanceId}`);return}i("Generating CloudFormation template...");let j=new c2({config:U,environment:Q});j.generate();let X=j.toJSON(),O=JSON.parse(X);i("Validating template...");let _=h9(O),w=b9(X),E=y9(O),M=[..._.errors,...w.errors,...E.errors];if(M.length>0){R("Template validation failed:");for(let I of M)R(` - ${I.path}: ${I.message}`);return}let T=[..._.warnings,...w.warnings,...E.warnings];if(T.length>0)for(let I of T)g(` - ${I.path}: ${I.message}`);C("Template validated successfully");let D=Object.keys(O.Resources).length;F(`
7816
- Resources to deploy: ${D}`);let N={};for(let I of Object.values(O.Resources)){let f=I.Type;N[f]=(N[f]||0)+1}for(let[I,f]of Object.entries(N).sort((m,l)=>l[1]-m[1]).slice(0,5))F(` - ${I}: ${f}`);if(!(Y||await y(`
7817
- Deploy now?`,!0))){F("Deployment cancelled");return}let h=new O0(G);i("Checking stack status...");let k=!1;try{let I=await h.describeStacks({stackName:z});k=I.Stacks&&I.Stacks.length>0}catch(I){k=!1}if(k){F("Stack exists, updating...");let I=new L("Updating CloudFormation stack...");I.start();try{await h.updateStack({stackName:z,templateBody:X,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:Q},{Key:"ManagedBy",Value:"ts-cloud"}]}),I.succeed("Update initiated"),i("Waiting for stack update to complete..."),await h.waitForStack(z,"stack-update-complete"),C("Stack updated successfully!")}catch(f){if(f.message.includes("No updates are to be performed")){I.succeed("No changes detected"),F("Stack is already up to date");return}throw f}}else{F("Creating new stack...");let I=new L("Creating CloudFormation stack...");I.start(),await h.createStack({stackName:z,templateBody:X,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:Q},{Key:"ManagedBy",Value:"ts-cloud"}]}),I.succeed("Stack creation initiated"),i("Waiting for stack creation to complete..."),await h.waitForStack(z,"stack-create-complete"),C("Stack created successfully!")}let b=await h.getStackOutputs(z);if(M2(`Deployment Complete!
7815
+ `);let z=J?.stack||A1(U,Q),G=U.project.region||"us-east-1",H=U.infrastructure?.deployStack!==!1,A=U.sites&&Object.keys(U.sites).length>0,K=U.infrastructure?.dns?.provider;if(A&&K){if(await fB(U,J?.site,K,G,J?.skipDnsVerification,Q,Y),!H){if(U.infrastructure?.compute){let k=Object.values(U.sites).map((y)=>y.domain).filter((y)=>!!y);if(k.length>0)i("Syncing CloudFront dynamic HTTP methods for app domains..."),await T5(k)}return}}if(!H){F("Infrastructure stack deployment disabled (infrastructure.deployStack: false)");return}let B=w2(U);if(F(`Cloud provider: ${B}`),F(`Stack: ${z}`),F(`Region: ${G}`),F(`Environment: ${Q}`),B==="hetzner"&&U.infrastructure?.compute){i("Provisioning Hetzner compute infrastructure...");let k=p9({config:U,provider:"hetzner"});if(!k.provisionComputeInfrastructure){R("Hetzner driver does not support compute provisioning");return}let y=await k.provisionComputeInfrastructure({config:U,environment:Q});if(C("Hetzner compute infrastructure ready"),y.appPublicIp)F(`App server: ${y.appPublicIp}`);if(y.appInstanceId)F(`Server ID: ${y.appInstanceId}`);return}i("Generating CloudFormation template...");let j=new c2({config:U,environment:Q});j.generate();let X=j.toJSON(),O=JSON.parse(X);i("Validating template...");let _=h9(O),w=b9(X),E=y9(O),M=[..._.errors,...w.errors,...E.errors];if(M.length>0){R("Template validation failed:");for(let k of M)R(` - ${k.path}: ${k.message}`);return}let T=[..._.warnings,...w.warnings,...E.warnings];if(T.length>0)for(let k of T)g(` - ${k.path}: ${k.message}`);C("Template validated successfully");let D=Object.keys(O.Resources).length;F(`
7816
+ Resources to deploy: ${D}`);let N={};for(let k of Object.values(O.Resources)){let y=k.Type;N[y]=(N[y]||0)+1}for(let[k,y]of Object.entries(N).sort((m,l)=>l[1]-m[1]).slice(0,5))F(` - ${k}: ${y}`);if(!(Y||await v(`
7817
+ Deploy now?`,!0))){F("Deployment cancelled");return}let h=new O0(G);i("Checking stack status...");let I=!1;try{let k=await h.describeStacks({stackName:z});I=k.Stacks&&k.Stacks.length>0}catch(k){I=!1}if(I){F("Stack exists, updating...");let k=new L("Updating CloudFormation stack...");k.start();try{await h.updateStack({stackName:z,templateBody:X,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:Q},{Key:"ManagedBy",Value:"ts-cloud"}]}),k.succeed("Update initiated"),i("Waiting for stack update to complete..."),await h.waitForStack(z,"stack-update-complete"),C("Stack updated successfully!")}catch(y){if(y.message.includes("No updates are to be performed")){k.succeed("No changes detected"),F("Stack is already up to date");return}throw y}}else{F("Creating new stack...");let k=new L("Creating CloudFormation stack...");k.start(),await h.createStack({stackName:z,templateBody:X,capabilities:["CAPABILITY_IAM","CAPABILITY_NAMED_IAM"],tags:[{Key:"Project",Value:U.project.name},{Key:"Environment",Value:Q},{Key:"ManagedBy",Value:"ts-cloud"}]}),k.succeed("Stack creation initiated"),i("Waiting for stack creation to complete..."),await h.waitForStack(z,"stack-create-complete"),C("Stack created successfully!")}let b=await h.getStackOutputs(z);if(M2(`Deployment Complete!
7818
7818
 
7819
7819
  Stack: ${z}
7820
7820
  Region: ${G}
@@ -7823,20 +7823,20 @@ Resources: ${D}
7823
7823
 
7824
7824
  View in console:
7825
7825
  https://console.aws.amazon.com/cloudformation/home?region=${G}#/stacks/stackinfo?stackId=${encodeURIComponent(z)}`,"green"),Object.keys(b).length>0){F(`
7826
- Stack Outputs:`);for(let[I,f]of Object.entries(b))F(` - ${I}: ${f}`)}if(U.infrastructure?.storage)for(let[I,f]of Object.entries(U.infrastructure.storage)){if(!f.website||!f.root)continue;let m=b[`${I}BucketName`]||b.FrontendBucketName,l=b[`${I}CloudFrontDistributionId`];if(!m){g(`Could not find bucket name for storage '${I}' — skipping file upload`);continue}if(!q1(f.root)){g(`Source directory not found: ${f.root} — skipping file upload for '${I}'`);continue}i(`Uploading files from ${f.root} to s3://${m}...`);let{uploadStaticFiles:p,invalidateCache:r}=await Promise.resolve().then(() => (u9(),g9)),s=await p({sourceDir:f.root,bucket:m,region:G,onProgress:(o,B0,c0)=>{if(o%10===0||o===B0)F(` ${o}/${B0}: ${c0}`)}});if(s.errors.length>0)g(`Upload completed with errors: ${s.errors.join(", ")}`);else{let o=s.skipped>0?`Uploaded ${s.uploaded} files (${s.skipped} unchanged)`:`Uploaded ${s.uploaded} files`;C(o)}if(l&&s.uploaded>0){i("Invalidating CloudFront cache...");let{invalidationId:o}=await r(l);C(`Cache invalidation created: ${o}`)}}if(U.infrastructure?.compute)await yB(U,Q,G);if(U.infrastructure?.compute&&U.sites){let I=Object.values(U.sites).map((f)=>f.domain).filter((f)=>!!f);if(I.length>0)i("Syncing CloudFront dynamic HTTP methods for app domains..."),await T5(I)}}catch(U){if(R(`Deployment failed: ${U.message}`),U.stack)F(`
7826
+ Stack Outputs:`);for(let[k,y]of Object.entries(b))F(` - ${k}: ${y}`)}if(U.infrastructure?.storage)for(let[k,y]of Object.entries(U.infrastructure.storage)){if(!y.website||!y.root)continue;let m=b[`${k}BucketName`]||b.FrontendBucketName,l=b[`${k}CloudFrontDistributionId`];if(!m){g(`Could not find bucket name for storage '${k}' — skipping file upload`);continue}if(!q1(y.root)){g(`Source directory not found: ${y.root} — skipping file upload for '${k}'`);continue}i(`Uploading files from ${y.root} to s3://${m}...`);let{uploadStaticFiles:p,invalidateCache:r}=await Promise.resolve().then(() => (u9(),g9)),s=await p({sourceDir:y.root,bucket:m,region:G,onProgress:(o,B0,c0)=>{if(o%10===0||o===B0)F(` ${o}/${B0}: ${c0}`)}});if(s.errors.length>0)g(`Upload completed with errors: ${s.errors.join(", ")}`);else{let o=s.skipped>0?`Uploaded ${s.uploaded} files (${s.skipped} unchanged)`:`Uploaded ${s.uploaded} files`;C(o)}if(l&&s.uploaded>0){i("Invalidating CloudFront cache...");let{invalidationId:o}=await r(l);C(`Cache invalidation created: ${o}`)}}if(U.infrastructure?.compute)await yB(U,Q,G);if(U.infrastructure?.compute&&U.sites){let k=Object.values(U.sites).map((y)=>y.domain).filter((y)=>!!y);if(k.length>0)i("Syncing CloudFront dynamic HTTP methods for app domains..."),await T5(k)}}catch(U){if(R(`Deployment failed: ${U.message}`),U.stack)F(`
7827
7827
  Stack trace:`),console.error(U.stack)}finally{if(Z)await Z()}}),$.command("deploy:server","Deploy EC2 infrastructure").option("--env <environment>","Environment (production, staging, development)").action(async(J)=>{V("Deploying Server Infrastructure");try{let Y=await c(),Q=J?.env||"production",Z=`${Y.project.slug}-server-${Q}`,U=Y.project.region||"us-east-1";F(`Stack: ${Z}`),F(`Region: ${U}`),F(`Environment: ${Q}`),i("Generating EC2 server infrastructure...");let W=new L("Deploying server infrastructure...");W.start(),await new Promise((z)=>setTimeout(z,2000)),W.succeed("Server infrastructure deployed successfully!"),C(`
7828
7828
  Deployment complete!`),F(`
7829
7829
  Next steps:`),F(" - cloud server:list - View deployed servers"),F(" - cloud server:ssh <name> - SSH into a server")}catch(Y){R(`Deployment failed: ${Y.message}`)}}),$.command("deploy:serverless","Deploy serverless infrastructure").option("--env <environment>","Environment (production, staging, development)").option("--function <name>","Deploy specific function only").action(async(J)=>{V("Deploying Serverless Infrastructure");try{let Y=await c(),Q=J?.env||"production",Z=`${Y.project.slug}-serverless-${Q}`,U=Y.project.region||"us-east-1";if(F(`Stack: ${Z}`),F(`Region: ${U}`),F(`Environment: ${Q}`),J?.function)F(`Function: ${J.function}`);i("Generating serverless infrastructure...");let W=new L("Deploying serverless infrastructure...");W.start(),await new Promise((z)=>setTimeout(z,2000)),W.succeed("Serverless infrastructure deployed successfully!"),C(`
7830
7830
  Deployment complete!`),F(`
7831
7831
  Next steps:`),F(" - cloud function:list - View deployed functions"),F(" - cloud function:logs <name> - View function logs"),F(" - cloud function:invoke <name> - Test function")}catch(Y){R(`Deployment failed: ${Y.message}`)}}),$.command("deploy:status","Check deployment status").option("--stack <name>","Stack name").option("--env <environment>","Environment").action(async(J)=>{V("Deployment Status");try{let Y=await c(),Q=J?.env||"production",Z=J?.stack||A1(Y,Q),U=Y.project.region||"us-east-1";F(`Stack: ${Z}`),F(`Region: ${U}`);let W=new L("Checking deployment status...");W.start();let G=await new O0(U).describeStacks({stackName:Z});if(G.Stacks.length===0){W.fail("Stack not found"),L1("No deployment found for this environment");return}let H=G.Stacks[0];if(W.succeed("Status retrieved"),F(`
7832
7832
  Status: ${H.StackStatus}`),F(`Created: ${H.CreationTime}`),H.LastUpdatedTime)F(`Last Updated: ${H.LastUpdatedTime}`);if(H.Outputs&&H.Outputs.length>0){F(`
7833
- Outputs:`);for(let A of H.Outputs)F(` ${A.OutputKey}: ${A.OutputValue}`)}}catch(Y){R(`Failed to get status: ${Y.message}`)}}),$.command("deploy:rollback","Rollback to previous version").option("--stack <name>","Stack name").option("--env <environment>","Environment").action(async(J)=>{V("Rolling Back Deployment");try{let Y=await c(),Q=J?.env||"production",Z=J?.stack||A1(Y,Q),U=Y.project.region||"us-east-1";if(F(`Stack: ${Z}`),F(`Region: ${U}`),!await y(`
7833
+ Outputs:`);for(let A of H.Outputs)F(` ${A.OutputKey}: ${A.OutputValue}`)}}catch(Y){R(`Failed to get status: ${Y.message}`)}}),$.command("deploy:rollback","Rollback to previous version").option("--stack <name>","Stack name").option("--env <environment>","Environment").action(async(J)=>{V("Rolling Back Deployment");try{let Y=await c(),Q=J?.env||"production",Z=J?.stack||A1(Y,Q),U=Y.project.region||"us-east-1";if(F(`Stack: ${Z}`),F(`Region: ${U}`),!await v(`
7834
7834
  Are you sure you want to rollback?`,!1)){F("Rollback cancelled");return}let z=new L("Rolling back stack...");z.start();let G=new O0(U);await G.deleteStack(Z),z.succeed("Stack deletion initiated"),i("Waiting for stack deletion..."),await G.waitForStack(Z,"stack-delete-complete"),C("Stack rolled back successfully!")}catch(Y){R(`Rollback failed: ${Y.message}`)}}),$.command("deploy:static","Deploy static site (S3 + CloudFront invalidation)").option("--source <path>","Source directory",{default:"dist"}).option("--bucket <name>","S3 bucket name").option("--distribution <id>","CloudFront distribution ID").option("--prefix <prefix>","S3 prefix/folder").option("--delete","Delete files not in source").option("--cache-control <value>","Cache-Control header",{default:"public, max-age=31536000"}).option("--no-invalidate","Skip CloudFront invalidation").option("--wait","Wait for invalidation to complete").option("--skip-security-scan","Skip pre-deployment security scan").option("--security-fail-on <severity>","Security scan fail threshold (critical, high, medium, low)",{default:"critical"}).action(async(J)=>{V("Deploying Static Site");try{let Q=(await c()).project.region||"us-east-1",Z=J?.source||"dist";if(!J?.skipSecurityScan){i("Scanning source directory for leaked secrets...");let{passed:w,result:E}=await r9({sourceDir:Z,failOnSeverity:J?.securityFailOn||"critical"});if(n9(E),!w){R(`
7835
7835
  ✗ Security scan failed - deployment blocked`),F(`
7836
7836
  Potential secrets detected in frontend build:`),F(" - API keys, tokens, or credentials may be bundled in your code"),F(" - These would be publicly accessible once deployed"),F(`
7837
7837
  To proceed anyway, use --skip-security-scan flag`);return}C(`✓ Security scan passed
7838
7838
  `)}else g(`Security scan skipped (--skip-security-scan)
7839
- `);let U=J?.bucket,W=J?.distribution,z=J?.prefix,G=J?.delete||!1,H=J?.cacheControl||"public, max-age=31536000",A=J?.invalidate!==!1,K=J?.wait||!1;if(!U){R("--bucket is required");return}if(!q1(Z)){R(`Source directory not found: ${Z}`);return}if(F(`Source: ${Z}`),F(`Bucket: s3://${U}${z?`/${z}`:""}`),F(`Cache-Control: ${H}`),W)F(`CloudFront Distribution: ${W}`);if(G)g("Delete mode enabled - files not in source will be removed");if(!await y(`
7839
+ `);let U=J?.bucket,W=J?.distribution,z=J?.prefix,G=J?.delete||!1,H=J?.cacheControl||"public, max-age=31536000",A=J?.invalidate!==!1,K=J?.wait||!1;if(!U){R("--bucket is required");return}if(!q1(Z)){R(`Source directory not found: ${Z}`);return}if(F(`Source: ${Z}`),F(`Bucket: s3://${U}${z?`/${z}`:""}`),F(`Cache-Control: ${H}`),W)F(`CloudFront Distribution: ${W}`);if(G)g("Delete mode enabled - files not in source will be removed");if(!await v(`
7840
7840
  Deploy static site now?`,!0)){F("Deployment cancelled");return}let j=new F0(Q),X=new L("Uploading files to S3...");X.start(),await j.sync({source:Z,bucket:U,prefix:z,delete:G,cacheControl:H,acl:"public-read"}),X.succeed("Files uploaded successfully!");let _=(await j.getBucketSize(U,z)/1024/1024).toFixed(2);if(F(`Total size: ${_} MB`),A&&W){let w=new _0,E=new L("Invalidating CloudFront cache...");E.start();let M=await w.invalidateAll(W);if(E.succeed("Invalidation created"),F(`Invalidation ID: ${M.Id}`),K){let T=new L("Waiting for invalidation to complete...");T.start(),await w.waitForInvalidation(W,M.Id),T.succeed("Invalidation completed!")}}M2(`Static Site Deployed!
7841
7841
 
7842
7842
  Source: ${Z}
@@ -7850,16 +7850,16 @@ https://${U}.s3.${Q}.amazonaws.com${z?`/${z}`:""}/index.html`,"green")}catch(Y){
7850
7850
  Potential secrets detected in container build context:`),F(" - Credentials may be baked into the Docker image"),F(" - Use Docker secrets or environment variables instead"),F(`
7851
7851
  To proceed anyway, use --skip-security-scan flag`);return}C(`✓ Security scan passed
7852
7852
  `)}else g(`Security scan skipped (--skip-security-scan)
7853
- `);if(F(`Cluster: ${Z}`),F(`Service: ${U}`),F(`Repository: ${W}`),F(`Image Tag: ${z}`),F(`Dockerfile: ${G}`),!await y(`
7854
- Deploy container now?`,!0)){F("Deployment cancelled");return}let j=new _5(Q),X=new q5(Q),O=new L("Getting ECR credentials...");O.start();let _=await j.getAuthorizationToken();if(!_.authorizationData?.[0]){O.fail("Failed to get ECR credentials");return}let w=_.authorizationData[0],M=(w.proxyEndpoint||"").replace("https://","");O.succeed("ECR credentials obtained");let T=new L("Logging into ECR...");T.start();let D=w.authorizationToken||"",x=Buffer.from(D,"base64").toString("utf8").split(":")[1],{spawn:h}=await import("child_process"),k=h("docker",["login","--username","AWS","--password-stdin",M],{stdio:["pipe","pipe","pipe"]});k.stdin.write(x),k.stdin.end(),await new Promise((r,s)=>{k.on("close",(o)=>{if(o===0)r();else s(Error(`Docker login failed with code ${o}`))})}),T.succeed("Logged into ECR");let b=new L("Building Docker image...");b.start();let I=`${M}/${W}:${z}`,f=h("docker",["build","-t",I,"-f",G,H],{stdio:["pipe","pipe","pipe"]});await new Promise((r,s)=>{let o="";f.stderr.on("data",(B0)=>{o+=B0.toString()}),f.on("close",(B0)=>{if(B0===0)r();else s(Error(`Docker build failed: ${o}`))})}),b.succeed("Docker image built");let m=new L("Pushing image to ECR...");m.start();let l=h("docker",["push",I],{stdio:["pipe","pipe","pipe"]});await new Promise((r,s)=>{let o="";l.stderr.on("data",(B0)=>{o+=B0.toString()}),l.on("close",(B0)=>{if(B0===0)r();else s(Error(`Docker push failed: ${o}`))})}),m.succeed("Image pushed to ECR");let p=new L("Updating ECS service...");if(p.start(),await X.updateService({cluster:Z,service:U,forceNewDeployment:A}),p.succeed("ECS service updated"),K){let r=new L("Waiting for deployment to stabilize...");r.start(),await X.waitForServiceStable(Z,U),r.succeed("Deployment stabilized")}C(`
7853
+ `);if(F(`Cluster: ${Z}`),F(`Service: ${U}`),F(`Repository: ${W}`),F(`Image Tag: ${z}`),F(`Dockerfile: ${G}`),!await v(`
7854
+ Deploy container now?`,!0)){F("Deployment cancelled");return}let j=new _5(Q),X=new q5(Q),O=new L("Getting ECR credentials...");O.start();let _=await j.getAuthorizationToken();if(!_.authorizationData?.[0]){O.fail("Failed to get ECR credentials");return}let w=_.authorizationData[0],M=(w.proxyEndpoint||"").replace("https://","");O.succeed("ECR credentials obtained");let T=new L("Logging into ECR...");T.start();let D=w.authorizationToken||"",x=Buffer.from(D,"base64").toString("utf8").split(":")[1],{spawn:h}=await import("child_process"),I=h("docker",["login","--username","AWS","--password-stdin",M],{stdio:["pipe","pipe","pipe"]});I.stdin.write(x),I.stdin.end(),await new Promise((r,s)=>{I.on("close",(o)=>{if(o===0)r();else s(Error(`Docker login failed with code ${o}`))})}),T.succeed("Logged into ECR");let b=new L("Building Docker image...");b.start();let k=`${M}/${W}:${z}`,y=h("docker",["build","-t",k,"-f",G,H],{stdio:["pipe","pipe","pipe"]});await new Promise((r,s)=>{let o="";y.stderr.on("data",(B0)=>{o+=B0.toString()}),y.on("close",(B0)=>{if(B0===0)r();else s(Error(`Docker build failed: ${o}`))})}),b.succeed("Docker image built");let m=new L("Pushing image to ECR...");m.start();let l=h("docker",["push",k],{stdio:["pipe","pipe","pipe"]});await new Promise((r,s)=>{let o="";l.stderr.on("data",(B0)=>{o+=B0.toString()}),l.on("close",(B0)=>{if(B0===0)r();else s(Error(`Docker push failed: ${o}`))})}),m.succeed("Image pushed to ECR");let p=new L("Updating ECS service...");if(p.start(),await X.updateService({cluster:Z,service:U,forceNewDeployment:A}),p.succeed("ECS service updated"),K){let r=new L("Waiting for deployment to stabilize...");r.start(),await X.waitForServiceStable(Z,U),r.succeed("Deployment stabilized")}C(`
7855
7855
  Container deployment complete!`),F(`
7856
- Image: ${I}`),F(`Cluster: ${Z}`),F(`Service: ${U}`)}catch(Y){R(`Deployment failed: ${Y.message}`)}})}async function vB($){let J=process.cwd(),Y=`${J}/.env`,Q=`${J}/.env.local`,W=({stage:["stage","staging"],staging:["staging","stage"]}[$]||[$]).map((K)=>`${J}/.env.${K}`).find((K)=>q1(K));if(!W){if(q1(Y))g(`No .env.${$} found, falling back to .env`);else R(`No .env.${$} or .env file found`);return null}let z=W.split("/").pop();i(`Loading environment file: ${z}`);let G=null,H=null;if(q1(Q)){G=`${Q}.bak`,w$(Q,G);let K=$U(Q,"utf-8");for(let j of K.split(`
7856
+ Image: ${k}`),F(`Cluster: ${Z}`),F(`Service: ${U}`)}catch(Y){R(`Deployment failed: ${Y.message}`)}})}async function vB($){let J=process.cwd(),Y=`${J}/.env`,Q=`${J}/.env.local`,W=({stage:["stage","staging"],staging:["staging","stage"]}[$]||[$]).map((K)=>`${J}/.env.${K}`).find((K)=>q1(K));if(!W){if(q1(Y))g(`No .env.${$} found, falling back to .env`);else R(`No .env.${$} or .env file found`);return null}let z=W.split("/").pop();i(`Loading environment file: ${z}`);let G=null,H=null;if(q1(Q)){G=`${Q}.bak`,w$(Q,G);let K=$U(Q,"utf-8");for(let j of K.split(`
7857
7857
  `)){let X=j.trim();if(!X||X.startsWith("#"))continue;let O=X.indexOf("=");if(O===-1)continue;let _=X.slice(0,O).trim();delete process.env[_]}let{unlinkSync:B}=await import("node:fs");B(Q),F("Temporarily moved .env.local out of the way and purged its values from process.env")}if(q1(Y))H=`${Y}.bak`,w$(Y,H);w$(W,Y);let A=$U(W,"utf-8");for(let K of A.split(`
7858
7858
  `)){let B=K.trim();if(!B||B.startsWith("#"))continue;let j=B.indexOf("=");if(j===-1)continue;let X=B.slice(0,j).trim(),O=B.slice(j+1).trim();process.env[X]=O}return C(`Loaded ${z}`),async()=>{let{unlinkSync:K}=await import("node:fs");if(H)w$(H,`${J}/.env`),K(H),F("Restored .env");if(G)w$(G,`${J}/.env.local`),K(G),F("Restored .env.local")}}async function fB($,J,Y,Q,Z,U,W=!1){let z=$.sites||{},G=J?[J]:Object.keys(z);if(G.length===0){g("No sites configured in cloud.config.ts");return}let H=H1(Y);if(!H){R(`DNS provider '${Y}' is not configured. Please set the required environment variables.`),F(`
7859
- For Cloudflare: CLOUDFLARE_API_TOKEN`),F("For Porkbun: PORKBUN_API_KEY, PORKBUN_SECRET_KEY"),F("For GoDaddy: GODADDY_API_KEY, GODADDY_API_SECRET");return}if(H.provider==="route53"){let K=$.infrastructure?.dns?.hostedZoneId;if(K&&!H.hostedZoneId)H.hostedZoneId=K}let A=e0(H);for(let K of G){let B=z[K];if(!B){R(`Site '${K}' not found in configuration`);continue}let j=B.domain;if(!j){R(`Site '${K}' has no domain configured`);continue}if(V(`Deploying Site: ${K}`),F(`Domain: ${j}`),F(`Source: ${B.root}`),F(`DNS Provider: ${Y}`),B.build){i(`Running build command: ${B.build}`);try{let{execSync:D}=await import("node:child_process");D(B.build,{stdio:"inherit",cwd:process.cwd()}),C("Build completed successfully")}catch(D){R(`Build failed: ${D.message}`);continue}}if(!q1(B.root)){if(R(`Source directory not found: ${B.root}`),!B.build)F('Run your build command first (e.g., bun run generate) or add a "build" option to your site config');continue}i("Checking existing DNS records...");let X=await A.listRecords(j);if(X.success&&X.records.length>0){let D=j.split("."),N=D.length>2?D[0]:"@",x=D.slice(-2).join("."),h=X.records.find((k)=>k.type==="CNAME"&&(k.name===j||k.name===N||k.name===`${N}.${x}`));if(h){let k=h.content.includes("netlify"),b=h.content.includes("vercel");if(h.content.includes("cloudfront.net"))F(`Domain already points to CloudFront: ${h.content}`),F("Proceeding with file upload...");else{let f=k?"Netlify":b?"Vercel":"another provider";if(g(`
7860
- Existing CNAME record detected:`),F(` ${h.name} -> ${h.content}`),k||b)F(`
7861
- This domain is currently pointing to ${f}.`),F("Deploying will update this record to point to AWS CloudFront.");if(!(W||await y(`
7862
- Update DNS record to point to AWS CloudFront?`,!0))){F("Deployment cancelled");continue}i(`Removing old ${f} CNAME record...`);let l=await A.deleteRecord(j,{name:h.name,type:"CNAME",content:h.content});if(l.success)C(`Removed CNAME: ${h.name} -> ${h.content}`);else g(`Could not remove old record: ${l.message}`),F("The deployment will attempt to update it instead.")}}}let O=B.root,_,w=!!B.installScript;if(w){let{mkdtempSync:D,copyFileSync:N,readdirSync:x,statSync:h}=await import("node:fs"),{tmpdir:k}=await import("node:os"),{join:b,resolve:I}=await import("node:path");_=D(b(k(),"cloud-install-"));let f=I(B.installScript);N(f,b(_,"index.html"));let m=f.split("/").pop();if(m!=="index.html")N(f,b(_,m));if(q1(B.root)){let l=x(B.root);for(let p of l){let r=b(B.root,p);if(h(r).isFile()&&p!=="index.html")N(r,b(_,p))}}O=_,F(`Install script: ${B.installScript}`),F(`Serving at: curl -fsSL https://${j} | bash`)}i("Deploying to AWS (S3 + CloudFront)...");let E=X6($,K,B,U),M=O6($,K);F(`Stack: ${E}`);let T=await uZ({siteName:M,stackName:E,domain:j,region:Q,bucket:_6($.project.slug,U,K,B.bucket),sourceDir:O,certificateArn:B.certificateArn,dnsProvider:H,skipDnsVerification:Z,passthroughUrls:w,dynamicApp:!!$.infrastructure?.compute?.cloudFrontOriginDomain,computeOriginDomain:$.infrastructure?.compute?.cloudFrontOriginDomain,computeOriginPort:$.infrastructure?.compute?.cloudFrontOriginPort??$.infrastructure?.api?.port??3008,computeOriginId:$.infrastructure?.compute?.cloudFrontOriginId??`${$.project.slug}-site-ec2`,onProgress:(D,N)=>{if(D==="infrastructure")i(N||"Setting up infrastructure...");else if(D==="upload"){if(N?.includes("/")&&!N.includes("1/")){let x=N.match(/(\d+)\/(\d+)/);if(x){let[,h,k]=x;if(Number(h)%10===0||h===k)F(` Uploaded ${h}/${k} files`)}}}else if(D==="invalidate")i("Invalidating CDN cache...")}});if(_){let{rmSync:D}=await import("node:fs");D(_,{recursive:!0,force:!0})}if(T.success){C(`
7859
+ For Cloudflare: CLOUDFLARE_API_TOKEN`),F("For Porkbun: PORKBUN_API_KEY, PORKBUN_SECRET_KEY"),F("For GoDaddy: GODADDY_API_KEY, GODADDY_API_SECRET");return}if(H.provider==="route53"){let K=$.infrastructure?.dns?.hostedZoneId;if(K&&!H.hostedZoneId)H.hostedZoneId=K}let A=e0(H);for(let K of G){let B=z[K];if(!B){R(`Site '${K}' not found in configuration`);continue}let j=B.domain;if(!j){R(`Site '${K}' has no domain configured`);continue}if(V(`Deploying Site: ${K}`),F(`Domain: ${j}`),F(`Source: ${B.root}`),F(`DNS Provider: ${Y}`),B.build){i(`Running build command: ${B.build}`);try{let{execSync:D}=await import("node:child_process");D(B.build,{stdio:"inherit",cwd:process.cwd()}),C("Build completed successfully")}catch(D){R(`Build failed: ${D.message}`);continue}}if(!q1(B.root)){if(R(`Source directory not found: ${B.root}`),!B.build)F('Run your build command first (e.g., bun run generate) or add a "build" option to your site config');continue}i("Checking existing DNS records...");let X=await A.listRecords(j);if(X.success&&X.records.length>0){let D=j.split("."),N=D.length>2?D[0]:"@",x=D.slice(-2).join("."),h=X.records.find((I)=>I.type==="CNAME"&&(I.name===j||I.name===N||I.name===`${N}.${x}`));if(h){let I=h.content.includes("netlify"),b=h.content.includes("vercel");if(h.content.includes("cloudfront.net"))F(`Domain already points to CloudFront: ${h.content}`),F("Proceeding with file upload...");else{let y=I?"Netlify":b?"Vercel":"another provider";if(g(`
7860
+ Existing CNAME record detected:`),F(` ${h.name} -> ${h.content}`),I||b)F(`
7861
+ This domain is currently pointing to ${y}.`),F("Deploying will update this record to point to AWS CloudFront.");if(!(W||await v(`
7862
+ Update DNS record to point to AWS CloudFront?`,!0))){F("Deployment cancelled");continue}i(`Removing old ${y} CNAME record...`);let l=await A.deleteRecord(j,{name:h.name,type:"CNAME",content:h.content});if(l.success)C(`Removed CNAME: ${h.name} -> ${h.content}`);else g(`Could not remove old record: ${l.message}`),F("The deployment will attempt to update it instead.")}}}let O=B.root,_,w=!!B.installScript;if(w){let{mkdtempSync:D,copyFileSync:N,readdirSync:x,statSync:h}=await import("node:fs"),{tmpdir:I}=await import("node:os"),{join:b,resolve:k}=await import("node:path");_=D(b(I(),"cloud-install-"));let y=k(B.installScript);N(y,b(_,"index.html"));let m=y.split("/").pop();if(m!=="index.html")N(y,b(_,m));if(q1(B.root)){let l=x(B.root);for(let p of l){let r=b(B.root,p);if(h(r).isFile()&&p!=="index.html")N(r,b(_,p))}}O=_,F(`Install script: ${B.installScript}`),F(`Serving at: curl -fsSL https://${j} | bash`)}i("Deploying to AWS (S3 + CloudFront)...");let E=X6($,K,B,U),M=O6($,K);F(`Stack: ${E}`);let T=await uZ({siteName:M,stackName:E,domain:j,region:Q,bucket:_6($.project.slug,U,K,B.bucket),sourceDir:O,certificateArn:B.certificateArn,dnsProvider:H,skipDnsVerification:Z,passthroughUrls:w,dynamicApp:!!$.infrastructure?.compute?.cloudFrontOriginDomain,computeOriginDomain:$.infrastructure?.compute?.cloudFrontOriginDomain,computeOriginPort:$.infrastructure?.compute?.cloudFrontOriginPort??$.infrastructure?.api?.port??3008,computeOriginId:$.infrastructure?.compute?.cloudFrontOriginId??`${$.project.slug}-site-ec2`,onProgress:(D,N)=>{if(D==="infrastructure")i(N||"Setting up infrastructure...");else if(D==="upload"){if(N?.includes("/")&&!N.includes("1/")){let x=N.match(/(\d+)\/(\d+)/);if(x){let[,h,I]=x;if(Number(h)%10===0||h===I)F(` Uploaded ${h}/${I} files`)}}}else if(D==="invalidate")i("Invalidating CDN cache...")}});if(_){let{rmSync:D}=await import("node:fs");D(_,{recursive:!0,force:!0})}if(T.success){C(`
7863
7863
  Deployment successful!`);let D=T.filesSkipped>0?`${T.filesUploaded} uploaded, ${T.filesSkipped} unchanged`:`${T.filesUploaded}`,N=w?`
7864
7864
  Install: curl -fsSL https://${T.domain} | bash`:"";M2(`Site Deployed!
7865
7865
 
@@ -7876,60 +7876,60 @@ Outputs:`);for(let H of z.Outputs)if(F(` - ${H.OutputKey}: ${H.OutputValue}`),H
7876
7876
  Tags:`);for(let H of z.Tags)F(` - ${H.Key}: ${H.Value}`)}i(`
7877
7877
  Loading stack resources...`);let G=await Z.listStackResources(J);if(G.StackResourceSummaries.length>0){F(`
7878
7878
  Resources (${G.StackResourceSummaries.length}):`);let H=["Logical ID","Type","Status"],A=G.StackResourceSummaries.slice(0,10).map((K)=>[K.LogicalResourceId,K.ResourceType,K.ResourceStatus]);if(d(H,A),G.StackResourceSummaries.length>10)F(`
7879
- ... and ${G.StackResourceSummaries.length-10} more resources`)}}catch(Y){R(`Failed to describe stack: ${Y.message}`)}}),$.command("stack:delete STACK_NAME","Delete a CloudFormation stack").action(async(J)=>{V(`Delete Stack: ${J}`);try{let Q=(await c()).project.region||"us-east-1";if(g("This will permanently delete the stack and all its resources!"),!await y(`
7879
+ ... and ${G.StackResourceSummaries.length-10} more resources`)}}catch(Y){R(`Failed to describe stack: ${Y.message}`)}}),$.command("stack:delete STACK_NAME","Delete a CloudFormation stack").action(async(J)=>{V(`Delete Stack: ${J}`);try{let Q=(await c()).project.region||"us-east-1";if(g("This will permanently delete the stack and all its resources!"),!await v(`
7880
7880
  Are you sure you want to delete this stack?`,!1)){F("Deletion cancelled");return}let U=new O0(Q),W=new L("Deleting stack...");W.start(),await U.deleteStack(J),W.succeed("Stack deletion initiated"),i("Waiting for stack deletion..."),await U.waitForStack(J,"stack-delete-complete"),C("Stack deleted successfully!")}catch(Y){R(`Failed to delete stack: ${Y.message}`)}}),$.command("stack:events STACK_NAME","Show stack events").option("--limit <number>","Limit number of events",{default:"20"}).action(async(J,Y)=>{V(`Stack Events: ${J}`);try{let Z=(await c()).project.region||"us-east-1",U=new O0(Z),W=new L("Loading events...");W.start();let z=await U.describeStackEvents(J);W.succeed(`Found ${z.StackEvents.length} events`);let G=Y?.limit?Number.parseInt(Y.limit):20,H=z.StackEvents.slice(0,G);if(H.length===0){F("No events found");return}let A=["Time","Resource","Status","Reason"],K=H.map((B)=>[new Date(B.Timestamp).toLocaleString(),B.LogicalResourceId,B.ResourceStatus,B.ResourceStatusReason||""]);d(A,K)}catch(Q){R(`Failed to load events: ${Q.message}`)}}),$.command("stack:outputs STACK_NAME","Show stack outputs").action(async(J)=>{V(`Stack Outputs: ${J}`);try{let Q=(await c()).project.region||"us-east-1",Z=new O0(Q),U=new L("Loading stack outputs...");U.start();let W=await Z.describeStacks({stackName:J});if(!W.Stacks||W.Stacks.length===0){U.fail("Stack not found");return}let z=W.Stacks[0];if(U.succeed("Stack outputs loaded"),!z.Outputs||z.Outputs.length===0){F("No outputs found for this stack");return}let G=["Key","Value","Description","Export Name"],H=z.Outputs.map((A)=>[A.OutputKey||"",A.OutputValue||"",A.Description||"",A.ExportName||""]);d(G,H),F(`
7881
7881
  Copy-friendly format:`);for(let A of z.Outputs)F(`${A.OutputKey}=${A.OutputValue}`)}catch(Y){R(`Failed to load outputs: ${Y.message}`)}}),$.command("stack:export STACK_NAME","Export stack template").option("--output <file>","Output file path").option("--format <format>","Output format (json or yaml)",{default:"json"}).action(async(J,Y)=>{V(`Export Stack: ${J}`);try{let Z=(await c()).project.region||"us-east-1",U=new O0(Z),W=new L("Fetching stack template...");W.start();let z=await U.getTemplate(J);if(!z.TemplateBody){W.fail("Template not found");return}W.succeed("Template fetched");let G=Y?.format||"json",H=z.TemplateBody;if(G==="json"){let A=JSON.parse(H);H=JSON.stringify(A,null,2)}if(Y?.output){let A=Y.output;gB(A,H,"utf-8"),C(`Template exported to: ${A}`);let B=(uB(A).size/1024).toFixed(2);F(`File size: ${B} KB`)}else F(`
7882
7882
  Template:`),console.log(H)}catch(Q){R(`Failed to export template: ${Q.message}`)}})}import{existsSync as dB}from"node:fs";S1();s1();function u5($,J){$.command("upgrade","Upgrade CLI to latest version").action(async()=>{V("Upgrading ts-cloud CLI");let Y=new L("Checking for updates...");if(Y.start(),await new Promise((U)=>setTimeout(U,2000)),Y.stop(),F(`
7883
- Current version: 0.1.0`),F("Latest version: 0.2.0"),!await y(`
7883
+ Current version: 0.1.0`),F("Latest version: 0.2.0"),!await v(`
7884
7884
  Upgrade to latest version?`,!0)){F("Operation cancelled");return}let Z=new L("Upgrading...");Z.start(),await new Promise((U)=>setTimeout(U,3000)),Z.succeed("Upgrade completed successfully"),C(`
7885
7885
  ts-cloud CLI upgraded to v0.2.0!`),F(`
7886
7886
  What's new in v0.2.0:`),F(" - New cost optimization commands"),F(" - Improved team collaboration features"),F(" - Better error messages"),F(" - Performance improvements"),F("\nTip: Run `cloud --help` to see all available commands")}),$.command("doctor","Check system requirements and AWS credentials").action(async()=>{if(V("System Diagnostics"),i("Checking Bun..."),C(`Bun ${process.versions.bun}`),i("Checking AWS CLI..."),await xJ())C("AWS CLI is installed");else R("AWS CLI is not installed"),F("Install: https://aws.amazon.com/cli/");if(i("Checking AWS credentials..."),await CJ()){C("AWS credentials are configured");let U=await IJ();if(U)F(`Account ID: ${U}`)}else R("AWS credentials are not configured"),F("Run: aws configure");i("Checking CloudFront list access...");let Z=!1;try{let{CloudFrontClient:U}=await Promise.resolve().then(() => (l1(),j5));await new U().listDistributions(),C("CloudFront list access is enabled"),Z=!0}catch(U){g(`CloudFront list check failed: ${U.message}`)}if(Z){i("Checking CloudFront create access...");try{let U=new O0("us-east-1"),W=JSON.stringify({AWSTemplateFormatVersion:"2010-09-09",Description:"Test CloudFront access",Resources:{TestOAC:{Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:"test-oac-validation",OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}}}});await U.validateTemplate(W),C("CloudFront create access appears enabled")}catch(U){if(U.message?.includes("403")||U.message?.includes("AccessDenied")||U.message?.includes("must be verified"))R("CloudFront create access denied - account verification required"),F(""),F("Your AWS account needs to be verified for CloudFront."),F("This is required before you can create CloudFront distributions."),F(""),F("To verify your account:"),F(" 1. Go to: https://console.aws.amazon.com/support/home#/"),F(" 2. Create a support case"),F(" 3. Select: Service limit increase > CloudFront"),F(' 4. Request: "Please verify my account for CloudFront access"'),F(""),F("Verification usually takes 1-2 business days.");else C("CloudFront create access appears enabled (validation passed)")}}i("Checking S3 access...");try{let{S3Client:U}=await Promise.resolve().then(() => (P1(),G5));await new U("us-east-1").listBuckets(),C("S3 access is enabled")}catch(U){g(`S3 check failed: ${U.message}`)}i("Checking ACM (SSL certificates) access...");try{await new y0("us-east-1").listCertificates(),C("ACM access is enabled")}catch(U){g(`ACM check failed: ${U.message}`)}if(i("Checking configuration..."),dB("cloud.config.ts"))C("cloud.config.ts found");else g("cloud.config.ts not found"),F("Run: cloud init")}),$.command("regions","List available AWS regions").action(async()=>{V("AWS Regions");let Y=new L("Fetching regions...");Y.start();let Q=await kJ();Y.stop(),Q.forEach((Z)=>{console.log(` ${Z}`)})}),$.command("version","Show the version of the CLI").alias("v").action(()=>{console.log(`ts-cloud v${J}`)})}z0();class b0{client;region;endpoint;constructor($="us-east-1",J){this.region=$,this.endpoint=J?.endpoint,this.client=new t}async request($,J){if(this.endpoint){let Y=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/x-amz-json-1.0","X-Amz-Target":`DynamoDB_20120810.${$}`},body:JSON.stringify(J)});if(!Y.ok){let Q=await Y.text();throw Error(`DynamoDB request failed: ${Y.status} ${Q}`)}return Y.json()}return this.client.request({service:"dynamodb",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.0","X-Amz-Target":`DynamoDB_20120810.${$}`},body:JSON.stringify(J)})}async createTable($){return this.request("CreateTable",$)}async deleteTable($){return this.request("DeleteTable",$)}async describeTable($){return this.request("DescribeTable",$)}async listTables($){return this.request("ListTables",$||{})}async putItem($){return this.request("PutItem",$)}async getItem($){return this.request("GetItem",$)}async updateItem($){return this.request("UpdateItem",$)}async deleteItem($){return this.request("DeleteItem",$)}async query($){return this.request("Query",$)}async scan($){return this.request("Scan",$)}async batchWriteItem($){return this.request("BatchWriteItem",$)}async batchGetItem($){return this.request("BatchGetItem",$)}async updateTimeToLive($){return this.request("UpdateTimeToLive",$)}static marshal($){let J={};for(let[Y,Q]of Object.entries($))J[Y]=b0.marshalValue(Q);return J}static marshalValue($){if($===null||$===void 0)return{NULL:!0};if(typeof $==="string")return{S:$};if(typeof $==="number")return{N:String($)};if(typeof $==="boolean")return{BOOL:$};if(Array.isArray($))return{L:$.map((J)=>b0.marshalValue(J))};if(typeof $==="object")return{M:b0.marshal($)};return{S:String($)}}static unmarshal($){let J={};for(let[Y,Q]of Object.entries($))J[Y]=b0.unmarshalValue(Q);return J}static unmarshalValue($){if($.S!==void 0)return $.S;if($.N!==void 0)return Number($.N);if($.BOOL!==void 0)return $.BOOL;if($.NULL!==void 0)return null;if($.L!==void 0)return $.L.map((J)=>b0.unmarshalValue(J));if($.M!==void 0)return b0.unmarshal($.M);if($.SS!==void 0)return $.SS;if($.NS!==void 0)return $.NS.map(Number);return null}}function d5($){$.command("analytics:sites:list","List all analytics sites").option("--table <name>","DynamoDB table name",{default:"ts-analytics"}).option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J)=>{V("Analytics Sites");try{let Y=new b0(J.region),Q=new L("Fetching sites...");Q.start();let Z=await Y.scan({TableName:J.table,FilterExpression:"begins_with(pk, :pk)",ExpressionAttributeValues:{":pk":{S:"SITE#"}}});if(Q.succeed(`Found ${Z.Items?.length||0} site(s)`),!Z.Items||Z.Items.length===0){F("No analytics sites found"),F("Use `cloud analytics:sites:create` to create a new site");return}let U=Z.Items.map((W)=>b0.unmarshal(W));d(["ID","Name","Domains","Active","Created"],U.map((W)=>[W.siteId||"N/A",W.name||"Unnamed",(W.domains||[]).join(", ")||"-",W.isActive?"Yes":"No",W.createdAt?new Date(W.createdAt).toLocaleDateString():"N/A"]))}catch(Y){R(`Failed to list sites: ${Y.message}`),process.exit(1)}}),$.command("analytics:sites:create","Create a new analytics site").option("--table <name>","DynamoDB table name",{default:"ts-analytics"}).option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","Site name").option("--domain <domain>","Site domain(s) (can be specified multiple times)").action(async(J)=>{V("Create Analytics Site");try{let Y=new b0(J.region),Q=J.name||await A0("Site name","My Site"),Z=[];if(J.domain)Z=Array.isArray(J.domain)?J.domain:[J.domain];else Z=(await A0("Site domains (comma-separated)","example.com")).split(",").map((A)=>A.trim()).filter(Boolean);if(F(`
7887
- Creating site: ${Q}`),F(`Domains: ${Z.join(", ")}`),!await y(`
7887
+ Creating site: ${Q}`),F(`Domains: ${Z.join(", ")}`),!await v(`
7888
7888
  Create this site?`,!0)){F("Operation cancelled");return}let W=new L("Creating site...");W.start();let z=`site_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,G=new Date().toISOString();await Y.putItem({TableName:J.table,Item:{pk:{S:`SITE#${z}`},sk:{S:`SITE#${z}`},siteId:{S:z},name:{S:Q},domains:{L:Z.map((H)=>({S:H}))},isActive:{BOOL:!0},createdAt:{S:G},updatedAt:{S:G}}}),W.succeed("Site created successfully"),C(`
7889
7889
  Site ID: ${z}`),F(`
7890
7890
  Add the tracking script to your website:`),F(` <script src="https://analytics.stacksjs.com/track.js" data-site-id="${z}"></script>`)}catch(Y){R(`Failed to create site: ${Y.message}`),process.exit(1)}}),$.command("analytics:sites:update <siteId>","Update an analytics site").option("--table <name>","DynamoDB table name",{default:"ts-analytics"}).option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","New site name").option("--domain <domain>","Set domains (replaces existing)").option("--active <boolean>","Set site active/inactive status").action(async(J,Y)=>{V("Update Analytics Site");try{let Q=new b0(Y.region),Z=await Q.getItem({TableName:Y.table,Key:{pk:{S:`SITE#${J}`},sk:{S:`SITE#${J}`}}});if(!Z.Item)R(`Site not found: ${J}`),process.exit(1);let U=b0.unmarshal(Z.Item);F(`Updating site: ${U.name||"Unnamed"} (${J})`),F("");let W=[],z={},G={};if(Y.name)W.push("#n = :name"),z["#n"]="name",G[":name"]={S:Y.name},F(` Name: ${U.name} -> ${Y.name}`);if(Y.domain!==void 0){let H=Array.isArray(Y.domain)?Y.domain:[Y.domain];W.push("domains = :domains"),G[":domains"]={L:H.map((A)=>({S:A}))},F(` Domains: ${JSON.stringify(U.domains||[])} -> ${JSON.stringify(H)}`)}if(Y.active!==void 0){let H=Y.active==="true"||Y.active==="1";W.push("isActive = :active"),G[":active"]={BOOL:H},F(` Active: ${U.isActive} -> ${H}`)}if(W.length===0){g("No updates specified. Use --name, --domain, or --active options.");return}W.push("updatedAt = :updatedAt"),G[":updatedAt"]={S:new Date().toISOString()},await Q.updateItem({TableName:Y.table,Key:{pk:{S:`SITE#${J}`},sk:{S:`SITE#${J}`}},UpdateExpression:`SET ${W.join(", ")}`,ExpressionAttributeNames:Object.keys(z).length>0?z:void 0,ExpressionAttributeValues:G}),F(""),C("Site updated successfully")}catch(Q){R(`Failed to update site: ${Q.message}`),process.exit(1)}}),$.command("analytics:query <siteId>","Query analytics data for a site").option("--table <name>","DynamoDB table name",{default:"ts-analytics"}).option("--region <region>","AWS region",{default:"us-east-1"}).option("--limit <n>","Max items to return",{default:"10"}).option("--type <type>","Filter by type (pageview, event, etc.)").action(async(J,Y)=>{V(`Analytics Data: ${J}`);try{let Q=new b0(Y.region),Z=new L("Querying data...");Z.start();let U=await Q.query({TableName:Y.table,KeyConditionExpression:"pk = :pk",ExpressionAttributeValues:{":pk":{S:`SITE#${J}`}},ScanIndexForward:!1,Limit:parseInt(Y.limit,10)});if(Z.succeed(`Found ${U.Items?.length||0} items`),!U.Items||U.Items.length===0){F("No data found for this site");return}let W=U.Items.map((z)=>b0.unmarshal(z));for(let z of W){if(F(""),F(`SK: ${z.sk}`),z.path)F(` Path: ${z.path}`);if(z.timestamp)F(` Time: ${z.timestamp}`);if(z.visitorId)F(` Visitor: ${z.visitorId}`);if(z.browser)F(` Browser: ${z.browser}`);if(z.country)F(` Country: ${z.country}`)}}catch(Q){R(`Failed to query data: ${Q.message}`),process.exit(1)}}),$.command("analytics:realtime <siteId>","Check realtime visitors for a site").option("--table <name>","DynamoDB table name",{default:"ts-analytics"}).option("--region <region>","AWS region",{default:"us-east-1"}).option("--minutes <n>","Minutes to look back",{default:"5"}).action(async(J,Y)=>{V(`Realtime: ${J}`);try{let Q=new b0(Y.region),Z=new L("Checking realtime...");Z.start();let U=parseInt(Y.minutes,10),W=new Date(Date.now()-U*60*1000),z=await Q.query({TableName:Y.table,KeyConditionExpression:"pk = :pk AND sk BETWEEN :start AND :end",ExpressionAttributeValues:{":pk":{S:`SITE#${J}`},":start":{S:`PAGEVIEW#${W.toISOString()}`},":end":{S:"PAGEVIEW#Z"}},ScanIndexForward:!1});if(Z.succeed(`Found ${z.Items?.length||0} pageviews in last ${U} minutes`),!z.Items||z.Items.length===0){g("No recent pageviews found"),F(""),F("Possible issues:"),F(" 1. Tracking script not installed correctly"),F(" 2. Site ID mismatch"),F(" 3. CORS or network issues");return}let G=z.Items.map((K)=>b0.unmarshal(K)),H=new Set(G.map((K)=>K.visitorId)).size;F(""),C(`${H} unique visitor(s) online`),F("");let A={};for(let K of G){let B=K.path||"/";A[B]=(A[B]||0)+1}F("Active pages:");for(let[K,B]of Object.entries(A).sort((j,X)=>X[1]-j[1]).slice(0,5))F(` ${K}: ${B} view(s)`);F(""),F("Recent pageviews:");for(let K of G.slice(0,5))F(` ${K.timestamp} - ${K.path} (${K.browser||"Unknown"})`)}catch(Q){R(`Failed to check realtime: ${Q.message}`),process.exit(1)}})}l1();function m5($){$.command("cdn:list","List all CloudFront distributions").action(async()=>{V("CloudFront Distributions");try{let J=await c(),Y=new _0,Q=new L("Fetching distributions...");Q.start();let Z=await Y.listDistributions();if(Q.succeed(`Found ${Z.length} distribution(s)`),Z.length===0){F("No CloudFront distributions found"),F("Use `cloud cdn:create` to create a new distribution");return}d(["ID","Domain","Status","Enabled","Aliases"],Z.map((U)=>[U.Id||"N/A",U.DomainName||"N/A",U.Status||"N/A",U.Enabled?"Yes":"No",(U.Aliases?.Items?.length||0).toString()]))}catch(J){R(`Failed to list distributions: ${J.message}`),process.exit(1)}}),$.command("cdn:status <distributionId>","Get CloudFront distribution status").action(async(J)=>{V(`CloudFront Distribution: ${J}`);try{let Y=new _0,Q=new L("Fetching distribution details...");Q.start();let Z=await Y.getDistribution(J);if(Q.succeed("Distribution details loaded"),F(`
7891
7891
  Distribution Information:`),F(` ID: ${Z.Id}`),F(` Domain: ${Z.DomainName}`),F(` Status: ${Z.Status}`),F(` ARN: ${Z.ARN}`),F(` Enabled: ${Z.Enabled?"Yes":"No"}`),Z.Aliases?.Items?.length)F(` Aliases: ${Z.Aliases.Items.join(", ")}`);let U=await Y.getDistributionConfig(J);F(`
7892
7892
  Origins:`);let W=U.DistributionConfig?.Origins?.Items||[];if(Array.isArray(W))for(let z of W)F(` - ${z.Id}: ${z.DomainName}`);if(U.DistributionConfig?.DefaultCacheBehavior){let z=U.DistributionConfig.DefaultCacheBehavior;F(`
7893
- Default Cache Behavior:`),F(` Target Origin: ${z.TargetOriginId}`),F(` Viewer Protocol: ${z.ViewerProtocolPolicy}`)}}catch(Y){R(`Failed to get distribution: ${Y.message}`),process.exit(1)}}),$.command("cdn:create","Create a new CloudFront distribution for an S3 bucket").option("--bucket <name>","S3 bucket name").option("--region <region>","S3 bucket region",{default:"us-east-1"}).option("--alias <domain>","Custom domain alias (CNAME)").option("--certificate <arn>","ACM certificate ARN for custom domain").option("--comment <text>","Distribution comment/description").action(async(J)=>{V("Create CloudFront Distribution");try{if(!J.bucket)R("--bucket is required"),F("Example: cloud cdn:create --bucket my-bucket --region us-east-1"),process.exit(1);let Y=new _0;if(F(`Bucket: ${J.bucket}`),F(`Region: ${J.region}`),J.alias)F(`Alias: ${J.alias}`);if(!await y(`
7893
+ Default Cache Behavior:`),F(` Target Origin: ${z.TargetOriginId}`),F(` Viewer Protocol: ${z.ViewerProtocolPolicy}`)}}catch(Y){R(`Failed to get distribution: ${Y.message}`),process.exit(1)}}),$.command("cdn:create","Create a new CloudFront distribution for an S3 bucket").option("--bucket <name>","S3 bucket name").option("--region <region>","S3 bucket region",{default:"us-east-1"}).option("--alias <domain>","Custom domain alias (CNAME)").option("--certificate <arn>","ACM certificate ARN for custom domain").option("--comment <text>","Distribution comment/description").action(async(J)=>{V("Create CloudFront Distribution");try{if(!J.bucket)R("--bucket is required"),F("Example: cloud cdn:create --bucket my-bucket --region us-east-1"),process.exit(1);let Y=new _0;if(F(`Bucket: ${J.bucket}`),F(`Region: ${J.region}`),J.alias)F(`Alias: ${J.alias}`);if(!await v(`
7894
7894
  Create this distribution?`,!0)){F("Operation cancelled");return}let Z=new L("Setting up Origin Access Control...");Z.start();let U=await Y.findOrCreateOriginAccessControl(`OAC-${J.bucket}`);if(U.isNew)Z.text="Created new Origin Access Control";Z.text="Creating distribution...";let W=J.alias?[J.alias]:[],z=await Y.createDistributionForS3({bucketName:J.bucket,bucketRegion:J.region,originAccessControlId:U.Id,aliases:W,certificateArn:J.certificate,comment:J.comment||"Created by ts-cloud CLI"});Z.succeed("Distribution created"),C(`
7895
7895
  Distribution ID: ${z.Id}`),F(`Domain: ${z.DomainName}`),F(`Status: ${z.Status}`),F(`
7896
7896
  Note: Distribution deployment may take 15-30 minutes.`),F(`
7897
- IMPORTANT: Update your S3 bucket policy to allow CloudFront access:`);let G=_0.getS3BucketPolicyForCloudFront(J.bucket,z.ARN);F(JSON.stringify(G,null,2))}catch(Y){R(`Failed to create distribution: ${Y.message}`),process.exit(1)}}),$.command("cdn:invalidate <distributionId>","Invalidate CloudFront cache").option("--paths <paths>","Paths to invalidate (comma-separated)",{default:"/*"}).action(async(J,Y)=>{V("Invalidate CloudFront Cache");try{let Q=new _0,Z=Y.paths.split(",").map((G)=>G.trim());if(F(`Distribution: ${J}`),F(`Paths: ${Z.join(", ")}`),!await y(`
7897
+ IMPORTANT: Update your S3 bucket policy to allow CloudFront access:`);let G=_0.getS3BucketPolicyForCloudFront(J.bucket,z.ARN);F(JSON.stringify(G,null,2))}catch(Y){R(`Failed to create distribution: ${Y.message}`),process.exit(1)}}),$.command("cdn:invalidate <distributionId>","Invalidate CloudFront cache").option("--paths <paths>","Paths to invalidate (comma-separated)",{default:"/*"}).action(async(J,Y)=>{V("Invalidate CloudFront Cache");try{let Q=new _0,Z=Y.paths.split(",").map((G)=>G.trim());if(F(`Distribution: ${J}`),F(`Paths: ${Z.join(", ")}`),!await v(`
7898
7898
  Create invalidation?`,!0)){F("Operation cancelled");return}let W=new L("Creating invalidation...");W.start();let z=await Q.createInvalidation({distributionId:J,paths:Z,callerReference:`cli-${Date.now()}`});W.succeed("Invalidation created"),C(`
7899
7899
  Invalidation ID: ${z.Id}`),F(`Status: ${z.Status}`),F(`
7900
- Note: Invalidation typically completes in 5-10 minutes.`)}catch(Q){R(`Failed to create invalidation: ${Q.message}`),process.exit(1)}}),$.command("cdn:disable <distributionId>","Disable a CloudFront distribution").action(async(J)=>{V("Disable CloudFront Distribution");try{let Y=new _0;if(g(`This will disable distribution: ${J}`),F("The distribution will stop serving content."),!await y(`
7900
+ Note: Invalidation typically completes in 5-10 minutes.`)}catch(Q){R(`Failed to create invalidation: ${Q.message}`),process.exit(1)}}),$.command("cdn:disable <distributionId>","Disable a CloudFront distribution").action(async(J)=>{V("Disable CloudFront Distribution");try{let Y=new _0;if(g(`This will disable distribution: ${J}`),F("The distribution will stop serving content."),!await v(`
7901
7901
  Disable this distribution?`,!1)){F("Operation cancelled");return}let Z=new L("Disabling distribution...");Z.start(),await Y.disableDistribution(J),Z.succeed("Distribution disabled"),F(`
7902
- Note: Changes may take 15-30 minutes to propagate.`),F("To delete the distribution, wait for it to be fully disabled first.")}catch(Y){R(`Failed to disable distribution: ${Y.message}`),process.exit(1)}}),$.command("cdn:delete <distributionId>","Delete a CloudFront distribution").action(async(J)=>{V("Delete CloudFront Distribution");try{let Y=new _0;if(g(`This will permanently delete distribution: ${J}`),g("The distribution must be disabled first."),!await y(`
7903
- Delete this distribution?`,!1)){F("Operation cancelled");return}let Z=new L("Checking distribution status...");Z.start();let U=await Y.getDistribution(J);if(U.Status!=="Deployed"||U.Enabled){Z.fail("Distribution must be disabled and deployed before deletion"),F('\nRun `cloud cdn:disable` first and wait for status to be "Deployed"');return}Z.text="Deleting distribution...",await Y.deleteDistribution(J),Z.succeed("Distribution deleted")}catch(Y){R(`Failed to delete distribution: ${Y.message}`),process.exit(1)}})}import{readdirSync as mB,statSync as cB}from"node:fs";import{join as lB,relative as pB}from"node:path";P1();function c5($){$.command("storage:list","List all S3 buckets").option("--region <region>","AWS region").action(async(J)=>{V("S3 Buckets");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new F0(Q),U=new L("Fetching buckets...");U.start();let z=(await Z.listBuckets()).Buckets||[];if(U.succeed(`Found ${z.length} bucket(s)`),z.length===0){F("No S3 buckets found"),F("Use `cloud storage:create` to create a new bucket");return}d(["Name","Created"],z.map((G)=>[G.Name||"N/A",G.CreationDate?new Date(G.CreationDate).toLocaleDateString():"N/A"]))}catch(Y){R(`Failed to list buckets: ${Y.message}`),process.exit(1)}}),$.command("storage:create <name>","Create a new S3 bucket").option("--region <region>","AWS region",{default:"us-east-1"}).option("--public","Enable public access").option("--versioning","Enable versioning").action(async(J,Y)=>{V("Create S3 Bucket");try{let Q=new F0(Y.region);if(F(`Bucket name: ${J}`),F(`Region: ${Y.region}`),F(`Public access: ${Y.public?"Yes":"No"}`),F(`Versioning: ${Y.versioning?"Yes":"No"}`),!await y(`
7902
+ Note: Changes may take 15-30 minutes to propagate.`),F("To delete the distribution, wait for it to be fully disabled first.")}catch(Y){R(`Failed to disable distribution: ${Y.message}`),process.exit(1)}}),$.command("cdn:delete <distributionId>","Delete a CloudFront distribution").action(async(J)=>{V("Delete CloudFront Distribution");try{let Y=new _0;if(g(`This will permanently delete distribution: ${J}`),g("The distribution must be disabled first."),!await v(`
7903
+ Delete this distribution?`,!1)){F("Operation cancelled");return}let Z=new L("Checking distribution status...");Z.start();let U=await Y.getDistribution(J);if(U.Status!=="Deployed"||U.Enabled){Z.fail("Distribution must be disabled and deployed before deletion"),F('\nRun `cloud cdn:disable` first and wait for status to be "Deployed"');return}Z.text="Deleting distribution...",await Y.deleteDistribution(J),Z.succeed("Distribution deleted")}catch(Y){R(`Failed to delete distribution: ${Y.message}`),process.exit(1)}})}import{readdirSync as mB,statSync as cB}from"node:fs";import{join as lB,relative as pB}from"node:path";P1();function c5($){$.command("storage:list","List all S3 buckets").option("--region <region>","AWS region").action(async(J)=>{V("S3 Buckets");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new F0(Q),U=new L("Fetching buckets...");U.start();let z=(await Z.listBuckets()).Buckets||[];if(U.succeed(`Found ${z.length} bucket(s)`),z.length===0){F("No S3 buckets found"),F("Use `cloud storage:create` to create a new bucket");return}d(["Name","Created"],z.map((G)=>[G.Name||"N/A",G.CreationDate?new Date(G.CreationDate).toLocaleDateString():"N/A"]))}catch(Y){R(`Failed to list buckets: ${Y.message}`),process.exit(1)}}),$.command("storage:create <name>","Create a new S3 bucket").option("--region <region>","AWS region",{default:"us-east-1"}).option("--public","Enable public access").option("--versioning","Enable versioning").action(async(J,Y)=>{V("Create S3 Bucket");try{let Q=new F0(Y.region);if(F(`Bucket name: ${J}`),F(`Region: ${Y.region}`),F(`Public access: ${Y.public?"Yes":"No"}`),F(`Versioning: ${Y.versioning?"Yes":"No"}`),!await v(`
7904
7904
  Create this bucket?`,!0)){F("Operation cancelled");return}let U=new L("Creating bucket...");if(U.start(),await Q.createBucket(J),!Y.public)U.text="Configuring public access block...",await Q.putPublicAccessBlock(J,{BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!0,RestrictPublicBuckets:!0});if(Y.versioning)U.text="Enabling versioning...",await Q.putBucketVersioning(J,"Enabled");U.succeed("Bucket created"),C(`
7905
- Bucket: ${J}`),F(`Region: ${Y.region}`),F(`URL: s3://${J}`)}catch(Q){R(`Failed to create bucket: ${Q.message}`),process.exit(1)}}),$.command("storage:delete <name>","Delete an S3 bucket").option("--force","Delete all objects first").action(async(J,Y)=>{V("Delete S3 Bucket");try{let Q=new F0("us-east-1");if(g(`This will permanently delete bucket: ${J}`),Y.force)g("All objects in the bucket will be deleted!");if(!await y(`
7905
+ Bucket: ${J}`),F(`Region: ${Y.region}`),F(`URL: s3://${J}`)}catch(Q){R(`Failed to create bucket: ${Q.message}`),process.exit(1)}}),$.command("storage:delete <name>","Delete an S3 bucket").option("--force","Delete all objects first").action(async(J,Y)=>{V("Delete S3 Bucket");try{let Q=new F0("us-east-1");if(g(`This will permanently delete bucket: ${J}`),Y.force)g("All objects in the bucket will be deleted!");if(!await v(`
7906
7906
  Delete this bucket?`,!1)){F("Operation cancelled");return}let U=new L("Deleting bucket...");if(U.start(),Y.force)U.text="Emptying bucket...",await Q.emptyBucket(J);await Q.deleteBucket(J),U.succeed("Bucket deleted")}catch(Q){R(`Failed to delete bucket: ${Q.message}`),process.exit(1)}}),$.command("storage:sync <source> <bucket>","Sync local directory to S3 bucket").option("--prefix <prefix>","S3 key prefix").option("--delete","Delete files in S3 that are not in source").option("--dry-run","Show what would be synced without making changes").action(async(J,Y,Q)=>{V("Sync to S3");try{let z=function(K,B){let j=mB(K,{withFileTypes:!0});for(let X of j){let O=lB(K,X.name);if(X.isDirectory())z(O,B);else{let _=pB(B,O),w=Q.prefix?`${Q.prefix}/${_}`:_,E=cB(O);W.push({path:O,key:w,size:E.size})}}},Z=new F0("us-east-1");if(F(`Source: ${J}`),F(`Destination: s3://${Y}/${Q.prefix||""}`),Q.dryRun)F("Dry run mode - no changes will be made");let U=new L("Scanning files...");U.start();let W=[];if(z(J,J),U.succeed(`Found ${W.length} local file(s)`),W.length===0){F("No files to sync");return}F(`
7907
7907
  Files to sync:`);for(let K of W.slice(0,10))F(` ${K.key} (${(K.size/1024).toFixed(2)} KB)`);if(W.length>10)F(` ... and ${W.length-10} more`);if(Q.dryRun){F(`
7908
- Dry run complete - no changes made`);return}if(!await y(`
7908
+ Dry run complete - no changes made`);return}if(!await v(`
7909
7909
  Sync these files?`,!0)){F("Operation cancelled");return}let H=new L("Uploading files...");H.start();let A=0;for(let K of W){H.text=`Uploading ${K.key}... (${A+1}/${W.length})`;let j=await Bun.file(K.path).arrayBuffer();await Z.putObject({bucket:Y,key:K.key,body:Buffer.from(j),contentType:rB(K.key)}),A++}if(H.succeed(`Uploaded ${A} file(s)`),Q.delete){let K=new L("Checking for files to delete...");K.start();let B=await Z.listObjects({bucket:Y,prefix:Q.prefix}),j=new Set(W.map((O)=>O.key)),X=B.objects.filter((O)=>O.Key&&!j.has(O.Key)).map((O)=>O.Key);if(X.length>0){K.text=`Deleting ${X.length} remote file(s)...`;for(let O of X)await Z.deleteObject(Y,O);K.succeed(`Deleted ${X.length} remote file(s)`)}else K.succeed("No files to delete")}C(`
7910
- Sync complete!`)}catch(Z){R(`Failed to sync: ${Z.message}`),process.exit(1)}}),$.command("storage:policy <bucket>","Show or set bucket policy").option("--set <file>","Set policy from JSON file").option("--public-read","Set a public read policy").option("--delete","Delete the bucket policy").action(async(J,Y)=>{V("S3 Bucket Policy");try{let Q=new F0("us-east-1");if(Y.delete){if(g(`This will delete the policy for bucket: ${J}`),!await y(`
7911
- Delete bucket policy?`,!1)){F("Operation cancelled");return}let W=new L("Deleting policy...");W.start(),await Q.deleteBucketPolicy(J),W.succeed("Policy deleted");return}if(Y.publicRead){if(g(`This will make bucket ${J} publicly readable!`),!await y(`
7910
+ Sync complete!`)}catch(Z){R(`Failed to sync: ${Z.message}`),process.exit(1)}}),$.command("storage:policy <bucket>","Show or set bucket policy").option("--set <file>","Set policy from JSON file").option("--public-read","Set a public read policy").option("--delete","Delete the bucket policy").action(async(J,Y)=>{V("S3 Bucket Policy");try{let Q=new F0("us-east-1");if(Y.delete){if(g(`This will delete the policy for bucket: ${J}`),!await v(`
7911
+ Delete bucket policy?`,!1)){F("Operation cancelled");return}let W=new L("Deleting policy...");W.start(),await Q.deleteBucketPolicy(J),W.succeed("Policy deleted");return}if(Y.publicRead){if(g(`This will make bucket ${J} publicly readable!`),!await v(`
7912
7912
  Set public read policy?`,!1)){F("Operation cancelled");return}let W=new L("Setting policy...");W.start();let z={Version:"2012-10-17",Statement:[{Sid:"PublicReadGetObject",Effect:"Allow",Principal:"*",Action:"s3:GetObject",Resource:`arn:aws:s3:::${J}/*`}]};await Q.putBucketPolicy(J,z),W.succeed("Public read policy set");return}if(Y.set){let U=new L("Setting policy...");U.start();let z=await Bun.file(Y.set).text();await Q.putBucketPolicy(J,z),U.succeed("Policy set");return}let Z=new L("Fetching policy...");Z.start();try{let U=await Q.getBucketPolicy(J);Z.succeed("Policy loaded"),F(`
7913
7913
  Bucket Policy:`),console.log(JSON.stringify(U||{},null,2))}catch(U){if(U.message?.includes("NoSuchBucketPolicy"))Z.succeed("No policy set"),F("This bucket has no policy configured.");else throw U}}catch(Q){R(`Failed to manage policy: ${Q.message}`),process.exit(1)}}),$.command("storage:ls <bucket>","List objects in a bucket").option("--prefix <prefix>","Filter by prefix").option("--limit <number>","Limit number of results",{default:"100"}).action(async(J,Y)=>{V(`Objects in ${J}`);try{let Q=new F0("us-east-1"),Z=new L("Listing objects...");Z.start();let U=await Q.listObjects({bucket:J,prefix:Y.prefix,maxKeys:Number.parseInt(Y.limit||"100")}),W=U.objects;if(Z.succeed(`Found ${W.length} object(s)${U.nextContinuationToken?" (truncated)":""}`),W.length===0){F("No objects found");return}if(d(["Key","Size","Last Modified"],W.map((z)=>[z.Key||"N/A",nB(z.Size||0),z.LastModified?new Date(z.LastModified).toLocaleString():"N/A"])),U.nextContinuationToken)F(`
7914
- More objects available. Use --limit to see more.`)}catch(Q){R(`Failed to list objects: ${Q.message}`),process.exit(1)}})}function rB($){let J=$.split(".").pop()?.toLowerCase();return{html:"text/html",css:"text/css",js:"application/javascript",json:"application/json",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",eot:"application/vnd.ms-fontobject",pdf:"application/pdf",zip:"application/zip",xml:"application/xml",txt:"text/plain",md:"text/markdown"}[J||""]||"application/octet-stream"}function nB($){if($===0)return"0 B";let J=1024,Y=["B","KB","MB","GB","TB"],Q=Math.floor(Math.log($)/Math.log(J));return`${Number.parseFloat(($/J**Q).toFixed(2))} ${Y[Q]}`}z0();class U2{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t}async describeCacheClusters($){let J={Action:"DescribeCacheClusters",Version:"2015-02-02",ShowCacheNodeInfo:"true"};if($)J.CacheClusterId=$;let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{CacheClusters:this.parseCacheClusters(Y)}}async describeReplicationGroups($){let J={Action:"DescribeReplicationGroups",Version:"2015-02-02"};if($)J.ReplicationGroupId=$;let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{ReplicationGroups:[]}}async createCacheCluster($){let J={Action:"CreateCacheCluster",Version:"2015-02-02",CacheClusterId:$.cacheClusterId,Engine:$.engine,CacheNodeType:$.cacheNodeType};if($.numCacheNodes)J.NumCacheNodes=$.numCacheNodes;if($.engineVersion)J.EngineVersion=$.engineVersion;if($.port)J.Port=$.port;if($.securityGroupIds&&$.securityGroupIds.length>0)$.securityGroupIds.forEach((Q,Z)=>{J[`SecurityGroupIds.member.${Z+1}`]=Q});if($.subnetGroupName)J.CacheSubnetGroupName=$.subnetGroupName;if($.tags&&$.tags.length>0)$.tags.forEach((Q,Z)=>{J[`Tags.member.${Z+1}.Key`]=Q.Key,J[`Tags.member.${Z+1}.Value`]=Q.Value});let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{CacheCluster:this.parseCacheCluster(Y)}}async deleteCacheCluster($,J){let Y={Action:"DeleteCacheCluster",Version:"2015-02-02",CacheClusterId:$};if(J)Y.FinalSnapshotIdentifier=J;await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(Y).toString()})}async rebootCacheCluster($,J){let Y={Action:"RebootCacheCluster",Version:"2015-02-02",CacheClusterId:$};J.forEach((Q,Z)=>{Y[`CacheNodeIdsToReboot.member.${Z+1}`]=Q}),await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(Y).toString()})}async describeCacheEngineVersions($){let J={Action:"DescribeCacheEngineVersions",Version:"2015-02-02"};if($)J.Engine=$;let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{CacheEngineVersions:[]}}async getCacheStatistics($){let J=await this.describeCacheClusters($);if(!J.CacheClusters||J.CacheClusters.length===0)throw Error(`Cache cluster ${$} not found`);return{cpuUtilization:0,evictions:0,hits:0,misses:0,connections:0}}parseCacheClusters($){if($.CacheClusterId)return[{CacheClusterId:$.CacheClusterId,CacheClusterStatus:$.CacheClusterStatus||"available",Engine:$.Engine||"redis",EngineVersion:$.EngineVersion||"7.0",CacheNodeType:$.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt($.NumCacheNodes||"1"),CacheClusterCreateTime:$.CacheClusterCreateTime||new Date().toISOString()}];return[]}parseCacheCluster($){return{CacheClusterId:$.CacheClusterId,CacheClusterStatus:$.CacheClusterStatus||"creating",Engine:$.Engine||"redis",EngineVersion:$.EngineVersion||"7.0",CacheNodeType:$.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt($.NumCacheNodes||"1"),CacheClusterCreateTime:$.CacheClusterCreateTime||new Date().toISOString()}}}function l5($){$.command("cache:list","List all ElastiCache clusters").option("--region <region>","AWS region").action(async(J)=>{V("ElastiCache Clusters");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new U2(Q),U=new L("Fetching clusters...");U.start();let z=(await Z.describeCacheClusters()).CacheClusters||[];if(U.succeed(`Found ${z.length} cluster(s)`),z.length===0){F("No ElastiCache clusters found"),F("Use `cloud cache:create` to create a new cluster");return}d(["Cluster ID","Engine","Node Type","Nodes","Status"],z.map((G)=>[G.CacheClusterId||"N/A",`${G.Engine||"N/A"} ${G.EngineVersion||""}`,G.CacheNodeType||"N/A",(G.NumCacheNodes||0).toString(),G.CacheClusterStatus||"N/A"]))}catch(Y){R(`Failed to list clusters: ${Y.message}`),process.exit(1)}}),$.command("cache:create <name>","Create a new ElastiCache cluster").option("--engine <engine>","Cache engine (redis or memcached)",{default:"redis"}).option("--node-type <type>","Node instance type",{default:"cache.t3.micro"}).option("--nodes <number>","Number of cache nodes",{default:"1"}).option("--region <region>","AWS region",{default:"us-east-1"}).option("--version <version>","Engine version").action(async(J,Y)=>{V("Create ElastiCache Cluster");try{let Q=new U2(Y.region);if(F(`Cluster ID: ${J}`),F(`Engine: ${Y.engine}`),F(`Node Type: ${Y.nodeType}`),F(`Number of Nodes: ${Y.nodes}`),F(`Region: ${Y.region}`),!await y(`
7914
+ More objects available. Use --limit to see more.`)}catch(Q){R(`Failed to list objects: ${Q.message}`),process.exit(1)}})}function rB($){let J=$.split(".").pop()?.toLowerCase();return{html:"text/html",css:"text/css",js:"application/javascript",json:"application/json",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",eot:"application/vnd.ms-fontobject",pdf:"application/pdf",zip:"application/zip",xml:"application/xml",txt:"text/plain",md:"text/markdown"}[J||""]||"application/octet-stream"}function nB($){if($===0)return"0 B";let J=1024,Y=["B","KB","MB","GB","TB"],Q=Math.floor(Math.log($)/Math.log(J));return`${Number.parseFloat(($/J**Q).toFixed(2))} ${Y[Q]}`}z0();class U2{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t}async describeCacheClusters($){let J={Action:"DescribeCacheClusters",Version:"2015-02-02",ShowCacheNodeInfo:"true"};if($)J.CacheClusterId=$;let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{CacheClusters:this.parseCacheClusters(Y)}}async describeReplicationGroups($){let J={Action:"DescribeReplicationGroups",Version:"2015-02-02"};if($)J.ReplicationGroupId=$;let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{ReplicationGroups:[]}}async createCacheCluster($){let J={Action:"CreateCacheCluster",Version:"2015-02-02",CacheClusterId:$.cacheClusterId,Engine:$.engine,CacheNodeType:$.cacheNodeType};if($.numCacheNodes)J.NumCacheNodes=$.numCacheNodes;if($.engineVersion)J.EngineVersion=$.engineVersion;if($.port)J.Port=$.port;if($.securityGroupIds&&$.securityGroupIds.length>0)$.securityGroupIds.forEach((Q,Z)=>{J[`SecurityGroupIds.member.${Z+1}`]=Q});if($.subnetGroupName)J.CacheSubnetGroupName=$.subnetGroupName;if($.tags&&$.tags.length>0)$.tags.forEach((Q,Z)=>{J[`Tags.member.${Z+1}.Key`]=Q.Key,J[`Tags.member.${Z+1}.Value`]=Q.Value});let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{CacheCluster:this.parseCacheCluster(Y)}}async deleteCacheCluster($,J){let Y={Action:"DeleteCacheCluster",Version:"2015-02-02",CacheClusterId:$};if(J)Y.FinalSnapshotIdentifier=J;await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(Y).toString()})}async rebootCacheCluster($,J){let Y={Action:"RebootCacheCluster",Version:"2015-02-02",CacheClusterId:$};J.forEach((Q,Z)=>{Y[`CacheNodeIdsToReboot.member.${Z+1}`]=Q}),await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(Y).toString()})}async describeCacheEngineVersions($){let J={Action:"DescribeCacheEngineVersions",Version:"2015-02-02"};if($)J.Engine=$;let Y=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(J).toString()});return{CacheEngineVersions:[]}}async getCacheStatistics($){let J=await this.describeCacheClusters($);if(!J.CacheClusters||J.CacheClusters.length===0)throw Error(`Cache cluster ${$} not found`);return{cpuUtilization:0,evictions:0,hits:0,misses:0,connections:0}}parseCacheClusters($){if($.CacheClusterId)return[{CacheClusterId:$.CacheClusterId,CacheClusterStatus:$.CacheClusterStatus||"available",Engine:$.Engine||"redis",EngineVersion:$.EngineVersion||"7.0",CacheNodeType:$.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt($.NumCacheNodes||"1"),CacheClusterCreateTime:$.CacheClusterCreateTime||new Date().toISOString()}];return[]}parseCacheCluster($){return{CacheClusterId:$.CacheClusterId,CacheClusterStatus:$.CacheClusterStatus||"creating",Engine:$.Engine||"redis",EngineVersion:$.EngineVersion||"7.0",CacheNodeType:$.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt($.NumCacheNodes||"1"),CacheClusterCreateTime:$.CacheClusterCreateTime||new Date().toISOString()}}}function l5($){$.command("cache:list","List all ElastiCache clusters").option("--region <region>","AWS region").action(async(J)=>{V("ElastiCache Clusters");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new U2(Q),U=new L("Fetching clusters...");U.start();let z=(await Z.describeCacheClusters()).CacheClusters||[];if(U.succeed(`Found ${z.length} cluster(s)`),z.length===0){F("No ElastiCache clusters found"),F("Use `cloud cache:create` to create a new cluster");return}d(["Cluster ID","Engine","Node Type","Nodes","Status"],z.map((G)=>[G.CacheClusterId||"N/A",`${G.Engine||"N/A"} ${G.EngineVersion||""}`,G.CacheNodeType||"N/A",(G.NumCacheNodes||0).toString(),G.CacheClusterStatus||"N/A"]))}catch(Y){R(`Failed to list clusters: ${Y.message}`),process.exit(1)}}),$.command("cache:create <name>","Create a new ElastiCache cluster").option("--engine <engine>","Cache engine (redis or memcached)",{default:"redis"}).option("--node-type <type>","Node instance type",{default:"cache.t3.micro"}).option("--nodes <number>","Number of cache nodes",{default:"1"}).option("--region <region>","AWS region",{default:"us-east-1"}).option("--version <version>","Engine version").action(async(J,Y)=>{V("Create ElastiCache Cluster");try{let Q=new U2(Y.region);if(F(`Cluster ID: ${J}`),F(`Engine: ${Y.engine}`),F(`Node Type: ${Y.nodeType}`),F(`Number of Nodes: ${Y.nodes}`),F(`Region: ${Y.region}`),!await v(`
7915
7915
  Create this cluster?`,!0)){F("Operation cancelled");return}let U=new L("Creating cluster...");U.start(),await Q.createCacheCluster({cacheClusterId:J,engine:Y.engine,cacheNodeType:Y.nodeType,numCacheNodes:Number.parseInt(Y.nodes),engineVersion:Y.version}),U.succeed("Cluster creation initiated"),C(`
7916
7916
  Cluster: ${J}`),F("Status: creating"),F(`
7917
- Note: Cluster creation may take several minutes.`),F("Use `cloud cache:list` to check status.")}catch(Q){R(`Failed to create cluster: ${Q.message}`),process.exit(1)}}),$.command("cache:delete <clusterId>","Delete an ElastiCache cluster").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete ElastiCache Cluster");try{let Q=new U2(Y.region);if(g(`This will permanently delete cluster: ${J}`),g("All data in the cluster will be lost!"),!await y(`
7917
+ Note: Cluster creation may take several minutes.`),F("Use `cloud cache:list` to check status.")}catch(Q){R(`Failed to create cluster: ${Q.message}`),process.exit(1)}}),$.command("cache:delete <clusterId>","Delete an ElastiCache cluster").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete ElastiCache Cluster");try{let Q=new U2(Y.region);if(g(`This will permanently delete cluster: ${J}`),g("All data in the cluster will be lost!"),!await v(`
7918
7918
  Delete this cluster?`,!1)){F("Operation cancelled");return}let U=new L("Deleting cluster...");U.start(),await Q.deleteCacheCluster(J),U.succeed("Cluster deletion initiated"),F(`
7919
7919
  Note: Cluster deletion may take several minutes.`)}catch(Q){R(`Failed to delete cluster: ${Q.message}`),process.exit(1)}}),$.command("cache:stats <clusterId>","Show ElastiCache cluster statistics").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V(`ElastiCache Stats: ${J}`);try{let Q=new U2(Y.region),Z=new L("Fetching cluster details...");Z.start();let W=(await Q.describeCacheClusters(J)).CacheClusters?.[0];if(!W){Z.fail("Cluster not found");return}if(Z.succeed("Cluster details loaded"),F(`
7920
7920
  Cluster Information:`),F(` Cluster ID: ${W.CacheClusterId}`),F(` Engine: ${W.Engine} ${W.EngineVersion}`),F(` Node Type: ${W.CacheNodeType}`),F(` Status: ${W.CacheClusterStatus}`),F(` Nodes: ${W.NumCacheNodes}`),F(` Availability Zone: ${W.PreferredAvailabilityZone||"Not set"}`),W.CacheNodes&&W.CacheNodes.length>0){F(`
7921
- Cache Nodes:`);for(let z of W.CacheNodes)if(F(` - ${z.CacheNodeId}: ${z.CacheNodeStatus}`),z.Endpoint)F(` Endpoint: ${z.Endpoint.Address}:${z.Endpoint.Port}`)}}catch(Q){R(`Failed to get cluster stats: ${Q.message}`),process.exit(1)}}),$.command("cache:flush <clusterId>","Flush all data from a Redis cluster").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Flush ElastiCache Cluster");try{let Q=new U2(Y.region),Z=new L("Getting cluster endpoint...");Z.start();let W=(await Q.describeCacheClusters(J)).CacheClusters?.[0];if(!W){Z.fail("Cluster not found");return}if(W.Engine!=="redis"){Z.fail("Flush is only supported for Redis clusters"),F("For Memcached, items expire automatically based on TTL.");return}Z.stop();let z=W.CacheNodes?.[0]?.Endpoint;if(!z){R("Could not determine cluster endpoint");return}if(g(`This will delete ALL data in cluster: ${J}`),g(`Endpoint: ${z.Address}:${z.Port}`),g("This action cannot be undone!"),!await y(`
7921
+ Cache Nodes:`);for(let z of W.CacheNodes)if(F(` - ${z.CacheNodeId}: ${z.CacheNodeStatus}`),z.Endpoint)F(` Endpoint: ${z.Endpoint.Address}:${z.Endpoint.Port}`)}}catch(Q){R(`Failed to get cluster stats: ${Q.message}`),process.exit(1)}}),$.command("cache:flush <clusterId>","Flush all data from a Redis cluster").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Flush ElastiCache Cluster");try{let Q=new U2(Y.region),Z=new L("Getting cluster endpoint...");Z.start();let W=(await Q.describeCacheClusters(J)).CacheClusters?.[0];if(!W){Z.fail("Cluster not found");return}if(W.Engine!=="redis"){Z.fail("Flush is only supported for Redis clusters"),F("For Memcached, items expire automatically based on TTL.");return}Z.stop();let z=W.CacheNodes?.[0]?.Endpoint;if(!z){R("Could not determine cluster endpoint");return}if(g(`This will delete ALL data in cluster: ${J}`),g(`Endpoint: ${z.Address}:${z.Port}`),g("This action cannot be undone!"),!await v(`
7922
7922
  Flush all data?`,!1)){F("Operation cancelled");return}F(`
7923
7923
  To flush the Redis cluster, connect and run FLUSHALL:`),F(` redis-cli -h ${z.Address} -p ${z.Port} FLUSHALL`),F(`
7924
- Note: Direct FLUSHALL via AWS API is not supported.`),F("You must connect to the cluster directly to execute this command.")}catch(Q){R(`Failed to get cluster info: ${Q.message}`),process.exit(1)}}),$.command("cache:reboot <clusterId>","Reboot cache cluster nodes").option("--region <region>","AWS region",{default:"us-east-1"}).option("--node <nodeId>","Specific node ID to reboot").action(async(J,Y)=>{V("Reboot ElastiCache Cluster");try{let Q=new U2(Y.region),Z=new L("Getting cluster info...");Z.start();let W=(await Q.describeCacheClusters(J)).CacheClusters?.[0];if(!W){Z.fail("Cluster not found");return}Z.stop();let z=Y.node?[Y.node]:W.CacheNodes?.map((A)=>A.CacheNodeId).filter(Boolean)||[];if(z.length===0){R("No nodes found to reboot");return}if(g(`This will reboot the following nodes: ${z.join(", ")}`),g("The cluster may be temporarily unavailable during reboot."),!await y(`
7924
+ Note: Direct FLUSHALL via AWS API is not supported.`),F("You must connect to the cluster directly to execute this command.")}catch(Q){R(`Failed to get cluster info: ${Q.message}`),process.exit(1)}}),$.command("cache:reboot <clusterId>","Reboot cache cluster nodes").option("--region <region>","AWS region",{default:"us-east-1"}).option("--node <nodeId>","Specific node ID to reboot").action(async(J,Y)=>{V("Reboot ElastiCache Cluster");try{let Q=new U2(Y.region),Z=new L("Getting cluster info...");Z.start();let W=(await Q.describeCacheClusters(J)).CacheClusters?.[0];if(!W){Z.fail("Cluster not found");return}Z.stop();let z=Y.node?[Y.node]:W.CacheNodes?.map((A)=>A.CacheNodeId).filter(Boolean)||[];if(z.length===0){R("No nodes found to reboot");return}if(g(`This will reboot the following nodes: ${z.join(", ")}`),g("The cluster may be temporarily unavailable during reboot."),!await v(`
7925
7925
  Reboot these nodes?`,!1)){F("Operation cancelled");return}let H=new L("Rebooting nodes...");H.start(),await Q.rebootCacheCluster(J,z),H.succeed("Reboot initiated"),F(`
7926
- Note: Reboot may take several minutes to complete.`),F("Use `cloud cache:stats` to check status.")}catch(Q){R(`Failed to reboot cluster: ${Q.message}`),process.exit(1)}})}p5();function r5($){$.command("queue:list","List all SQS queues").option("--region <region>","AWS region").action(async(J)=>{V("SQS Queues");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new x1(Q),U=new L("Fetching queues...");U.start();let z=(await Z.listQueues()).QueueUrls||[];if(U.succeed(`Found ${z.length} queue(s)`),z.length===0){F("No SQS queues found"),F("Use `cloud queue:create` to create a new queue");return}let G=[];for(let H of z)try{let A=await Z.getQueueAttributes(H),K=H.split("/").pop()||H;G.push({url:H,name:K,messages:A.Attributes?.ApproximateNumberOfMessages||"0",type:A.Attributes?.FifoQueue==="true"?"FIFO":"Standard"})}catch{let A=H.split("/").pop()||H;G.push({url:H,name:A,messages:"N/A",type:"Unknown"})}d(["Queue Name","Messages","Type"],G.map((H)=>[H.name,H.messages,H.type]))}catch(Y){R(`Failed to list queues: ${Y.message}`),process.exit(1)}}),$.command("queue:create <name>","Create a new SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).option("--fifo","Create a FIFO queue").option("--dlq <queueArn>","Dead letter queue ARN").option("--max-retries <number>","Max receive count before DLQ",{default:"3"}).option("--visibility <seconds>","Visibility timeout in seconds",{default:"30"}).option("--retention <days>","Message retention in days",{default:"4"}).action(async(J,Y)=>{V("Create SQS Queue");try{let Q=new x1(Y.region),Z=Y.fifo&&!J.endsWith(".fifo")?`${J}.fifo`:J;if(F(`Queue name: ${Z}`),F(`Type: ${Y.fifo?"FIFO":"Standard"}`),F(`Visibility timeout: ${Y.visibility} seconds`),F(`Message retention: ${Y.retention} days`),Y.dlq)F(`Dead letter queue: ${Y.dlq}`),F(`Max retries: ${Y.maxRetries}`);if(!await y(`
7926
+ Note: Reboot may take several minutes to complete.`),F("Use `cloud cache:stats` to check status.")}catch(Q){R(`Failed to reboot cluster: ${Q.message}`),process.exit(1)}})}p5();function r5($){$.command("queue:list","List all SQS queues").option("--region <region>","AWS region").action(async(J)=>{V("SQS Queues");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new x1(Q),U=new L("Fetching queues...");U.start();let z=(await Z.listQueues()).QueueUrls||[];if(U.succeed(`Found ${z.length} queue(s)`),z.length===0){F("No SQS queues found"),F("Use `cloud queue:create` to create a new queue");return}let G=[];for(let H of z)try{let A=await Z.getQueueAttributes(H),K=H.split("/").pop()||H;G.push({url:H,name:K,messages:A.Attributes?.ApproximateNumberOfMessages||"0",type:A.Attributes?.FifoQueue==="true"?"FIFO":"Standard"})}catch{let A=H.split("/").pop()||H;G.push({url:H,name:A,messages:"N/A",type:"Unknown"})}d(["Queue Name","Messages","Type"],G.map((H)=>[H.name,H.messages,H.type]))}catch(Y){R(`Failed to list queues: ${Y.message}`),process.exit(1)}}),$.command("queue:create <name>","Create a new SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).option("--fifo","Create a FIFO queue").option("--dlq <queueArn>","Dead letter queue ARN").option("--max-retries <number>","Max receive count before DLQ",{default:"3"}).option("--visibility <seconds>","Visibility timeout in seconds",{default:"30"}).option("--retention <days>","Message retention in days",{default:"4"}).action(async(J,Y)=>{V("Create SQS Queue");try{let Q=new x1(Y.region),Z=Y.fifo&&!J.endsWith(".fifo")?`${J}.fifo`:J;if(F(`Queue name: ${Z}`),F(`Type: ${Y.fifo?"FIFO":"Standard"}`),F(`Visibility timeout: ${Y.visibility} seconds`),F(`Message retention: ${Y.retention} days`),Y.dlq)F(`Dead letter queue: ${Y.dlq}`),F(`Max retries: ${Y.maxRetries}`);if(!await v(`
7927
7927
  Create this queue?`,!0)){F("Operation cancelled");return}let W=new L("Creating queue...");W.start();let z=await Q.createQueue({queueName:Z,fifo:Y.fifo,visibilityTimeout:Number.parseInt(Y.visibility),messageRetentionPeriod:Number.parseInt(Y.retention)*24*60*60,contentBasedDeduplication:Y.fifo?!0:void 0,deadLetterTargetArn:Y.dlq,maxReceiveCount:Y.dlq?Number.parseInt(Y.maxRetries):void 0});W.succeed("Queue created"),C(`
7928
7928
  Queue URL: ${z.QueueUrl}`),F(`
7929
- To send a message:`),F(` cloud queue:send ${Z} --message "Hello World"`)}catch(Q){R(`Failed to create queue: ${Q.message}`),process.exit(1)}}),$.command("queue:delete <name>","Delete an SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete SQS Queue");try{let Q=new x1(Y.region);if(g(`This will permanently delete queue: ${J}`),g("All messages in the queue will be lost!"),!await y(`
7929
+ To send a message:`),F(` cloud queue:send ${Z} --message "Hello World"`)}catch(Q){R(`Failed to create queue: ${Q.message}`),process.exit(1)}}),$.command("queue:delete <name>","Delete an SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete SQS Queue");try{let Q=new x1(Y.region);if(g(`This will permanently delete queue: ${J}`),g("All messages in the queue will be lost!"),!await v(`
7930
7930
  Delete this queue?`,!1)){F("Operation cancelled");return}let U=new L("Getting queue URL...");U.start();let W=await Q.getQueueUrl(J);if(!W.QueueUrl){U.fail("Queue not found");return}U.text="Deleting queue...",await Q.deleteQueue(W.QueueUrl),U.succeed("Queue deleted")}catch(Q){R(`Failed to delete queue: ${Q.message}`),process.exit(1)}}),$.command("queue:send <name>","Send a message to an SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).option("--message <body>","Message body").option("--file <path>","Read message body from file").option("--group <id>","Message group ID (for FIFO queues)").option("--dedup <id>","Deduplication ID (for FIFO queues)").option("--delay <seconds>","Delay delivery in seconds",{default:"0"}).action(async(J,Y)=>{V("Send SQS Message");try{let Q=new x1(Y.region),Z;if(Y.file)Z=await Bun.file(Y.file).text();else if(Y.message)Z=Y.message;else Z=await A0("Message body");if(!Z){R("Message body is required");return}let U=new L("Getting queue URL...");U.start();let W=await Q.getQueueUrl(J);if(!W.QueueUrl){U.fail("Queue not found");return}U.text="Sending message...";let z=await Q.sendMessage({queueUrl:W.QueueUrl,messageBody:Z,delaySeconds:Number.parseInt(Y.delay),messageGroupId:Y.group,messageDeduplicationId:Y.dedup});U.succeed("Message sent"),C(`
7931
7931
  Message ID: ${z.MessageId}`)}catch(Q){R(`Failed to send message: ${Q.message}`),process.exit(1)}}),$.command("queue:receive <name>","Receive messages from an SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).option("--max <number>","Maximum number of messages",{default:"1"}).option("--wait <seconds>","Long polling wait time",{default:"0"}).option("--delete","Delete messages after receiving").action(async(J,Y)=>{V("Receive SQS Messages");try{let Q=new x1(Y.region),Z=new L("Getting queue URL...");Z.start();let U=await Q.getQueueUrl(J);if(!U.QueueUrl){Z.fail("Queue not found");return}Z.text="Receiving messages...";let z=(await Q.receiveMessages({queueUrl:U.QueueUrl,maxMessages:Number.parseInt(Y.max),waitTimeSeconds:Number.parseInt(Y.wait)})).Messages||[];if(Z.succeed(`Received ${z.length} message(s)`),z.length===0){F("No messages available");return}for(let G of z){if(F(`
7932
- --- Message: ${G.MessageId} ---`),F(`Body: ${G.Body}`),G.Attributes)F(`Sent: ${G.Attributes.SentTimestamp?new Date(Number.parseInt(G.Attributes.SentTimestamp)).toISOString():"N/A"}`),F(`Receive Count: ${G.Attributes.ApproximateReceiveCount||"N/A"}`);if(Y.delete&&G.ReceiptHandle)await Q.deleteMessage(U.QueueUrl,G.ReceiptHandle),F("(Deleted)")}}catch(Q){R(`Failed to receive messages: ${Q.message}`),process.exit(1)}}),$.command("queue:purge <name>","Purge all messages from an SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Purge SQS Queue");try{let Q=new x1(Y.region);if(g(`This will delete ALL messages in queue: ${J}`),g("This action cannot be undone!"),!await y(`
7932
+ --- Message: ${G.MessageId} ---`),F(`Body: ${G.Body}`),G.Attributes)F(`Sent: ${G.Attributes.SentTimestamp?new Date(Number.parseInt(G.Attributes.SentTimestamp)).toISOString():"N/A"}`),F(`Receive Count: ${G.Attributes.ApproximateReceiveCount||"N/A"}`);if(Y.delete&&G.ReceiptHandle)await Q.deleteMessage(U.QueueUrl,G.ReceiptHandle),F("(Deleted)")}}catch(Q){R(`Failed to receive messages: ${Q.message}`),process.exit(1)}}),$.command("queue:purge <name>","Purge all messages from an SQS queue").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Purge SQS Queue");try{let Q=new x1(Y.region);if(g(`This will delete ALL messages in queue: ${J}`),g("This action cannot be undone!"),!await v(`
7933
7933
  Purge this queue?`,!1)){F("Operation cancelled");return}let U=new L("Getting queue URL...");U.start();let W=await Q.getQueueUrl(J);if(!W.QueueUrl){U.fail("Queue not found");return}U.text="Purging queue...",await Q.purgeQueue(W.QueueUrl),U.succeed("Queue purged"),F(`
7934
7934
  Note: It may take up to 60 seconds for the purge to complete.`)}catch(Q){R(`Failed to purge queue: ${Q.message}`),process.exit(1)}}),$.command("queue:stats <name>","Show SQS queue statistics").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V(`SQS Queue Stats: ${J}`);try{let Q=new x1(Y.region),Z=new L("Fetching queue stats...");Z.start();let U=await Q.getQueueUrl(J);if(!U.QueueUrl){Z.fail("Queue not found");return}let W=await Q.getQueueAttributes(U.QueueUrl);Z.succeed("Stats loaded");let z=W.Attributes||{};if(F(`
7935
7935
  Queue Information:`),F(` URL: ${U.QueueUrl}`),F(` ARN: ${z.QueueArn||"N/A"}`),F(` Type: ${z.FifoQueue==="true"?"FIFO":"Standard"}`),F(`
@@ -7942,63 +7942,63 @@ Inbound Rules:`);for(let H of G.IpPermissions){let A=H.IpProtocol==="-1"?"All":H
7942
7942
  No inbound rules configured.`);if(G.IpPermissionsEgress&&G.IpPermissionsEgress.length>0){F(`
7943
7943
  Outbound Rules:`);for(let H of G.IpPermissionsEgress){let A=H.IpProtocol==="-1"?"All":H.IpProtocol?.toUpperCase(),K=H.FromPort===H.ToPort?H.FromPort?.toString()||"All":`${H.FromPort}-${H.ToPort}`;for(let B of H.IpRanges||[])F(` - ${A} ${K} to ${B.CidrIp}${B.Description?` (${B.Description})`:""}`);for(let B of H.UserIdGroupPairs||[])F(` - ${A} ${K} to ${B.GroupId}${B.Description?` (${B.Description})`:""}`)}}else F(`
7944
7944
  No outbound rules configured.`);if(G.Tags&&G.Tags.length>0){F(`
7945
- Tags:`);for(let H of G.Tags)F(` ${H.Key}: ${H.Value}`)}}catch(Q){R(`Failed to get security group: ${Q.message}`),process.exit(1)}}),$.command("network:create-vpc <cidr>","Create a new VPC").option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","VPC name tag").option("--tenancy <tenancy>","Instance tenancy (default or dedicated)",{default:"default"}).action(async(J,Y)=>{V("Create VPC");try{let Q=new m0(Y.region);if(F(`CIDR Block: ${J}`),F(`Region: ${Y.region}`),F(`Tenancy: ${Y.tenancy}`),Y.name)F(`Name: ${Y.name}`);if(!await y(`
7945
+ Tags:`);for(let H of G.Tags)F(` ${H.Key}: ${H.Value}`)}}catch(Q){R(`Failed to get security group: ${Q.message}`),process.exit(1)}}),$.command("network:create-vpc <cidr>","Create a new VPC").option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","VPC name tag").option("--tenancy <tenancy>","Instance tenancy (default or dedicated)",{default:"default"}).action(async(J,Y)=>{V("Create VPC");try{let Q=new m0(Y.region);if(F(`CIDR Block: ${J}`),F(`Region: ${Y.region}`),F(`Tenancy: ${Y.tenancy}`),Y.name)F(`Name: ${Y.name}`);if(!await v(`
7946
7946
  Create this VPC?`,!0)){F("Operation cancelled");return}let U=new L("Creating VPC...");U.start();let W=await Q.createVpc({CidrBlock:J,InstanceTenancy:Y.tenancy,TagSpecifications:Y.name?[{ResourceType:"vpc",Tags:[{Key:"Name",Value:Y.name}]}]:void 0});U.succeed("VPC created"),C(`
7947
- VPC ID: ${W.Vpc?.VpcId}`),F(`CIDR: ${W.Vpc?.CidrBlock}`),F(`State: ${W.Vpc?.State}`)}catch(Q){R(`Failed to create VPC: ${Q.message}`),process.exit(1)}}),$.command("network:create-subnet <vpcId> <cidr>","Create a new subnet").option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","Subnet name tag").option("--az <zone>","Availability zone").option("--public","Auto-assign public IPs").action(async(J,Y,Q)=>{V("Create Subnet");try{let Z=new m0(Q.region);if(F(`VPC: ${J}`),F(`CIDR Block: ${Y}`),Q.az)F(`Availability Zone: ${Q.az}`);if(Q.name)F(`Name: ${Q.name}`);if(F(`Auto-assign Public IP: ${Q.public?"Yes":"No"}`),!await y(`
7947
+ VPC ID: ${W.Vpc?.VpcId}`),F(`CIDR: ${W.Vpc?.CidrBlock}`),F(`State: ${W.Vpc?.State}`)}catch(Q){R(`Failed to create VPC: ${Q.message}`),process.exit(1)}}),$.command("network:create-subnet <vpcId> <cidr>","Create a new subnet").option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","Subnet name tag").option("--az <zone>","Availability zone").option("--public","Auto-assign public IPs").action(async(J,Y,Q)=>{V("Create Subnet");try{let Z=new m0(Q.region);if(F(`VPC: ${J}`),F(`CIDR Block: ${Y}`),Q.az)F(`Availability Zone: ${Q.az}`);if(Q.name)F(`Name: ${Q.name}`);if(F(`Auto-assign Public IP: ${Q.public?"Yes":"No"}`),!await v(`
7948
7948
  Create this subnet?`,!0)){F("Operation cancelled");return}let W=new L("Creating subnet...");W.start();let z=await Z.createSubnet({VpcId:J,CidrBlock:Y,AvailabilityZone:Q.az,TagSpecifications:Q.name?[{ResourceType:"subnet",Tags:[{Key:"Name",Value:Q.name}]}]:void 0});if(Q.public&&z.Subnet?.SubnetId)W.text="Enabling auto-assign public IP...",await Z.modifySubnetAttribute({SubnetId:z.Subnet.SubnetId,MapPublicIpOnLaunch:{Value:!0}});W.succeed("Subnet created"),C(`
7949
- Subnet ID: ${z.Subnet?.SubnetId}`),F(`CIDR: ${z.Subnet?.CidrBlock}`),F(`Availability Zone: ${z.Subnet?.AvailabilityZone}`)}catch(Z){R(`Failed to create subnet: ${Z.message}`),process.exit(1)}}),$.command("network:create-sg <vpcId> <name>","Create a new security group").option("--region <region>","AWS region",{default:"us-east-1"}).option("--description <desc>","Security group description").action(async(J,Y,Q)=>{V("Create Security Group");try{let Z=new m0(Q.region),U=Q.description||`Security group for ${Y}`;if(F(`VPC: ${J}`),F(`Name: ${Y}`),F(`Description: ${U}`),!await y(`
7949
+ Subnet ID: ${z.Subnet?.SubnetId}`),F(`CIDR: ${z.Subnet?.CidrBlock}`),F(`Availability Zone: ${z.Subnet?.AvailabilityZone}`)}catch(Z){R(`Failed to create subnet: ${Z.message}`),process.exit(1)}}),$.command("network:create-sg <vpcId> <name>","Create a new security group").option("--region <region>","AWS region",{default:"us-east-1"}).option("--description <desc>","Security group description").action(async(J,Y,Q)=>{V("Create Security Group");try{let Z=new m0(Q.region),U=Q.description||`Security group for ${Y}`;if(F(`VPC: ${J}`),F(`Name: ${Y}`),F(`Description: ${U}`),!await v(`
7950
7950
  Create this security group?`,!0)){F("Operation cancelled");return}let z=new L("Creating security group...");z.start();let G=await Z.createSecurityGroup({GroupName:Y,Description:U,VpcId:J,TagSpecifications:[{ResourceType:"security-group",Tags:[{Key:"Name",Value:Y}]}]});z.succeed("Security group created"),C(`
7951
7951
  Group ID: ${G.GroupId}`),F(`
7952
- To add rules:`),F(` cloud network:sg-rule ${G.GroupId} --inbound --port 443 --cidr 0.0.0.0/0`)}catch(Z){R(`Failed to create security group: ${Z.message}`),process.exit(1)}}),$.command("network:sg-rule <groupId>","Add a rule to a security group").option("--region <region>","AWS region",{default:"us-east-1"}).option("--inbound","Add inbound rule").option("--outbound","Add outbound rule").option("--protocol <protocol>","Protocol (tcp, udp, icmp, or -1 for all)",{default:"tcp"}).option("--port <port>","Port number or range (e.g., 80 or 80-443)").option("--cidr <cidr>","CIDR block (e.g., 0.0.0.0/0)").option("--source-group <groupId>","Source security group").option("--description <desc>","Rule description").action(async(J,Y)=>{V("Add Security Group Rule");try{let Q=new m0(Y.region);if(!Y.inbound&&!Y.outbound){R("Specify --inbound or --outbound");return}if(!Y.cidr&&!Y.sourceGroup){R("Specify --cidr or --source-group");return}let Z,U;if(Y.port)if(Y.port.includes("-")){let[K,B]=Y.port.split("-");Z=Number.parseInt(K),U=Number.parseInt(B)}else Z=Number.parseInt(Y.port),U=Z;else if(Y.protocol!=="-1"){R("Port is required for TCP/UDP protocols");return}let W=Y.inbound?"Inbound":"Outbound",z=Y.protocol==="-1"?"All":Z===U?Z:`${Z}-${U}`;if(F(`Security Group: ${J}`),F(`Direction: ${W}`),F(`Protocol: ${Y.protocol}`),F(`Port(s): ${z}`),F(`Source: ${Y.cidr||Y.sourceGroup}`),!await y(`
7953
- Add this rule?`,!0)){F("Operation cancelled");return}let H=new L("Adding rule...");H.start();let A={IpProtocol:Y.protocol,FromPort:Z,ToPort:U};if(Y.cidr)A.IpRanges=[{CidrIp:Y.cidr,Description:Y.description}];if(Y.sourceGroup)A.UserIdGroupPairs=[{GroupId:Y.sourceGroup,Description:Y.description}];if(Y.inbound)await Q.authorizeSecurityGroupIngress({GroupId:J,IpPermissions:[A]});else await Q.authorizeSecurityGroupEgress({GroupId:J,IpPermissions:[A]});H.succeed("Rule added")}catch(Q){R(`Failed to add rule: ${Q.message}`),process.exit(1)}}),$.command("network:elastic-ips","List Elastic IP addresses").option("--region <region>","AWS region").action(async(J)=>{V("Elastic IP Addresses");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new m0(Q),U=new L("Fetching Elastic IPs...");U.start();let z=(await Z.describeAddresses()).Addresses||[];if(U.succeed(`Found ${z.length} Elastic IP(s)`),z.length===0){F("No Elastic IPs found");return}d(["Public IP","Allocation ID","Association ID","Instance","Name"],z.map((G)=>[G.PublicIp||"N/A",G.AllocationId||"N/A",G.AssociationId||"-",G.InstanceId||"-",G.Tags?.find((H)=>H.Key==="Name")?.Value||"-"]))}catch(Y){R(`Failed to list Elastic IPs: ${Y.message}`),process.exit(1)}}),$.command("network:route-tables","List route tables").option("--region <region>","AWS region").option("--vpc <vpcId>","Filter by VPC ID").action(async(J)=>{V("Route Tables");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new m0(Q),U=new L("Fetching route tables...");U.start();let W=J.vpc?[{Name:"vpc-id",Values:[J.vpc]}]:void 0,G=(await Z.describeRouteTables({Filters:W})).RouteTables||[];if(U.succeed(`Found ${G.length} route table(s)`),G.length===0){F("No route tables found");return}d(["Route Table ID","VPC","Name","Main","Associations","Routes"],G.map((H)=>[H.RouteTableId||"N/A",H.VpcId||"N/A",H.Tags?.find((A)=>A.Key==="Name")?.Value||"-",H.Associations?.some((A)=>A.Main)?"Yes":"No",(H.Associations?.length||0).toString(),(H.Routes?.length||0).toString()]))}catch(Y){R(`Failed to list route tables: ${Y.message}`),process.exit(1)}})}z0();class p1{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t}async createRule($){let J={Action:"PutRule",Name:$.name,ScheduleExpression:$.scheduleExpression,Version:"2015-10-07"};if($.description)J.Description=$.description;if($.state)J.State=$.state;else J.State="ENABLED";return{RuleArn:(await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.PutRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$.name,ScheduleExpression:$.scheduleExpression,State:$.state||"ENABLED",Description:$.description})})).RuleArn}}async putTargets($,J){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.PutTargets","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Rule:$,Targets:J})})}async listRules($){let J={};if($)J.NamePrefix=$;return{Rules:(await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.ListRules","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})).Rules||[]}}async describeRule($){let J=await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.DescribeRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$})});return{Name:J.Name,Arn:J.Arn,ScheduleExpression:J.ScheduleExpression,State:J.State,Description:J.Description}}async listTargetsByRule($){return{Targets:(await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.ListTargetsByRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Rule:$})})).Targets||[]}}async deleteRule($,J){if(J)try{let Y=await this.listTargetsByRule($);if(Y.Targets&&Y.Targets.length>0)await this.removeTargets($,Y.Targets.map((Q)=>Q.Id))}catch{}await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.DeleteRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$,Force:J||!1})})}async removeTargets($,J){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.RemoveTargets","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Rule:$,Ids:J})})}async enableRule($){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.EnableRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$})})}async disableRule($){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.DisableRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$})})}async createLambdaSchedule($){let J=await this.createRule({name:$.name,scheduleExpression:$.scheduleExpression,description:$.description,state:"ENABLED"});return await this.putTargets($.name,[{Id:"1",Arn:$.functionArn,Input:$.input}]),J}async createEcsSchedule($){let J=await this.createRule({name:$.name,scheduleExpression:$.scheduleExpression,description:$.description,state:"ENABLED"});return await this.putTargets($.name,[{Id:"1",Arn:$.clusterArn,RoleArn:$.roleArn,Input:JSON.stringify({containerOverrides:[]})}]),J}async listSchedules($){let J={};if($?.NamePrefix)J.NamePrefix=$.NamePrefix;if($?.State)J.State=$.State;let Y=$?.GroupName||"default";return{Schedules:(await this.client.request({service:"scheduler",region:this.region,method:"GET",path:"/schedules",queryParams:{...J,ScheduleGroup:Y}}))?.Schedules||[]}}async getSchedule($){try{let J={};if($.GroupName)J.groupName=$.GroupName;return await this.client.request({service:"scheduler",region:this.region,method:"GET",path:`/schedules/${encodeURIComponent($.Name)}`,queryParams:Object.keys(J).length>0?J:void 0})}catch(J){if(J.statusCode===404||J.code==="ResourceNotFoundException")return null;throw J}}async createSchedule($){let J={ScheduleExpression:$.ScheduleExpression,FlexibleTimeWindow:$.FlexibleTimeWindow,Target:$.Target};if($.GroupName)J.GroupName=$.GroupName;if($.ScheduleExpressionTimezone)J.ScheduleExpressionTimezone=$.ScheduleExpressionTimezone;if($.Description)J.Description=$.Description;if($.State)J.State=$.State;if($.StartDate)J.StartDate=$.StartDate.toISOString();if($.EndDate)J.EndDate=$.EndDate.toISOString();return{ScheduleArn:(await this.client.request({service:"scheduler",region:this.region,method:"POST",path:`/schedules/${encodeURIComponent($.Name)}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(J)}))?.ScheduleArn||""}}async updateSchedule($){let J={};if($.GroupName)J.GroupName=$.GroupName;if($.ScheduleExpression)J.ScheduleExpression=$.ScheduleExpression;if($.ScheduleExpressionTimezone)J.ScheduleExpressionTimezone=$.ScheduleExpressionTimezone;if($.Description!==void 0)J.Description=$.Description;if($.State)J.State=$.State;if($.FlexibleTimeWindow)J.FlexibleTimeWindow=$.FlexibleTimeWindow;if($.Target)J.Target=$.Target;return{ScheduleArn:(await this.client.request({service:"scheduler",region:this.region,method:"PUT",path:`/schedules/${encodeURIComponent($.Name)}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(J)}))?.ScheduleArn||""}}async deleteSchedule($){let J={};if($.GroupName)J.groupName=$.GroupName;await this.client.request({service:"scheduler",region:this.region,method:"DELETE",path:`/schedules/${encodeURIComponent($.Name)}`,queryParams:Object.keys(J).length>0?J:void 0})}async listScheduleGroups($){let J={};if($?.NamePrefix)J.NamePrefix=$.NamePrefix;return{ScheduleGroups:(await this.client.request({service:"scheduler",region:this.region,method:"GET",path:"/schedule-groups",queryParams:Object.keys(J).length>0?J:void 0}))?.ScheduleGroups||[]}}}function a5($){$.command("scheduler:list","List all EventBridge schedules").option("--region <region>","AWS region").option("--group <name>","Schedule group name",{default:"default"}).action(async(J)=>{V("EventBridge Schedules");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new p1(Q),U=new L("Fetching schedules...");U.start();let z=(await Z.listSchedules({GroupName:J.group})).Schedules||[];if(U.succeed(`Found ${z.length} schedule(s)`),z.length===0){F("No schedules found"),F("Use `cloud scheduler:create` to create a new schedule");return}d(["Name","State","Schedule Expression","Group"],z.map((G)=>[G.Name||"N/A",G.State||"N/A",G.ScheduleExpression||"N/A",G.GroupName||"default"]))}catch(Y){R(`Failed to list schedules: ${Y.message}`),process.exit(1)}}),$.command("scheduler:create <name>","Create a new EventBridge schedule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--schedule <expression>","Schedule expression (rate or cron)").option("--target-arn <arn>","Target ARN (Lambda, SQS, SNS, etc.)").option("--role-arn <arn>","IAM role ARN for scheduler").option("--input <json>","JSON input to pass to target").option("--group <name>","Schedule group name",{default:"default"}).option("--timezone <tz>","Timezone for cron expressions",{default:"UTC"}).option("--description <text>","Schedule description").option("--start <datetime>","Start date/time (ISO 8601)").option("--end <datetime>","End date/time (ISO 8601)").action(async(J,Y)=>{V("Create EventBridge Schedule");try{if(!Y.schedule){R("--schedule is required"),F("Examples:"),F(" Rate: rate(5 minutes), rate(1 hour), rate(1 day)"),F(" Cron: cron(0 12 * * ? *) - every day at 12:00 UTC");return}if(!Y.targetArn){R("--target-arn is required");return}if(!Y.roleArn){R("--role-arn is required"),F("The role must have permissions to invoke the target.");return}let Q=new p1(Y.region);if(F(`Name: ${J}`),F(`Schedule: ${Y.schedule}`),F(`Target: ${Y.targetArn}`),F(`Group: ${Y.group}`),F(`Timezone: ${Y.timezone}`),!await y(`
7952
+ To add rules:`),F(` cloud network:sg-rule ${G.GroupId} --inbound --port 443 --cidr 0.0.0.0/0`)}catch(Z){R(`Failed to create security group: ${Z.message}`),process.exit(1)}}),$.command("network:sg-rule <groupId>","Add a rule to a security group").option("--region <region>","AWS region",{default:"us-east-1"}).option("--inbound","Add inbound rule").option("--outbound","Add outbound rule").option("--protocol <protocol>","Protocol (tcp, udp, icmp, or -1 for all)",{default:"tcp"}).option("--port <port>","Port number or range (e.g., 80 or 80-443)").option("--cidr <cidr>","CIDR block (e.g., 0.0.0.0/0)").option("--source-group <groupId>","Source security group").option("--description <desc>","Rule description").action(async(J,Y)=>{V("Add Security Group Rule");try{let Q=new m0(Y.region);if(!Y.inbound&&!Y.outbound){R("Specify --inbound or --outbound");return}if(!Y.cidr&&!Y.sourceGroup){R("Specify --cidr or --source-group");return}let Z,U;if(Y.port)if(Y.port.includes("-")){let[K,B]=Y.port.split("-");Z=Number.parseInt(K),U=Number.parseInt(B)}else Z=Number.parseInt(Y.port),U=Z;else if(Y.protocol!=="-1"){R("Port is required for TCP/UDP protocols");return}let W=Y.inbound?"Inbound":"Outbound",z=Y.protocol==="-1"?"All":Z===U?Z:`${Z}-${U}`;if(F(`Security Group: ${J}`),F(`Direction: ${W}`),F(`Protocol: ${Y.protocol}`),F(`Port(s): ${z}`),F(`Source: ${Y.cidr||Y.sourceGroup}`),!await v(`
7953
+ Add this rule?`,!0)){F("Operation cancelled");return}let H=new L("Adding rule...");H.start();let A={IpProtocol:Y.protocol,FromPort:Z,ToPort:U};if(Y.cidr)A.IpRanges=[{CidrIp:Y.cidr,Description:Y.description}];if(Y.sourceGroup)A.UserIdGroupPairs=[{GroupId:Y.sourceGroup,Description:Y.description}];if(Y.inbound)await Q.authorizeSecurityGroupIngress({GroupId:J,IpPermissions:[A]});else await Q.authorizeSecurityGroupEgress({GroupId:J,IpPermissions:[A]});H.succeed("Rule added")}catch(Q){R(`Failed to add rule: ${Q.message}`),process.exit(1)}}),$.command("network:elastic-ips","List Elastic IP addresses").option("--region <region>","AWS region").action(async(J)=>{V("Elastic IP Addresses");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new m0(Q),U=new L("Fetching Elastic IPs...");U.start();let z=(await Z.describeAddresses()).Addresses||[];if(U.succeed(`Found ${z.length} Elastic IP(s)`),z.length===0){F("No Elastic IPs found");return}d(["Public IP","Allocation ID","Association ID","Instance","Name"],z.map((G)=>[G.PublicIp||"N/A",G.AllocationId||"N/A",G.AssociationId||"-",G.InstanceId||"-",G.Tags?.find((H)=>H.Key==="Name")?.Value||"-"]))}catch(Y){R(`Failed to list Elastic IPs: ${Y.message}`),process.exit(1)}}),$.command("network:route-tables","List route tables").option("--region <region>","AWS region").option("--vpc <vpcId>","Filter by VPC ID").action(async(J)=>{V("Route Tables");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new m0(Q),U=new L("Fetching route tables...");U.start();let W=J.vpc?[{Name:"vpc-id",Values:[J.vpc]}]:void 0,G=(await Z.describeRouteTables({Filters:W})).RouteTables||[];if(U.succeed(`Found ${G.length} route table(s)`),G.length===0){F("No route tables found");return}d(["Route Table ID","VPC","Name","Main","Associations","Routes"],G.map((H)=>[H.RouteTableId||"N/A",H.VpcId||"N/A",H.Tags?.find((A)=>A.Key==="Name")?.Value||"-",H.Associations?.some((A)=>A.Main)?"Yes":"No",(H.Associations?.length||0).toString(),(H.Routes?.length||0).toString()]))}catch(Y){R(`Failed to list route tables: ${Y.message}`),process.exit(1)}})}z0();class p1{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t}async createRule($){let J={Action:"PutRule",Name:$.name,ScheduleExpression:$.scheduleExpression,Version:"2015-10-07"};if($.description)J.Description=$.description;if($.state)J.State=$.state;else J.State="ENABLED";return{RuleArn:(await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.PutRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$.name,ScheduleExpression:$.scheduleExpression,State:$.state||"ENABLED",Description:$.description})})).RuleArn}}async putTargets($,J){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.PutTargets","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Rule:$,Targets:J})})}async listRules($){let J={};if($)J.NamePrefix=$;return{Rules:(await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.ListRules","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})).Rules||[]}}async describeRule($){let J=await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.DescribeRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$})});return{Name:J.Name,Arn:J.Arn,ScheduleExpression:J.ScheduleExpression,State:J.State,Description:J.Description}}async listTargetsByRule($){return{Targets:(await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.ListTargetsByRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Rule:$})})).Targets||[]}}async deleteRule($,J){if(J)try{let Y=await this.listTargetsByRule($);if(Y.Targets&&Y.Targets.length>0)await this.removeTargets($,Y.Targets.map((Q)=>Q.Id))}catch{}await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.DeleteRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$,Force:J||!1})})}async removeTargets($,J){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.RemoveTargets","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Rule:$,Ids:J})})}async enableRule($){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.EnableRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$})})}async disableRule($){await this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AWSEvents.DisableRule","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({Name:$})})}async createLambdaSchedule($){let J=await this.createRule({name:$.name,scheduleExpression:$.scheduleExpression,description:$.description,state:"ENABLED"});return await this.putTargets($.name,[{Id:"1",Arn:$.functionArn,Input:$.input}]),J}async createEcsSchedule($){let J=await this.createRule({name:$.name,scheduleExpression:$.scheduleExpression,description:$.description,state:"ENABLED"});return await this.putTargets($.name,[{Id:"1",Arn:$.clusterArn,RoleArn:$.roleArn,Input:JSON.stringify({containerOverrides:[]})}]),J}async listSchedules($){let J={};if($?.NamePrefix)J.NamePrefix=$.NamePrefix;if($?.State)J.State=$.State;let Y=$?.GroupName||"default";return{Schedules:(await this.client.request({service:"scheduler",region:this.region,method:"GET",path:"/schedules",queryParams:{...J,ScheduleGroup:Y}}))?.Schedules||[]}}async getSchedule($){try{let J={};if($.GroupName)J.groupName=$.GroupName;return await this.client.request({service:"scheduler",region:this.region,method:"GET",path:`/schedules/${encodeURIComponent($.Name)}`,queryParams:Object.keys(J).length>0?J:void 0})}catch(J){if(J.statusCode===404||J.code==="ResourceNotFoundException")return null;throw J}}async createSchedule($){let J={ScheduleExpression:$.ScheduleExpression,FlexibleTimeWindow:$.FlexibleTimeWindow,Target:$.Target};if($.GroupName)J.GroupName=$.GroupName;if($.ScheduleExpressionTimezone)J.ScheduleExpressionTimezone=$.ScheduleExpressionTimezone;if($.Description)J.Description=$.Description;if($.State)J.State=$.State;if($.StartDate)J.StartDate=$.StartDate.toISOString();if($.EndDate)J.EndDate=$.EndDate.toISOString();return{ScheduleArn:(await this.client.request({service:"scheduler",region:this.region,method:"POST",path:`/schedules/${encodeURIComponent($.Name)}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(J)}))?.ScheduleArn||""}}async updateSchedule($){let J={};if($.GroupName)J.GroupName=$.GroupName;if($.ScheduleExpression)J.ScheduleExpression=$.ScheduleExpression;if($.ScheduleExpressionTimezone)J.ScheduleExpressionTimezone=$.ScheduleExpressionTimezone;if($.Description!==void 0)J.Description=$.Description;if($.State)J.State=$.State;if($.FlexibleTimeWindow)J.FlexibleTimeWindow=$.FlexibleTimeWindow;if($.Target)J.Target=$.Target;return{ScheduleArn:(await this.client.request({service:"scheduler",region:this.region,method:"PUT",path:`/schedules/${encodeURIComponent($.Name)}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(J)}))?.ScheduleArn||""}}async deleteSchedule($){let J={};if($.GroupName)J.groupName=$.GroupName;await this.client.request({service:"scheduler",region:this.region,method:"DELETE",path:`/schedules/${encodeURIComponent($.Name)}`,queryParams:Object.keys(J).length>0?J:void 0})}async listScheduleGroups($){let J={};if($?.NamePrefix)J.NamePrefix=$.NamePrefix;return{ScheduleGroups:(await this.client.request({service:"scheduler",region:this.region,method:"GET",path:"/schedule-groups",queryParams:Object.keys(J).length>0?J:void 0}))?.ScheduleGroups||[]}}}function a5($){$.command("scheduler:list","List all EventBridge schedules").option("--region <region>","AWS region").option("--group <name>","Schedule group name",{default:"default"}).action(async(J)=>{V("EventBridge Schedules");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new p1(Q),U=new L("Fetching schedules...");U.start();let z=(await Z.listSchedules({GroupName:J.group})).Schedules||[];if(U.succeed(`Found ${z.length} schedule(s)`),z.length===0){F("No schedules found"),F("Use `cloud scheduler:create` to create a new schedule");return}d(["Name","State","Schedule Expression","Group"],z.map((G)=>[G.Name||"N/A",G.State||"N/A",G.ScheduleExpression||"N/A",G.GroupName||"default"]))}catch(Y){R(`Failed to list schedules: ${Y.message}`),process.exit(1)}}),$.command("scheduler:create <name>","Create a new EventBridge schedule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--schedule <expression>","Schedule expression (rate or cron)").option("--target-arn <arn>","Target ARN (Lambda, SQS, SNS, etc.)").option("--role-arn <arn>","IAM role ARN for scheduler").option("--input <json>","JSON input to pass to target").option("--group <name>","Schedule group name",{default:"default"}).option("--timezone <tz>","Timezone for cron expressions",{default:"UTC"}).option("--description <text>","Schedule description").option("--start <datetime>","Start date/time (ISO 8601)").option("--end <datetime>","End date/time (ISO 8601)").action(async(J,Y)=>{V("Create EventBridge Schedule");try{if(!Y.schedule){R("--schedule is required"),F("Examples:"),F(" Rate: rate(5 minutes), rate(1 hour), rate(1 day)"),F(" Cron: cron(0 12 * * ? *) - every day at 12:00 UTC");return}if(!Y.targetArn){R("--target-arn is required");return}if(!Y.roleArn){R("--role-arn is required"),F("The role must have permissions to invoke the target.");return}let Q=new p1(Y.region);if(F(`Name: ${J}`),F(`Schedule: ${Y.schedule}`),F(`Target: ${Y.targetArn}`),F(`Group: ${Y.group}`),F(`Timezone: ${Y.timezone}`),!await v(`
7954
7954
  Create this schedule?`,!0)){F("Operation cancelled");return}let U=new L("Creating schedule...");U.start(),await Q.createSchedule({Name:J,GroupName:Y.group,ScheduleExpression:Y.schedule,ScheduleExpressionTimezone:Y.timezone,Description:Y.description,State:"ENABLED",FlexibleTimeWindow:{Mode:"OFF"},Target:{Arn:Y.targetArn,RoleArn:Y.roleArn,Input:Y.input},StartDate:Y.start?new Date(Y.start):void 0,EndDate:Y.end?new Date(Y.end):void 0}),U.succeed("Schedule created"),C(`
7955
- Schedule: ${J}`),F(`Expression: ${Y.schedule}`)}catch(Q){R(`Failed to create schedule: ${Q.message}`),process.exit(1)}}),$.command("scheduler:delete <name>","Delete an EventBridge schedule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--group <name>","Schedule group name",{default:"default"}).action(async(J,Y)=>{V("Delete EventBridge Schedule");try{let Q=new p1(Y.region);if(g(`This will delete schedule: ${J}`),!await y(`
7955
+ Schedule: ${J}`),F(`Expression: ${Y.schedule}`)}catch(Q){R(`Failed to create schedule: ${Q.message}`),process.exit(1)}}),$.command("scheduler:delete <name>","Delete an EventBridge schedule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--group <name>","Schedule group name",{default:"default"}).action(async(J,Y)=>{V("Delete EventBridge Schedule");try{let Q=new p1(Y.region);if(g(`This will delete schedule: ${J}`),!await v(`
7956
7956
  Delete this schedule?`,!1)){F("Operation cancelled");return}let U=new L("Deleting schedule...");U.start(),await Q.deleteSchedule({Name:J,GroupName:Y.group}),U.succeed("Schedule deleted")}catch(Q){R(`Failed to delete schedule: ${Q.message}`),process.exit(1)}}),$.command("scheduler:enable <name>","Enable an EventBridge schedule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--group <name>","Schedule group name",{default:"default"}).action(async(J,Y)=>{V("Enable EventBridge Schedule");try{let Q=new p1(Y.region),Z=new L("Getting schedule...");Z.start();let U=await Q.getSchedule({Name:J,GroupName:Y.group});if(!U){Z.fail("Schedule not found");return}Z.text="Enabling schedule...",await Q.updateSchedule({Name:J,GroupName:Y.group,ScheduleExpression:U.ScheduleExpression,ScheduleExpressionTimezone:U.ScheduleExpressionTimezone,FlexibleTimeWindow:U.FlexibleTimeWindow,Target:U.Target,State:"ENABLED"}),Z.succeed("Schedule enabled")}catch(Q){R(`Failed to enable schedule: ${Q.message}`),process.exit(1)}}),$.command("scheduler:disable <name>","Disable an EventBridge schedule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--group <name>","Schedule group name",{default:"default"}).action(async(J,Y)=>{V("Disable EventBridge Schedule");try{let Q=new p1(Y.region),Z=new L("Getting schedule...");Z.start();let U=await Q.getSchedule({Name:J,GroupName:Y.group});if(!U){Z.fail("Schedule not found");return}Z.text="Disabling schedule...",await Q.updateSchedule({Name:J,GroupName:Y.group,ScheduleExpression:U.ScheduleExpression,ScheduleExpressionTimezone:U.ScheduleExpressionTimezone,FlexibleTimeWindow:U.FlexibleTimeWindow,Target:U.Target,State:"DISABLED"}),Z.succeed("Schedule disabled")}catch(Q){R(`Failed to disable schedule: ${Q.message}`),process.exit(1)}}),$.command("scheduler:describe <name>","Show EventBridge schedule details").option("--region <region>","AWS region",{default:"us-east-1"}).option("--group <name>","Schedule group name",{default:"default"}).action(async(J,Y)=>{V(`Schedule: ${J}`);try{let Q=new p1(Y.region),Z=new L("Fetching schedule...");Z.start();let U=await Q.getSchedule({Name:J,GroupName:Y.group});if(!U){Z.fail("Schedule not found");return}if(Z.succeed("Schedule loaded"),F(`
7957
7957
  Schedule Information:`),F(` Name: ${U.Name}`),F(` ARN: ${U.Arn}`),F(` Group: ${U.GroupName}`),F(` State: ${U.State}`),F(` Expression: ${U.ScheduleExpression}`),F(` Timezone: ${U.ScheduleExpressionTimezone}`),U.Description)F(` Description: ${U.Description}`);if(U.Target){if(F(`
7958
7958
  Target:`),F(` ARN: ${U.Target.Arn}`),F(` Role ARN: ${U.Target.RoleArn}`),U.Target.Input)F(` Input: ${U.Target.Input}`)}if(F(`
7959
7959
  Flexible Time Window:`),F(` Mode: ${U.FlexibleTimeWindow?.Mode}`),U.FlexibleTimeWindow?.MaximumWindowInMinutes)F(` Max Window: ${U.FlexibleTimeWindow.MaximumWindowInMinutes} minutes`);if(U.StartDate)F(`
7960
7960
  Start Date: ${U.StartDate}`);if(U.EndDate)F(`End Date: ${U.EndDate}`);F(`
7961
7961
  Created: ${U.CreationDate||"N/A"}`),F(`Last Modified: ${U.LastModificationDate||"N/A"}`)}catch(Q){R(`Failed to get schedule: ${Q.message}`),process.exit(1)}}),$.command("scheduler:groups","List schedule groups").option("--region <region>","AWS region").action(async(J)=>{V("Schedule Groups");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new p1(Q),U=new L("Fetching groups...");U.start();let z=(await Z.listScheduleGroups()).ScheduleGroups||[];if(U.succeed(`Found ${z.length} group(s)`),z.length===0){F("No schedule groups found");return}d(["Name","State","Created"],z.map((G)=>[G.Name||"N/A",G.State||"N/A",G.CreationDate?new Date(G.CreationDate).toLocaleString():"N/A"]))}catch(Y){R(`Failed to list groups: ${Y.message}`),process.exit(1)}})}z0();class C1{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}async request($,J){return this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSEvents.${$}`},body:JSON.stringify(J)})}async putRule($){return this.request("PutRule",$)}async deleteRule($){return this.request("DeleteRule",$)}async describeRule($){return this.request("DescribeRule",$)}async listRules($){return this.request("ListRules",$||{})}async listEventBuses($){return this.request("ListEventBuses",$||{})}async enableRule($){return this.request("EnableRule",$)}async disableRule($){return this.request("DisableRule",$)}async putTargets($){return this.request("PutTargets",$)}async removeTargets($){return this.request("RemoveTargets",$)}async listTargetsByRule($){return this.request("ListTargetsByRule",$)}async putEvents($){return this.request("PutEvents",$)}async createSchedule($){return this.client.request({service:"scheduler",region:this.region,method:"POST",path:`/schedules/${$.Name}`,headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}}function i5($){$.command("events:list","List all EventBridge rules").option("--region <region>","AWS region").option("--bus <name>","Event bus name",{default:"default"}).action(async(J)=>{V("EventBridge Rules");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new C1(Q),U=new L("Fetching rules...");U.start();let z=(await Z.listRules({EventBusName:J.bus})).Rules||[];if(U.succeed(`Found ${z.length} rule(s)`),z.length===0){F("No EventBridge rules found"),F("Use `cloud events:create` to create a new rule");return}d(["Name","State","Schedule/Pattern","Description"],z.map((G)=>[G.Name||"N/A",G.State||"N/A",G.ScheduleExpression||(G.EventPattern?"Event Pattern":"N/A"),(G.Description||"").substring(0,40)]))}catch(Y){R(`Failed to list rules: ${Y.message}`),process.exit(1)}}),$.command("events:create <name>","Create a new EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).option("--schedule <expression>","Schedule expression (rate or cron)").option("--pattern <json>","Event pattern JSON").option("--pattern-file <path>","Event pattern from JSON file").option("--description <text>","Rule description").option("--disabled","Create in disabled state").action(async(J,Y)=>{V("Create EventBridge Rule");try{if(!Y.schedule&&!Y.pattern&&!Y.patternFile){R("Either --schedule or --pattern/--pattern-file is required"),F(`
7962
- Examples:`),F(' Schedule: --schedule "rate(5 minutes)"'),F(` Pattern: --pattern '{"source": ["aws.ec2"]}'`);return}let Q=new C1(Y.region),Z;if(Y.patternFile)Z=await Bun.file(Y.patternFile).text();else if(Y.pattern)Z=Y.pattern;if(F(`Name: ${J}`),F(`Event Bus: ${Y.bus}`),Y.schedule)F(`Schedule: ${Y.schedule}`);if(Z)F(`Event Pattern: ${Z}`);if(F(`State: ${Y.disabled?"DISABLED":"ENABLED"}`),!await y(`
7962
+ Examples:`),F(' Schedule: --schedule "rate(5 minutes)"'),F(` Pattern: --pattern '{"source": ["aws.ec2"]}'`);return}let Q=new C1(Y.region),Z;if(Y.patternFile)Z=await Bun.file(Y.patternFile).text();else if(Y.pattern)Z=Y.pattern;if(F(`Name: ${J}`),F(`Event Bus: ${Y.bus}`),Y.schedule)F(`Schedule: ${Y.schedule}`);if(Z)F(`Event Pattern: ${Z}`);if(F(`State: ${Y.disabled?"DISABLED":"ENABLED"}`),!await v(`
7963
7963
  Create this rule?`,!0)){F("Operation cancelled");return}let W=new L("Creating rule...");W.start();let z=await Q.putRule({Name:J,EventBusName:Y.bus,ScheduleExpression:Y.schedule,EventPattern:Z,Description:Y.description,State:Y.disabled?"DISABLED":"ENABLED"});W.succeed("Rule created"),C(`
7964
- Rule ARN: ${z.RuleArn}`),F("\nNote: Add targets to the rule with `cloud events:target`")}catch(Q){R(`Failed to create rule: ${Q.message}`),process.exit(1)}}),$.command("events:delete <name>","Delete an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).option("--force","Remove all targets and delete rule").action(async(J,Y)=>{V("Delete EventBridge Rule");try{let Q=new C1(Y.region);if(g(`This will delete rule: ${J}`),!await y(`
7964
+ Rule ARN: ${z.RuleArn}`),F("\nNote: Add targets to the rule with `cloud events:target`")}catch(Q){R(`Failed to create rule: ${Q.message}`),process.exit(1)}}),$.command("events:delete <name>","Delete an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).option("--force","Remove all targets and delete rule").action(async(J,Y)=>{V("Delete EventBridge Rule");try{let Q=new C1(Y.region);if(g(`This will delete rule: ${J}`),!await v(`
7965
7965
  Delete this rule?`,!1)){F("Operation cancelled");return}let U=new L("Checking targets...");U.start();let W=await Q.listTargetsByRule({Rule:J,EventBusName:Y.bus});if(W.Targets&&W.Targets.length>0){if(!Y.force){U.fail("Rule has targets"),F(`
7966
7966
  The rule has ${W.Targets.length} target(s).`),F("Use --force to remove targets and delete the rule.");return}U.text="Removing targets...",await Q.removeTargets({Rule:J,EventBusName:Y.bus,Ids:W.Targets.map((z)=>z.Id)})}U.text="Deleting rule...",await Q.deleteRule({Name:J,EventBusName:Y.bus}),U.succeed("Rule deleted")}catch(Q){R(`Failed to delete rule: ${Q.message}`),process.exit(1)}}),$.command("events:describe <name>","Show EventBridge rule details").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).action(async(J,Y)=>{V(`Rule: ${J}`);try{let Q=new C1(Y.region),Z=new L("Fetching rule...");Z.start();let U=await Q.describeRule({Name:J,EventBusName:Y.bus});if(!U){Z.fail("Rule not found");return}let W=await Q.listTargetsByRule({Rule:J,EventBusName:Y.bus});if(Z.succeed("Rule loaded"),F(`
7967
7967
  Rule Information:`),F(` Name: ${U.Name}`),F(` ARN: ${U.Arn}`),F(` State: ${U.State}`),F(` Event Bus: ${U.EventBusName}`),U.Description)F(` Description: ${U.Description}`);if(U.ScheduleExpression)F(`
7968
7968
  Schedule Expression: ${U.ScheduleExpression}`);if(U.EventPattern)F(`
7969
7969
  Event Pattern:`),console.log(JSON.stringify(JSON.parse(U.EventPattern),null,2));if(W.Targets&&W.Targets.length>0){F(`
7970
7970
  Targets (${W.Targets.length}):`);for(let z of W.Targets)if(F(` - ${z.Id}: ${z.Arn}`),z.Input)F(` Input: ${z.Input}`)}else F(`
7971
- No targets configured.`)}catch(Q){R(`Failed to get rule: ${Q.message}`),process.exit(1)}}),$.command("events:target <ruleName>","Add a target to an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).option("--id <id>","Target ID").option("--arn <arn>","Target ARN (Lambda, SQS, SNS, etc.)").option("--role <arn>","IAM role ARN (for some targets)").option("--input <json>","Constant JSON input").option("--input-path <path>","JSONPath expression for input").action(async(J,Y)=>{V("Add EventBridge Target");try{if(!Y.arn){R("--arn is required");return}let Q=new C1(Y.region),Z=Y.id||`target-${Date.now()}`;if(F(`Rule: ${J}`),F(`Target ID: ${Z}`),F(`Target ARN: ${Y.arn}`),!await y(`
7971
+ No targets configured.`)}catch(Q){R(`Failed to get rule: ${Q.message}`),process.exit(1)}}),$.command("events:target <ruleName>","Add a target to an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).option("--id <id>","Target ID").option("--arn <arn>","Target ARN (Lambda, SQS, SNS, etc.)").option("--role <arn>","IAM role ARN (for some targets)").option("--input <json>","Constant JSON input").option("--input-path <path>","JSONPath expression for input").action(async(J,Y)=>{V("Add EventBridge Target");try{if(!Y.arn){R("--arn is required");return}let Q=new C1(Y.region),Z=Y.id||`target-${Date.now()}`;if(F(`Rule: ${J}`),F(`Target ID: ${Z}`),F(`Target ARN: ${Y.arn}`),!await v(`
7972
7972
  Add this target?`,!0)){F("Operation cancelled");return}let W=new L("Adding target...");W.start();let z={Id:Z,Arn:Y.arn};if(Y.role)z.RoleArn=Y.role;if(Y.input)z.Input=Y.input;if(Y.inputPath)z.InputPath=Y.inputPath;await Q.putTargets({Rule:J,EventBusName:Y.bus,Targets:[z]}),W.succeed("Target added"),C(`
7973
- Target ${Z} added to rule ${J}`)}catch(Q){R(`Failed to add target: ${Q.message}`),process.exit(1)}}),$.command("events:buses","List event buses").option("--region <region>","AWS region").action(async(J)=>{V("Event Buses");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new C1(Q),U=new L("Fetching event buses...");U.start();let z=(await Z.listEventBuses()).EventBuses||[];if(U.succeed(`Found ${z.length} event bus(es)`),z.length===0){F("No event buses found");return}d(["Name","ARN","Policy"],z.map((G)=>[G.Name||"N/A",G.Arn||"N/A",G.Policy?"Custom":"Default"]))}catch(Y){R(`Failed to list event buses: ${Y.message}`),process.exit(1)}}),$.command("events:enable <name>","Enable an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).action(async(J,Y)=>{V("Enable EventBridge Rule");try{let Q=new C1(Y.region),Z=new L("Enabling rule...");Z.start(),await Q.enableRule({Name:J,EventBusName:Y.bus}),Z.succeed("Rule enabled")}catch(Q){R(`Failed to enable rule: ${Q.message}`),process.exit(1)}}),$.command("events:disable <name>","Disable an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).action(async(J,Y)=>{V("Disable EventBridge Rule");try{let Q=new C1(Y.region),Z=new L("Disabling rule...");Z.start(),await Q.disableRule({Name:J,EventBusName:Y.bus}),Z.succeed("Rule disabled")}catch(Q){R(`Failed to disable rule: ${Q.message}`),process.exit(1)}})}z0();class I1{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t(J)}async createEmailIdentity($){return await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/identities",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}async getEmailIdentity($){let J=await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/identities/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}});return{IdentityType:J.IdentityType,IdentityName:$,SendingEnabled:J.VerifiedForSendingStatus,VerificationStatus:J.VerificationStatus,DkimAttributes:J.DkimAttributes,MailFromAttributes:J.MailFromAttributes}}async putEmailIdentityMailFromAttributes($,J){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent($)}/mail-from`,headers:{"Content-Type":"application/json"},body:JSON.stringify(J)})}async listEmailIdentities($){let J="/v2/email/identities",Y=[];if($?.PageSize)Y.push(`PageSize=${$.PageSize}`);if($?.NextToken)Y.push(`NextToken=${encodeURIComponent($.NextToken)}`);if(Y.length>0)J+=`?${Y.join("&")}`;let Q=await this.client.request({service:"email",region:this.region,method:"GET",path:J,headers:{"Content-Type":"application/json"}});return{EmailIdentities:Q.EmailIdentities,NextToken:Q.NextToken}}async deleteEmailIdentity($){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/identities/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async putEmailIdentityDkimAttributes($){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent($.EmailIdentity)}/dkim`,headers:{"Content-Type":"application/json"},body:JSON.stringify({SigningEnabled:$.SigningEnabled})})}async sendEmail($){return{MessageId:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})).MessageId}}async sendBulkEmail($){return{BulkEmailEntryResults:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-bulk-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})).BulkEmailEntryResults}}async createEmailTemplate($){await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/templates",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}async getEmailTemplate($){return await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/templates/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async deleteEmailTemplate($){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/templates/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async listEmailTemplates($){let J="/v2/email/templates",Y=[];if($?.PageSize)Y.push(`PageSize=${$.PageSize}`);if($?.NextToken)Y.push(`NextToken=${encodeURIComponent($.NextToken)}`);if(Y.length>0)J+=`?${Y.join("&")}`;return await this.client.request({service:"email",region:this.region,method:"GET",path:J,headers:{"Content-Type":"application/json"}})}async getSendStatistics(){return{SendDataPoints:(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendStatistics&Version=2010-12-01"})).GetSendStatisticsResponse?.GetSendStatisticsResult?.SendDataPoints?.member}}async getSendQuota(){let J=(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendQuota&Version=2010-12-01"})).GetSendQuotaResponse?.GetSendQuotaResult;return{Max24HourSend:J?.Max24HourSend?Number(J.Max24HourSend):void 0,MaxSendRate:J?.MaxSendRate?Number(J.MaxSendRate):void 0,SentLast24Hours:J?.SentLast24Hours?Number(J.SentLast24Hours):void 0}}async verifyDomain($){let J=await this.createEmailIdentity({EmailIdentity:$});return{dkimTokens:J.DkimAttributes?.Tokens,verificationStatus:J.DkimAttributes?.Status}}async sendSimpleEmail($){let J=Array.isArray($.to)?$.to:[$.to],Y=$.replyTo?Array.isArray($.replyTo)?$.replyTo:[$.replyTo]:void 0,Q={};if($.text)Q.Text={Data:$.text};if($.html)Q.Html={Data:$.html};return this.sendEmail({FromEmailAddress:$.from,Destination:{ToAddresses:J},Content:{Simple:{Subject:{Data:$.subject},Body:Q}},ReplyToAddresses:Y})}async sendTemplatedEmail($){let J=Array.isArray($.to)?$.to:[$.to],Y=$.replyTo?Array.isArray($.replyTo)?$.replyTo:[$.replyTo]:void 0;return this.sendEmail({FromEmailAddress:$.from,Destination:{ToAddresses:J},Content:{Template:{TemplateName:$.templateName,TemplateData:JSON.stringify($.templateData)}},ReplyToAddresses:Y})}async getDkimRecords($){let J=await this.getEmailIdentity($);if(!J.DkimAttributes?.Tokens)return[];return J.DkimAttributes.Tokens.map((Y)=>({name:`${Y}._domainkey.${$}`,type:"CNAME",value:`${Y}.dkim.amazonses.com`}))}async isDomainVerified($){try{let J=await this.getEmailIdentity($);return J.VerificationStatus==="SUCCESS"&&J.SendingEnabled===!0}catch{return!1}}async waitForDomainVerification($,J=60,Y=30000){for(let Q=0;Q<J;Q++){if(await this.isDomainVerified($))return!0;await new Promise((U)=>setTimeout(U,Y))}return!1}buildFormBody($){return Object.entries($).filter(([,Y])=>Y!==void 0).map(([Y,Q])=>`${encodeURIComponent(Y)}=${encodeURIComponent(Q)}`).join("&")}async createReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CreateReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async deleteReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async setActiveReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"SetActiveReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async listReceiptRuleSets($){let J={Action:"ListReceiptRuleSets",Version:"2010-12-01"};if($)J.NextToken=$;let Y=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListReceiptRuleSetsResponse?.ListReceiptRuleSetsResult||Y?.ListReceiptRuleSetsResult,Z=Q?.RuleSets?.member;return{RuleSets:Array.isArray(Z)?Z:Z?[Z]:[],NextToken:Q?.NextToken}}async describeReceiptRuleSet($){let J=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})}),Y=J?.DescribeReceiptRuleSetResponse?.DescribeReceiptRuleSetResult||J?.DescribeReceiptRuleSetResult,Q=Y?.Rules?.member;return{Metadata:Y?.Metadata,Rules:Array.isArray(Q)?Q:Q?[Q]:[]}}async createReceiptRule($){let J={Action:"CreateReceiptRule",Version:"2010-12-01",RuleSetName:$.RuleSetName,"Rule.Name":$.Rule.Name,"Rule.Enabled":$.Rule.Enabled!==!1?"true":"false"};if($.Rule.TlsPolicy)J["Rule.TlsPolicy"]=$.Rule.TlsPolicy;if($.Rule.ScanEnabled!==void 0)J["Rule.ScanEnabled"]=$.Rule.ScanEnabled?"true":"false";if($.After)J.After=$.After;if($.Rule.Recipients)$.Rule.Recipients.forEach((Y,Q)=>{J[`Rule.Recipients.member.${Q+1}`]=Y});$.Rule.Actions.forEach((Y,Q)=>{let Z=Q+1;if(Y.S3Action){if(J[`Rule.Actions.member.${Z}.S3Action.BucketName`]=Y.S3Action.BucketName,Y.S3Action.ObjectKeyPrefix)J[`Rule.Actions.member.${Z}.S3Action.ObjectKeyPrefix`]=Y.S3Action.ObjectKeyPrefix;if(Y.S3Action.KmsKeyArn)J[`Rule.Actions.member.${Z}.S3Action.KmsKeyArn`]=Y.S3Action.KmsKeyArn}if(Y.LambdaAction)J[`Rule.Actions.member.${Z}.LambdaAction.FunctionArn`]=Y.LambdaAction.FunctionArn,J[`Rule.Actions.member.${Z}.LambdaAction.InvocationType`]=Y.LambdaAction.InvocationType||"Event";if(Y.SNSAction){if(J[`Rule.Actions.member.${Z}.SNSAction.TopicArn`]=Y.SNSAction.TopicArn,Y.SNSAction.Encoding)J[`Rule.Actions.member.${Z}.SNSAction.Encoding`]=Y.SNSAction.Encoding}if(Y.StopAction){if(J[`Rule.Actions.member.${Z}.StopAction.Scope`]=Y.StopAction.Scope,Y.StopAction.TopicArn)J[`Rule.Actions.member.${Z}.StopAction.TopicArn`]=Y.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async deleteReceiptRule($,J){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRule",Version:"2010-12-01",RuleSetName:$,RuleName:J})})}async receiptRuleSetExists($){try{return await this.describeReceiptRuleSet($),!0}catch(J){if(J.code==="RuleSetDoesNotExist"||J.statusCode===400)return!1;throw J}}async getActiveReceiptRuleSet(){let $=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeActiveReceiptRuleSet",Version:"2010-12-01"})}),J=$?.DescribeActiveReceiptRuleSetResponse?.DescribeActiveReceiptRuleSetResult||$?.DescribeActiveReceiptRuleSetResult;if(!J?.Metadata)return null;let Y=J?.Rules?.member;return{Metadata:J?.Metadata,Rules:Array.isArray(Y)?Y:Y?[Y]:[]}}async updateReceiptRule($){let J={Action:"UpdateReceiptRule",Version:"2010-12-01",RuleSetName:$.RuleSetName,"Rule.Name":$.Rule.Name};if($.Rule.Enabled!==void 0)J["Rule.Enabled"]=$.Rule.Enabled?"true":"false";if($.Rule.TlsPolicy)J["Rule.TlsPolicy"]=$.Rule.TlsPolicy;if($.Rule.ScanEnabled!==void 0)J["Rule.ScanEnabled"]=$.Rule.ScanEnabled?"true":"false";if($.Rule.Recipients)$.Rule.Recipients.forEach((Y,Q)=>{J[`Rule.Recipients.member.${Q+1}`]=Y});$.Rule.Actions.forEach((Y,Q)=>{let Z=Q+1;if(Y.S3Action){if(J[`Rule.Actions.member.${Z}.S3Action.BucketName`]=Y.S3Action.BucketName,Y.S3Action.ObjectKeyPrefix)J[`Rule.Actions.member.${Z}.S3Action.ObjectKeyPrefix`]=Y.S3Action.ObjectKeyPrefix;if(Y.S3Action.KmsKeyArn)J[`Rule.Actions.member.${Z}.S3Action.KmsKeyArn`]=Y.S3Action.KmsKeyArn}if(Y.LambdaAction)J[`Rule.Actions.member.${Z}.LambdaAction.FunctionArn`]=Y.LambdaAction.FunctionArn,J[`Rule.Actions.member.${Z}.LambdaAction.InvocationType`]=Y.LambdaAction.InvocationType||"Event";if(Y.SNSAction){if(J[`Rule.Actions.member.${Z}.SNSAction.TopicArn`]=Y.SNSAction.TopicArn,Y.SNSAction.Encoding)J[`Rule.Actions.member.${Z}.SNSAction.Encoding`]=Y.SNSAction.Encoding}if(Y.StopAction){if(J[`Rule.Actions.member.${Z}.StopAction.Scope`]=Y.StopAction.Scope,Y.StopAction.TopicArn)J[`Rule.Actions.member.${Z}.StopAction.TopicArn`]=Y.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async sendRawEmail($){let J=Buffer.from($.rawMessage).toString("base64"),Y={Action:"SendRawEmail",Version:"2010-12-01",Source:$.source,"RawMessage.Data":J};$.destinations.forEach((U,W)=>{Y[`Destinations.member.${W+1}`]=U});let Q=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(Y)});return{MessageId:(Q?.SendRawEmailResponse?.SendRawEmailResult||Q?.SendRawEmailResult)?.MessageId}}async getSuppressedDestination($){try{return(await this.client.request({service:"ses",region:this.region,method:"GET",path:`/v2/email/suppression/addresses/${encodeURIComponent($)}`}))?.SuppressedDestination||null}catch(J){if(J.message?.includes("404")||J.message?.includes("NotFoundException"))return null;throw J}}async deleteSuppressedDestination($){await this.client.request({service:"ses",region:this.region,method:"DELETE",path:`/v2/email/suppression/addresses/${encodeURIComponent($)}`})}}function t5($){$.command("email:identities","List verified email identities").option("--region <region>","AWS region").action(async(J)=>{V("Email Identities");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new I1(Q),U=new L("Fetching identities...");U.start();let z=(await Z.listEmailIdentities()).EmailIdentities||[];if(U.succeed(`Found ${z.length} identity(s)`),z.length===0){F("No email identities found"),F("Use `cloud email:verify` to verify an email or domain");return}let G=[];for(let H of z){let A=H.IdentityName||"Unknown",K="Unknown";try{K=(await Z.getEmailIdentity(A)).VerificationStatus||"Unknown"}catch{}let B=H.IdentityType==="EMAIL_ADDRESS"?"Email":H.IdentityType==="DOMAIN"?"Domain":H.IdentityType||"Unknown";G.push([A,B,K])}d(["Identity","Type","Verification Status"],G)}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);R(`Failed to list identities: ${Q}`),process.exit(1)}}),$.command("email:verify <identity>","Verify an email address or domain").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Verify Email Identity");try{let Q=new I1(Y.region),Z=J.includes("@");if(F(`Identity: ${J}`),F(`Type: ${Z?"Email Address":"Domain"}`),!await y(`
7973
+ Target ${Z} added to rule ${J}`)}catch(Q){R(`Failed to add target: ${Q.message}`),process.exit(1)}}),$.command("events:buses","List event buses").option("--region <region>","AWS region").action(async(J)=>{V("Event Buses");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new C1(Q),U=new L("Fetching event buses...");U.start();let z=(await Z.listEventBuses()).EventBuses||[];if(U.succeed(`Found ${z.length} event bus(es)`),z.length===0){F("No event buses found");return}d(["Name","ARN","Policy"],z.map((G)=>[G.Name||"N/A",G.Arn||"N/A",G.Policy?"Custom":"Default"]))}catch(Y){R(`Failed to list event buses: ${Y.message}`),process.exit(1)}}),$.command("events:enable <name>","Enable an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).action(async(J,Y)=>{V("Enable EventBridge Rule");try{let Q=new C1(Y.region),Z=new L("Enabling rule...");Z.start(),await Q.enableRule({Name:J,EventBusName:Y.bus}),Z.succeed("Rule enabled")}catch(Q){R(`Failed to enable rule: ${Q.message}`),process.exit(1)}}),$.command("events:disable <name>","Disable an EventBridge rule").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bus <name>","Event bus name",{default:"default"}).action(async(J,Y)=>{V("Disable EventBridge Rule");try{let Q=new C1(Y.region),Z=new L("Disabling rule...");Z.start(),await Q.disableRule({Name:J,EventBusName:Y.bus}),Z.succeed("Rule disabled")}catch(Q){R(`Failed to disable rule: ${Q.message}`),process.exit(1)}})}z0();class I1{client;region;constructor($="us-east-1",J){this.region=$,this.client=new t(J)}async createEmailIdentity($){return await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/identities",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}async getEmailIdentity($){let J=await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/identities/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}});return{IdentityType:J.IdentityType,IdentityName:$,SendingEnabled:J.VerifiedForSendingStatus,VerificationStatus:J.VerificationStatus,DkimAttributes:J.DkimAttributes,MailFromAttributes:J.MailFromAttributes}}async putEmailIdentityMailFromAttributes($,J){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent($)}/mail-from`,headers:{"Content-Type":"application/json"},body:JSON.stringify(J)})}async listEmailIdentities($){let J="/v2/email/identities",Y=[];if($?.PageSize)Y.push(`PageSize=${$.PageSize}`);if($?.NextToken)Y.push(`NextToken=${encodeURIComponent($.NextToken)}`);if(Y.length>0)J+=`?${Y.join("&")}`;let Q=await this.client.request({service:"email",region:this.region,method:"GET",path:J,headers:{"Content-Type":"application/json"}});return{EmailIdentities:Q.EmailIdentities,NextToken:Q.NextToken}}async deleteEmailIdentity($){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/identities/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async putEmailIdentityDkimAttributes($){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent($.EmailIdentity)}/dkim`,headers:{"Content-Type":"application/json"},body:JSON.stringify({SigningEnabled:$.SigningEnabled})})}async sendEmail($){return{MessageId:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})).MessageId}}async sendBulkEmail($){return{BulkEmailEntryResults:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-bulk-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})).BulkEmailEntryResults}}async createEmailTemplate($){await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/templates",headers:{"Content-Type":"application/json"},body:JSON.stringify($)})}async getEmailTemplate($){return await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/templates/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async deleteEmailTemplate($){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/templates/${encodeURIComponent($)}`,headers:{"Content-Type":"application/json"}})}async listEmailTemplates($){let J="/v2/email/templates",Y=[];if($?.PageSize)Y.push(`PageSize=${$.PageSize}`);if($?.NextToken)Y.push(`NextToken=${encodeURIComponent($.NextToken)}`);if(Y.length>0)J+=`?${Y.join("&")}`;return await this.client.request({service:"email",region:this.region,method:"GET",path:J,headers:{"Content-Type":"application/json"}})}async getSendStatistics(){return{SendDataPoints:(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendStatistics&Version=2010-12-01"})).GetSendStatisticsResponse?.GetSendStatisticsResult?.SendDataPoints?.member}}async getSendQuota(){let J=(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendQuota&Version=2010-12-01"})).GetSendQuotaResponse?.GetSendQuotaResult;return{Max24HourSend:J?.Max24HourSend?Number(J.Max24HourSend):void 0,MaxSendRate:J?.MaxSendRate?Number(J.MaxSendRate):void 0,SentLast24Hours:J?.SentLast24Hours?Number(J.SentLast24Hours):void 0}}async verifyDomain($){let J=await this.createEmailIdentity({EmailIdentity:$});return{dkimTokens:J.DkimAttributes?.Tokens,verificationStatus:J.DkimAttributes?.Status}}async sendSimpleEmail($){let J=Array.isArray($.to)?$.to:[$.to],Y=$.replyTo?Array.isArray($.replyTo)?$.replyTo:[$.replyTo]:void 0,Q={};if($.text)Q.Text={Data:$.text};if($.html)Q.Html={Data:$.html};return this.sendEmail({FromEmailAddress:$.from,Destination:{ToAddresses:J},Content:{Simple:{Subject:{Data:$.subject},Body:Q}},ReplyToAddresses:Y})}async sendTemplatedEmail($){let J=Array.isArray($.to)?$.to:[$.to],Y=$.replyTo?Array.isArray($.replyTo)?$.replyTo:[$.replyTo]:void 0;return this.sendEmail({FromEmailAddress:$.from,Destination:{ToAddresses:J},Content:{Template:{TemplateName:$.templateName,TemplateData:JSON.stringify($.templateData)}},ReplyToAddresses:Y})}async getDkimRecords($){let J=await this.getEmailIdentity($);if(!J.DkimAttributes?.Tokens)return[];return J.DkimAttributes.Tokens.map((Y)=>({name:`${Y}._domainkey.${$}`,type:"CNAME",value:`${Y}.dkim.amazonses.com`}))}async isDomainVerified($){try{let J=await this.getEmailIdentity($);return J.VerificationStatus==="SUCCESS"&&J.SendingEnabled===!0}catch{return!1}}async waitForDomainVerification($,J=60,Y=30000){for(let Q=0;Q<J;Q++){if(await this.isDomainVerified($))return!0;await new Promise((U)=>setTimeout(U,Y))}return!1}buildFormBody($){return Object.entries($).filter(([,Y])=>Y!==void 0).map(([Y,Q])=>`${encodeURIComponent(Y)}=${encodeURIComponent(Q)}`).join("&")}async createReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CreateReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async deleteReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async setActiveReceiptRuleSet($){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"SetActiveReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})})}async listReceiptRuleSets($){let J={Action:"ListReceiptRuleSets",Version:"2010-12-01"};if($)J.NextToken=$;let Y=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListReceiptRuleSetsResponse?.ListReceiptRuleSetsResult||Y?.ListReceiptRuleSetsResult,Z=Q?.RuleSets?.member;return{RuleSets:Array.isArray(Z)?Z:Z?[Z]:[],NextToken:Q?.NextToken}}async describeReceiptRuleSet($){let J=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeReceiptRuleSet",Version:"2010-12-01",RuleSetName:$})}),Y=J?.DescribeReceiptRuleSetResponse?.DescribeReceiptRuleSetResult||J?.DescribeReceiptRuleSetResult,Q=Y?.Rules?.member;return{Metadata:Y?.Metadata,Rules:Array.isArray(Q)?Q:Q?[Q]:[]}}async createReceiptRule($){let J={Action:"CreateReceiptRule",Version:"2010-12-01",RuleSetName:$.RuleSetName,"Rule.Name":$.Rule.Name,"Rule.Enabled":$.Rule.Enabled!==!1?"true":"false"};if($.Rule.TlsPolicy)J["Rule.TlsPolicy"]=$.Rule.TlsPolicy;if($.Rule.ScanEnabled!==void 0)J["Rule.ScanEnabled"]=$.Rule.ScanEnabled?"true":"false";if($.After)J.After=$.After;if($.Rule.Recipients)$.Rule.Recipients.forEach((Y,Q)=>{J[`Rule.Recipients.member.${Q+1}`]=Y});$.Rule.Actions.forEach((Y,Q)=>{let Z=Q+1;if(Y.S3Action){if(J[`Rule.Actions.member.${Z}.S3Action.BucketName`]=Y.S3Action.BucketName,Y.S3Action.ObjectKeyPrefix)J[`Rule.Actions.member.${Z}.S3Action.ObjectKeyPrefix`]=Y.S3Action.ObjectKeyPrefix;if(Y.S3Action.KmsKeyArn)J[`Rule.Actions.member.${Z}.S3Action.KmsKeyArn`]=Y.S3Action.KmsKeyArn}if(Y.LambdaAction)J[`Rule.Actions.member.${Z}.LambdaAction.FunctionArn`]=Y.LambdaAction.FunctionArn,J[`Rule.Actions.member.${Z}.LambdaAction.InvocationType`]=Y.LambdaAction.InvocationType||"Event";if(Y.SNSAction){if(J[`Rule.Actions.member.${Z}.SNSAction.TopicArn`]=Y.SNSAction.TopicArn,Y.SNSAction.Encoding)J[`Rule.Actions.member.${Z}.SNSAction.Encoding`]=Y.SNSAction.Encoding}if(Y.StopAction){if(J[`Rule.Actions.member.${Z}.StopAction.Scope`]=Y.StopAction.Scope,Y.StopAction.TopicArn)J[`Rule.Actions.member.${Z}.StopAction.TopicArn`]=Y.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async deleteReceiptRule($,J){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRule",Version:"2010-12-01",RuleSetName:$,RuleName:J})})}async receiptRuleSetExists($){try{return await this.describeReceiptRuleSet($),!0}catch(J){if(J.code==="RuleSetDoesNotExist"||J.statusCode===400)return!1;throw J}}async getActiveReceiptRuleSet(){let $=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeActiveReceiptRuleSet",Version:"2010-12-01"})}),J=$?.DescribeActiveReceiptRuleSetResponse?.DescribeActiveReceiptRuleSetResult||$?.DescribeActiveReceiptRuleSetResult;if(!J?.Metadata)return null;let Y=J?.Rules?.member;return{Metadata:J?.Metadata,Rules:Array.isArray(Y)?Y:Y?[Y]:[]}}async updateReceiptRule($){let J={Action:"UpdateReceiptRule",Version:"2010-12-01",RuleSetName:$.RuleSetName,"Rule.Name":$.Rule.Name};if($.Rule.Enabled!==void 0)J["Rule.Enabled"]=$.Rule.Enabled?"true":"false";if($.Rule.TlsPolicy)J["Rule.TlsPolicy"]=$.Rule.TlsPolicy;if($.Rule.ScanEnabled!==void 0)J["Rule.ScanEnabled"]=$.Rule.ScanEnabled?"true":"false";if($.Rule.Recipients)$.Rule.Recipients.forEach((Y,Q)=>{J[`Rule.Recipients.member.${Q+1}`]=Y});$.Rule.Actions.forEach((Y,Q)=>{let Z=Q+1;if(Y.S3Action){if(J[`Rule.Actions.member.${Z}.S3Action.BucketName`]=Y.S3Action.BucketName,Y.S3Action.ObjectKeyPrefix)J[`Rule.Actions.member.${Z}.S3Action.ObjectKeyPrefix`]=Y.S3Action.ObjectKeyPrefix;if(Y.S3Action.KmsKeyArn)J[`Rule.Actions.member.${Z}.S3Action.KmsKeyArn`]=Y.S3Action.KmsKeyArn}if(Y.LambdaAction)J[`Rule.Actions.member.${Z}.LambdaAction.FunctionArn`]=Y.LambdaAction.FunctionArn,J[`Rule.Actions.member.${Z}.LambdaAction.InvocationType`]=Y.LambdaAction.InvocationType||"Event";if(Y.SNSAction){if(J[`Rule.Actions.member.${Z}.SNSAction.TopicArn`]=Y.SNSAction.TopicArn,Y.SNSAction.Encoding)J[`Rule.Actions.member.${Z}.SNSAction.Encoding`]=Y.SNSAction.Encoding}if(Y.StopAction){if(J[`Rule.Actions.member.${Z}.StopAction.Scope`]=Y.StopAction.Scope,Y.StopAction.TopicArn)J[`Rule.Actions.member.${Z}.StopAction.TopicArn`]=Y.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async sendRawEmail($){let J=Buffer.from($.rawMessage).toString("base64"),Y={Action:"SendRawEmail",Version:"2010-12-01",Source:$.source,"RawMessage.Data":J};$.destinations.forEach((U,W)=>{Y[`Destinations.member.${W+1}`]=U});let Q=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(Y)});return{MessageId:(Q?.SendRawEmailResponse?.SendRawEmailResult||Q?.SendRawEmailResult)?.MessageId}}async getSuppressedDestination($){try{return(await this.client.request({service:"ses",region:this.region,method:"GET",path:`/v2/email/suppression/addresses/${encodeURIComponent($)}`}))?.SuppressedDestination||null}catch(J){if(J.message?.includes("404")||J.message?.includes("NotFoundException"))return null;throw J}}async deleteSuppressedDestination($){await this.client.request({service:"ses",region:this.region,method:"DELETE",path:`/v2/email/suppression/addresses/${encodeURIComponent($)}`})}}function t5($){$.command("email:identities","List verified email identities").option("--region <region>","AWS region").action(async(J)=>{V("Email Identities");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new I1(Q),U=new L("Fetching identities...");U.start();let z=(await Z.listEmailIdentities()).EmailIdentities||[];if(U.succeed(`Found ${z.length} identity(s)`),z.length===0){F("No email identities found"),F("Use `cloud email:verify` to verify an email or domain");return}let G=[];for(let H of z){let A=H.IdentityName||"Unknown",K="Unknown";try{K=(await Z.getEmailIdentity(A)).VerificationStatus||"Unknown"}catch{}let B=H.IdentityType==="EMAIL_ADDRESS"?"Email":H.IdentityType==="DOMAIN"?"Domain":H.IdentityType||"Unknown";G.push([A,B,K])}d(["Identity","Type","Verification Status"],G)}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);R(`Failed to list identities: ${Q}`),process.exit(1)}}),$.command("email:verify <identity>","Verify an email address or domain").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Verify Email Identity");try{let Q=new I1(Y.region),Z=J.includes("@");if(F(`Identity: ${J}`),F(`Type: ${Z?"Email Address":"Domain"}`),!await v(`
7974
7974
  Send verification?`,!0)){F("Operation cancelled");return}let W=new L("Initiating verification...");if(W.start(),Z)await Q.createEmailIdentity({EmailIdentity:J}),W.succeed("Verification email sent"),F(`
7975
7975
  A verification email has been sent to ${J}`),F("Click the link in the email to complete verification.");else{let z=await Q.verifyDomain(J);W.succeed("Domain verification initiated");let G=z.dkimTokens||[];if(G.length>0){F(`
7976
7976
  DKIM Records (for email authentication):`);for(let H of G)F(`
7977
7977
  Name: ${H}._domainkey.${J}`),F(" Type: CNAME"),F(` Value: ${H}.dkim.amazonses.com`)}F(`
7978
- Verification Status: ${z.verificationStatus||"PENDING"}`)}}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);R(`Failed to verify identity: ${Z}`),process.exit(1)}}),$.command("email:delete <identity>","Delete a verified email identity").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete Email Identity");try{let Q=new I1(Y.region);if(g(`This will remove identity: ${J}`),!await y(`
7978
+ Verification Status: ${z.verificationStatus||"PENDING"}`)}}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);R(`Failed to verify identity: ${Z}`),process.exit(1)}}),$.command("email:delete <identity>","Delete a verified email identity").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete Email Identity");try{let Q=new I1(Y.region);if(g(`This will remove identity: ${J}`),!await v(`
7979
7979
  Delete this identity?`,!1)){F("Operation cancelled");return}let U=new L("Deleting identity...");U.start(),await Q.deleteEmailIdentity(J),U.succeed("Identity deleted")}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);R(`Failed to delete identity: ${Z}`),process.exit(1)}}),$.command("email:send","Send a test email").option("--region <region>","AWS region",{default:"us-east-1"}).option("--from <email>","From email address (must be verified)").option("--to <email>","To email address").option("--subject <text>","Email subject").option("--body <text>","Email body (text)").option("--html <html>","Email body (HTML)").action(async(J)=>{V("Send Email");try{let Y=new I1(J.region),Q=J.from||await A0("From (verified email)"),Z=J.to||await A0("To"),U=J.subject||await A0("Subject","Test Email from ts-cloud"),W=J.body||await A0("Body","This is a test email sent from ts-cloud CLI.");if(F(`
7980
- From: ${Q}`),F(`To: ${Z}`),F(`Subject: ${U}`),!await y(`
7980
+ From: ${Q}`),F(`To: ${Z}`),F(`Subject: ${U}`),!await v(`
7981
7981
  Send this email?`,!0)){F("Operation cancelled");return}let G=new L("Sending email...");G.start();let H=await Y.sendEmail({FromEmailAddress:Q,Destination:{ToAddresses:[Z]},Content:{Simple:{Subject:{Data:U},Body:{Text:{Data:W},...J.html&&{Html:{Data:J.html}}}}}});G.succeed("Email sent"),C(`
7982
7982
  Message ID: ${H.MessageId}`)}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);R(`Failed to send email: ${Q}`),process.exit(1)}}),$.command("email:templates","List email templates").option("--region <region>","AWS region").action(async(J)=>{V("Email Templates");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new I1(Q),U=new L("Fetching templates...");U.start();let z=(await Z.listEmailTemplates()).TemplatesMetadata||[];if(U.succeed(`Found ${z.length} template(s)`),z.length===0){F("No email templates found"),F("Use `cloud email:template:create` to create a template");return}d(["Name","Created"],z.map((G)=>[G.TemplateName||"N/A",G.CreatedTimestamp?new Date(G.CreatedTimestamp).toLocaleString():"N/A"]))}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);R(`Failed to list templates: ${Q}`),process.exit(1)}}),$.command("email:template:create <name>","Create an email template").option("--region <region>","AWS region",{default:"us-east-1"}).option("--subject <text>","Email subject (supports {{variable}} placeholders)").option("--text <text>","Text body").option("--html <html>","HTML body").option("--html-file <path>","HTML body from file").action(async(J,Y)=>{V("Create Email Template");try{let Q=new I1(Y.region),Z=Y.subject||await A0("Subject template","Hello {{name}}"),U=Y.text||await A0("Text body","Hello {{name}}, this is a test."),W=Y.html;if(Y.htmlFile)W=await Bun.file(Y.htmlFile).text();if(F(`
7983
- Template Name: ${J}`),F(`Subject: ${Z}`),!await y(`
7983
+ Template Name: ${J}`),F(`Subject: ${Z}`),!await v(`
7984
7984
  Create this template?`,!0)){F("Operation cancelled");return}let G=new L("Creating template...");G.start(),await Q.createEmailTemplate({TemplateName:J,TemplateContent:{Subject:Z,Text:U,Html:W}}),G.succeed("Template created"),F(`
7985
- To send using this template:`),F(` cloud email:send:template --template ${J} --to user@example.com --data '{"name":"John"}'`)}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);R(`Failed to create template: ${Z}`),process.exit(1)}}),$.command("email:template:delete <name>","Delete an email template").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete Email Template");try{let Q=new I1(Y.region);if(g(`This will delete template: ${J}`),!await y(`
7985
+ To send using this template:`),F(` cloud email:send:template --template ${J} --to user@example.com --data '{"name":"John"}'`)}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);R(`Failed to create template: ${Z}`),process.exit(1)}}),$.command("email:template:delete <name>","Delete an email template").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete Email Template");try{let Q=new I1(Y.region);if(g(`This will delete template: ${J}`),!await v(`
7986
7986
  Delete this template?`,!1)){F("Operation cancelled");return}let U=new L("Deleting template...");U.start(),await Q.deleteEmailTemplate(J),U.succeed("Template deleted")}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);R(`Failed to delete template: ${Z}`),process.exit(1)}}),$.command("email:stats","Show SES sending statistics").option("--region <region>","AWS region").action(async(J)=>{V("Email Statistics");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new I1(Q),U=new L("Fetching statistics...");U.start();let[W,z]=await Promise.all([Z.getSendQuota(),Z.getSendStatistics()]);U.succeed("Statistics loaded"),F(`
7987
7987
  Sending Quota:`),F(` Max 24-hour Send: ${W.Max24HourSend||0}`),F(` Max Send Rate: ${W.MaxSendRate||0} emails/second`),F(` Sent Last 24h: ${W.SentLast24Hours||0}`);let G=(W.Max24HourSend||0)-(W.SentLast24Hours||0);if(F(` Remaining: ${G}`),z.SendDataPoints&&z.SendDataPoints.length>0){F(`
7988
7988
  Recent Statistics:`);let H=0,A=0,K=0,B=0;for(let j of z.SendDataPoints)H+=j.DeliveryAttempts||0,A+=j.Bounces||0,K+=j.Complaints||0,B+=j.Rejects||0;if(F(` Total Attempts: ${H}`),F(` Bounces: ${A}`),F(` Complaints: ${K}`),F(` Rejects: ${B}`),H>0){let j=(A/H*100).toFixed(2),X=(K/H*100).toFixed(2);if(F(`
7989
7989
  Bounce Rate: ${j}%`),F(` Complaint Rate: ${X}%`),Number.parseFloat(j)>5)g(`
7990
7990
  Warning: Bounce rate is high (>5%). This may affect your sender reputation.`);if(Number.parseFloat(X)>0.1)g(`
7991
- Warning: Complaint rate is high (>0.1%). This may affect your sender reputation.`)}}}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);R(`Failed to get statistics: ${Q}`),process.exit(1)}})}z0();class E1{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}buildFormBody($){return Object.entries($).filter(([,Y])=>Y!==void 0).map(([Y,Q])=>`${encodeURIComponent(Y)}=${encodeURIComponent(Q)}`).join("&")}async createTopic($){let J={Action:"CreateTopic",Version:"2010-03-31",Name:$.Name};if($.DisplayName)J["Attributes.entry.1.key"]="DisplayName",J["Attributes.entry.1.value"]=$.DisplayName;if($.Tags)$.Tags.forEach((Q,Z)=>{J[`Tags.member.${Z+1}.Key`]=Q.Key,J[`Tags.member.${Z+1}.Value`]=Q.Value});if($.Attributes){let Q=$.DisplayName?2:1;Object.entries($.Attributes).forEach(([Z,U])=>{J[`Attributes.entry.${Q}.key`]=Z,J[`Attributes.entry.${Q}.value`]=U,Q++})}let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)});return{TopicArn:Y?.CreateTopicResponse?.CreateTopicResult?.TopicArn||Y?.TopicArn}}async deleteTopic($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteTopic",Version:"2010-03-31",TopicArn:$})})}async listTopics($){let J={Action:"ListTopics",Version:"2010-03-31"};if($)J.NextToken=$;let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListTopicsResponse?.ListTopicsResult||Y?.ListTopicsResult,Z=Q?.Topics?.member;return{Topics:Array.isArray(Z)?Z:Z?[Z]:[],NextToken:Q?.NextToken}}async getTopicAttributes($){let Y=(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"GetTopicAttributes",Version:"2010-03-31",TopicArn:$})}))?.GetTopicAttributesResponse?.GetTopicAttributesResult?.Attributes?.entry,Q={TopicArn:$};if(Array.isArray(Y))Y.forEach((Z)=>{Q[Z.key]=Z.value});return Q}async setTopicAttributes($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"SetTopicAttributes",Version:"2010-03-31",TopicArn:$.TopicArn,AttributeName:$.AttributeName,AttributeValue:$.AttributeValue})})}async subscribe($){let J={Action:"Subscribe",Version:"2010-03-31",TopicArn:$.TopicArn,Protocol:$.Protocol,Endpoint:$.Endpoint};if($.ReturnSubscriptionArn)J.ReturnSubscriptionArn="true";if($.Attributes){let Q=1;Object.entries($.Attributes).forEach(([Z,U])=>{J[`Attributes.entry.${Q}.key`]=Z,J[`Attributes.entry.${Q}.value`]=U,Q++})}let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)});return{SubscriptionArn:Y?.SubscribeResponse?.SubscribeResult?.SubscriptionArn||Y?.SubscriptionArn}}async unsubscribe($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"Unsubscribe",Version:"2010-03-31",SubscriptionArn:$})})}async listSubscriptionsByTopic($,J){let Y={Action:"ListSubscriptionsByTopic",Version:"2010-03-31",TopicArn:$};if(J)Y.NextToken=J;let Q=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(Y)}),Z=Q?.ListSubscriptionsByTopicResponse?.ListSubscriptionsByTopicResult?.Subscriptions?.member;return{Subscriptions:Array.isArray(Z)?Z:Z?[Z]:[],NextToken:Q?.ListSubscriptionsByTopicResponse?.ListSubscriptionsByTopicResult?.NextToken}}async publish($){let J={Action:"Publish",Version:"2010-03-31",Message:$.Message};if($.TopicArn)J.TopicArn=$.TopicArn;if($.TargetArn)J.TargetArn=$.TargetArn;if($.PhoneNumber)J.PhoneNumber=$.PhoneNumber;if($.Subject)J.Subject=$.Subject;if($.MessageStructure)J.MessageStructure=$.MessageStructure;if($.MessageAttributes){let Q=1;Object.entries($.MessageAttributes).forEach(([Z,U])=>{if(J[`MessageAttributes.entry.${Q}.Name`]=Z,J[`MessageAttributes.entry.${Q}.Value.DataType`]=U.DataType,U.StringValue)J[`MessageAttributes.entry.${Q}.Value.StringValue`]=U.StringValue;if(U.BinaryValue)J[`MessageAttributes.entry.${Q}.Value.BinaryValue`]=U.BinaryValue;Q++})}let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)});return{MessageId:Y?.PublishResponse?.PublishResult?.MessageId||Y?.MessageId}}async publishSMS($,J,Y){let Q={};if(Y)Q["AWS.SNS.SMS.SenderID"]={DataType:"String",StringValue:Y};return this.publish({PhoneNumber:$,Message:J,MessageAttributes:Object.keys(Q).length>0?Q:void 0})}async subscribeEmail($,J){return this.subscribe({TopicArn:$,Protocol:"email",Endpoint:J})}async subscribeLambda($,J){return this.subscribe({TopicArn:$,Protocol:"lambda",Endpoint:J})}async subscribeSqs($,J,Y){let Q={};if(Y)Q.RawMessageDelivery="true";return this.subscribe({TopicArn:$,Protocol:"sqs",Endpoint:J,Attributes:Object.keys(Q).length>0?Q:void 0})}async subscribeHttp($,J,Y){let Q=J.startsWith("https")?"https":"http",Z={};if(Y)Z.RawMessageDelivery="true";return this.subscribe({TopicArn:$,Protocol:Q,Endpoint:J,Attributes:Object.keys(Z).length>0?Z:void 0})}async subscribeSms($,J){return this.subscribe({TopicArn:$,Protocol:"sms",Endpoint:J})}async topicExists($){try{return await this.getTopicAttributes($),!0}catch(J){if(J.code==="NotFound"||J.statusCode===404)return!1;throw J}}async getSMSAttributes(){let J=(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"GetSMSAttributes",Version:"2010-03-31"})}))?.GetSMSAttributesResponse?.GetSMSAttributesResult?.attributes?.entry,Y={};if(Array.isArray(J))J.forEach((Q)=>{Y[Q.key]=Q.value});else if(J)Y[J.key]=J.value;return Y}async setSMSAttributes($){let J={Action:"SetSMSAttributes",Version:"2010-03-31"},Y=1;Object.entries($).forEach(([Q,Z])=>{if(Z!==void 0)J[`attributes.entry.${Y}.key`]=Q,J[`attributes.entry.${Y}.value`]=Z,Y++}),await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async checkIfPhoneNumberIsOptedOut($){return(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CheckIfPhoneNumberIsOptedOut",Version:"2010-03-31",phoneNumber:$})}))?.CheckIfPhoneNumberIsOptedOutResponse?.CheckIfPhoneNumberIsOptedOutResult?.isOptedOut==="true"}async listPhoneNumbersOptedOut($){let J={Action:"ListPhoneNumbersOptedOut",Version:"2010-03-31"};if($)J.nextToken=$;let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListPhoneNumbersOptedOutResponse?.ListPhoneNumbersOptedOutResult?.phoneNumbers?.member;return{phoneNumbers:Array.isArray(Q)?Q:Q?[Q]:[],nextToken:Y?.ListPhoneNumbersOptedOutResponse?.ListPhoneNumbersOptedOutResult?.nextToken}}async optInPhoneNumber($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"OptInPhoneNumber",Version:"2010-03-31",phoneNumber:$})})}async listSMSSandboxPhoneNumbers($){let J={Action:"ListSMSSandboxPhoneNumbers",Version:"2010-03-31"};if($)J.NextToken=$;let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListSMSSandboxPhoneNumbersResponse?.ListSMSSandboxPhoneNumbersResult?.PhoneNumbers?.member;return{PhoneNumbers:Array.isArray(Q)?Q:Q?[Q]:[],NextToken:Y?.ListSMSSandboxPhoneNumbersResponse?.ListSMSSandboxPhoneNumbersResult?.NextToken}}async createSMSSandboxPhoneNumber($,J){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CreateSMSSandboxPhoneNumber",Version:"2010-03-31",PhoneNumber:$,LanguageCode:J||"en-US"})})}async verifySMSSandboxPhoneNumber($,J){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"VerifySMSSandboxPhoneNumber",Version:"2010-03-31",PhoneNumber:$,OneTimePassword:J})})}async deleteSMSSandboxPhoneNumber($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteSMSSandboxPhoneNumber",Version:"2010-03-31",PhoneNumber:$})})}async getSMSSandboxAccountStatus(){return{IsInSandbox:(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"GetSMSSandboxAccountStatus",Version:"2010-03-31"})}))?.GetSMSSandboxAccountStatusResponse?.GetSMSSandboxAccountStatusResult?.IsInSandbox==="true"}}}function s5($){$.command("notify:topics","List all SNS topics").option("--region <region>","AWS region").action(async(J)=>{V("SNS Topics");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new E1(Q),U=new L("Fetching topics...");U.start();let z=(await Z.listTopics()).Topics||[];if(U.succeed(`Found ${z.length} topic(s)`),z.length===0){F("No SNS topics found"),F("Use `cloud notify:create` to create a new topic");return}d(["Topic ARN","Name"],z.map((G)=>{let H=G.TopicArn?.split(":").pop()||"N/A";return[G.TopicArn||"N/A",H]}))}catch(Y){R(`Failed to list topics: ${Y.message}`),process.exit(1)}}),$.command("notify:create <name>","Create a new SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).option("--fifo","Create a FIFO topic").option("--display-name <name>","Display name for SMS subscriptions").action(async(J,Y)=>{V("Create SNS Topic");try{let Q=new E1(Y.region),Z=Y.fifo&&!J.endsWith(".fifo")?`${J}.fifo`:J;if(F(`Topic name: ${Z}`),F(`Type: ${Y.fifo?"FIFO":"Standard"}`),!await y(`
7991
+ Warning: Complaint rate is high (>0.1%). This may affect your sender reputation.`)}}}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);R(`Failed to get statistics: ${Q}`),process.exit(1)}})}z0();class E1{client;region;constructor($="us-east-1"){this.region=$,this.client=new t}buildFormBody($){return Object.entries($).filter(([,Y])=>Y!==void 0).map(([Y,Q])=>`${encodeURIComponent(Y)}=${encodeURIComponent(Q)}`).join("&")}async createTopic($){let J={Action:"CreateTopic",Version:"2010-03-31",Name:$.Name};if($.DisplayName)J["Attributes.entry.1.key"]="DisplayName",J["Attributes.entry.1.value"]=$.DisplayName;if($.Tags)$.Tags.forEach((Q,Z)=>{J[`Tags.member.${Z+1}.Key`]=Q.Key,J[`Tags.member.${Z+1}.Value`]=Q.Value});if($.Attributes){let Q=$.DisplayName?2:1;Object.entries($.Attributes).forEach(([Z,U])=>{J[`Attributes.entry.${Q}.key`]=Z,J[`Attributes.entry.${Q}.value`]=U,Q++})}let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)});return{TopicArn:Y?.CreateTopicResponse?.CreateTopicResult?.TopicArn||Y?.TopicArn}}async deleteTopic($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteTopic",Version:"2010-03-31",TopicArn:$})})}async listTopics($){let J={Action:"ListTopics",Version:"2010-03-31"};if($)J.NextToken=$;let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListTopicsResponse?.ListTopicsResult||Y?.ListTopicsResult,Z=Q?.Topics?.member;return{Topics:Array.isArray(Z)?Z:Z?[Z]:[],NextToken:Q?.NextToken}}async getTopicAttributes($){let Y=(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"GetTopicAttributes",Version:"2010-03-31",TopicArn:$})}))?.GetTopicAttributesResponse?.GetTopicAttributesResult?.Attributes?.entry,Q={TopicArn:$};if(Array.isArray(Y))Y.forEach((Z)=>{Q[Z.key]=Z.value});return Q}async setTopicAttributes($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"SetTopicAttributes",Version:"2010-03-31",TopicArn:$.TopicArn,AttributeName:$.AttributeName,AttributeValue:$.AttributeValue})})}async subscribe($){let J={Action:"Subscribe",Version:"2010-03-31",TopicArn:$.TopicArn,Protocol:$.Protocol,Endpoint:$.Endpoint};if($.ReturnSubscriptionArn)J.ReturnSubscriptionArn="true";if($.Attributes){let Q=1;Object.entries($.Attributes).forEach(([Z,U])=>{J[`Attributes.entry.${Q}.key`]=Z,J[`Attributes.entry.${Q}.value`]=U,Q++})}let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)});return{SubscriptionArn:Y?.SubscribeResponse?.SubscribeResult?.SubscriptionArn||Y?.SubscriptionArn}}async unsubscribe($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"Unsubscribe",Version:"2010-03-31",SubscriptionArn:$})})}async listSubscriptionsByTopic($,J){let Y={Action:"ListSubscriptionsByTopic",Version:"2010-03-31",TopicArn:$};if(J)Y.NextToken=J;let Q=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(Y)}),Z=Q?.ListSubscriptionsByTopicResponse?.ListSubscriptionsByTopicResult?.Subscriptions?.member;return{Subscriptions:Array.isArray(Z)?Z:Z?[Z]:[],NextToken:Q?.ListSubscriptionsByTopicResponse?.ListSubscriptionsByTopicResult?.NextToken}}async publish($){let J={Action:"Publish",Version:"2010-03-31",Message:$.Message};if($.TopicArn)J.TopicArn=$.TopicArn;if($.TargetArn)J.TargetArn=$.TargetArn;if($.PhoneNumber)J.PhoneNumber=$.PhoneNumber;if($.Subject)J.Subject=$.Subject;if($.MessageStructure)J.MessageStructure=$.MessageStructure;if($.MessageAttributes){let Q=1;Object.entries($.MessageAttributes).forEach(([Z,U])=>{if(J[`MessageAttributes.entry.${Q}.Name`]=Z,J[`MessageAttributes.entry.${Q}.Value.DataType`]=U.DataType,U.StringValue)J[`MessageAttributes.entry.${Q}.Value.StringValue`]=U.StringValue;if(U.BinaryValue)J[`MessageAttributes.entry.${Q}.Value.BinaryValue`]=U.BinaryValue;Q++})}let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)});return{MessageId:Y?.PublishResponse?.PublishResult?.MessageId||Y?.MessageId}}async publishSMS($,J,Y){let Q={};if(Y)Q["AWS.SNS.SMS.SenderID"]={DataType:"String",StringValue:Y};return this.publish({PhoneNumber:$,Message:J,MessageAttributes:Object.keys(Q).length>0?Q:void 0})}async subscribeEmail($,J){return this.subscribe({TopicArn:$,Protocol:"email",Endpoint:J})}async subscribeLambda($,J){return this.subscribe({TopicArn:$,Protocol:"lambda",Endpoint:J})}async subscribeSqs($,J,Y){let Q={};if(Y)Q.RawMessageDelivery="true";return this.subscribe({TopicArn:$,Protocol:"sqs",Endpoint:J,Attributes:Object.keys(Q).length>0?Q:void 0})}async subscribeHttp($,J,Y){let Q=J.startsWith("https")?"https":"http",Z={};if(Y)Z.RawMessageDelivery="true";return this.subscribe({TopicArn:$,Protocol:Q,Endpoint:J,Attributes:Object.keys(Z).length>0?Z:void 0})}async subscribeSms($,J){return this.subscribe({TopicArn:$,Protocol:"sms",Endpoint:J})}async topicExists($){try{return await this.getTopicAttributes($),!0}catch(J){if(J.code==="NotFound"||J.statusCode===404)return!1;throw J}}async getSMSAttributes(){let J=(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"GetSMSAttributes",Version:"2010-03-31"})}))?.GetSMSAttributesResponse?.GetSMSAttributesResult?.attributes?.entry,Y={};if(Array.isArray(J))J.forEach((Q)=>{Y[Q.key]=Q.value});else if(J)Y[J.key]=J.value;return Y}async setSMSAttributes($){let J={Action:"SetSMSAttributes",Version:"2010-03-31"},Y=1;Object.entries($).forEach(([Q,Z])=>{if(Z!==void 0)J[`attributes.entry.${Y}.key`]=Q,J[`attributes.entry.${Y}.value`]=Z,Y++}),await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)})}async checkIfPhoneNumberIsOptedOut($){return(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CheckIfPhoneNumberIsOptedOut",Version:"2010-03-31",phoneNumber:$})}))?.CheckIfPhoneNumberIsOptedOutResponse?.CheckIfPhoneNumberIsOptedOutResult?.isOptedOut==="true"}async listPhoneNumbersOptedOut($){let J={Action:"ListPhoneNumbersOptedOut",Version:"2010-03-31"};if($)J.nextToken=$;let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListPhoneNumbersOptedOutResponse?.ListPhoneNumbersOptedOutResult?.phoneNumbers?.member;return{phoneNumbers:Array.isArray(Q)?Q:Q?[Q]:[],nextToken:Y?.ListPhoneNumbersOptedOutResponse?.ListPhoneNumbersOptedOutResult?.nextToken}}async optInPhoneNumber($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"OptInPhoneNumber",Version:"2010-03-31",phoneNumber:$})})}async listSMSSandboxPhoneNumbers($){let J={Action:"ListSMSSandboxPhoneNumbers",Version:"2010-03-31"};if($)J.NextToken=$;let Y=await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(J)}),Q=Y?.ListSMSSandboxPhoneNumbersResponse?.ListSMSSandboxPhoneNumbersResult?.PhoneNumbers?.member;return{PhoneNumbers:Array.isArray(Q)?Q:Q?[Q]:[],NextToken:Y?.ListSMSSandboxPhoneNumbersResponse?.ListSMSSandboxPhoneNumbersResult?.NextToken}}async createSMSSandboxPhoneNumber($,J){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CreateSMSSandboxPhoneNumber",Version:"2010-03-31",PhoneNumber:$,LanguageCode:J||"en-US"})})}async verifySMSSandboxPhoneNumber($,J){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"VerifySMSSandboxPhoneNumber",Version:"2010-03-31",PhoneNumber:$,OneTimePassword:J})})}async deleteSMSSandboxPhoneNumber($){await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteSMSSandboxPhoneNumber",Version:"2010-03-31",PhoneNumber:$})})}async getSMSSandboxAccountStatus(){return{IsInSandbox:(await this.client.request({service:"sns",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"GetSMSSandboxAccountStatus",Version:"2010-03-31"})}))?.GetSMSSandboxAccountStatusResponse?.GetSMSSandboxAccountStatusResult?.IsInSandbox==="true"}}}function s5($){$.command("notify:topics","List all SNS topics").option("--region <region>","AWS region").action(async(J)=>{V("SNS Topics");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=new E1(Q),U=new L("Fetching topics...");U.start();let z=(await Z.listTopics()).Topics||[];if(U.succeed(`Found ${z.length} topic(s)`),z.length===0){F("No SNS topics found"),F("Use `cloud notify:create` to create a new topic");return}d(["Topic ARN","Name"],z.map((G)=>{let H=G.TopicArn?.split(":").pop()||"N/A";return[G.TopicArn||"N/A",H]}))}catch(Y){R(`Failed to list topics: ${Y.message}`),process.exit(1)}}),$.command("notify:create <name>","Create a new SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).option("--fifo","Create a FIFO topic").option("--display-name <name>","Display name for SMS subscriptions").action(async(J,Y)=>{V("Create SNS Topic");try{let Q=new E1(Y.region),Z=Y.fifo&&!J.endsWith(".fifo")?`${J}.fifo`:J;if(F(`Topic name: ${Z}`),F(`Type: ${Y.fifo?"FIFO":"Standard"}`),!await v(`
7992
7992
  Create this topic?`,!0)){F("Operation cancelled");return}let W=new L("Creating topic...");W.start();let z={};if(Y.fifo)z.FifoTopic="true",z.ContentBasedDeduplication="true";if(Y.displayName)z.DisplayName=Y.displayName;let G=await Q.createTopic({Name:Z,Attributes:Object.keys(z).length>0?z:void 0});W.succeed("Topic created"),C(`
7993
7993
  Topic ARN: ${G.TopicArn}`),F(`
7994
- To subscribe:`),F(` cloud notify:subscribe ${G.TopicArn} --email user@example.com`)}catch(Q){R(`Failed to create topic: ${Q.message}`),process.exit(1)}}),$.command("notify:delete <topicArn>","Delete an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete SNS Topic");try{let Q=new E1(Y.region);if(g(`This will delete topic: ${J}`),g("All subscriptions will be removed."),!await y(`
7995
- Delete this topic?`,!1)){F("Operation cancelled");return}let U=new L("Deleting topic...");U.start(),await Q.deleteTopic(J),U.succeed("Topic deleted")}catch(Q){R(`Failed to delete topic: ${Q.message}`),process.exit(1)}}),$.command("notify:subscribe <topicArn>","Subscribe to an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).option("--email <address>","Email address").option("--sms <number>","Phone number (E.164 format)").option("--sqs <queueArn>","SQS queue ARN").option("--lambda <functionArn>","Lambda function ARN").option("--https <url>","HTTPS endpoint URL").option("--filter <json>","Filter policy JSON").action(async(J,Y)=>{V("Subscribe to SNS Topic");try{let Q=new E1(Y.region),Z,U;if(Y.email)Z="email",U=Y.email;else if(Y.sms)Z="sms",U=Y.sms;else if(Y.sqs)Z="sqs",U=Y.sqs;else if(Y.lambda)Z="lambda",U=Y.lambda;else if(Y.https)Z="https",U=Y.https;else{R("Specify a subscription type: --email, --sms, --sqs, --lambda, or --https");return}if(F(`Topic: ${J}`),F(`Protocol: ${Z}`),F(`Endpoint: ${U}`),!await y(`
7994
+ To subscribe:`),F(` cloud notify:subscribe ${G.TopicArn} --email user@example.com`)}catch(Q){R(`Failed to create topic: ${Q.message}`),process.exit(1)}}),$.command("notify:delete <topicArn>","Delete an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete SNS Topic");try{let Q=new E1(Y.region);if(g(`This will delete topic: ${J}`),g("All subscriptions will be removed."),!await v(`
7995
+ Delete this topic?`,!1)){F("Operation cancelled");return}let U=new L("Deleting topic...");U.start(),await Q.deleteTopic(J),U.succeed("Topic deleted")}catch(Q){R(`Failed to delete topic: ${Q.message}`),process.exit(1)}}),$.command("notify:subscribe <topicArn>","Subscribe to an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).option("--email <address>","Email address").option("--sms <number>","Phone number (E.164 format)").option("--sqs <queueArn>","SQS queue ARN").option("--lambda <functionArn>","Lambda function ARN").option("--https <url>","HTTPS endpoint URL").option("--filter <json>","Filter policy JSON").action(async(J,Y)=>{V("Subscribe to SNS Topic");try{let Q=new E1(Y.region),Z,U;if(Y.email)Z="email",U=Y.email;else if(Y.sms)Z="sms",U=Y.sms;else if(Y.sqs)Z="sqs",U=Y.sqs;else if(Y.lambda)Z="lambda",U=Y.lambda;else if(Y.https)Z="https",U=Y.https;else{R("Specify a subscription type: --email, --sms, --sqs, --lambda, or --https");return}if(F(`Topic: ${J}`),F(`Protocol: ${Z}`),F(`Endpoint: ${U}`),!await v(`
7996
7996
  Create this subscription?`,!0)){F("Operation cancelled");return}let z=new L("Creating subscription...");z.start();let G={TopicArn:J,Protocol:Z,Endpoint:U};if(Y.filter)G.Attributes={FilterPolicy:Y.filter};let H=await Q.subscribe(G);if(z.succeed("Subscription created"),H.SubscriptionArn==="pending confirmation")F(`
7997
7997
  Subscription is pending confirmation.`),F("The subscriber will receive a confirmation message.");else C(`
7998
- Subscription ARN: ${H.SubscriptionArn}`)}catch(Q){R(`Failed to subscribe: ${Q.message}`),process.exit(1)}}),$.command("notify:unsubscribe <subscriptionArn>","Unsubscribe from an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Unsubscribe from SNS Topic");try{let Q=new E1(Y.region);if(g(`This will remove subscription: ${J}`),!await y(`
7999
- Unsubscribe?`,!1)){F("Operation cancelled");return}let U=new L("Unsubscribing...");U.start(),await Q.unsubscribe(J),U.succeed("Unsubscribed")}catch(Q){R(`Failed to unsubscribe: ${Q.message}`),process.exit(1)}}),$.command("notify:subscriptions <topicArn>","List subscriptions for a topic").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Topic Subscriptions");try{let Q=new E1(Y.region),Z=new L("Fetching subscriptions...");Z.start();let W=(await Q.listSubscriptionsByTopic(J)).Subscriptions||[];if(Z.succeed(`Found ${W.length} subscription(s)`),W.length===0){F("No subscriptions found");return}d(["Protocol","Endpoint","Status","Subscription ARN"],W.map((z)=>[z.Protocol||"N/A",z.Endpoint||"N/A",z.SubscriptionArn==="PendingConfirmation"?"Pending":"Confirmed",(z.SubscriptionArn||"N/A").substring(0,50)]))}catch(Q){R(`Failed to list subscriptions: ${Q.message}`),process.exit(1)}}),$.command("notify:publish <topicArn>","Publish a message to an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).option("--message <text>","Message body").option("--subject <text>","Message subject (for email)").option("--file <path>","Read message from file").option("--json","Send as JSON message structure").option("--group <id>","Message group ID (for FIFO topics)").option("--dedup <id>","Deduplication ID (for FIFO topics)").action(async(J,Y)=>{V("Publish to SNS Topic");try{let Q=new E1(Y.region),Z;if(Y.file)Z=await Bun.file(Y.file).text();else if(Y.message)Z=Y.message;else Z=await A0("Message");if(!Z){R("Message is required");return}if(F(`Topic: ${J}`),F(`Message length: ${Z.length} characters`),!await y(`
7998
+ Subscription ARN: ${H.SubscriptionArn}`)}catch(Q){R(`Failed to subscribe: ${Q.message}`),process.exit(1)}}),$.command("notify:unsubscribe <subscriptionArn>","Unsubscribe from an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Unsubscribe from SNS Topic");try{let Q=new E1(Y.region);if(g(`This will remove subscription: ${J}`),!await v(`
7999
+ Unsubscribe?`,!1)){F("Operation cancelled");return}let U=new L("Unsubscribing...");U.start(),await Q.unsubscribe(J),U.succeed("Unsubscribed")}catch(Q){R(`Failed to unsubscribe: ${Q.message}`),process.exit(1)}}),$.command("notify:subscriptions <topicArn>","List subscriptions for a topic").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Topic Subscriptions");try{let Q=new E1(Y.region),Z=new L("Fetching subscriptions...");Z.start();let W=(await Q.listSubscriptionsByTopic(J)).Subscriptions||[];if(Z.succeed(`Found ${W.length} subscription(s)`),W.length===0){F("No subscriptions found");return}d(["Protocol","Endpoint","Status","Subscription ARN"],W.map((z)=>[z.Protocol||"N/A",z.Endpoint||"N/A",z.SubscriptionArn==="PendingConfirmation"?"Pending":"Confirmed",(z.SubscriptionArn||"N/A").substring(0,50)]))}catch(Q){R(`Failed to list subscriptions: ${Q.message}`),process.exit(1)}}),$.command("notify:publish <topicArn>","Publish a message to an SNS topic").option("--region <region>","AWS region",{default:"us-east-1"}).option("--message <text>","Message body").option("--subject <text>","Message subject (for email)").option("--file <path>","Read message from file").option("--json","Send as JSON message structure").option("--group <id>","Message group ID (for FIFO topics)").option("--dedup <id>","Deduplication ID (for FIFO topics)").action(async(J,Y)=>{V("Publish to SNS Topic");try{let Q=new E1(Y.region),Z;if(Y.file)Z=await Bun.file(Y.file).text();else if(Y.message)Z=Y.message;else Z=await A0("Message");if(!Z){R("Message is required");return}if(F(`Topic: ${J}`),F(`Message length: ${Z.length} characters`),!await v(`
8000
8000
  Publish this message?`,!0)){F("Operation cancelled");return}let W=new L("Publishing message...");W.start();let z={TopicArn:J,Message:Z};if(Y.subject)z.Subject=Y.subject;if(Y.json)z.MessageStructure="json";if(Y.group)z.MessageGroupId=Y.group;if(Y.dedup)z.MessageDeduplicationId=Y.dedup;let G=await Q.publish(z);W.succeed("Message published"),C(`
8001
- Message ID: ${G.MessageId}`)}catch(Q){R(`Failed to publish message: ${Q.message}`),process.exit(1)}}),$.command("notify:sms <phoneNumber>","Send an SMS message directly").option("--region <region>","AWS region",{default:"us-east-1"}).option("--message <text>","Message body").option("--sender <id>","Sender ID or short code").option("--type <type>","Message type (Transactional or Promotional)",{default:"Transactional"}).action(async(J,Y)=>{V("Send SMS");try{let Q=new E1(Y.region),Z=Y.message||await A0("Message");if(!Z){R("Message is required");return}if(F(`To: ${J}`),F(`Message: ${Z}`),F(`Type: ${Y.type}`),!await y(`
8001
+ Message ID: ${G.MessageId}`)}catch(Q){R(`Failed to publish message: ${Q.message}`),process.exit(1)}}),$.command("notify:sms <phoneNumber>","Send an SMS message directly").option("--region <region>","AWS region",{default:"us-east-1"}).option("--message <text>","Message body").option("--sender <id>","Sender ID or short code").option("--type <type>","Message type (Transactional or Promotional)",{default:"Transactional"}).action(async(J,Y)=>{V("Send SMS");try{let Q=new E1(Y.region),Z=Y.message||await A0("Message");if(!Z){R("Message is required");return}if(F(`To: ${J}`),F(`Message: ${Z}`),F(`Type: ${Y.type}`),!await v(`
8002
8002
  Send this SMS?`,!0)){F("Operation cancelled");return}let W=new L("Sending SMS...");W.start();let z={PhoneNumber:J,Message:Z,MessageAttributes:{"AWS.SNS.SMS.SMSType":{DataType:"String",StringValue:Y.type}}};if(Y.sender)z.MessageAttributes["AWS.SNS.SMS.SenderID"]={DataType:"String",StringValue:Y.sender};let G=await Q.publish(z);W.succeed("SMS sent"),C(`
8003
8003
  Message ID: ${G.MessageId}`)}catch(Q){R(`Failed to send SMS: ${Q.message}`),process.exit(1)}}),$.command("notify:topic:attributes <topicArn>","Show topic attributes").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Topic Attributes");try{let Q=new E1(Y.region),Z=new L("Fetching attributes...");Z.start();let U=await Q.getTopicAttributes(J);if(Z.succeed("Attributes loaded"),F(`
8004
8004
  Topic Information:`),F(` ARN: ${J}`),F(` Display Name: ${U.DisplayName||"Not set"}`),F(` Owner: ${U.Owner||"N/A"}`),F(`
@@ -8031,29 +8031,29 @@ Status:`),F(` Logging: ${G.IsLogging?"Active":"Stopped"}`),G.LatestDeliveryTime
8031
8031
  Event Selectors:`);for(let K of A.EventSelectors)if(F(` - Read/Write: ${K.ReadWriteType}`),F(` Management Events: ${K.IncludeManagementEvents?"Yes":"No"}`),K.DataResources&&K.DataResources.length>0)F(` Data Resources: ${K.DataResources.length} configured`)}}catch{}}catch(Q){R(`Failed to get trail: ${Q.message}`),process.exit(1)}}),$.command("audit:events","Look up recent CloudTrail events").option("--region <region>","AWS region").option("--user <username>","Filter by IAM user").option("--event <eventName>","Filter by event name").option("--resource <resourceName>","Filter by resource name").option("--hours <number>","Hours to look back",{default:"24"}).option("--limit <number>","Maximum events to return",{default:"50"}).action(async(J)=>{V("CloudTrail Events");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await W2(Q),U=new L("Looking up events...");U.start();let W=new Date,G={StartTime:new Date(W.getTime()-Number.parseInt(J.hours)*60*60*1000),EndTime:W,MaxResults:Number.parseInt(J.limit)};if(J.user)G.LookupAttributes=[{AttributeKey:"Username",AttributeValue:J.user}];else if(J.event)G.LookupAttributes=[{AttributeKey:"EventName",AttributeValue:J.event}];else if(J.resource)G.LookupAttributes=[{AttributeKey:"ResourceName",AttributeValue:J.resource}];let A=(await Z.lookupEvents(G)).Events||[];if(U.succeed(`Found ${A.length} event(s)`),A.length===0){F("No events found matching criteria");return}d(["Time","Event","User","Source IP","Resources"],A.map((K)=>[K.EventTime?new Date(K.EventTime).toLocaleString():"N/A",K.EventName||"N/A",K.Username||"N/A",K.SourceIPAddress||"N/A",(K.Resources||[]).map((B)=>B.ResourceName).join(", ").substring(0,30)||"-"]))}catch(Y){R(`Failed to lookup events: ${Y.message}`),process.exit(1)}}),$.command("audit:event <eventId>","Show CloudTrail event details").option("--region <region>","AWS region").action(async(J,Y)=>{V(`Event: ${J}`);try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1",U=await W2(Z),W=new L("Fetching event...");W.start();let G=(await U.lookupEvents({LookupAttributes:[{AttributeKey:"EventId",AttributeValue:J}],MaxResults:1})).Events?.[0];if(!G){W.fail("Event not found");return}if(W.succeed("Event loaded"),F(`
8032
8032
  Event Information:`),F(` Event ID: ${G.EventId}`),F(` Event Name: ${G.EventName}`),F(` Event Time: ${G.EventTime?new Date(G.EventTime).toLocaleString():"N/A"}`),F(` Event Source: ${G.EventSource}`),F(` Username: ${G.Username}`),F(` Source IP: ${G.SourceIPAddress}`),F(` Access Key: ${G.AccessKeyId||"N/A"}`),G.Resources&&G.Resources.length>0){F(`
8033
8033
  Resources:`);for(let H of G.Resources)F(` - ${H.ResourceType}: ${H.ResourceName}`)}if(G.CloudTrailEvent){F(`
8034
- Full Event Record:`);let H=JSON.parse(G.CloudTrailEvent);console.log(JSON.stringify(H,null,2))}}catch(Q){R(`Failed to get event: ${Q.message}`),process.exit(1)}}),$.command("audit:create <trailName>","Create a new CloudTrail trail").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bucket <name>","S3 bucket for logs").option("--prefix <prefix>","S3 key prefix").option("--multi-region","Enable multi-region trail").option("--validation","Enable log file validation").option("--global-events","Include global service events").action(async(J,Y)=>{V("Create CloudTrail Trail");try{if(!Y.bucket){R("--bucket is required");return}let Q=await W2(Y.region);if(F(`Trail Name: ${J}`),F(`S3 Bucket: ${Y.bucket}`),F(`Multi-Region: ${Y.multiRegion?"Yes":"No"}`),F(`Log Validation: ${Y.validation?"Yes":"No"}`),F(`Global Events: ${Y.globalEvents?"Yes":"No"}`),!await y(`
8034
+ Full Event Record:`);let H=JSON.parse(G.CloudTrailEvent);console.log(JSON.stringify(H,null,2))}}catch(Q){R(`Failed to get event: ${Q.message}`),process.exit(1)}}),$.command("audit:create <trailName>","Create a new CloudTrail trail").option("--region <region>","AWS region",{default:"us-east-1"}).option("--bucket <name>","S3 bucket for logs").option("--prefix <prefix>","S3 key prefix").option("--multi-region","Enable multi-region trail").option("--validation","Enable log file validation").option("--global-events","Include global service events").action(async(J,Y)=>{V("Create CloudTrail Trail");try{if(!Y.bucket){R("--bucket is required");return}let Q=await W2(Y.region);if(F(`Trail Name: ${J}`),F(`S3 Bucket: ${Y.bucket}`),F(`Multi-Region: ${Y.multiRegion?"Yes":"No"}`),F(`Log Validation: ${Y.validation?"Yes":"No"}`),F(`Global Events: ${Y.globalEvents?"Yes":"No"}`),!await v(`
8035
8035
  Create this trail?`,!0)){F("Operation cancelled");return}let U=new L("Creating trail...");U.start();let W=await Q.createTrail({Name:J,S3BucketName:Y.bucket,S3KeyPrefix:Y.prefix,IsMultiRegionTrail:Y.multiRegion,EnableLogFileValidation:Y.validation,IncludeGlobalServiceEvents:Y.globalEvents??!0});U.text="Starting logging...",await Q.startLogging(J),U.succeed("Trail created and logging started"),C(`
8036
- Trail ARN: ${W.TrailARN}`),F(`S3 Bucket: ${W.S3BucketName}`)}catch(Q){R(`Failed to create trail: ${Q.message}`),process.exit(1)}}),$.command("audit:start <trailName>","Start CloudTrail logging").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Start CloudTrail Logging");try{let Q=await W2(Y.region),Z=new L("Starting logging...");Z.start(),await Q.startLogging(J),Z.succeed("Logging started")}catch(Q){R(`Failed to start logging: ${Q.message}`),process.exit(1)}}),$.command("audit:stop <trailName>","Stop CloudTrail logging").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Stop CloudTrail Logging");try{let Q=await W2(Y.region);if(g(`This will stop logging for trail: ${J}`),!await y(`
8037
- Stop logging?`,!1)){F("Operation cancelled");return}let U=new L("Stopping logging...");U.start(),await Q.stopLogging(J),U.succeed("Logging stopped")}catch(Q){R(`Failed to stop logging: ${Q.message}`),process.exit(1)}}),$.command("audit:delete <trailName>","Delete a CloudTrail trail").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete CloudTrail Trail");try{let Q=await W2(Y.region);if(g(`This will permanently delete trail: ${J}`),!await y(`
8036
+ Trail ARN: ${W.TrailARN}`),F(`S3 Bucket: ${W.S3BucketName}`)}catch(Q){R(`Failed to create trail: ${Q.message}`),process.exit(1)}}),$.command("audit:start <trailName>","Start CloudTrail logging").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Start CloudTrail Logging");try{let Q=await W2(Y.region),Z=new L("Starting logging...");Z.start(),await Q.startLogging(J),Z.succeed("Logging started")}catch(Q){R(`Failed to start logging: ${Q.message}`),process.exit(1)}}),$.command("audit:stop <trailName>","Stop CloudTrail logging").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Stop CloudTrail Logging");try{let Q=await W2(Y.region);if(g(`This will stop logging for trail: ${J}`),!await v(`
8037
+ Stop logging?`,!1)){F("Operation cancelled");return}let U=new L("Stopping logging...");U.start(),await Q.stopLogging(J),U.succeed("Logging stopped")}catch(Q){R(`Failed to stop logging: ${Q.message}`),process.exit(1)}}),$.command("audit:delete <trailName>","Delete a CloudTrail trail").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(J,Y)=>{V("Delete CloudTrail Trail");try{let Q=await W2(Y.region);if(g(`This will permanently delete trail: ${J}`),!await v(`
8038
8038
  Delete this trail?`,!1)){F("Operation cancelled");return}let U=new L("Deleting trail...");U.start(),await Q.deleteTrail(J),U.succeed("Trail deleted")}catch(Q){R(`Failed to delete trail: ${Q.message}`),process.exit(1)}})}function YJ($){$.command("status","Show overall infrastructure health dashboard").option("--region <region>","AWS region").action(async(J)=>{V("Infrastructure Status Dashboard");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1";F(`Region: ${Q}`),F(`Project: ${Y.project.name||"Unknown"}`),F("");let Z=[],U=new L("Checking EC2 instances...");U.start();try{let{EC2Client:O}=await Promise.resolve().then(() => (d9(),dZ)),w=await new O(Q).describeInstances({Filters:[{Name:"instance-state-name",Values:["running","pending","stopping","stopped"]}]}),E=0,M=0,T=0;for(let D of w.Reservations||[])for(let N of D.Instances||[])if(T++,N.State?.Name==="running")E++;else if(N.State?.Name==="stopped")M++;U.succeed("EC2 instances checked"),Z.push({name:"EC2 Instances",status:E>0?"OK":T>0?"WARN":"INFO",details:`${E} running, ${M} stopped, ${T} total`})}catch(O){U.fail("EC2 check failed"),Z.push({name:"EC2 Instances",status:"ERROR",details:O.message})}let W=new L("Checking RDS instances...");W.start();try{let{RDSClient:O}=await Promise.resolve().then(() => (ZU(),QU)),E=(await new O(Q).describeDBInstances()).DBInstances||[],M=E.filter((T)=>T.DBInstanceStatus==="available").length;W.succeed("RDS instances checked"),Z.push({name:"RDS Databases",status:E.length>0&&M===E.length?"OK":E.length>0?"WARN":"INFO",details:`${M} available, ${E.length} total`})}catch(O){W.fail("RDS check failed"),Z.push({name:"RDS Databases",status:"ERROR",details:O.message})}let z=new L("Checking Lambda functions...");z.start();try{let{LambdaClient:O}=await Promise.resolve().then(() => (JJ(),$J)),E=(await new O(Q).listFunctions()).Functions||[];z.succeed("Lambda functions checked"),Z.push({name:"Lambda Functions",status:"OK",details:`${E.length} function(s)`})}catch(O){z.fail("Lambda check failed"),Z.push({name:"Lambda Functions",status:"ERROR",details:O.message})}let G=new L("Checking S3 buckets...");G.start();try{let{S3Client:O}=await Promise.resolve().then(() => (P1(),G5)),E=(await new O(Q).listBuckets()).Buckets||[];G.succeed("S3 buckets checked"),Z.push({name:"S3 Buckets",status:"OK",details:`${E.length} bucket(s)`})}catch(O){G.fail("S3 check failed"),Z.push({name:"S3 Buckets",status:"ERROR",details:O.message})}let H=new L("Checking CloudFront distributions...");H.start();try{let{CloudFrontClient:O}=await Promise.resolve().then(() => (l1(),j5)),w=await new O().listDistributions(),E=w.filter((M)=>M.Status==="Deployed").length;H.succeed("CloudFront checked"),Z.push({name:"CloudFront",status:w.length>0&&E===w.length?"OK":w.length>0?"WARN":"INFO",details:`${E} deployed, ${w.length} total`})}catch(O){H.fail("CloudFront check failed"),Z.push({name:"CloudFront",status:"ERROR",details:O.message})}let A=new L("Checking SQS queues...");A.start();try{let{SQSClient:O}=await Promise.resolve().then(() => (p5(),JU)),E=(await new O(Q).listQueues()).QueueUrls||[];A.succeed("SQS queues checked"),Z.push({name:"SQS Queues",status:"OK",details:`${E.length} queue(s)`})}catch(O){A.fail("SQS check failed"),Z.push({name:"SQS Queues",status:"ERROR",details:O.message})}let K=new L("Checking CloudFormation stacks...");K.start();try{let{CloudFormationClient:O}=await Promise.resolve().then(() => (S1(),a7)),E=(await new O(Q).listStacks(["CREATE_COMPLETE","UPDATE_COMPLETE","CREATE_IN_PROGRESS","UPDATE_IN_PROGRESS","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_COMPLETE"])).StackSummaries||[],M=E.filter((N)=>N.StackStatus==="CREATE_COMPLETE"||N.StackStatus==="UPDATE_COMPLETE").length,T=E.filter((N)=>N.StackStatus?.includes("IN_PROGRESS")).length,D=E.filter((N)=>N.StackStatus?.includes("ROLLBACK")).length;K.succeed("CloudFormation checked"),Z.push({name:"CloudFormation",status:D>0?"WARN":T>0?"INFO":"OK",details:`${M} healthy, ${T} in progress, ${D} rolled back`})}catch(O){K.fail("CloudFormation check failed"),Z.push({name:"CloudFormation",status:"ERROR",details:O.message})}let B=new L("Checking SSL certificates...");B.start();try{let{ACMClient:O}=await Promise.resolve().then(() => (s1(),UQ)),_=new O("us-east-1"),E=(await _.listCertificates()).CertificateSummaryList||[],M=await Promise.all(E.map((x)=>_.describeCertificate({CertificateArn:x.CertificateArn}))),T=M.filter((x)=>x.Status==="ISSUED").length,D=M.filter((x)=>x.Status==="PENDING_VALIDATION").length,N=M.filter((x)=>{if(x.NotAfter)return(new Date(x.NotAfter).getTime()-Date.now())/86400000<30;return!1}).length;B.succeed("SSL certificates checked"),Z.push({name:"SSL Certificates",status:N>0?"WARN":D>0?"INFO":"OK",details:`${T} issued, ${D} pending${N>0?`, ${N} expiring soon`:""}`})}catch(O){B.fail("ACM check failed"),Z.push({name:"SSL Certificates",status:"ERROR",details:O.message})}F(`
8039
8039
  `+"=".repeat(60)),F("HEALTH SUMMARY"),F("=".repeat(60)+`
8040
8040
  `);for(let O of Z){let _="";if(O.status==="OK")_=`${Y0.green}[OK]${Y0.reset}`;else if(O.status==="WARN")_=`${Y0.yellow}[WARN]${Y0.reset}`;else if(O.status==="ERROR")_=`${Y0.red}[ERROR]${Y0.reset}`;else _=`${Y0.blue}[INFO]${Y0.reset}`;console.log(`${_} ${O.name.padEnd(20)} ${O.details}`)}let j=Z.some((O)=>O.status==="ERROR"),X=Z.some((O)=>O.status==="WARN");if(F(""),j)R("Some services have errors. Check the details above.");else if(X)g("Some services need attention. Check the warnings above.");else C("All services are healthy!")}catch(Y){R(`Failed to get status: ${Y.message}`),process.exit(1)}}),$.command("status:costs","Show current month cost summary").option("--region <region>","AWS region").action(async(J)=>{V("Cost Summary");try{F("Fetching cost data from AWS Cost Explorer..."),F("");let Y=new Date,Q=new Date(Y.getFullYear(),Y.getMonth(),1),Z=new Date(Y.getFullYear(),Y.getMonth()+1,0);F(`Period: ${Q.toISOString().split("T")[0]} to ${Z.toISOString().split("T")[0]}`),F(""),F("Note: Cost data requires AWS Cost Explorer API access."),F("Run `cloud cost` for detailed cost analysis.")}catch(Y){R(`Failed to get cost summary: ${Y.message}`),process.exit(1)}}),$.command("status:alarms","Show CloudWatch alarm status").option("--region <region>","AWS region").action(async(J)=>{V("CloudWatch Alarms");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",{AWSClient:Z}=await Promise.resolve().then(() => (z0(),F2));class U{client;region;constructor(j){this.region=j,this.client=new Z}async describeAlarms(){return this.client.request({service:"monitoring",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=DescribeAlarms&Version=2010-08-01"})}}let W=new U(Q),z=new L("Fetching alarms...");z.start();let H=(await W.describeAlarms()).MetricAlarms||[];if(z.succeed(`Found ${H.length} alarm(s)`),H.length===0){F("No CloudWatch alarms configured");return}let A=H.filter((j)=>j.StateValue==="ALARM"),K=H.filter((j)=>j.StateValue==="OK"),B=H.filter((j)=>j.StateValue==="INSUFFICIENT_DATA");if(F(""),F(`Alarming: ${A.length}`),F(`OK: ${K.length}`),F(`Insufficient Data: ${B.length}`),A.length>0){F(`
8041
- Alarms in ALARM state:`);for(let j of A)R(` - ${j.AlarmName}: ${j.AlarmDescription||"No description"}`)}}catch(Y){R(`Failed to get alarms: ${Y.message}`),process.exit(1)}})}async function V1($){let{AWSClient:J}=await Promise.resolve().then(() => (z0(),F2));class Y{client;region;constructor(Q){this.region=Q,this.client=new J}async jsonRpcRequest(Q,Z){return this.client.request({service:"backup",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`CryoControllerFrontendService.${Q}`},body:JSON.stringify(Z)})}async listBackupVaults(){return this.jsonRpcRequest("ListBackupVaults",{})}async listBackupPlans(){return this.jsonRpcRequest("ListBackupPlans",{})}async listRecoveryPointsByBackupVault(Q,Z){return this.jsonRpcRequest("ListRecoveryPointsByBackupVault",{BackupVaultName:Q,...Z})}async describeBackupVault(Q){return this.jsonRpcRequest("DescribeBackupVault",{BackupVaultName:Q})}async getBackupPlan(Q){return this.jsonRpcRequest("GetBackupPlan",{BackupPlanId:Q})}async createBackupVault(Q,Z){return this.jsonRpcRequest("CreateBackupVault",{BackupVaultName:Q,...Z})}async deleteBackupVault(Q){return this.jsonRpcRequest("DeleteBackupVault",{BackupVaultName:Q})}async createBackupPlan(Q){return this.jsonRpcRequest("CreateBackupPlan",{BackupPlan:Q})}async deleteBackupPlan(Q){return this.jsonRpcRequest("DeleteBackupPlan",{BackupPlanId:Q})}async startBackupJob(Q){return this.jsonRpcRequest("StartBackupJob",Q)}async startRestoreJob(Q){return this.jsonRpcRequest("StartRestoreJob",Q)}async describeBackupJob(Q){return this.jsonRpcRequest("DescribeBackupJob",{BackupJobId:Q})}async describeRestoreJob(Q){return this.jsonRpcRequest("DescribeRestoreJob",{RestoreJobId:Q})}async listBackupJobs(Q){return this.jsonRpcRequest("ListBackupJobs",Q||{})}async listRestoreJobs(Q){return this.jsonRpcRequest("ListRestoreJobs",Q||{})}async createBackupSelection(Q,Z){return this.jsonRpcRequest("CreateBackupSelection",{BackupPlanId:Q,BackupSelection:Z})}async listBackupSelections(Q){return this.jsonRpcRequest("ListBackupSelections",{BackupPlanId:Q})}}return new Y($)}function QJ($){$.command("backup:vaults","List backup vaults").option("--region <region>","AWS region").action(async(J)=>{V("Backup Vaults");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await V1(Q),U=new L("Fetching vaults...");U.start();let z=(await Z.listBackupVaults()).BackupVaultList||[];if(U.succeed(`Found ${z.length} vault(s)`),z.length===0){F("No backup vaults found"),F("Use `cloud backup:create-vault` to create a new vault");return}d(["Vault Name","Recovery Points","Created","Encrypted"],z.map((G)=>[G.BackupVaultName||"N/A",(G.NumberOfRecoveryPoints||0).toString(),G.CreationDate?new Date(G.CreationDate).toLocaleDateString():"N/A",G.EncryptionKeyArn?"Yes":"Default"]))}catch(Y){R(`Failed to list vaults: ${Y.message}`),process.exit(1)}}),$.command("backup:list","List backup plans").option("--region <region>","AWS region").action(async(J)=>{V("Backup Plans");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await V1(Q),U=new L("Fetching backup plans...");U.start();let z=(await Z.listBackupPlans()).BackupPlansList||[];if(U.succeed(`Found ${z.length} backup plan(s)`),z.length===0){F("No backup plans found"),F("Use `cloud backup:create` to create a backup plan");return}d(["Plan Name","Plan ID","Version","Created"],z.map((G)=>[G.BackupPlanName||"N/A",G.BackupPlanId||"N/A",G.VersionId?.substring(0,8)||"N/A",G.CreationDate?new Date(G.CreationDate).toLocaleDateString():"N/A"]))}catch(Y){R(`Failed to list backup plans: ${Y.message}`),process.exit(1)}}),$.command("backup:recovery-points <vaultName>","List recovery points in a vault").option("--region <region>","AWS region").option("--limit <number>","Maximum results",{default:"50"}).action(async(J,Y)=>{V(`Recovery Points: ${J}`);try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1",U=await V1(Z),W=new L("Fetching recovery points...");W.start();let G=(await U.listRecoveryPointsByBackupVault(J,{MaxResults:Number.parseInt(Y.limit)})).RecoveryPoints||[];if(W.succeed(`Found ${G.length} recovery point(s)`),G.length===0){F("No recovery points found");return}d(["Resource","Status","Created","Size","Lifecycle"],G.map((H)=>[H.ResourceArn?.split(":").pop()||"N/A",H.Status||"N/A",H.CreationDate?new Date(H.CreationDate).toLocaleString():"N/A",H.BackupSizeInBytes?zU(H.BackupSizeInBytes):"N/A",H.Lifecycle?.DeleteAfterDays?`${H.Lifecycle.DeleteAfterDays} days`:"Indefinite"]))}catch(Q){R(`Failed to list recovery points: ${Q.message}`),process.exit(1)}}),$.command("backup:create-vault <vaultName>","Create a backup vault").option("--region <region>","AWS region",{default:"us-east-1"}).option("--kms-key <arn>","KMS key ARN for encryption").action(async(J,Y)=>{V("Create Backup Vault");try{let Q=await V1(Y.region);if(F(`Vault Name: ${J}`),F(`Region: ${Y.region}`),F(`Encryption: ${Y.kmsKey?"Custom KMS":"AWS Managed"}`),!await y(`
8041
+ Alarms in ALARM state:`);for(let j of A)R(` - ${j.AlarmName}: ${j.AlarmDescription||"No description"}`)}}catch(Y){R(`Failed to get alarms: ${Y.message}`),process.exit(1)}})}async function V1($){let{AWSClient:J}=await Promise.resolve().then(() => (z0(),F2));class Y{client;region;constructor(Q){this.region=Q,this.client=new J}async jsonRpcRequest(Q,Z){return this.client.request({service:"backup",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`CryoControllerFrontendService.${Q}`},body:JSON.stringify(Z)})}async listBackupVaults(){return this.jsonRpcRequest("ListBackupVaults",{})}async listBackupPlans(){return this.jsonRpcRequest("ListBackupPlans",{})}async listRecoveryPointsByBackupVault(Q,Z){return this.jsonRpcRequest("ListRecoveryPointsByBackupVault",{BackupVaultName:Q,...Z})}async describeBackupVault(Q){return this.jsonRpcRequest("DescribeBackupVault",{BackupVaultName:Q})}async getBackupPlan(Q){return this.jsonRpcRequest("GetBackupPlan",{BackupPlanId:Q})}async createBackupVault(Q,Z){return this.jsonRpcRequest("CreateBackupVault",{BackupVaultName:Q,...Z})}async deleteBackupVault(Q){return this.jsonRpcRequest("DeleteBackupVault",{BackupVaultName:Q})}async createBackupPlan(Q){return this.jsonRpcRequest("CreateBackupPlan",{BackupPlan:Q})}async deleteBackupPlan(Q){return this.jsonRpcRequest("DeleteBackupPlan",{BackupPlanId:Q})}async startBackupJob(Q){return this.jsonRpcRequest("StartBackupJob",Q)}async startRestoreJob(Q){return this.jsonRpcRequest("StartRestoreJob",Q)}async describeBackupJob(Q){return this.jsonRpcRequest("DescribeBackupJob",{BackupJobId:Q})}async describeRestoreJob(Q){return this.jsonRpcRequest("DescribeRestoreJob",{RestoreJobId:Q})}async listBackupJobs(Q){return this.jsonRpcRequest("ListBackupJobs",Q||{})}async listRestoreJobs(Q){return this.jsonRpcRequest("ListRestoreJobs",Q||{})}async createBackupSelection(Q,Z){return this.jsonRpcRequest("CreateBackupSelection",{BackupPlanId:Q,BackupSelection:Z})}async listBackupSelections(Q){return this.jsonRpcRequest("ListBackupSelections",{BackupPlanId:Q})}}return new Y($)}function QJ($){$.command("backup:vaults","List backup vaults").option("--region <region>","AWS region").action(async(J)=>{V("Backup Vaults");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await V1(Q),U=new L("Fetching vaults...");U.start();let z=(await Z.listBackupVaults()).BackupVaultList||[];if(U.succeed(`Found ${z.length} vault(s)`),z.length===0){F("No backup vaults found"),F("Use `cloud backup:create-vault` to create a new vault");return}d(["Vault Name","Recovery Points","Created","Encrypted"],z.map((G)=>[G.BackupVaultName||"N/A",(G.NumberOfRecoveryPoints||0).toString(),G.CreationDate?new Date(G.CreationDate).toLocaleDateString():"N/A",G.EncryptionKeyArn?"Yes":"Default"]))}catch(Y){R(`Failed to list vaults: ${Y.message}`),process.exit(1)}}),$.command("backup:list","List backup plans").option("--region <region>","AWS region").action(async(J)=>{V("Backup Plans");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await V1(Q),U=new L("Fetching backup plans...");U.start();let z=(await Z.listBackupPlans()).BackupPlansList||[];if(U.succeed(`Found ${z.length} backup plan(s)`),z.length===0){F("No backup plans found"),F("Use `cloud backup:create` to create a backup plan");return}d(["Plan Name","Plan ID","Version","Created"],z.map((G)=>[G.BackupPlanName||"N/A",G.BackupPlanId||"N/A",G.VersionId?.substring(0,8)||"N/A",G.CreationDate?new Date(G.CreationDate).toLocaleDateString():"N/A"]))}catch(Y){R(`Failed to list backup plans: ${Y.message}`),process.exit(1)}}),$.command("backup:recovery-points <vaultName>","List recovery points in a vault").option("--region <region>","AWS region").option("--limit <number>","Maximum results",{default:"50"}).action(async(J,Y)=>{V(`Recovery Points: ${J}`);try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1",U=await V1(Z),W=new L("Fetching recovery points...");W.start();let G=(await U.listRecoveryPointsByBackupVault(J,{MaxResults:Number.parseInt(Y.limit)})).RecoveryPoints||[];if(W.succeed(`Found ${G.length} recovery point(s)`),G.length===0){F("No recovery points found");return}d(["Resource","Status","Created","Size","Lifecycle"],G.map((H)=>[H.ResourceArn?.split(":").pop()||"N/A",H.Status||"N/A",H.CreationDate?new Date(H.CreationDate).toLocaleString():"N/A",H.BackupSizeInBytes?zU(H.BackupSizeInBytes):"N/A",H.Lifecycle?.DeleteAfterDays?`${H.Lifecycle.DeleteAfterDays} days`:"Indefinite"]))}catch(Q){R(`Failed to list recovery points: ${Q.message}`),process.exit(1)}}),$.command("backup:create-vault <vaultName>","Create a backup vault").option("--region <region>","AWS region",{default:"us-east-1"}).option("--kms-key <arn>","KMS key ARN for encryption").action(async(J,Y)=>{V("Create Backup Vault");try{let Q=await V1(Y.region);if(F(`Vault Name: ${J}`),F(`Region: ${Y.region}`),F(`Encryption: ${Y.kmsKey?"Custom KMS":"AWS Managed"}`),!await v(`
8042
8042
  Create this vault?`,!0)){F("Operation cancelled");return}let U=new L("Creating vault...");U.start(),await Q.createBackupVault(J,{EncryptionKeyArn:Y.kmsKey}),U.succeed("Vault created"),C(`
8043
- Vault: ${J}`)}catch(Q){R(`Failed to create vault: ${Q.message}`),process.exit(1)}}),$.command("backup:create <planName>","Create a backup plan").option("--region <region>","AWS region",{default:"us-east-1"}).option("--vault <name>","Target backup vault",{default:"Default"}).option("--schedule <cron>","Backup schedule (cron expression)",{default:"cron(0 5 ? * * *)"}).option("--retention <days>","Retention period in days",{default:"30"}).option("--lifecycle-cold <days>","Move to cold storage after days").action(async(J,Y)=>{V("Create Backup Plan");try{let Q=await V1(Y.region);if(F(`Plan Name: ${J}`),F(`Vault: ${Y.vault}`),F(`Schedule: ${Y.schedule}`),F(`Retention: ${Y.retention} days`),!await y(`
8043
+ Vault: ${J}`)}catch(Q){R(`Failed to create vault: ${Q.message}`),process.exit(1)}}),$.command("backup:create <planName>","Create a backup plan").option("--region <region>","AWS region",{default:"us-east-1"}).option("--vault <name>","Target backup vault",{default:"Default"}).option("--schedule <cron>","Backup schedule (cron expression)",{default:"cron(0 5 ? * * *)"}).option("--retention <days>","Retention period in days",{default:"30"}).option("--lifecycle-cold <days>","Move to cold storage after days").action(async(J,Y)=>{V("Create Backup Plan");try{let Q=await V1(Y.region);if(F(`Plan Name: ${J}`),F(`Vault: ${Y.vault}`),F(`Schedule: ${Y.schedule}`),F(`Retention: ${Y.retention} days`),!await v(`
8044
8044
  Create this backup plan?`,!0)){F("Operation cancelled");return}let U=new L("Creating backup plan...");U.start();let W={DeleteAfterDays:Number.parseInt(Y.retention)};if(Y.lifecycleCold)W.MoveToColdStorageAfterDays=Number.parseInt(Y.lifecycleCold);let z=await Q.createBackupPlan({BackupPlanName:J,Rules:[{RuleName:`${J}-daily`,TargetBackupVaultName:Y.vault,ScheduleExpression:Y.schedule,StartWindowMinutes:60,CompletionWindowMinutes:180,Lifecycle:W}]});U.succeed("Backup plan created"),C(`
8045
- Plan ID: ${z.BackupPlanId}`),F("\nNote: Add resource selections with `cloud backup:add-selection`")}catch(Q){R(`Failed to create backup plan: ${Q.message}`),process.exit(1)}}),$.command("backup:add-selection <planId>","Add resources to a backup plan").option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","Selection name").option("--role <arn>","IAM role ARN for backup").option("--resource <arn>","Resource ARN to backup").option("--tag-key <key>","Tag key for resource selection").option("--tag-value <value>","Tag value for resource selection").action(async(J,Y)=>{V("Add Backup Selection");try{if(!Y.role){R("--role is required (IAM role ARN for AWS Backup)");return}if(!Y.resource&&!Y.tagKey){R("Specify --resource or --tag-key/--tag-value");return}let Q=await V1(Y.region),U={SelectionName:Y.name||`selection-${Date.now()}`,IamRoleArn:Y.role};if(Y.resource)U.Resources=[Y.resource],F(`Resource: ${Y.resource}`);if(Y.tagKey&&Y.tagValue)U.ListOfTags=[{ConditionType:"STRINGEQUALS",ConditionKey:Y.tagKey,ConditionValue:Y.tagValue}],F(`Tag: ${Y.tagKey}=${Y.tagValue}`);if(!await y(`
8045
+ Plan ID: ${z.BackupPlanId}`),F("\nNote: Add resource selections with `cloud backup:add-selection`")}catch(Q){R(`Failed to create backup plan: ${Q.message}`),process.exit(1)}}),$.command("backup:add-selection <planId>","Add resources to a backup plan").option("--region <region>","AWS region",{default:"us-east-1"}).option("--name <name>","Selection name").option("--role <arn>","IAM role ARN for backup").option("--resource <arn>","Resource ARN to backup").option("--tag-key <key>","Tag key for resource selection").option("--tag-value <value>","Tag value for resource selection").action(async(J,Y)=>{V("Add Backup Selection");try{if(!Y.role){R("--role is required (IAM role ARN for AWS Backup)");return}if(!Y.resource&&!Y.tagKey){R("Specify --resource or --tag-key/--tag-value");return}let Q=await V1(Y.region),U={SelectionName:Y.name||`selection-${Date.now()}`,IamRoleArn:Y.role};if(Y.resource)U.Resources=[Y.resource],F(`Resource: ${Y.resource}`);if(Y.tagKey&&Y.tagValue)U.ListOfTags=[{ConditionType:"STRINGEQUALS",ConditionKey:Y.tagKey,ConditionValue:Y.tagValue}],F(`Tag: ${Y.tagKey}=${Y.tagValue}`);if(!await v(`
8046
8046
  Add this selection?`,!0)){F("Operation cancelled");return}let z=new L("Adding selection...");z.start();let G=await Q.createBackupSelection(J,U);z.succeed("Selection added"),C(`
8047
- Selection ID: ${G.SelectionId}`)}catch(Q){R(`Failed to add selection: ${Q.message}`),process.exit(1)}}),$.command("backup:start <resourceArn>","Start an on-demand backup").option("--region <region>","AWS region",{default:"us-east-1"}).option("--vault <name>","Backup vault name",{default:"Default"}).option("--role <arn>","IAM role ARN for backup").action(async(J,Y)=>{V("Start Backup Job");try{if(!Y.role){R("--role is required (IAM role ARN for AWS Backup)");return}let Q=await V1(Y.region);if(F(`Resource: ${J}`),F(`Vault: ${Y.vault}`),!await y(`
8047
+ Selection ID: ${G.SelectionId}`)}catch(Q){R(`Failed to add selection: ${Q.message}`),process.exit(1)}}),$.command("backup:start <resourceArn>","Start an on-demand backup").option("--region <region>","AWS region",{default:"us-east-1"}).option("--vault <name>","Backup vault name",{default:"Default"}).option("--role <arn>","IAM role ARN for backup").action(async(J,Y)=>{V("Start Backup Job");try{if(!Y.role){R("--role is required (IAM role ARN for AWS Backup)");return}let Q=await V1(Y.region);if(F(`Resource: ${J}`),F(`Vault: ${Y.vault}`),!await v(`
8048
8048
  Start backup?`,!0)){F("Operation cancelled");return}let U=new L("Starting backup job...");U.start();let W=await Q.startBackupJob({BackupVaultName:Y.vault,ResourceArn:J,IamRoleArn:Y.role,IdempotencyToken:`cli-${Date.now()}`});U.succeed("Backup job started"),C(`
8049
8049
  Job ID: ${W.BackupJobId}`),F("Use `cloud backup:jobs` to check status")}catch(Q){R(`Failed to start backup: ${Q.message}`),process.exit(1)}}),$.command("backup:restore <recoveryPointArn>","Start a restore job").option("--region <region>","AWS region",{default:"us-east-1"}).option("--role <arn>","IAM role ARN for restore").option("--metadata <json>","Restore metadata JSON").action(async(J,Y)=>{V("Start Restore Job");try{if(!Y.role){R("--role is required (IAM role ARN for AWS Backup)");return}let Q=await V1(Y.region);F(`Recovery Point: ${J}`);let Z={};if(Y.metadata)Z=JSON.parse(Y.metadata);if(g(`
8050
- Restore will create new resources. Review carefully.`),!await y(`
8050
+ Restore will create new resources. Review carefully.`),!await v(`
8051
8051
  Start restore?`,!1)){F("Operation cancelled");return}let W=new L("Starting restore job...");W.start();let z=await Q.startRestoreJob({RecoveryPointArn:J,IamRoleArn:Y.role,Metadata:Z,IdempotencyToken:`cli-${Date.now()}`});W.succeed("Restore job started"),C(`
8052
8052
  Job ID: ${z.RestoreJobId}`),F("Use `cloud backup:restore-jobs` to check status")}catch(Q){R(`Failed to start restore: ${Q.message}`),process.exit(1)}}),$.command("backup:jobs","List recent backup jobs").option("--region <region>","AWS region").option("--state <state>","Filter by state (CREATED, PENDING, RUNNING, COMPLETED, FAILED)").action(async(J)=>{V("Backup Jobs");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await V1(Q),U=new L("Fetching backup jobs...");U.start();let z=(await Z.listBackupJobs({ByState:J.state,MaxResults:50})).BackupJobs||[];if(U.succeed(`Found ${z.length} job(s)`),z.length===0){F("No backup jobs found");return}d(["Job ID","Resource","State","Started","Size"],z.map((G)=>[G.BackupJobId?.substring(0,16)||"N/A",G.ResourceArn?.split(":").pop()||"N/A",G.State||"N/A",G.CreationDate?new Date(G.CreationDate).toLocaleString():"N/A",G.BackupSizeInBytes?zU(G.BackupSizeInBytes):"N/A"]))}catch(Y){R(`Failed to list backup jobs: ${Y.message}`),process.exit(1)}}),$.command("backup:restore-jobs","List recent restore jobs").option("--region <region>","AWS region").option("--status <status>","Filter by status").action(async(J)=>{V("Restore Jobs");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await V1(Q),U=new L("Fetching restore jobs...");U.start();let z=(await Z.listRestoreJobs({ByStatus:J.status,MaxResults:50})).RestoreJobs||[];if(U.succeed(`Found ${z.length} job(s)`),z.length===0){F("No restore jobs found");return}d(["Job ID","Resource","Status","Started","Completed"],z.map((G)=>[G.RestoreJobId?.substring(0,16)||"N/A",G.CreatedResourceArn?.split(":").pop()||"Pending",G.Status||"N/A",G.CreationDate?new Date(G.CreationDate).toLocaleString():"N/A",G.CompletionDate?new Date(G.CompletionDate).toLocaleString():"-"]))}catch(Y){R(`Failed to list restore jobs: ${Y.message}`),process.exit(1)}}),$.command("backup:schedule","Show backup schedule overview").option("--region <region>","AWS region").action(async(J)=>{V("Backup Schedule Overview");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",Z=await V1(Q),U=new L("Fetching backup plans...");U.start();let z=(await Z.listBackupPlans()).BackupPlansList||[];if(U.succeed(`Found ${z.length} backup plan(s)`),z.length===0){F("No backup plans configured");return}for(let G of z){F(`
8053
8053
  ${G.BackupPlanName}`),F("=".repeat(40));try{let A=(await Z.getBackupPlan(G.BackupPlanId)).BackupPlan?.Rules||[];for(let B of A)if(F(` Rule: ${B.RuleName}`),F(` Schedule: ${B.ScheduleExpression}`),F(` Vault: ${B.TargetBackupVaultName}`),B.Lifecycle?.DeleteAfterDays)F(` Retention: ${B.Lifecycle.DeleteAfterDays} days`);let K=await Z.listBackupSelections(G.BackupPlanId);if(K.BackupSelectionsList&&K.BackupSelectionsList.length>0)F(` Selections: ${K.BackupSelectionsList.length}`)}catch{F(" (Unable to load plan details)")}}}catch(Y){R(`Failed to get schedule: ${Y.message}`),process.exit(1)}})}function zU($){if($===0)return"0 B";let J=1024,Y=["B","KB","MB","GB","TB"],Q=Math.floor(Math.log($)/Math.log(J));return`${Number.parseFloat(($/J**Q).toFixed(2))} ${Y[Q]}`}function ZJ($){$.command("api:list","List all API Gateway APIs").option("--region <region>","AWS region").action(async(J)=>{V("API Gateway APIs");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1",{LambdaClient:Z}=await Promise.resolve().then(() => (JJ(),$J)),U=new Z(Q),W=new L("Fetching APIs...");W.start();let{CloudFormationClient:z}=await Promise.resolve().then(() => (S1(),a7)),A=(await new z(Q).listStacks(["CREATE_COMPLETE","UPDATE_COMPLETE"])).StackSummaries.filter((K)=>K.StackName?.includes("api")||K.StackName?.includes("Api")||K.StackName?.includes("API"));if(W.succeed("APIs listed"),F(`
8054
8054
  API-related CloudFormation stacks:`),A.length===0)F("No API Gateway stacks found"),F(`
8055
- To create an API, you can:`),F(" 1. Use cloud.config.ts to define your API"),F(" 2. Deploy with `cloud deploy`");else d(["Stack Name","Status","Created"],A.map((K)=>[K.StackName||"N/A",K.StackStatus||"N/A",K.CreationTime?new Date(K.CreationTime).toLocaleDateString():"N/A"]));F("\nTip: Use AWS Console or `aws apigateway get-rest-apis` for detailed API listing")}catch(Y){R(`Failed to list APIs: ${Y.message}`),process.exit(1)}}),$.command("api:describe <apiId>","Show API Gateway API details").option("--region <region>","AWS region").action(async(J,Y)=>{V(`API: ${J}`);try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1";F(`API ID: ${J}`),F(`Region: ${Z}`),F(""),F("For detailed API information, use AWS CLI:"),F(` aws apigateway get-rest-api --rest-api-id ${J} --region ${Z}`),F(` aws apigateway get-resources --rest-api-id ${J} --region ${Z}`),F(` aws apigateway get-stages --rest-api-id ${J} --region ${Z}`)}catch(Q){R(`Failed to describe API: ${Q.message}`),process.exit(1)}}),$.command("api:stages <apiId>","List API stages").option("--region <region>","AWS region").action(async(J,Y)=>{V(`API Stages: ${J}`);try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1";F(`API ID: ${J}`),F(`Region: ${Z}`),F(""),F("Common stages:"),F(" - prod (production)"),F(" - staging"),F(" - dev (development)"),F(""),F("For detailed stage information, use AWS CLI:"),F(` aws apigateway get-stages --rest-api-id ${J} --region ${Z}`)}catch(Q){R(`Failed to list stages: ${Q.message}`),process.exit(1)}}),$.command("api:deploy <apiId>","Deploy API to a stage").option("--region <region>","AWS region",{default:"us-east-1"}).option("--stage <name>","Stage name",{default:"prod"}).option("--description <text>","Deployment description").action(async(J,Y)=>{V("Deploy API");try{if(F(`API ID: ${J}`),F(`Stage: ${Y.stage}`),!await y(`
8056
- Deploy to this stage?`,!0)){F("Operation cancelled");return}if(F(""),F("To deploy an API Gateway API:"),F(" aws apigateway create-deployment \\"),F(` --rest-api-id ${J} \\`),F(` --stage-name ${Y.stage} \\`),F(` --region ${Y.region}`),Y.description)F(` --description "${Y.description}"`)}catch(Q){R(`Failed to deploy API: ${Q.message}`),process.exit(1)}}),$.command("api:domains","List custom domain names").option("--region <region>","AWS region").action(async(J)=>{V("API Gateway Custom Domains");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1";F(`Region: ${Q}`),F(""),F("To list custom domains, use AWS CLI:"),F(` aws apigateway get-domain-names --region ${Q}`),F(""),F("To create a custom domain:"),F(" 1. Request or import an SSL certificate in ACM"),F(" 2. Create a custom domain in API Gateway"),F(" 3. Create a base path mapping to your API"),F(" 4. Add a DNS record pointing to the distribution")}catch(Y){R(`Failed to list domains: ${Y.message}`),process.exit(1)}}),$.command("api:usage <apiId>","Show API usage statistics").option("--region <region>","AWS region").option("--stage <name>","Stage name",{default:"prod"}).option("--days <number>","Number of days to show",{default:"7"}).action(async(J,Y)=>{V("API Usage Statistics");try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1";F(`API ID: ${J}`),F(`Stage: ${Y.stage}`),F(`Period: Last ${Y.days} days`),F("");let U=new Date,W=new Date;W.setDate(W.getDate()-Number.parseInt(Y.days)),F("To view API metrics in CloudWatch:"),F(" aws cloudwatch get-metric-statistics \\"),F(" --namespace AWS/ApiGateway \\"),F(" --metric-name Count \\"),F(` --dimensions Name=ApiName,Value=${J} Name=Stage,Value=${Y.stage} \\`),F(` --start-time ${W.toISOString()} \\`),F(` --end-time ${U.toISOString()} \\`),F(" --period 86400 \\"),F(" --statistics Sum \\"),F(` --region ${Z}`),F(""),F("Available metrics:"),F(" - Count: Total API calls"),F(" - Latency: Response latency"),F(" - 4XXError: Client errors"),F(" - 5XXError: Server errors"),F(" - IntegrationLatency: Backend latency")}catch(Q){R(`Failed to get usage: ${Q.message}`),process.exit(1)}}),$.command("api:export <apiId>","Export API specification").option("--region <region>","AWS region",{default:"us-east-1"}).option("--stage <name>","Stage name",{default:"prod"}).option("--format <format>","Export format (oas30, swagger)",{default:"oas30"}).option("--output <file>","Output file path").action(async(J,Y)=>{V("Export API Specification");try{F(`API ID: ${J}`),F(`Stage: ${Y.stage}`),F(`Format: ${Y.format==="oas30"?"OpenAPI 3.0":"Swagger 2.0"}`),F("");let Q=Y.format==="oas30"?"oas30":"swagger";F("To export the API specification:"),F(" aws apigateway get-export \\"),F(` --rest-api-id ${J} \\`),F(` --stage-name ${Y.stage} \\`),F(` --export-type ${Q} \\`),F(" --accepts application/json \\"),F(` --region ${Y.region} \\`),F(` ${Y.output||"api-spec.json"}`)}catch(Q){R(`Failed to export API: ${Q.message}`),process.exit(1)}}),$.command("api:logs <apiId>","View API Gateway logs").option("--region <region>","AWS region").option("--stage <name>","Stage name",{default:"prod"}).option("--tail","Tail the logs").action(async(J,Y)=>{V("API Gateway Logs");try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1",U=`API-Gateway-Execution-Logs_${J}/${Y.stage}`;if(F(`Log Group: ${U}`),F(""),F("To view logs:"),F(" aws logs filter-log-events \\"),F(` --log-group-name "${U}" \\`),F(` --region ${Z}`),Y.tail)F(""),F("For real-time log tailing, use:"),F(` aws logs tail "${U}" --follow --region ${Z}`);F(""),F("Note: Ensure logging is enabled for the API stage."),F("You can enable it in the stage settings.")}catch(Q){R(`Failed to get logs: ${Q.message}`),process.exit(1)}}),$.command("api:test <apiId> <path>","Test an API endpoint").option("--region <region>","AWS region").option("--stage <name>","Stage name",{default:"prod"}).option("--method <method>","HTTP method",{default:"GET"}).option("--body <json>","Request body (JSON)").option("--header <header>","Request header (can be specified multiple times)").action(async(J,Y,Q)=>{V("Test API Endpoint");try{let Z=await c(),U=Q.region||Z.project.region||"us-east-1",W=`https://${J}.execute-api.${U}.amazonaws.com/${Q.stage}${Y.startsWith("/")?Y:`/${Y}`}`;F(`URL: ${W}`),F(`Method: ${Q.method}`);let z={"Content-Type":"application/json"};if(Q.header){let X=Array.isArray(Q.header)?Q.header:[Q.header];for(let O of X){let[_,...w]=O.split(":");z[_.trim()]=w.join(":").trim()}}F("Headers:");for(let[X,O]of Object.entries(z))F(` ${X}: ${O}`);if(Q.body)F(`Body: ${Q.body}`);if(!await y(`
8055
+ To create an API, you can:`),F(" 1. Use cloud.config.ts to define your API"),F(" 2. Deploy with `cloud deploy`");else d(["Stack Name","Status","Created"],A.map((K)=>[K.StackName||"N/A",K.StackStatus||"N/A",K.CreationTime?new Date(K.CreationTime).toLocaleDateString():"N/A"]));F("\nTip: Use AWS Console or `aws apigateway get-rest-apis` for detailed API listing")}catch(Y){R(`Failed to list APIs: ${Y.message}`),process.exit(1)}}),$.command("api:describe <apiId>","Show API Gateway API details").option("--region <region>","AWS region").action(async(J,Y)=>{V(`API: ${J}`);try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1";F(`API ID: ${J}`),F(`Region: ${Z}`),F(""),F("For detailed API information, use AWS CLI:"),F(` aws apigateway get-rest-api --rest-api-id ${J} --region ${Z}`),F(` aws apigateway get-resources --rest-api-id ${J} --region ${Z}`),F(` aws apigateway get-stages --rest-api-id ${J} --region ${Z}`)}catch(Q){R(`Failed to describe API: ${Q.message}`),process.exit(1)}}),$.command("api:stages <apiId>","List API stages").option("--region <region>","AWS region").action(async(J,Y)=>{V(`API Stages: ${J}`);try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1";F(`API ID: ${J}`),F(`Region: ${Z}`),F(""),F("Common stages:"),F(" - prod (production)"),F(" - staging"),F(" - dev (development)"),F(""),F("For detailed stage information, use AWS CLI:"),F(` aws apigateway get-stages --rest-api-id ${J} --region ${Z}`)}catch(Q){R(`Failed to list stages: ${Q.message}`),process.exit(1)}}),$.command("api:deploy <apiId>","Deploy API to a stage").option("--region <region>","AWS region",{default:"us-east-1"}).option("--stage <name>","Stage name",{default:"prod"}).option("--description <text>","Deployment description").action(async(J,Y)=>{V("Deploy API");try{if(F(`API ID: ${J}`),F(`Stage: ${Y.stage}`),!await v(`
8056
+ Deploy to this stage?`,!0)){F("Operation cancelled");return}if(F(""),F("To deploy an API Gateway API:"),F(" aws apigateway create-deployment \\"),F(` --rest-api-id ${J} \\`),F(` --stage-name ${Y.stage} \\`),F(` --region ${Y.region}`),Y.description)F(` --description "${Y.description}"`)}catch(Q){R(`Failed to deploy API: ${Q.message}`),process.exit(1)}}),$.command("api:domains","List custom domain names").option("--region <region>","AWS region").action(async(J)=>{V("API Gateway Custom Domains");try{let Y=await c(),Q=J.region||Y.project.region||"us-east-1";F(`Region: ${Q}`),F(""),F("To list custom domains, use AWS CLI:"),F(` aws apigateway get-domain-names --region ${Q}`),F(""),F("To create a custom domain:"),F(" 1. Request or import an SSL certificate in ACM"),F(" 2. Create a custom domain in API Gateway"),F(" 3. Create a base path mapping to your API"),F(" 4. Add a DNS record pointing to the distribution")}catch(Y){R(`Failed to list domains: ${Y.message}`),process.exit(1)}}),$.command("api:usage <apiId>","Show API usage statistics").option("--region <region>","AWS region").option("--stage <name>","Stage name",{default:"prod"}).option("--days <number>","Number of days to show",{default:"7"}).action(async(J,Y)=>{V("API Usage Statistics");try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1";F(`API ID: ${J}`),F(`Stage: ${Y.stage}`),F(`Period: Last ${Y.days} days`),F("");let U=new Date,W=new Date;W.setDate(W.getDate()-Number.parseInt(Y.days)),F("To view API metrics in CloudWatch:"),F(" aws cloudwatch get-metric-statistics \\"),F(" --namespace AWS/ApiGateway \\"),F(" --metric-name Count \\"),F(` --dimensions Name=ApiName,Value=${J} Name=Stage,Value=${Y.stage} \\`),F(` --start-time ${W.toISOString()} \\`),F(` --end-time ${U.toISOString()} \\`),F(" --period 86400 \\"),F(" --statistics Sum \\"),F(` --region ${Z}`),F(""),F("Available metrics:"),F(" - Count: Total API calls"),F(" - Latency: Response latency"),F(" - 4XXError: Client errors"),F(" - 5XXError: Server errors"),F(" - IntegrationLatency: Backend latency")}catch(Q){R(`Failed to get usage: ${Q.message}`),process.exit(1)}}),$.command("api:export <apiId>","Export API specification").option("--region <region>","AWS region",{default:"us-east-1"}).option("--stage <name>","Stage name",{default:"prod"}).option("--format <format>","Export format (oas30, swagger)",{default:"oas30"}).option("--output <file>","Output file path").action(async(J,Y)=>{V("Export API Specification");try{F(`API ID: ${J}`),F(`Stage: ${Y.stage}`),F(`Format: ${Y.format==="oas30"?"OpenAPI 3.0":"Swagger 2.0"}`),F("");let Q=Y.format==="oas30"?"oas30":"swagger";F("To export the API specification:"),F(" aws apigateway get-export \\"),F(` --rest-api-id ${J} \\`),F(` --stage-name ${Y.stage} \\`),F(` --export-type ${Q} \\`),F(" --accepts application/json \\"),F(` --region ${Y.region} \\`),F(` ${Y.output||"api-spec.json"}`)}catch(Q){R(`Failed to export API: ${Q.message}`),process.exit(1)}}),$.command("api:logs <apiId>","View API Gateway logs").option("--region <region>","AWS region").option("--stage <name>","Stage name",{default:"prod"}).option("--tail","Tail the logs").action(async(J,Y)=>{V("API Gateway Logs");try{let Q=await c(),Z=Y.region||Q.project.region||"us-east-1",U=`API-Gateway-Execution-Logs_${J}/${Y.stage}`;if(F(`Log Group: ${U}`),F(""),F("To view logs:"),F(" aws logs filter-log-events \\"),F(` --log-group-name "${U}" \\`),F(` --region ${Z}`),Y.tail)F(""),F("For real-time log tailing, use:"),F(` aws logs tail "${U}" --follow --region ${Z}`);F(""),F("Note: Ensure logging is enabled for the API stage."),F("You can enable it in the stage settings.")}catch(Q){R(`Failed to get logs: ${Q.message}`),process.exit(1)}}),$.command("api:test <apiId> <path>","Test an API endpoint").option("--region <region>","AWS region").option("--stage <name>","Stage name",{default:"prod"}).option("--method <method>","HTTP method",{default:"GET"}).option("--body <json>","Request body (JSON)").option("--header <header>","Request header (can be specified multiple times)").action(async(J,Y,Q)=>{V("Test API Endpoint");try{let Z=await c(),U=Q.region||Z.project.region||"us-east-1",W=`https://${J}.execute-api.${U}.amazonaws.com/${Q.stage}${Y.startsWith("/")?Y:`/${Y}`}`;F(`URL: ${W}`),F(`Method: ${Q.method}`);let z={"Content-Type":"application/json"};if(Q.header){let X=Array.isArray(Q.header)?Q.header:[Q.header];for(let O of X){let[_,...w]=O.split(":");z[_.trim()]=w.join(":").trim()}}F("Headers:");for(let[X,O]of Object.entries(z))F(` ${X}: ${O}`);if(Q.body)F(`Body: ${Q.body}`);if(!await v(`
8057
8057
  Send request?`,!0)){F("Operation cancelled");return}let H=new L("Sending request...");H.start();let A=Date.now(),K=await fetch(W,{method:Q.method,headers:z,body:Q.body}),B=Date.now()-A,j=await K.text();H.succeed(`Response received (${B}ms)`),F(`
8058
8058
  Status: ${K.status} ${K.statusText}`),F(`
8059
8059
  Response Headers:`),K.headers.forEach((X,O)=>{F(` ${O}: ${X}`)}),F(`
@@ -8066,9 +8066,9 @@ Press Ctrl+C to stop the tunnel`)}),z.on("request",(H)=>{if(J.verbose)F(`→ ${H
8066
8066
  Tunnel closed`)});let G=()=>{F(`
8067
8067
  Shutting down tunnel...`),z.disconnect(),process.exit(0)};process.on("SIGINT",G),process.on("SIGTERM",G),await z.connect(),await new Promise(()=>{})}catch(Z){Q.fail("Failed to connect"),R(`Error: ${Z.message}`),process.exit(1)}}),$.command("tunnel:status","Check tunnel server status").option("--server <url>","Tunnel server URL",{default:"https://localtunnel.dev"}).action(async(J)=>{V("Tunnel Server Status");let Y=new L("Checking server status...");Y.start();try{let Q=J.server.startsWith("http")?J.server:`https://${J.server}`,Z=await fetch(`${Q}/status`,{method:"GET",headers:{Accept:"application/json"}});if(Z.ok){let U=await Z.json();if(Y.succeed("Server is online"),F(`
8068
8068
  Server: ${J.server}`),F(`Status: ${U.status||"operational"}`),U.version)F(`Version: ${U.version}`);if(U.connections!==void 0)F(`Active connections: ${U.connections}`);if(U.uptime)F(`Uptime: ${U.uptime}`);if(U.activeSubdomains?.length)F(`Active subdomains: ${U.activeSubdomains.join(", ")}`)}else Y.fail(`Server returned status ${Z.status}`)}catch(Q){Y.fail("Failed to check server status"),R(`Error: ${Q.message}`),F(`
8069
- The tunnel server may be offline or unreachable.`)}}),$.command("tunnel:info","Show tunnel configuration and setup info").action(async()=>{V("Local Tunnel Information"),F("ts-cloud uses localtunnels for secure tunnel connections."),F(""),F("Default server: localtunnel.dev"),F(""),F("Usage:"),F(" cloud tunnel --port 3000 # Expose port 3000"),F(" cloud tunnel --port 8080 --subdomain myapp"),F(""),F("Features:"),F(" - Secure WebSocket-based tunnels"),F(" - Custom subdomains (when available)"),F(" - Automatic reconnection"),F(" - Request logging"),F(" - Binary data support"),F(""),F("Self-hosted tunnel server:"),F(" You can run your own tunnel server using localtunnels."),F(" See: https://github.com/stacksjs/localtunnels"),F(""),F("Environment variables:"),F(" TUNNEL_SERVER - Custom tunnel server URL"),F(" TUNNEL_SUBDOMAIN - Default subdomain to request")}),$.command("tunnel:deploy","Deploy tunnel infrastructure to AWS").option("--region <region>","AWS region",{default:"us-east-1"}).option("--prefix <prefix>","Resource name prefix",{default:"localtunnel"}).option("--verbose","Enable verbose logging").action(async(J)=>{if(V("Deploy Tunnel Infrastructure"),F(`Region: ${J.region}`),F(`Prefix: ${J.prefix}`),F(""),F("This will deploy:"),F(" - DynamoDB tables for connection tracking"),F(" - Lambda functions for handling requests"),F(" - Lambda Function URLs for public access"),F(""),!await y("Deploy tunnel infrastructure?",!1)){F("Operation cancelled");return}let Q=new L("Deploying infrastructure...");Q.start();try{let Z;try{Z=(await import("localtunnels/cloud")).deployTunnelInfrastructure}catch{Q.fail("localtunnels package not found"),F(`
8069
+ The tunnel server may be offline or unreachable.`)}}),$.command("tunnel:info","Show tunnel configuration and setup info").action(async()=>{V("Local Tunnel Information"),F("ts-cloud uses localtunnels for secure tunnel connections."),F(""),F("Default server: localtunnel.dev"),F(""),F("Usage:"),F(" cloud tunnel --port 3000 # Expose port 3000"),F(" cloud tunnel --port 8080 --subdomain myapp"),F(""),F("Features:"),F(" - Secure WebSocket-based tunnels"),F(" - Custom subdomains (when available)"),F(" - Automatic reconnection"),F(" - Request logging"),F(" - Binary data support"),F(""),F("Self-hosted tunnel server:"),F(" You can run your own tunnel server using localtunnels."),F(" See: https://github.com/stacksjs/localtunnels"),F(""),F("Environment variables:"),F(" TUNNEL_SERVER - Custom tunnel server URL"),F(" TUNNEL_SUBDOMAIN - Default subdomain to request")}),$.command("tunnel:deploy","Deploy tunnel infrastructure to AWS").option("--region <region>","AWS region",{default:"us-east-1"}).option("--prefix <prefix>","Resource name prefix",{default:"localtunnel"}).option("--verbose","Enable verbose logging").action(async(J)=>{if(V("Deploy Tunnel Infrastructure"),F(`Region: ${J.region}`),F(`Prefix: ${J.prefix}`),F(""),F("This will deploy:"),F(" - DynamoDB tables for connection tracking"),F(" - Lambda functions for handling requests"),F(" - Lambda Function URLs for public access"),F(""),!await v("Deploy tunnel infrastructure?",!1)){F("Operation cancelled");return}let Q=new L("Deploying infrastructure...");Q.start();try{let Z;try{Z=(await import("localtunnels/cloud")).deployTunnelInfrastructure}catch{Q.fail("localtunnels package not found"),F(`
8070
8070
  To deploy tunnel infrastructure, install localtunnels:`),F(" bun add localtunnels"),F(`
8071
- Or deploy using the localtunnels CLI directly:`),F(" bunx localtunnels deploy --region us-east-1");return}let U=await Z({region:J.region,prefix:J.prefix,verbose:J.verbose});if(Q.succeed("Deployment complete!"),F(""),F("Resources created:"),F(" DynamoDB Tables:"),F(` - ${U.connectionsTable}`),F(` - ${U.responsesTable}`),F(""),F(" Lambda Functions:"),F(` - ${U.functions.http}`),F(` - ${U.functions.message}`),F(""),U.httpUrl||U.wsUrl){if(F("Endpoints:"),U.httpUrl)F(` HTTP URL: ${U.httpUrl}`);if(U.wsUrl)F(` WebSocket URL: ${U.wsUrl}`)}}catch(Z){if(Q.fail("Deployment failed"),R(`Error: ${Z.message}`),J.verbose)console.error(Z.stack);process.exit(1)}}),$.command("tunnel:destroy","Destroy tunnel infrastructure from AWS").option("--region <region>","AWS region",{default:"us-east-1"}).option("--prefix <prefix>","Resource name prefix",{default:"localtunnel"}).option("--verbose","Enable verbose logging").action(async(J)=>{if(V("Destroy Tunnel Infrastructure"),F(`Region: ${J.region}`),F(`Prefix: ${J.prefix}`),F(""),g("This will permanently delete:"),g(" - All DynamoDB tables and data"),g(" - All Lambda functions"),g(" - All IAM roles and policies"),F(""),!await y("Are you sure you want to destroy this infrastructure?",!1)){F("Operation cancelled");return}let Q=new L("Destroying infrastructure...");Q.start();try{let Z;try{Z=(await import("localtunnels/cloud")).destroyTunnelInfrastructure}catch{Q.fail("localtunnels package not found"),F(`
8071
+ Or deploy using the localtunnels CLI directly:`),F(" bunx localtunnels deploy --region us-east-1");return}let U=await Z({region:J.region,prefix:J.prefix,verbose:J.verbose});if(Q.succeed("Deployment complete!"),F(""),F("Resources created:"),F(" DynamoDB Tables:"),F(` - ${U.connectionsTable}`),F(` - ${U.responsesTable}`),F(""),F(" Lambda Functions:"),F(` - ${U.functions.http}`),F(` - ${U.functions.message}`),F(""),U.httpUrl||U.wsUrl){if(F("Endpoints:"),U.httpUrl)F(` HTTP URL: ${U.httpUrl}`);if(U.wsUrl)F(` WebSocket URL: ${U.wsUrl}`)}}catch(Z){if(Q.fail("Deployment failed"),R(`Error: ${Z.message}`),J.verbose)console.error(Z.stack);process.exit(1)}}),$.command("tunnel:destroy","Destroy tunnel infrastructure from AWS").option("--region <region>","AWS region",{default:"us-east-1"}).option("--prefix <prefix>","Resource name prefix",{default:"localtunnel"}).option("--verbose","Enable verbose logging").action(async(J)=>{if(V("Destroy Tunnel Infrastructure"),F(`Region: ${J.region}`),F(`Prefix: ${J.prefix}`),F(""),g("This will permanently delete:"),g(" - All DynamoDB tables and data"),g(" - All Lambda functions"),g(" - All IAM roles and policies"),F(""),!await v("Are you sure you want to destroy this infrastructure?",!1)){F("Operation cancelled");return}let Q=new L("Destroying infrastructure...");Q.start();try{let Z;try{Z=(await import("localtunnels/cloud")).destroyTunnelInfrastructure}catch{Q.fail("localtunnels package not found"),F(`
8072
8072
  To destroy tunnel infrastructure, install localtunnels:`),F(" bun add localtunnels"),F(`
8073
8073
  Or destroy using the localtunnels CLI directly:`),F(" bunx localtunnels destroy --region us-east-1");return}await Z({region:J.region,prefix:J.prefix,verbose:J.verbose}),Q.succeed("Infrastructure destroyed!")}catch(Z){if(Q.fail("Destruction failed"),R(`Error: ${Z.message}`),J.verbose)console.error(Z.stack);process.exit(1)}}),$.command("tunnel:logs","View tunnel server logs").option("--region <region>","AWS region",{default:"us-east-1"}).option("--prefix <prefix>","Resource name prefix",{default:"localtunnel"}).option("--tail","Tail the logs").action(async(J)=>{V("Tunnel Server Logs"),F("Tunnel server log groups:"),F(` - /aws/lambda/${J.prefix}-connect`),F(` - /aws/lambda/${J.prefix}-disconnect`),F(` - /aws/lambda/${J.prefix}-message`),F(` - /aws/lambda/${J.prefix}-http`),F(""),F("To view logs:"),F(` aws logs tail /aws/lambda/${J.prefix}-http --region ${J.region}${J.tail?" --follow":""}`),F(""),F("Or use CloudWatch Insights:"),F(" 1. Go to CloudWatch > Logs Insights"),F(" 2. Select the tunnel log groups"),F(" 3. Run queries like:"),F(" fields @timestamp, @message | filter @message like /error/i")}),$.command("tunnel:test <url>","Test a tunnel connection").action(async(J)=>{V("Test Tunnel Connection");let Y=new L(`Testing ${J}...`);Y.start();try{let Q=Date.now(),Z=await fetch(J,{method:"GET",headers:{"User-Agent":"ts-cloud-tunnel-test"}}),U=Date.now()-Q;Y.succeed(`Connected in ${U}ms`),F(`
8074
8074
  Status: ${Z.status} ${Z.statusText}`),F(`