@stacksjs/ts-cloud 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -17
- package/dist/aws/setup-sms.d.ts +1 -0
- package/dist/bin/cli.js +11 -11
- package/dist/config.d.ts +1 -1
- package/dist/generators/infrastructure.d.ts +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +43 -43
- package/dist/types.d.ts +1 -1
- package/dist/validation/template.d.ts +1 -1
- package/package.json +5 -6
- package/src/aws/acm.ts +0 -768
- package/src/aws/application-autoscaling.ts +0 -845
- package/src/aws/bedrock.ts +0 -4074
- package/src/aws/client.ts +0 -891
- package/src/aws/cloudformation.ts +0 -896
- package/src/aws/cloudfront.ts +0 -1531
- package/src/aws/cloudwatch-logs.ts +0 -154
- package/src/aws/comprehend.ts +0 -839
- package/src/aws/connect.ts +0 -1056
- package/src/aws/deploy-imap.ts +0 -384
- package/src/aws/dynamodb.ts +0 -340
- package/src/aws/ec2.ts +0 -1385
- package/src/aws/ecr.ts +0 -621
- package/src/aws/ecs.ts +0 -615
- package/src/aws/elasticache.ts +0 -301
- package/src/aws/elbv2.ts +0 -942
- package/src/aws/email.ts +0 -928
- package/src/aws/eventbridge.ts +0 -248
- package/src/aws/iam.ts +0 -1689
- package/src/aws/imap-server.ts +0 -2100
- package/src/aws/index.ts +0 -213
- package/src/aws/kendra.ts +0 -1097
- package/src/aws/lambda.ts +0 -786
- package/src/aws/opensearch.ts +0 -158
- package/src/aws/personalize.ts +0 -977
- package/src/aws/polly.ts +0 -559
- package/src/aws/rds.ts +0 -888
- package/src/aws/rekognition.ts +0 -846
- package/src/aws/route53-domains.ts +0 -359
- package/src/aws/route53.ts +0 -1046
- package/src/aws/s3.ts +0 -2334
- package/src/aws/scheduler.ts +0 -571
- package/src/aws/secrets-manager.ts +0 -769
- package/src/aws/ses.ts +0 -1081
- package/src/aws/setup-phone.ts +0 -104
- package/src/aws/setup-sms.ts +0 -580
- package/src/aws/sms.ts +0 -1735
- package/src/aws/smtp-server.ts +0 -531
- package/src/aws/sns.ts +0 -758
- package/src/aws/sqs.ts +0 -382
- package/src/aws/ssm.ts +0 -807
- package/src/aws/sts.ts +0 -92
- package/src/aws/support.ts +0 -391
- package/src/aws/test-imap.ts +0 -86
- package/src/aws/textract.ts +0 -780
- package/src/aws/transcribe.ts +0 -108
- package/src/aws/translate.ts +0 -641
- package/src/aws/voice.ts +0 -1379
- package/src/config.ts +0 -35
- package/src/deploy/index.ts +0 -7
- package/src/deploy/static-site-external-dns.ts +0 -945
- package/src/deploy/static-site.ts +0 -1175
- package/src/dns/cloudflare.ts +0 -548
- package/src/dns/godaddy.ts +0 -412
- package/src/dns/index.ts +0 -205
- package/src/dns/porkbun.ts +0 -362
- package/src/dns/route53-adapter.ts +0 -414
- package/src/dns/types.ts +0 -119
- package/src/dns/validator.ts +0 -369
- package/src/generators/index.ts +0 -5
- package/src/generators/infrastructure.ts +0 -1660
- package/src/index.ts +0 -163
- package/src/push/apns.ts +0 -452
- package/src/push/fcm.ts +0 -506
- package/src/push/index.ts +0 -58
- package/src/security/pre-deploy-scanner.ts +0 -655
- package/src/ssl/acme-client.ts +0 -478
- package/src/ssl/index.ts +0 -7
- package/src/ssl/letsencrypt.ts +0 -747
- package/src/types.ts +0 -2
- package/src/utils/cli.ts +0 -398
- package/src/validation/index.ts +0 -5
- package/src/validation/template.ts +0 -405
package/dist/bin/cli.js
CHANGED
|
@@ -186,7 +186,7 @@ ${Object.entries($).filter(([U])=>!U.startsWith("@_")).map(([U,Z])=>W(U,Z," ","
|
|
|
186
186
|
</FunctionConfig>
|
|
187
187
|
<FunctionCode>${Buffer.from(Y).toString("base64")}</FunctionCode>
|
|
188
188
|
</UpdateFunctionRequest>`,Z=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/function/${J}`,body:U,headers:{"Content-Type":"application/xml","If-Match":W},returnHeaders:!0});return{ETag:Z.headers?.etag||Z.ETag||"",FunctionSummary:Z.body?.FunctionSummary||Z.FunctionSummary||Z.body||Z}}async deleteFunction($,J){let Y=J;if(!Y){let Q=await this.getFunction($,"DEVELOPMENT");if(!Q)return;Y=Q.ETag}await this.client.request({service:"cloudfront",region:"us-east-1",method:"DELETE",path:`/2020-05-31/function/${$}`,headers:{"If-Match":Y}})}async createIndexRewriteFunction($){return this.createFunction({name:$,code:`function handler(event) {
|
|
189
|
-
|
|
189
|
+
const request = event.request;
|
|
190
190
|
var uri = request.uri;
|
|
191
191
|
|
|
192
192
|
// Check if the request is for a directory (ends with /)
|
|
@@ -277,7 +277,7 @@ ${Object.entries($).filter(([U])=>!U.startsWith("@_")).map(([U,Z])=>W(U,Z," ","
|
|
|
277
277
|
</Items>
|
|
278
278
|
</CustomErrorResponses>
|
|
279
279
|
</DistributionConfig>`,F=await this.client.request({service:"cloudfront",region:"us-east-1",method:"POST",path:"/2020-05-31/distribution",body:E,headers:{"Content-Type":"application/xml"},returnHeaders:!0}),T=F.body?.Distribution||F.Distribution||F.body||F;return{Id:T.Id,ARN:T.ARN,DomainName:T.DomainName,Status:T.Status,ETag:F.headers?.etag||F.ETag||""}}static getS3BucketPolicyForCloudFront($,J){return{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:`arn:aws:s3:::${$}/*`,Condition:{StringEquals:{"AWS:SourceArn":J}}}]}}async waitForDistributionDeployed($,J=60){for(let Y=0;Y<J;Y++){if((await this.getDistribution($)).Status==="Deployed")return!0;await new Promise((W)=>setTimeout(W,30000))}return!1}async disableDistribution($){let J=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${$}/config`,returnHeaders:!0}),Y=J.headers?.etag||J.headers?.ETag||"",Q=J.body?.DistributionConfig||J.DistributionConfig;if(!Q)throw Error("Failed to get current distribution config");Q.Enabled=!1;let W=this.buildDistributionConfigXml(Q),U=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${$}/config`,body:W,headers:{"Content-Type":"application/xml","If-Match":Y},returnHeaders:!0});return{ETag:U.headers?.etag||U.headers?.ETag||U.ETag||""}}async deleteDistribution($,J){let Y=J||"";if(!Y){let Q=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${$}`,returnHeaders:!0});Y=Q.headers?.etag||Q.headers?.ETag||""}await this.client.request({service:"cloudfront",region:"us-east-1",method:"DELETE",path:`/2020-05-31/distribution/${$}`,headers:{"If-Match":Y}})}async waitForDistributionDisabled($,J=60){for(let Y=0;Y<J;Y++){let Q=await this.getDistribution($);if(Q.Status==="Deployed"&&!Q.Enabled)return!0;await new Promise((W)=>setTimeout(W,30000))}return!1}async removeAlias($,J){let Y=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${$}/config`,returnHeaders:!0}),Q=Y.headers?.etag||Y.headers?.ETag||"",W=Y.body?.DistributionConfig||Y.DistributionConfig;if(!W)throw Error("Failed to get current distribution config");let U=[];if(W.Aliases?.Items){if(Array.isArray(W.Aliases.Items))U=W.Aliases.Items;else if(typeof W.Aliases.Items==="object"){let K=W.Aliases.Items.CNAME;if(typeof K==="string")U=[K];else if(Array.isArray(K))U=K}}if(U.length===0)throw Error("Distribution has no aliases to remove");let Z=U.filter((K)=>K!==J);if(Z.length===U.length)throw Error(`Alias ${J} not found in distribution`);if(W.Aliases.Quantity=Z.length,W.Aliases.Items=Z.length>0?Z:void 0,Z.length===0)W.ViewerCertificate={CloudFrontDefaultCertificate:!0,MinimumProtocolVersion:"TLSv1.2_2021"};let z=this.buildDistributionConfigXml(W),H=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${$}/config`,body:z,headers:{"Content-Type":"application/xml","If-Match":Q},returnHeaders:!0});return{ETag:H.headers?.etag||H.headers?.ETag||H.ETag||""}}}var M0=Q$(()=>{W$()});var S6={};l$(S6,{uploadStaticFiles:()=>A9,invalidateCache:()=>R9,generateStaticSiteTemplate:()=>T9,deployStaticSiteFull:()=>TW,deployStaticSite:()=>L9,deleteStaticSite:()=>wW});function T9($){let{bucketName:J,domain:Y,certificateArn:Q,hostedZoneId:W,defaultRootObject:U="index.html",errorDocument:Z="404.html"}=$,z={},H={};z.S3Bucket={Type:"AWS::S3::Bucket",Properties:{BucketName:J,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:U,ErrorDocument:Z}}},H.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},H.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},z.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`OAC-${J}`,Description:`OAC for ${J}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},z.UrlRewriteFunction={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-url-rewrite"},AutoPublish:!0,FunctionConfig:{Comment:"Append .html extension to URLs without extensions",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
|
|
280
|
-
|
|
280
|
+
const request = event.request;
|
|
281
281
|
var uri = request.uri;
|
|
282
282
|
|
|
283
283
|
// If URI ends with /, serve index.html
|
|
@@ -291,7 +291,7 @@ ${Object.entries($).filter(([U])=>!U.startsWith("@_")).map(([U,Z])=>W(U,Z," ","
|
|
|
291
291
|
|
|
292
292
|
return request;
|
|
293
293
|
}`}};let K={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:`/${Z}`,ErrorCachingMinTTL:300}]};if(Y&&Q)K.Aliases=[Y],K.ViewerCertificate={AcmCertificateArn:Q,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};else K.ViewerCertificate={CloudFrontDefaultCertificate:!0};if(z.CloudFrontDistribution={Type:"AWS::CloudFront::Distribution",DependsOn:["S3Bucket","CloudFrontOAC","UrlRewriteFunction"],Properties:{DistributionConfig:K}},H.DistributionId={Description:"CloudFront Distribution ID",Value:{Ref:"CloudFrontDistribution"}},H.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&&W)z.DNSRecord={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:W,Name:Y,Type:"A",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},z.DNSRecordIPv6={Type:"AWS::Route53::RecordSet",DependsOn:"CloudFrontDistribution",Properties:{HostedZoneId:W,Name:Y,Type:"AAAA",AliasTarget:{DNSName:{"Fn::GetAtt":["CloudFrontDistribution","DomainName"]},HostedZoneId:"Z2FDTNDATAQYW2",EvaluateTargetHealth:!1}}},H.SiteUrl={Description:"Site URL",Value:{"Fn::Sub":"https://${DNSRecord}"}};return{AWSTemplateFormatVersion:"2010-09-09",Description:`Static site infrastructure for ${Y||J}`,Resources:z,Outputs:H}}async function L9($){if($.dnsProvider&&$.dnsProvider.provider!=="route53"){let D=$.domain||($.subdomain&&$.baseDomain?`${$.subdomain}.${$.baseDomain}`:void 0);if(!D)return{success:!1,stackName:$.stackName||`${$.siteName}-static-site`,bucket:$.bucket||`${$.siteName}-${Date.now()}`,message:"Domain is required when using external DNS provider"};return P6({siteName:$.siteName,region:$.region,domain:D,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 W=$.bucket||(Q?Q.replace(/\./g,"-"):`${$.siteName}-${Date.now()}`),U=$.stackName||`${$.siteName}-static-site`,Z=new X$(Y),z=new I$,H=new S$("us-east-1"),K=new v1("us-east-1"),B=$.hostedZoneId,O=$.certificateArn;if(Q&&!B){let D=await z.findHostedZoneForDomain(Q);if(D)B=D.Id.replace("/hostedzone/","");else return{success:!1,stackName:U,bucket:W,message:`No Route53 hosted zone found for ${$.baseDomain||Q}. Please create one first.`}}if(Q&&!O&&B){let D=await H.findCertificateByDomain(Q);if(D&&D.Status==="ISSUED")O=D.CertificateArn;else O=(await K.requestAndValidate({domainName:Q,hostedZoneId:B,waitForValidation:!0,maxWaitMinutes:10})).certificateArn}let X=!1,j;try{let D=await Z.describeStacks({stackName:U});if(D.Stacks.length>0){let k=D.Stacks[0],f=k.StackStatus;if(f==="DELETE_IN_PROGRESS")console.log("Previous stack is still being deleted, waiting..."),await Z.waitForStack(U,"stack-delete-complete"),X=!1;else if(f==="DELETE_COMPLETE")X=!1;else X=!0,j=(k.Outputs||[]).find((v)=>v.OutputKey==="BucketName")?.OutputValue}}catch(D){if(D.message?.includes("does not exist")||D.code==="ValidationError")X=!1;else throw D}let q=j||W;if(!X){let D=new j$(J),k=new q$,f=!1;if(Q){try{console.log(`Checking for existing CloudFront distribution for ${Q}...`);let h=await k.listDistributions();for(let v of h){let x=[];if(v.Aliases?.Items){if(Array.isArray(v.Aliases.Items))x=v.Aliases.Items;else if(typeof v.Aliases.Items==="object"){let d=v.Aliases.Items.CNAME;if(typeof d==="string")x=[d];else if(Array.isArray(d))x=d}}if(x.includes(Q)){f=!0,console.log(`Found existing CloudFront distribution ${v.Id} for ${Q}`);let m=(await k.getDistributionConfig(v.Id)).DistributionConfig?.Origins?.Items,a;if(m){let o=[];if(Array.isArray(m))o=m;else if(m.Origin)o=Array.isArray(m.Origin)?m.Origin:[m.Origin];else o=[m];for(let t of o){let Z$=(t.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(Z$){a=Z$[1];break}}}if(a){let o=Q.replace(/\./g,"-");if(!a.startsWith(o)&&!a.includes($.siteName)){console.log(`Warning: Found distribution with mismatched bucket ${a}, skipping...`);continue}if(console.log(`Using existing S3 bucket: ${a}`),B&&v.DomainName)try{console.log(`Ensuring Route53 records exist for ${Q}...`),await z.createAliasRecord({HostedZoneId:B,Name:Q,Type:"A",TargetHostedZoneId:I$.CloudFrontHostedZoneId,TargetDNSName:v.DomainName,EvaluateTargetHealth:!1}),await z.createAliasRecord({HostedZoneId:B,Name:Q,Type:"AAAA",TargetHostedZoneId:I$.CloudFrontHostedZoneId,TargetDNSName:v.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records ensured for ${Q}`)}catch(t){console.log(`Note: Could not update Route53 records: ${t.message}`)}return{success:!0,stackName:`existing-${v.Id}`,bucket:a,distributionId:v.Id,distributionDomain:v.DomainName,domain:Q,certificateArn:O,message:"Using existing CloudFront distribution"}}}}}catch{}if(B)try{let v=(await z.listResourceRecordSets({HostedZoneId:B})).ResourceRecordSets||[];for(let x of v)if(x.Name===`${Q}.`&&(x.Type==="A"||x.Type==="AAAA")){if(x.AliasTarget){console.log(`Found orphaned Route53 ${x.Type} record for ${Q}, cleaning up...`);try{await z.deleteRecord({HostedZoneId:B,RecordSet:x}),console.log(`Deleted orphaned Route53 ${x.Type} record for ${Q}`)}catch(d){console.log(`Note: Could not delete Route53 record: ${d.message}`)}}}}catch{}}if(!f)try{if((await D.headBucket(W)).exists){console.log(`Found orphaned S3 bucket ${W}, cleaning up...`);try{let v=D.emptyBucket(W).then(()=>D.deleteBucket(W)),x=new Promise((d,m)=>setTimeout(()=>m(Error("Bucket cleanup timeout")),30000));await Promise.race([v,x]),console.log(`Deleted orphaned S3 bucket ${W}`)}catch(v){console.log(`Note: Could not clean up S3 bucket: ${v.message}`);let x=Date.now().toString(36);q=`${W}-${x}`,console.log(`Using alternative bucket name: ${q}`)}}}catch{}}let E=T9({bucketName:q,domain:Q,certificateArn:O,hostedZoneId:B,defaultRootObject:$.defaultRootObject,errorDocument:$.errorDocument}),F=Object.entries($.tags||{}).map(([D,k])=>({Key:D,Value:k}));F.push({Key:"ManagedBy",Value:"ts-cloud"}),F.push({Key:"Application",Value:$.siteName});let T,w=!1;if(X){w=!0,console.log(`Updating CloudFormation stack: ${U}`),console.log(`Using existing bucket: ${q}`),console.log(`Domain: ${Q||"not specified"}`),console.log(`Certificate ARN: ${O||"not specified"}`);try{T=(await Z.updateStack({stackName:U,templateBody:JSON.stringify(E),capabilities:["CAPABILITY_IAM"],tags:F})).StackId,console.log(`Update initiated, stack ID: ${T}`)}catch(D){if(D.message?.includes("No updates are to be performed")){let k=await Z.describeStacks({stackName:U});T=k.Stacks[0].StackId;let f=k.Stacks[0]?.Outputs||[],h=(v)=>f.find((x)=>x.OutputKey===v)?.OutputValue;return{success:!0,stackId:T,stackName:U,bucket:h("BucketName")||q,distributionId:h("DistributionId"),distributionDomain:h("DistributionDomain"),domain:Q,certificateArn:O,message:"Static site infrastructure is already up to date"}}else throw D}}else console.log(`Creating CloudFormation stack: ${U}`),console.log(`Bucket name: ${q}`),console.log(`Domain: ${Q||"not specified"}`),console.log(`Certificate ARN: ${O||"not specified"}`),console.log("Stack does not exist, creating..."),T=(await Z.createStack({stackName:U,templateBody:JSON.stringify(E),capabilities:["CAPABILITY_IAM"],tags:F,onFailure:"DELETE"})).StackId,console.log(`Create initiated, stack ID: ${T}`);console.log(`Waiting for stack to reach ${w?"stack-update-complete":"stack-create-complete"}...`);try{await Z.waitForStack(U,w?"stack-update-complete":"stack-create-complete"),console.log("Stack operation completed successfully!")}catch(D){if(D.message?.includes("must be verified")||D.message?.includes("Access denied for operation")||D.message?.includes("failed")){console.log("CloudFormation deployment failed, trying direct API creation...");let k=new q$;if(Q)try{let f=await k.listDistributions();for(let h of f){let v=[];if(h.Aliases?.Items){if(Array.isArray(h.Aliases.Items))v=h.Aliases.Items;else if(typeof h.Aliases.Items==="object"){let x=h.Aliases.Items.CNAME;if(typeof x==="string")v=[x];else if(Array.isArray(x))v=x}}if(v.includes(Q)){console.log(`Found existing CloudFront distribution ${h.Id} with alias ${Q}`);let d=(await k.getDistributionConfig(h.Id)).DistributionConfig?.Origins?.Items,m;if(d){let a=[];if(Array.isArray(d))a=d;else if(d.Origin)a=Array.isArray(d.Origin)?d.Origin:[d.Origin];else a=[d];for(let o of a){let V$=(o.DomainName||"").match(/^([^.]+)\.s3[\.-]/);if(V$){m=V$[1];break}}}if(m)return console.log(`Using existing S3 bucket: ${m}`),{success:!0,stackName:`existing-${h.Id}`,bucket:m,distributionId:h.Id,distributionDomain:h.DomainName,domain:Q,certificateArn:O,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 f=new j$(J);if((await f.headBucket(q)).exists)console.log(`Using existing S3 bucket: ${q}`);else console.log(`Creating S3 bucket: ${q}...`),await f.createBucket(q);await f.putBucketWebsite(q,{IndexDocument:$.defaultRootObject||"index.html",ErrorDocument:$.errorDocument||"404.html"}),await f.putPublicAccessBlock(q,{BlockPublicAcls:!0,IgnorePublicAcls:!0,BlockPublicPolicy:!1,RestrictPublicBuckets:!1}),console.log(`S3 bucket ${q} configured`);let v=`OAC-${q}`;console.log(`Creating Origin Access Control: ${v}...`);let x=await k.findOrCreateOriginAccessControl(v);console.log(`Origin Access Control ${x.Id} ready`),console.log("Creating CloudFront distribution...");let d=await k.createDistributionForS3({bucketName:q,bucketRegion:J,originAccessControlId:x.Id,aliases:Q?[Q]:[],certificateArn:O,defaultRootObject:$.defaultRootObject||"index.html",comment:`Distribution for ${Q||q}`});console.log(`CloudFront distribution ${d.Id} created`),console.log("Updating S3 bucket policy...");let m=q$.getS3BucketPolicyForCloudFront(q,d.ARN);if(await f.putBucketPolicy(q,m),console.log("S3 bucket policy updated"),Q&&B){console.log(`Creating Route53 records for ${Q}...`);try{await z.createAliasRecord({HostedZoneId:B,Name:Q,Type:"A",TargetHostedZoneId:I$.CloudFrontHostedZoneId,TargetDNSName:d.DomainName,EvaluateTargetHealth:!1}),await z.createAliasRecord({HostedZoneId:B,Name:Q,Type:"AAAA",TargetHostedZoneId:I$.CloudFrontHostedZoneId,TargetDNSName:d.DomainName,EvaluateTargetHealth:!1}),console.log(`Route53 records created for ${Q}`)}catch(a){console.log(`Note: Could not create Route53 records: ${a.message}`)}}return{success:!0,stackName:`direct-${d.Id}`,bucket:q,distributionId:d.Id,distributionDomain:d.DomainName,domain:Q,certificateArn:O,message:"Static site infrastructure created via direct API calls"}}catch(f){return console.log(`Direct API creation failed: ${f.message}`),{success:!1,stackId:T,stackName:U,bucket:q,message:`Deployment failed: ${f.message}`}}}return{success:!1,stackId:T,stackName:U,bucket:q,message:`Stack deployment failed: ${D.message}`}}let R=(await Z.describeStacks({stackName:U})).Stacks[0]?.Outputs||[],C=(D)=>R.find((k)=>k.OutputKey===D)?.OutputValue;return{success:!0,stackId:T,stackName:U,bucket:C("BucketName")||q,distributionId:C("DistributionId"),distributionDomain:C("DistributionDomain"),domain:Q,certificateArn:O,message:"Static site infrastructure deployed successfully"}}async function A9($){let{sourceDir:J,bucket:Y,region:Q,cacheControl:W="max-age=31536000, public",onProgress:U}=$,Z=new j$(Q),{readdir:z}=await import("node:fs/promises"),{join:H,relative:K}=await import("node:path"),{createHash:B}=await import("node:crypto");async function O(R){let C=[],D=await z(R,{withFileTypes:!0});for(let k of D){let f=H(R,k.name);if(k.isDirectory())C.push(...await O(f));else C.push(f)}return C}function X(R){let C=R.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"}[C||""]||"application/octet-stream"}function j(R){return B("md5").update(R).digest("hex")}async function q(){let R=new Map,C;do{let D=await Z.listObjects({bucket:Y,maxKeys:1000,continuationToken:C});for(let k of D.objects){let f=k.ETag?.replace(/"/g,"")||"";R.set(k.Key,f)}C=D.nextContinuationToken}while(C);return R}let E=await O(J),F=[],T=0,w=0,S=await q();for(let R of E){let C=K(J,R),D=X(R),k=R.endsWith(".html")?"max-age=3600, public":W;try{let f=Buffer.from(await Bun.file(R).arrayBuffer()),h=j(f),v=S.get(C);if(v&&v===h){w++,U?.(T+w,E.length,C);continue}await Z.putObject({bucket:Y,key:C,body:f,contentType:D,cacheControl:k}),T++,U?.(T+w,E.length,C)}catch(f){F.push(`Failed to upload ${C}: ${f.message}`)}}return{uploaded:T,skipped:w,errors:F}}async function R9($){return{invalidationId:(await new q$().invalidateAll($)).Id}}async function wW($,J="us-east-1"){let Y=new X$(J);try{let Z=((await Y.describeStacks({stackName:$})).Stacks[0]?.Outputs||[]).find((z)=>z.OutputKey==="BucketName")?.OutputValue;if(Z)await new j$(J).emptyBucket(Z)}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 TW($){let{sourceDir:J,cleanBucket:Y=!1,onProgress:Q,...W}=$;Q?.("infrastructure","Deploying CloudFormation stack...");let U=await L9(W);if(!U.success)return U;if(Y){Q?.("clean","Cleaning old files from S3...");try{await new j$(W.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 Z=await A9({sourceDir:J,bucket:U.bucket,region:W.region||"us-east-1",cacheControl:W.cacheControl,onProgress:(H,K,B)=>{Q?.("upload",`${H}/${K}: ${B}`)}});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..."),await R9(U.distributionId);Q?.("complete","Deployment complete!");let z=Z.skipped>0?`Deployed ${Z.uploaded} files (${Z.skipped} unchanged)`:`Deployed ${Z.uploaded} files successfully`;return{...U,filesUploaded:Z.uploaded,filesSkipped:Z.skipped,message:z}}var D6=Q$(()=>{G0();V0();M0();b1();X0();C6()});function LW($){let{bucketName:J,domain:Y,aliases:Q,certificateArn:W,defaultRootObject:U="index.html",errorDocument:Z="404.html"}=$,z={},H={};z.S3Bucket={Type:"AWS::S3::Bucket",Properties:{BucketName:J,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!1,IgnorePublicAcls:!0,RestrictPublicBuckets:!1},WebsiteConfiguration:{IndexDocument:U,ErrorDocument:Z}}},H.BucketName={Description:"S3 Bucket Name",Value:{Ref:"S3Bucket"}},H.BucketArn={Description:"S3 Bucket ARN",Value:{"Fn::GetAtt":["S3Bucket","Arn"]}},z.CloudFrontOAC={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`OAC-${J}`,Description:`OAC for ${J}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},z.UrlRewriteFunction={Type:"AWS::CloudFront::Function",Properties:{Name:{"Fn::Sub":"${AWS::StackName}-url-rewrite"},AutoPublish:!0,FunctionConfig:{Comment:"Append .html extension to URLs without extensions",Runtime:"cloudfront-js-2.0"},FunctionCode:`function handler(event) {
|
|
294
|
-
|
|
294
|
+
const request = event.request;
|
|
295
295
|
var uri = request.uri;
|
|
296
296
|
|
|
297
297
|
// If URI ends with /, serve index.html
|
|
@@ -345,10 +345,10 @@ ${H.body}`:H.body}).join(`
|
|
|
345
345
|
`).length-1;this.output.write(Y0.move(-999,$*-1))}render(){let $=O5(this._render(this)??"",Z5.stdout.columns,{hard:!0,trim:!1});if($===this._prevFrame)return;if(this.state==="initial")this.output.write(Y0.hide);else{let J=GY(this._prevFrame,$);if(this.restoreCursor(),J&&J?.length===1){let Y=J[0];this.output.write(Y0.move(0,Y)),this.output.write(p1.lines(1));let Q=$.split(`
|
|
346
346
|
`);this.output.write(Q[Y]),this._prevFrame=$,this.output.write(Y0.move(0,Q.length-Y-1));return}if(J&&J?.length>1){let Y=J[0];this.output.write(Y0.move(0,Y)),this.output.write(p1.down());let W=$.split(`
|
|
347
347
|
`).slice(Y);this.output.write(W.join(`
|
|
348
|
-
`)),this._prevFrame=$;return}this.output.write(p1.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function IY($,J){if($===void 0)return 0;if(J.length===0)return 0;let Q=J.findIndex((W)=>W.value===$);return Q!==-1?Q:0}function xY($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function hY($,J){if(!J)return;if($)return J;return J[0]}class bY extends JJ{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Q;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return r1.default.inverse(r1.default.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`${$}${r1.default.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??xY;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 W=J.findIndex((U)=>U.value===Q);if(W!==-1)this.toggleSelected(Q),this.#$=W}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Q,W)=>this.#W(Q,W)),this.on("userInput",(Q)=>this.#U(Q))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#W($,J){let Y=J.name==="up",Q=J.name==="down",W=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(W)this.value=hY(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.#$=IY(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 yY extends JJ{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((W)=>W.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((W)=>({...W,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 OU=B$(_$(),1);var XU=B$(_$(),1);var jU=B$(_$(),1),K0={red:["\x1B[31m","\x1B[39m"],green:["\x1B[32m","\x1B[39m"],blue:["\x1B[34m","\x1B[39m"],yellow:["\x1B[33m","\x1B[39m"],cyan:["\x1B[36m","\x1B[39m"],magenta:["\x1B[35m","\x1B[39m"],white:["\x1B[37m","\x1B[39m"],gray:["\x1B[90m","\x1B[39m"],bgRed:["\x1B[41m","\x1B[49m"],bgGreen:["\x1B[42m","\x1B[49m"],bgBlue:["\x1B[44m","\x1B[49m"],bgYellow:["\x1B[43m","\x1B[49m"],bgCyan:["\x1B[46m","\x1B[49m"],bgMagenta:["\x1B[45m","\x1B[49m"],bold:["\x1B[1m","\x1B[22m"],italic:["\x1B[3m","\x1B[23m"],underline:["\x1B[4m","\x1B[24m"],dim:["\x1B[2m","\x1B[22m"],inverse:["\x1B[7m","\x1B[27m"],hidden:["\x1B[8m","\x1B[28m"],strikethrough:["\x1B[9m","\x1B[29m"]},m0={primary:"blue",secondary:"cyan",success:"green",warning:"yellow",error:"red",info:"magenta",muted:"gray"};function vY(){return!0}function fY(){let $={};$.supportsColor=vY();function J(Q,W=[]){let U=Q===""?[]:[...W,Q],Z=function(H){if(!$.supportsColor)return H;let K="",B="";for(let O of U)if(O in m0&&m0[O]in K0){let X=m0[O];K+=K0[X][0],B=K0[X][1]+B}else if(O in K0)K+=K0[O][0],B=K0[O][1]+B;return K+H+B},z=[...Object.keys(K0),...Object.keys(m0)];for(let H of z)if(!(H in Z))Object.defineProperty(Z,H,{get(){return J(H,U)}});return Z}let Y=[...Object.keys(K0),...Object.keys(m0)];for(let Q of Y)if(!(Q in $))Object.defineProperty($,Q,{get(){return J(Q)}});return $}var qU=fY();var gY=JY();var G$=($,J)=>gY?$:J,VU=G$("◆","*"),MU=G$("■","x"),EU=G$("▲","x"),_U=G$("◇","o"),FU=G$("┌","T"),uY=G$("│","|"),wU=G$("└","—"),TU=G$("●",">"),LU=G$("○"," "),AU=G$("◻","[•]"),RU=G$("◼","[+]"),SU=G$("◻","[ ]"),DU=G$("▪","•"),PU=G$("─","-"),CU=G$("╮","+"),NU=G$("├","+"),kU=G$("╯","+"),IU=G$("●","•"),xU=G$("◆","*"),hU=G$("▲","!"),bU=G$("■","x");var yU=B$(_$(),1);var vU=B$(_$(),1);var fU=B$(_$(),1);var gU=B$(_$(),1);var uU=B$(_$(),1);var dU=B$(_$(),1);var mU=B$(_$(),1);var cU=B$(_$(),1);var lU=B$(_$(),1),pU=B$(_$(),1);var rU={light:G$("─","-"),heavy:G$("━","="),block:G$("█","#")};var aU=B$(_$(),1);var nU=B$(_$(),1);var dY=B$(_$(),1);function mY(){return`${dY.default.gray(uY)} `}var sU=mY();var iU=B$(_$(),1);var tU=B$(_$(),1);var YJ="0.1.
|
|
348
|
+
`)),this._prevFrame=$;return}this.output.write(p1.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function IY($,J){if($===void 0)return 0;if(J.length===0)return 0;let Q=J.findIndex((W)=>W.value===$);return Q!==-1?Q:0}function xY($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function hY($,J){if(!J)return;if($)return J;return J[0]}class bY extends JJ{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Q;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return r1.default.inverse(r1.default.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`${$}${r1.default.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??xY;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 W=J.findIndex((U)=>U.value===Q);if(W!==-1)this.toggleSelected(Q),this.#$=W}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Q,W)=>this.#W(Q,W)),this.on("userInput",(Q)=>this.#U(Q))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#W($,J){let Y=J.name==="up",Q=J.name==="down",W=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(W)this.value=hY(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.#$=IY(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 yY extends JJ{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((W)=>W.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((W)=>({...W,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 OU=B$(_$(),1);var XU=B$(_$(),1);var jU=B$(_$(),1),K0={red:["\x1B[31m","\x1B[39m"],green:["\x1B[32m","\x1B[39m"],blue:["\x1B[34m","\x1B[39m"],yellow:["\x1B[33m","\x1B[39m"],cyan:["\x1B[36m","\x1B[39m"],magenta:["\x1B[35m","\x1B[39m"],white:["\x1B[37m","\x1B[39m"],gray:["\x1B[90m","\x1B[39m"],bgRed:["\x1B[41m","\x1B[49m"],bgGreen:["\x1B[42m","\x1B[49m"],bgBlue:["\x1B[44m","\x1B[49m"],bgYellow:["\x1B[43m","\x1B[49m"],bgCyan:["\x1B[46m","\x1B[49m"],bgMagenta:["\x1B[45m","\x1B[49m"],bold:["\x1B[1m","\x1B[22m"],italic:["\x1B[3m","\x1B[23m"],underline:["\x1B[4m","\x1B[24m"],dim:["\x1B[2m","\x1B[22m"],inverse:["\x1B[7m","\x1B[27m"],hidden:["\x1B[8m","\x1B[28m"],strikethrough:["\x1B[9m","\x1B[29m"]},m0={primary:"blue",secondary:"cyan",success:"green",warning:"yellow",error:"red",info:"magenta",muted:"gray"};function vY(){return!0}function fY(){let $={};$.supportsColor=vY();function J(Q,W=[]){let U=Q===""?[]:[...W,Q],Z=function(H){if(!$.supportsColor)return H;let K="",B="";for(let O of U)if(O in m0&&m0[O]in K0){let X=m0[O];K+=K0[X][0],B=K0[X][1]+B}else if(O in K0)K+=K0[O][0],B=K0[O][1]+B;return K+H+B},z=[...Object.keys(K0),...Object.keys(m0)];for(let H of z)if(!(H in Z))Object.defineProperty(Z,H,{get(){return J(H,U)}});return Z}let Y=[...Object.keys(K0),...Object.keys(m0)];for(let Q of Y)if(!(Q in $))Object.defineProperty($,Q,{get(){return J(Q)}});return $}var qU=fY();var gY=JY();var G$=($,J)=>gY?$:J,VU=G$("◆","*"),MU=G$("■","x"),EU=G$("▲","x"),_U=G$("◇","o"),FU=G$("┌","T"),uY=G$("│","|"),wU=G$("└","—"),TU=G$("●",">"),LU=G$("○"," "),AU=G$("◻","[•]"),RU=G$("◼","[+]"),SU=G$("◻","[ ]"),DU=G$("▪","•"),PU=G$("─","-"),CU=G$("╮","+"),NU=G$("├","+"),kU=G$("╯","+"),IU=G$("●","•"),xU=G$("◆","*"),hU=G$("▲","!"),bU=G$("■","x");var yU=B$(_$(),1);var vU=B$(_$(),1);var fU=B$(_$(),1);var gU=B$(_$(),1);var uU=B$(_$(),1);var dU=B$(_$(),1);var mU=B$(_$(),1);var cU=B$(_$(),1);var lU=B$(_$(),1),pU=B$(_$(),1);var rU={light:G$("─","-"),heavy:G$("━","="),block:G$("█","#")};var aU=B$(_$(),1);var nU=B$(_$(),1);var dY=B$(_$(),1);function mY(){return`${dY.default.gray(uY)} `}var sU=mY();var iU=B$(_$(),1);var tU=B$(_$(),1);var YJ="0.1.11";import{existsSync as KJ}from"node:fs";import{mkdir as CQ,writeFile as c5}from"node:fs/promises";var s={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 A0($,J){return`${s[J]}${$}${s.reset}`}function A($){console.log(`${s.green}✓${s.reset} ${$}`)}function _($){console.error(`${s.red}✗${s.reset} ${$}`)}function N($){console.warn(`${s.yellow}⚠${s.reset} ${$}`)}var i$=N;function G($){console.log(`${s.blue}ℹ${s.reset} ${$}`)}function r($){console.log(`${s.cyan}→${s.reset} ${$}`)}function V($){console.log(`
|
|
349
349
|
${s.bright}${s.cyan}${$}${s.reset}
|
|
350
350
|
`)}class M{frames=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];interval=null;currentFrame=0;message;constructor($){this.message=$}get text(){return this.message}set text($){this.message=$}start(){this.interval=setInterval(()=>{process.stdout.write(`\r${s.cyan}${this.frames[this.currentFrame]}${s.reset} ${this.message}`),this.currentFrame=(this.currentFrame+1)%this.frames.length},80)}succeed($){this.stop(),A($||this.message)}fail($){this.stop(),_($||this.message)}warn($){this.stop(),i$($||this.message)}stop(){if(this.interval)clearInterval(this.interval),process.stdout.write("\r")}}async function U$($,J){let Q=(await import("node:readline")).createInterface({input:process.stdin,output:process.stdout});return new Promise((W)=>{let U=J?`${s.cyan}?${s.reset} ${$} ${s.gray}(${J})${s.reset}: `:`${s.cyan}?${s.reset} ${$}: `;Q.question(U,(Z)=>{Q.close(),W(Z||J||"")})})}async function P($,J=!1){let Y=await U$(`${$} (y/n)`,J?"y":"n");return Y.toLowerCase()==="y"||Y.toLowerCase()==="yes"}async function HJ($,J){console.log(`${s.cyan}?${s.reset} ${$}`),J.forEach((W,U)=>{console.log(` ${s.gray}${U+1}.${s.reset} ${W}`)});let Y=await U$("Select","1"),Q=Number.parseInt(Y)-1;if(Q>=0&&Q<J.length)return J[Q];return J[0]}function b($,J){let Y=$.map((W,U)=>{let Z=Math.max(...J.map((z)=>(z[U]||"").length));return Math.max(W.length,Z)}),Q=$.map((W,U)=>W.padEnd(Y[U])).join(" ");console.log(A0(Q,"bright")),console.log(A0("─".repeat(Q.length),"gray")),J.forEach((W)=>{let U=W.map((Z,z)=>(Z||"").padEnd(Y[z])).join(" ");console.log(U)})}function C0($,J="cyan"){let Y=$.split(`
|
|
351
|
-
`),Q=Math.max(...Y.map((U)=>U.length)),W="─".repeat(Q+2);console.log(A0(`┌${W}┐`,J)),Y.forEach((U)=>{console.log(A0(`│ ${U.padEnd(Q)} │`,J))}),console.log(A0(`└${W}┘`,J))}async function g5(){return!0}async function u5(){try{let{AWSClient:$}=await Promise.resolve().then(() => (W$(),L0));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 d5(){try{let{AWSClient:$}=await Promise.resolve().then(() => (W$(),L0)),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 m5(){try{let{AWSClient:$}=await Promise.resolve().then(() => (W$(),L0)),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 W=Array.isArray(Y.regionInfo)?Y.regionInfo:[Y.regionInfo];Q.push(...W.map((U)=>U.regionName))}return Q.length>0?Q:f5()}catch{return f5()}}function f5(){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 BJ($){$.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"),KJ("cloud.config.ts")){if(!await P("cloud.config.ts already exists. Overwrite?",!1)){G("Initialization cancelled");return}}let Y=J?.name||await U$("Project name","my-app"),Q=J?.mode||await HJ("Select deployment mode",["serverless","server","hybrid"]),W=J?.region||await HJ("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),U=new M("Creating configuration file...");U.start();let Z=`import { defineConfig } from '
|
|
351
|
+
`),Q=Math.max(...Y.map((U)=>U.length)),W="─".repeat(Q+2);console.log(A0(`┌${W}┐`,J)),Y.forEach((U)=>{console.log(A0(`│ ${U.padEnd(Q)} │`,J))}),console.log(A0(`└${W}┘`,J))}async function g5(){return!0}async function u5(){try{let{AWSClient:$}=await Promise.resolve().then(() => (W$(),L0));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 d5(){try{let{AWSClient:$}=await Promise.resolve().then(() => (W$(),L0)),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 m5(){try{let{AWSClient:$}=await Promise.resolve().then(() => (W$(),L0)),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 W=Array.isArray(Y.regionInfo)?Y.regionInfo:[Y.regionInfo];Q.push(...W.map((U)=>U.regionName))}return Q.length>0?Q:f5()}catch{return f5()}}function f5(){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 BJ($){$.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"),KJ("cloud.config.ts")){if(!await P("cloud.config.ts already exists. Overwrite?",!1)){G("Initialization cancelled");return}}let Y=J?.name||await U$("Project name","my-app"),Q=J?.mode||await HJ("Select deployment mode",["serverless","server","hybrid"]),W=J?.region||await HJ("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),U=new M("Creating configuration file...");U.start();let Z=`import { defineConfig } from 'ts-cloud-types'
|
|
352
352
|
|
|
353
353
|
export default defineConfig({
|
|
354
354
|
project: {
|
|
@@ -864,7 +864,7 @@ run()
|
|
|
864
864
|
| sort @timestamp desc
|
|
865
865
|
| limit 50`,region:Q,title:"Recent Errors and Warnings"}}),Z+=6;return g1.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:W="GreaterThanThreshold",evaluationPeriods:U=1,period:Z=300,statistic:z="Average",treatMissingData:H="missing"}=$;return{MetricName:J,Namespace:Y,Threshold:Q,ComparisonOperator:W,EvaluationPeriods:U,Period:Z,Statistic:z,TreatMissingData:H}},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"})}}}s0();await s0();await s0();await s0();import{createHash as b8}from"node:crypto";import h$ from"node:fs";import gJ from"node:path";class uJ{cacheDir;ttl;constructor($,J={}){if(this.cacheDir=$,this.ttl=J.ttl||86400000,!h$.existsSync($))h$.mkdirSync($,{recursive:!0})}getCachePath($){let J=b8("sha256").update($).digest("hex");return gJ.join(this.cacheDir,`${J}.json`)}get($){let J=this.getCachePath($);if(!h$.existsSync(J))return;try{let Y=h$.readFileSync(J,"utf-8"),Q=JSON.parse(Y);if(Date.now()-Q.timestamp>this.ttl){h$.unlinkSync(J);return}return Q.value}catch{h$.unlinkSync(J);return}}set($,J,Y){let Q=this.getCachePath($),W={value:J,timestamp:Date.now(),hash:Y};h$.writeFileSync(Q,JSON.stringify(W),"utf-8")}has($){return this.get($)!==void 0}clear(){let $=h$.readdirSync(this.cacheDir);for(let J of $)h$.unlinkSync(gJ.join(this.cacheDir,J))}prune(){let $=h$.readdirSync(this.cacheDir),J=Date.now();for(let Y of $){let Q=gJ.join(this.cacheDir,Y);try{let W=h$.readFileSync(Q,"utf-8"),U=JSON.parse(W);if(J-U.timestamp>this.ttl)h$.unlinkSync(Q)}catch{h$.unlinkSync(Q)}}}}class dJ{cache;constructor($=".ts-cloud/cache/templates"){this.cache=new uJ($,{ttl:86400000})}getTemplate($){return this.cache.get(`template:${$}`)}setTemplate($,J){let Y=this.hashTemplate(J);this.cache.set(`template:${$}`,J,Y)}hasChanged($,J){let Y=this.cache.get(`template:${$}`);if(!Y)return!0;let Q=this.hashTemplate(Y),W=this.hashTemplate(J);return Q!==W}hashTemplate($){return b8("sha256").update($).digest("hex")}clear(){this.cache.clear()}prune(){this.cache.prune()}}var v7=new dJ;var iH={enabled:process.env.TS_CLOUD_LOCAL==="true"||!0,localstackEndpoint:process.env.LOCALSTACK_ENDPOINT||"http://localhost:4566",postgresUrl:process.env.POSTGRES_URL||"postgresql://tscloud:tscloud@localhost:5432/tscloud",redisUrl:process.env.REDIS_URL||"redis://localhost:6379",dynamodbEndpoint:process.env.DYNAMODB_ENDPOINT||"http://localhost:8000",s3Endpoint:process.env.S3_ENDPOINT||"http://localhost:9000",emailEndpoint:process.env.EMAIL_ENDPOINT||"smtp://localhost:1025",awsRegion:process.env.AWS_REGION||"us-east-1",awsAccessKeyId:process.env.AWS_ACCESS_KEY_ID||"test",awsSecretAccessKey:process.env.AWS_SECRET_ACCESS_KEY||"test"};class mJ{environments=new Map;async createPreviewEnvironment($){let{branch:J,pr:Y,commitSha:Q,ttl:W=24,baseConfig:U,region:Z="us-east-1"}=$,z=this.generatePreviewId(J,Y,Q),H=this.generatePreviewName(J,Y),K=`preview-${H}`,B=new Date,O=new Date(B.getTime()+W*60*60*1000),X={id:z,name:H,branch:J,pr:Y,commitSha:Q,createdAt:B,expiresAt:O,status:"creating",stackName:K,region:Z,resources:[]};this.environments.set(z,X);try{let j=this.createPreviewConfig(U,H);return X.status="active",X.url=`https://${H}.preview.example.com`,X}catch(j){throw X.status="failed",j}}async destroyPreviewEnvironment($){let J=this.environments.get($);if(!J)throw Error(`Preview environment ${$} not found`);J.status="destroying";try{J.status="destroyed",this.environments.delete($)}catch(Y){throw Error(`Failed to destroy preview environment: ${Y}`)}}getPreviewEnvironment($){return this.environments.get($)}getPreviewEnvironmentByBranch($){return Array.from(this.environments.values()).find((J)=>J.branch===$)}getPreviewEnvironmentByPR($){return Array.from(this.environments.values()).find((J)=>J.pr===$)}listPreviewEnvironments(){return Array.from(this.environments.values())}listActivePreviewEnvironments(){return this.listPreviewEnvironments().filter(($)=>$.status==="active")}async cleanupExpiredEnvironments($={}){let{maxAge:J,keepCount:Y,dryRun:Q=!1}=$,W=[],U=[],Z=new Date,z=this.listPreviewEnvironments().sort((H,K)=>K.createdAt.getTime()-H.createdAt.getTime());for(let H=0;H<z.length;H++){let K=z[H];if(K.status!=="active")continue;let B=!1;if(K.expiresAt<Z)B=!0;if(J){if((Z.getTime()-K.createdAt.getTime())/3600000>J)B=!0}if(Y&&H>=Y)B=!0;if(B)if(Q)W.push(K.id);else try{await this.destroyPreviewEnvironment(K.id),W.push(K.id)}catch(O){U.push(K.id)}}return{destroyed:W,failed:U}}async updatePreviewEnvironment($,J){let Y=this.environments.get($);if(!Y)throw Error(`Preview environment ${$} not found`);Y.commitSha=J,Y.status="creating";try{return Y.status="active",Y}catch(Q){throw Y.status="failed",Q}}async getPreviewEnvironmentsCost(){let $={},J=0;for(let Y of this.environments.values())$[Y.id]=0,J+=0;return{total:J,byEnvironment:$}}generatePreviewId($,J,Y){let Q=$.replace(/[^a-z0-9-]/gi,"-").toLowerCase(),W=Y?.substring(0,7)||Date.now().toString();return J?`pr-${J}-${W}`:`${Q}-${W}`}generatePreviewName($,J){let Y=$.replace(/[^a-z0-9-]/gi,"-").toLowerCase();return J?`pr-${J}`:Y}createPreviewConfig($,J){return{...$,project:{...$.project,name:`${$.project.name} Preview (${J})`,slug:`${$.project.slug}-preview-${J}`}}}}var f7=new mJ;class cJ{channels=[];addChannel($){this.channels.push($)}removeChannel($){this.channels=this.channels.filter((J)=>J.type!==$)}async notify($){let J=this.channels.map((Y)=>this.sendToChannel(Y,$));await Promise.allSettled(J)}async sendToChannel($,J){switch($.type){case"slack":await this.sendToSlack($.config,J);break;case"discord":await this.sendToDiscord($.config,J);break;case"email":await this.sendToEmail($.config,J);break;case"webhook":await this.sendToWebhook($.config,J);break}}async sendToSlack($,J){let Y=this.formatSlackMessage(J,$),Q=await fetch($.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)});if(!Q.ok)throw Error(`Failed to send Slack notification: ${Q.statusText}`)}formatSlackMessage($,J){let{environment:Y,type:Q}=$,W={created:":rocket:",updated:":arrows_counterclockwise:",destroyed:":wastebasket:",failed:":x:",expired:":hourglass_flowing_sand:"}[Q],U={created:"#36a64f",updated:"#2196F3",destroyed:"#808080",failed:"#f44336",expired:"#ff9800"}[Q],Z={created:"Preview Environment Created",updated:"Preview Environment Updated",destroyed:"Preview Environment Destroyed",failed:"Preview Environment Failed",expired:"Preview Environment Expired"}[Q];return{username:J.username||"ts-cloud",icon_emoji:J.iconEmoji||":cloud:",channel:J.channel,attachments:[{color:U,title:`${W} ${Z}`,fields:[{title:"Environment",value:Y.name,short:!0},{title:"Branch",value:Y.branch,short:!0},...Y.pr?[{title:"PR",value:`#${Y.pr}`,short:!0}]:[],{title:"Commit",value:Y.commitSha.substring(0,7),short:!0},...Y.url?[{title:"URL",value:Y.url,short:!1}]:[],...Q==="created"?[{title:"Expires",value:Y.expiresAt.toLocaleString(),short:!0}]:[]],footer:"ts-cloud Preview Environments",ts:Math.floor($.timestamp.getTime()/1000)}]}}async sendToDiscord($,J){let Y=this.formatDiscordMessage(J,$),Q=await fetch($.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)});if(!Q.ok)throw Error(`Failed to send Discord notification: ${Q.statusText}`)}formatDiscordMessage($,J){let{environment:Y,type:Q}=$,W={created:":rocket:",updated:":arrows_counterclockwise:",destroyed:":wastebasket:",failed:":x:",expired:":hourglass:"}[Q],U={created:3581519,updated:2201331,destroyed:8421504,failed:16007990,expired:16750592}[Q],Z={created:"Preview Environment Created",updated:"Preview Environment Updated",destroyed:"Preview Environment Destroyed",failed:"Preview Environment Failed",expired:"Preview Environment Expired"}[Q];return{username:J.username||"ts-cloud",avatar_url:J.avatarUrl,embeds:[{title:`${W} ${Z}`,color:U,fields:[{name:"Environment",value:Y.name,inline:!0},{name:"Branch",value:Y.branch,inline:!0},...Y.pr?[{name:"PR",value:`#${Y.pr}`,inline:!0}]:[],{name:"Commit",value:`\`${Y.commitSha.substring(0,7)}\``,inline:!0},...Y.url?[{name:"URL",value:Y.url,inline:!1}]:[]],timestamp:$.timestamp.toISOString(),footer:{text:"ts-cloud Preview Environments"}}]}}async sendToEmail($,J){console.log(`Email notification would be sent to ${$.to.join(", ")}`)}async sendToWebhook($,J){let Y=await fetch($.url,{method:$.method||"POST",headers:{"Content-Type":"application/json",...$.headers},body:JSON.stringify({event:J.type,environment:J.environment,timestamp:J.timestamp.toISOString(),metadata:J.metadata})});if(!Y.ok)throw Error(`Failed to send webhook notification: ${Y.statusText}`)}}var g7=new cJ;class u7{total;current=0;width;format;message;showETA;showPercentage;showCounter;startTime=Date.now();lastUpdate=0;constructor($){this.total=$.total,this.current=$.current||0,this.width=$.width||40,this.format=$.format||":message :bar :percent :eta",this.message=$.message||"Progress",this.showETA=$.showETA!==!1,this.showPercentage=$.showPercentage!==!1,this.showCounter=$.showCounter!==!1}tick($=1){this.current=Math.min(this.total,this.current+$),this.lastUpdate=Date.now()}update($){this.current=Math.min(this.total,Math.max(0,$)),this.lastUpdate=Date.now()}setMessage($){this.message=$}getPercentage(){return Math.min(100,this.current/this.total*100)}getETA(){if(this.current===0)return 0;let $=Date.now()-this.startTime,J=this.current/$,Y=this.total-this.current;return Math.round(Y/J)}getETAFormatted(){if(this.current===0)return"calculating...";if(this.current===this.total)return"complete";let $=this.getETA();if($<1000)return"< 1s";if($<60000)return`${Math.round($/1000)}s`;let J=Math.floor($/60000);if(J<60)return`${J}m`;let Y=Math.floor(J/60),Q=J%60;if(Y<24)return Q>0?`${Y}h ${Q}m`:`${Y}h`;let W=Math.floor(Y/24),U=Y%24;return U>0?`${W}d ${U}h`:`${W}d`}render(){let $=this.getPercentage(),J=Math.floor(this.width*this.current/this.total),Y=this.width-J,Q="█".repeat(J)+"░".repeat(Y),W=`${$.toFixed(1)}%`,U=`${this.current}/${this.total}`,Z=this.showETA?`ETA: ${this.getETAFormatted()}`:"",z=this.format.replace(":message",this.message).replace(":bar",Q).replace(":percent",this.showPercentage?W:"").replace(":counter",this.showCounter?U:"").replace(":eta",Z).replace(":current",String(this.current)).replace(":total",String(this.total));return z=z.replace(/\s+/g," ").trim(),z}isComplete(){return this.current>=this.total}}class d7{variables=new Map;workingDirectory=process.cwd();set($,J){this.variables.set($,J)}get($){return this.variables.get($)}has($){return this.variables.has($)}delete($){this.variables.delete($)}getAll(){return Object.fromEntries(this.variables)}clear(){this.variables.clear()}setWorkingDirectory($){this.workingDirectory=$}getWorkingDirectory(){return this.workingDirectory}}class y8{deployments=new Map;async deploy($,J){let Y=this.generateDeploymentId(),Q={id:Y,regions:J.regions.map((W)=>({region:W.code,stackName:this.getStackName($,W.code),status:"pending"})),status:"deploying",startTime:new Date};this.deployments.set(Y,Q);try{let W=J.regions.find((Z)=>Z.isPrimary)||J.regions[0];await this.deployToRegion($,W,Q);let U=J.regions.filter((Z)=>Z.code!==W.code);if(await Promise.all(U.map((Z)=>this.deployToRegion($,Z,Q))),J.globalResources)await this.deployGlobalResources(Q,J);if(J.replication)await this.setupReplication(Q,J);if(J.failover?.enabled)await this.setupFailover(Q,J);return Q.status="deployed",Q.endTime=new Date,Q}catch(W){throw Q.status="failed",Q.endTime=new Date,W}}async deployToRegion($,J,Y){let Q=Y.regions.find((W)=>W.region===J.code);if(!Q)throw Error(`Region deployment not found: ${J.code}`);Q.status="deploying",Q.startTime=new Date;try{let W=this.createRegionConfig($,J);await this.deployStack(Q.stackName,W,J.code),Q.status="deployed",Q.endTime=new Date,Q.outputs={stackId:`arn:aws:cloudformation:${J.code}:123456789012:stack/${Q.stackName}/guid`,endpoint:`https://${Q.stackName}.${J.code}.example.com`}}catch(W){throw Q.status="failed",Q.endTime=new Date,Q.error=W instanceof Error?W.message:String(W),W}}async deployGlobalResources($,J){let Y={};if(J.globalResources?.route53)Y.route53=await this.deployRoute53($,J);if(J.globalResources?.cloudfront)Y.cloudfront=await this.deployCloudFront($,J);if(J.globalResources?.waf)Y.waf=await this.deployWAF($);$.globalResources=Y}async deployRoute53($,J){let Y=[],Q=[];for(let W of $.regions){if(W.status!=="deployed")continue;let U={id:`health-${W.region}`,endpoint:W.outputs?.endpoint,path:J.failover?.healthCheckPath||"/health",region:W.region};Y.push(U);let Z={name:"example.com",type:"A",region:W.region,setIdentifier:W.region,healthCheckId:U.id,resourceRecords:[W.outputs?.endpoint]};Q.push(Z)}return{healthChecks:Y,recordSets:Q,hostedZoneId:"Z1234567890ABC"}}async deployCloudFront($,J){return{distributionId:"E1234567890ABC",domainName:"d1234567890abc.cloudfront.net",origins:$.regions.filter((Q)=>Q.status==="deployed").map((Q,W)=>{let U=J.regions[W];return{id:`origin-${Q.region}`,domainName:Q.outputs?.endpoint,weight:U?.weight||100}}),status:"Deployed"}}async deployWAF($){return{webAclId:"arn:aws:wafv2:us-east-1:123456789012:global/webacl/test/a1234567-b890-c123-d456-e789012345f6",webAclArn:"arn:aws:wafv2:us-east-1:123456789012:global/webacl/test/a1234567-b890-c123-d456-e789012345f6"}}async setupReplication($,J){if(J.replication?.s3)await this.setupS3Replication($);if(J.replication?.dynamodb)await this.setupDynamoDBReplication($);if(J.replication?.secrets)await this.setupSecretsReplication($)}async setupS3Replication($){let J=$.regions.filter((Y)=>Y.status==="deployed");for(let Y=0;Y<J.length-1;Y++){let Q=J[Y],W=J[Y+1];console.log(`Setting up S3 replication: ${Q.region} -> ${W.region}`)}}async setupDynamoDBReplication($){let J=$.regions.filter((Y)=>Y.status==="deployed").map((Y)=>Y.region);console.log(`Setting up DynamoDB global table in regions: ${J.join(", ")}`)}async setupSecretsReplication($){let J=$.regions.filter((Y)=>Y.status==="deployed").map((Y)=>Y.region);console.log(`Setting up Secrets Manager replication in regions: ${J.join(", ")}`)}async setupFailover($,J){let Y=$.regions.find((W,U)=>J.regions[U]?.isPrimary)||$.regions[0],Q=$.regions.filter((W)=>W.region!==Y.region);console.log(`Setting up failover: primary=${Y.region}, secondary=${Q.map((W)=>W.region).join(", ")}`)}async destroy($){let J=this.deployments.get($);if(!J)throw Error(`Deployment not found: ${$}`);J.status="rolling-back";try{if(J.globalResources)await this.destroyGlobalResources(J.globalResources);await Promise.all(J.regions.map((Y)=>this.destroyRegionStack(Y))),this.deployments.delete($)}catch(Y){throw J.status="failed",Y}}async destroyGlobalResources($){if($.waf)console.log("Destroying WAF resources");if($.cloudfront)console.log("Destroying CloudFront distribution");if($.route53)console.log("Destroying Route53 resources")}async destroyRegionStack($){if($.status!=="deployed")return;$.status="rolling-back";try{console.log(`Destroying stack ${$.stackName} in ${$.region}`),$.status="pending"}catch(J){throw $.status="failed",$.error=J instanceof Error?J.message:String(J),J}}getDeployment($){return this.deployments.get($)}listDeployments(){return Array.from(this.deployments.values())}getStackName($,J){return`${$.project.slug}-${J}`}createRegionConfig($,J){return{...$,infrastructure:{...$.infrastructure}}}async deployStack($,J,Y){console.log(`Deploying stack ${$} to ${Y}`)}generateDeploymentId(){return`deploy-${Date.now()}-${Math.random().toString(36).substring(7)}`}}var FK=new y8;class v8{references=[];exports=new Map;addExport($){let J=`${$.region}:${$.exportName}`;if(!this.exports.has($.region))this.exports.set($.region,[]);this.exports.get($.region).push($)}getExport($,J){let Y=this.exports.get($);if(!Y)return;return Y.find((W)=>W.exportName===J)?.value}createReference($,J,Y,Q){let W=`/cross-region/${$}/${Y}/${Q}`;return this.references.push({sourceRegion:$,targetRegion:J,resourceType:Y,resourceId:Q,value:W}),W}async resolveReference($,J){let Y=this.references.find((Q)=>Q.targetRegion===$&&Q.value===J);if(!Y)throw Error(`Reference not found: ${J}`);return`arn:aws:resource:${Y.sourceRegion}:123456789012:${Y.resourceType}/${Y.resourceId}`}getReferencesForRegion($){return this.references.filter((J)=>J.sourceRegion===$||J.targetRegion===$)}clear(){this.references=[],this.exports.clear()}}class f8{resources=new Map;register($){this.resources.set($.id,$)}get($){return this.resources.get($)}getByType($){return Array.from(this.resources.values()).filter((J)=>J.type===$)}getCloudFrontDistributions(){return this.getByType("cloudfront")}getRoute53HostedZones(){return this.getByType("route53")}getWAFWebACLs(){return this.getByType("waf")}remove($){this.resources.delete($)}clear(){this.resources.clear()}}class g8{pairs=[];addPair($){this.pairs.push($)}getPairedRegion($){let J=this.pairs.find((Y)=>Y.primary===$||Y.secondary===$);if(!J)return;return J.primary===$?J.secondary:J.primary}getAllPairs(){return[...this.pairs]}getReplicatedPairs(){return this.pairs.filter(($)=>$.replicationConfig)}getFailoverPairs(){return this.pairs.filter(($)=>$.failoverConfig?.automatic)}arePaired($,J){return this.pairs.some((Y)=>Y.primary===$&&Y.secondary===J||Y.primary===J&&Y.secondary===$)}clear(){this.pairs=[]}}class u8{dependencies=[];addDependency($){this.dependencies.push($)}getDependencies($,J){return this.dependencies.filter((Y)=>Y.dependentStack===$&&Y.dependentRegion===J)}getDependents($,J){return this.dependencies.filter((Y)=>Y.dependsOnStack===$&&Y.dependsOnRegion===J)}hasDependencies($,J){return this.getDependencies($,J).length>0}getDeploymentOrder($){let J=new Set,Y=[],Q=(W)=>{let U=`${W.name}:${W.region}`;if(J.has(U))return;J.add(U);let Z=this.getDependencies(W.name,W.region);for(let z of Z)Q({name:z.dependsOnStack,region:z.dependsOnRegion});Y.push(W)};for(let W of $)Q(W);return Y}detectCircularDependencies(){let $=new Set,J=new Set,Y=(Q,W)=>{let U=`${Q}:${W}`;if(J.has(U))return!0;if($.has(U))return!1;$.add(U),J.add(U);let Z=this.getDependencies(Q,W);for(let z of Z)if(Y(z.dependsOnStack,z.dependsOnRegion))return!0;return J.delete(U),!1};for(let Q of this.dependencies)if(Y(Q.dependentStack,Q.dependentRegion))return!0;return!1}clear(){this.dependencies=[]}}var TK=new v8,LK=new f8,AK=new g8,RK=new u8;class d8{accounts=new Map;crossAccountRoles=[];accountMappings=[];registerAccount($){this.accounts.set($.id,$)}getAccount($){return this.accounts.get($)}getAccountByAlias($){return Array.from(this.accounts.values()).find((J)=>J.alias===$)}listAccounts(){return Array.from(this.accounts.values())}getAccountsByRole($){return Array.from(this.accounts.values()).filter((J)=>J.role===$)}createCrossAccountRole($,J,Y,Q,W){let U={roleArn:`arn:aws:iam::${J}:role/${Y}`,roleName:Y,sourceAccountId:$,targetAccountId:J,permissions:Q,externalId:W?.externalId,sessionDuration:W?.sessionDuration||3600};return this.crossAccountRoles.push(U),U}getAssumeRolePolicyDocument($,J){let Y={Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:`arn:aws:iam::${$}:root`},Action:"sts:AssumeRole"}]};if(J)Y.Statement[0].Condition={StringEquals:{"sts:ExternalId":J}};return Y}generateCrossAccountPolicy($){return{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:$,Resource:"*"}]}}mapEnvironmentToAccount($,J,Y){this.accountMappings.push({environment:$,accountId:J,region:Y})}getAccountForEnvironment($){return this.accountMappings.find((J)=>J.environment===$)}async assumeRole($,J,Y){return console.log(`Assuming role: ${$} with session: ${J}`),{accessKeyId:"AKIAIOSFODNN7EXAMPLE",secretAccessKey:"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",sessionToken:"token",expiration:new Date(Date.now()+3600000)}}async getCredentialsForAccount($){let J=this.accounts.get($);if(!J)throw Error(`Account not found: ${$}`);if(J.assumeRoleArn){let Y=await this.assumeRole(J.assumeRoleArn,`ts-cloud-${Date.now()}`);return{accessKeyId:Y.accessKeyId,secretAccessKey:Y.secretAccessKey,sessionToken:Y.sessionToken}}throw Error("No credentials available for account")}listCrossAccountRoles(){return[...this.crossAccountRoles]}getCrossAccountRolesForAccount($){return this.crossAccountRoles.filter((J)=>J.sourceAccountId===$||J.targetAccountId===$)}async validateAccountAccess($){try{let J=await this.getCredentialsForAccount($);return console.log(`Validating access to account: ${$}`),!0}catch{return!1}}async getConsolidatedBilling(){let $={};for(let Y of this.accounts.values())$[Y.id]=Math.random()*1000;return{totalCost:Object.values($).reduce((Y,Q)=>Y+Q,0),byAccount:$}}clear(){this.accounts.clear(),this.crossAccountRoles=[],this.accountMappings=[]}}class m8{organizationId;organizationalUnits=new Map;getOrganizationId(){return this.organizationId}setOrganizationId($){this.organizationId=$}createOrganizationalUnit($,J){let Y={id:`ou-${Date.now()}`,name:$,parentId:J,accounts:[]};return this.organizationalUnits.set(Y.id,Y),Y}getOrganizationalUnit($){return this.organizationalUnits.get($)}listOrganizationalUnits(){return Array.from(this.organizationalUnits.values())}addAccountToOU($,J){let Y=this.organizationalUnits.get($);if(!Y)throw Error(`Organizational unit not found: ${$}`);if(!Y.accounts.includes(J))Y.accounts.push(J)}removeAccountFromOU($,J){let Y=this.organizationalUnits.get($);if(!Y)throw Error(`Organizational unit not found: ${$}`);Y.accounts=Y.accounts.filter((Q)=>Q!==J)}getAccountsInOU($){let J=this.organizationalUnits.get($);if(!J)return[];return[...J.accounts]}applyServiceControlPolicy($,J){return{id:`scp-${Date.now()}`,name:"Custom SCP",targetId:$,policyDocument:J}}clear(){this.organizationId=void 0,this.organizationalUnits.clear()}}var IK=new d8,xK=new m8;class lJ{backupPlans=new Map;backupVaults=new Map;restoreJobs=new Map;continuousBackups=new Map;planCounter=0;restoreCounter=0;continuousBackupCounter=0;createVault($){this.backupVaults.set($.name,$)}getVault($){return this.backupVaults.get($)}createBackupPlan($){let J=`backup-plan-${Date.now()}-${this.planCounter++}`,Y={id:J,...$};return this.backupPlans.set(J,Y),Y}getBackupPlan($){return this.backupPlans.get($)}listBackupPlans(){return Array.from(this.backupPlans.values())}createRDSBackupPlan($){let{dbInstanceArn:J,schedule:Y="0 2 * * *",retentionDays:Q=7,vaultName:W="default-vault"}=$;return this.createBackupPlan({name:"RDS Daily Backup",schedule:Y,retentionDays:Q,vaultName:W,resources:[{resourceArn:J,resourceType:"rds",region:"us-east-1"}],lifecycle:{moveTocoldStorageAfterDays:30,deleteAfterDays:Q}})}createDynamoDBBackupPlan($){let{tableArn:J,schedule:Y="0 3 * * *",retentionDays:Q=35,crossRegionCopy:W}=$;return this.createBackupPlan({name:"DynamoDB Daily Backup",schedule:Y,retentionDays:Q,vaultName:"dynamodb-vault",resources:[{resourceArn:J,resourceType:"dynamodb",region:"us-east-1"}],lifecycle:{deleteAfterDays:Q},tags:W?{CrossRegionCopy:W.join(",")}:void 0})}createEFSBackupPlan($){let{fileSystemArn:J,schedule:Y="0 1 * * *",retentionDays:Q=30}=$;return this.createBackupPlan({name:"EFS Daily Backup",schedule:Y,retentionDays:Q,vaultName:"efs-vault",resources:[{resourceArn:J,resourceType:"efs",region:"us-east-1"}],lifecycle:{deleteAfterDays:Q}})}enableContinuousBackup($,J=35){let Y=`continuous-backup-${Date.now()}-${this.continuousBackupCounter++}`,Q={id:Y,resourceId:$,enabled:!0,retentionDays:J};return this.continuousBackups.set(Y,Q),Q}getContinuousBackup($){return this.continuousBackups.get($)}enablePointInTimeRecovery($,J){return{enabled:!0,earliestRestorableTime:new Date(Date.now()-604800000),latestRestorableTime:new Date}}async restoreFromBackup($){let{backupId:J,resourceType:Y,targetRegion:Q}=$,W={id:`restore-${Date.now()}-${this.restoreCounter++}`,backupId:J,resourceType:Y,status:"pending",startTime:new Date,targetRegion:Q};return this.restoreJobs.set(W.id,W),setTimeout(()=>{W.status="running"},100),setTimeout(()=>{W.status="completed",W.endTime=new Date},1000),W}async restoreToPointInTime($){let{sourceResourceArn:J,targetResourceName:Y,restoreTime:Q,resourceType:W}=$,U={id:`pitr-${Date.now()}-${this.restoreCounter++}`,backupId:`pitr-${Q.getTime()}`,resourceType:W,status:"pending",startTime:new Date};return this.restoreJobs.set(U.id,U),console.log(`Restoring ${W} from ${J} to ${Y} at ${Q.toISOString()}`),setTimeout(()=>{U.status="completed",U.endTime=new Date},2000),U}getRestoreJob($){return this.restoreJobs.get($)}listRestoreJobs(){return Array.from(this.restoreJobs.values())}setupCrossRegionReplication($){let{sourceVault:J,sourceRegion:Y,targetRegions:Q}=$;console.log("Setting up cross-region replication:"),console.log(` Source: ${J} in ${Y}`),console.log(` Targets: ${Q.join(", ")}`)}generateBackupVaultCF($){return{Type:"AWS::Backup::BackupVault",Properties:{BackupVaultName:$.name,...$.encryptionKeyArn&&{EncryptionKeyArn:$.encryptionKeyArn},...$.accessPolicy&&{AccessPolicy:$.accessPolicy}}}}generateBackupPlanCF($){return{Type:"AWS::Backup::BackupPlan",Properties:{BackupPlan:{BackupPlanName:$.name,BackupPlanRule:[{RuleName:"DailyBackup",TargetBackupVault:$.vaultName,ScheduleExpression:`cron(${$.schedule})`,StartWindowMinutes:60,CompletionWindowMinutes:120,Lifecycle:$.lifecycle?{...$.lifecycle.moveTocoldStorageAfterDays&&{MoveToColdStorageAfterDays:$.lifecycle.moveTocoldStorageAfterDays},...$.lifecycle.deleteAfterDays&&{DeleteAfterDays:$.lifecycle.deleteAfterDays}}:void 0}]},...$.tags&&{BackupPlanTags:$.tags}}}}generateBackupSelectionCF($){return{Type:"AWS::Backup::BackupSelection",Properties:{BackupPlanId:{Ref:`BackupPlan${$.id}`},BackupSelection:{SelectionName:`${$.name}Selection`,IamRoleArn:"arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole",Resources:$.resources.map((J)=>J.resourceArn)}}}}clear(){this.backupPlans.clear(),this.backupVaults.clear(),this.restoreJobs.clear(),this.continuousBackups.clear(),this.planCounter=0,this.restoreCounter=0,this.continuousBackupCounter=0}}var m7=new lJ;class pJ{drPlans=new Map;failoverTests=new Map;planCounter=0;testCounter=0;createDRPlan($){let J=`dr-plan-${Date.now()}-${this.planCounter++}`,Y={id:J,...$};return this.drPlans.set(J,Y),Y}createRDSDRPlan($){let{primaryDbArn:J,secondaryDbArn:Y,primaryRegion:Q,secondaryRegion:W,rto:U=60,rpo:Z=5}=$;return this.createDRPlan({name:"RDS Multi-Region DR",primaryRegion:Q,secondaryRegion:W,rto:U,rpo:Z,resources:[{resourceId:"primary-db",resourceType:"rds",primaryArn:J,secondaryArn:Y,replicationEnabled:!0}],runbook:this.generateRDSRunbook(Q,W),testSchedule:"0 0 1 * *"})}createDynamoDBDRPlan($){let{tableArn:J,regions:Y,rto:Q=15,rpo:W=1}=$;return this.createDRPlan({name:"DynamoDB Global Tables DR",primaryRegion:Y[0],secondaryRegion:Y[1],rto:Q,rpo:W,resources:[{resourceId:"dynamodb-table",resourceType:"dynamodb",primaryArn:J,replicationEnabled:!0}],runbook:this.generateDynamoDBRunbook(Y)})}generateRDSRunbook($,J){return{estimatedDuration:60,requiredApprovals:["cto","engineering-lead"],steps:[{order:1,name:"Verify Primary Database Failure",description:"Confirm that the primary database is truly unavailable and not experiencing temporary issues",action:"aws rds describe-db-instances --region "+$,automatable:!0,estimatedDuration:2,rollbackable:!1},{order:2,name:"Check Replication Lag",description:"Verify that the read replica is up to date",action:"Check ReplicaLag metric in CloudWatch",automatable:!0,estimatedDuration:1,rollbackable:!1},{order:3,name:"Promote Read Replica",description:"Promote the read replica in the secondary region to be the new primary",action:"aws rds promote-read-replica --db-instance-identifier replica --region "+J,automatable:!0,estimatedDuration:10,rollbackable:!1},{order:4,name:"Update DNS Records",description:"Update Route53 records to point to the new primary database",action:"Update Route53 failover record set",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:5,name:"Update Application Configuration",description:"Update application connection strings if needed",action:"Deploy configuration update to ECS/Lambda",automatable:!0,estimatedDuration:10,rollbackable:!0},{order:6,name:"Verify Application Connectivity",description:"Test that applications can connect to the new primary",action:"Run smoke tests",automatable:!0,estimatedDuration:5,rollbackable:!1},{order:7,name:"Monitor for Issues",description:"Monitor CloudWatch metrics and application logs",action:"Monitor for 30 minutes",automatable:!1,estimatedDuration:30,rollbackable:!1}]}}generateDynamoDBRunbook($){return{estimatedDuration:15,steps:[{order:1,name:"Verify Primary Region Failure",description:"Confirm that the primary region is experiencing an outage",action:"Check AWS Health Dashboard",automatable:!0,estimatedDuration:2,rollbackable:!1},{order:2,name:"Update Route53 Failover",description:"Update Route53 to direct traffic to secondary region",action:"Update Route53 health check and failover records",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:3,name:"Update Application Endpoints",description:"Update Lambda/ECS to use secondary region DynamoDB endpoint",action:"Deploy configuration update",automatable:!0,estimatedDuration:5,rollbackable:!0},{order:4,name:"Verify Data Consistency",description:"Verify that data is consistent in secondary region",action:"Run data validation queries",automatable:!0,estimatedDuration:3,rollbackable:!1}]}}async executeFailover($,J=!1){let Y=this.drPlans.get($);if(!Y)throw Error(`DR plan not found: ${$}`);let Q=Date.now(),W=0;console.log(`${J?"[DRY RUN] ":""}Executing failover for plan: ${Y.name}`),console.log(`Primary: ${Y.primaryRegion} -> Secondary: ${Y.secondaryRegion}`),console.log(`RTO: ${Y.rto} minutes, RPO: ${Y.rpo} minutes`),console.log("");for(let Z of Y.runbook.steps){if(console.log(`Step ${Z.order}: ${Z.name}`),console.log(` ${Z.description}`),console.log(` Action: ${Z.action}`),console.log(` Estimated: ${Z.estimatedDuration} minutes`),J)console.log(" [SKIPPED - DRY RUN]");else if(Z.automatable)console.log(" [AUTOMATED]");else console.log(" [MANUAL - WAITING]");W++,console.log("")}return{success:!0,duration:(Date.now()-Q)/1000/60,completedSteps:W}}scheduleFailoverTest($,J){let Y={id:`failover-test-${Date.now()}-${this.testCounter++}`,planId:$,status:"scheduled",startTime:J};return this.failoverTests.set(Y.id,Y),Y}async runFailoverTest($){let J=this.drPlans.get($);if(!J)throw Error(`DR plan not found: ${$}`);let Y={id:`failover-test-${Date.now()}-${this.testCounter++}`,planId:$,status:"running",startTime:new Date,results:[]};this.failoverTests.set(Y.id,Y),console.log(`Running failover test for plan: ${J.name}`),console.log("This is a non-destructive test using test resources"),console.log("");for(let Q of J.runbook.steps){let W=Date.now();console.log(`Testing step ${Q.order}: ${Q.name}`);let U={step:Q.name,status:"success",duration:(Date.now()-W)/1000,message:`Successfully validated step ${Q.order}`};Y.results.push(U)}return Y.status="completed",Y.endTime=new Date,Y}getDRPlan($){return this.drPlans.get($)}listDRPlans(){return Array.from(this.drPlans.values())}getFailoverTest($){return this.failoverTests.get($)}listFailoverTests(){return Array.from(this.failoverTests.values())}validateDRPlan($){let J=[],Y=[];if($.rto<$.rpo)Y.push("RTO cannot be less than RPO");if($.rto>240)J.push("RTO exceeds 4 hours - consider improving recovery time");if($.rpo>60)J.push("RPO exceeds 1 hour - consider more frequent backups");if($.resources.length===0)Y.push("No resources defined in DR plan");for(let U of $.resources){if(!U.replicationEnabled)J.push(`Resource ${U.resourceId} does not have replication enabled`);if(!U.secondaryArn&&U.resourceType!=="dynamodb")J.push(`Resource ${U.resourceId} does not have secondary resource defined`)}if($.runbook.steps.length===0)Y.push("No recovery steps defined in runbook");let Q=$.runbook.steps.reduce((U,Z)=>U+Z.estimatedDuration,0);if(Q>$.rto)J.push(`Estimated recovery duration (${Q}m) exceeds RTO (${$.rto}m)`);let W=$.runbook.steps.filter((U)=>!U.automatable);if(W.length>0)J.push(`${W.length} manual steps in runbook - consider automation`);return{valid:Y.length===0,warnings:J,errors:Y}}clear(){this.drPlans.clear(),this.failoverTests.clear(),this.planCounter=0,this.testCounter=0}}var c7=new pJ;class rJ{configRules=new Map;configRecorders=new Map;deliveryChannels=new Map;ruleCounter=0;createConfigRecorder($){return this.configRecorders.set($.name,$),$}createDeliveryChannel($){return this.deliveryChannels.set($.name,$),$}createConfigRule($){let J=`config-rule-${Date.now()}-${this.ruleCounter++}`,Y={id:J,...$};return this.configRules.set(J,Y),Y}createS3EncryptionRule(){return this.createConfigRule({name:"s3-bucket-server-side-encryption-enabled",description:"Checks that S3 buckets have server-side encryption enabled",source:"AWS_MANAGED",identifier:"S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createS3PublicAccessBlockRule(){return this.createConfigRule({name:"s3-bucket-public-read-prohibited",description:"Checks that S3 buckets do not allow public read access",source:"AWS_MANAGED",identifier:"S3_BUCKET_PUBLIC_READ_PROHIBITED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createS3VersioningRule(){return this.createConfigRule({name:"s3-bucket-versioning-enabled",description:"Checks whether versioning is enabled for S3 buckets",source:"AWS_MANAGED",identifier:"S3_BUCKET_VERSIONING_ENABLED",scope:{complianceResourceTypes:["AWS::S3::Bucket"]}})}createRdsEncryptionRule(){return this.createConfigRule({name:"rds-storage-encrypted",description:"Checks whether storage encryption is enabled for RDS DB instances",source:"AWS_MANAGED",identifier:"RDS_STORAGE_ENCRYPTED",scope:{complianceResourceTypes:["AWS::RDS::DBInstance"]}})}createRdsSnapshotEncryptionRule(){return this.createConfigRule({name:"rds-snapshots-public-prohibited",description:"Checks if RDS snapshots are public",source:"AWS_MANAGED",identifier:"RDS_SNAPSHOTS_PUBLIC_PROHIBITED",scope:{complianceResourceTypes:["AWS::RDS::DBSnapshot","AWS::RDS::DBClusterSnapshot"]}})}createRdsBackupRule($=7){return this.createConfigRule({name:"db-backup-enabled",description:"Checks whether RDS DB instances have backups enabled",source:"AWS_MANAGED",identifier:"DB_BACKUP_ENABLED",inputParameters:{backupRetentionPeriod:$},scope:{complianceResourceTypes:["AWS::RDS::DBInstance"]}})}createEc2InstanceProfileRule(){return this.createConfigRule({name:"ec2-instance-managed-by-systems-manager",description:"Checks if EC2 instances are managed by Systems Manager",source:"AWS_MANAGED",identifier:"EC2_INSTANCE_MANAGED_BY_SSM",scope:{complianceResourceTypes:["AWS::EC2::Instance"]}})}createEbsEncryptionRule(){return this.createConfigRule({name:"encrypted-volumes",description:"Checks whether EBS volumes are encrypted",source:"AWS_MANAGED",identifier:"ENCRYPTED_VOLUMES",scope:{complianceResourceTypes:["AWS::EC2::Volume"]}})}createIamPasswordPolicyRule(){return this.createConfigRule({name:"iam-password-policy",description:"Checks whether the IAM password policy meets specified requirements",source:"AWS_MANAGED",identifier:"IAM_PASSWORD_POLICY",inputParameters:{RequireUppercaseCharacters:!0,RequireLowercaseCharacters:!0,RequireSymbols:!0,RequireNumbers:!0,MinimumPasswordLength:14,PasswordReusePrevention:24,MaxPasswordAge:90}})}createIamMfaRule(){return this.createConfigRule({name:"iam-user-mfa-enabled",description:"Checks whether IAM users have MFA enabled",source:"AWS_MANAGED",identifier:"IAM_USER_MFA_ENABLED"})}createRootAccountMfaRule(){return this.createConfigRule({name:"root-account-mfa-enabled",description:"Checks whether the root account has MFA enabled",source:"AWS_MANAGED",identifier:"ROOT_ACCOUNT_MFA_ENABLED"})}createVpcFlowLogsRule(){return this.createConfigRule({name:"vpc-flow-logs-enabled",description:"Checks whether VPC Flow Logs is enabled",source:"AWS_MANAGED",identifier:"VPC_FLOW_LOGS_ENABLED",scope:{complianceResourceTypes:["AWS::EC2::VPC"]}})}createCloudTrailEnabledRule(){return this.createConfigRule({name:"cloudtrail-enabled",description:"Checks whether CloudTrail is enabled",source:"AWS_MANAGED",identifier:"CLOUD_TRAIL_ENABLED",maxExecutionFrequency:"TwentyFour_Hours"})}createCloudWatchAlarmRule(){return this.createConfigRule({name:"cloudwatch-alarm-action-check",description:"Checks whether CloudWatch alarms have actions configured",source:"AWS_MANAGED",identifier:"CLOUDWATCH_ALARM_ACTION_CHECK",inputParameters:{alarmActionRequired:!0,insufficientDataActionRequired:!1,okActionRequired:!1},scope:{complianceResourceTypes:["AWS::CloudWatch::Alarm"]}})}createCustomLambdaRule($){return this.createConfigRule({name:$.name,description:$.description,source:"CUSTOM_LAMBDA",lambdaFunctionArn:$.lambdaFunctionArn,scope:$.resourceTypes?{complianceResourceTypes:$.resourceTypes}:void 0,maxExecutionFrequency:$.maxExecutionFrequency,inputParameters:$.inputParameters})}createCompliancePreset($){let J=[];switch($){case"hipaa":J.push(this.createS3EncryptionRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamPasswordPolicyRule(),this.createRdsBackupRule(7),this.createVpcFlowLogsRule());break;case"pci-dss":J.push(this.createS3EncryptionRule(),this.createS3PublicAccessBlockRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamPasswordPolicyRule(),this.createIamMfaRule(),this.createRootAccountMfaRule(),this.createVpcFlowLogsRule());break;case"sox":J.push(this.createS3VersioningRule(),this.createCloudTrailEnabledRule(),this.createRdsBackupRule(30),this.createIamPasswordPolicyRule());break;case"gdpr":J.push(this.createS3EncryptionRule(),this.createRdsEncryptionRule(),this.createEbsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createRdsSnapshotEncryptionRule());break;case"basic":J.push(this.createS3EncryptionRule(),this.createS3PublicAccessBlockRule(),this.createRdsEncryptionRule(),this.createCloudTrailEnabledRule(),this.createIamMfaRule(),this.createRootAccountMfaRule());break}return J}getConfigRule($){return this.configRules.get($)}listConfigRules(){return Array.from(this.configRules.values())}getConfigRecorder($){return this.configRecorders.get($)}listConfigRecorders(){return Array.from(this.configRecorders.values())}getDeliveryChannel($){return this.deliveryChannels.get($)}listDeliveryChannels(){return Array.from(this.deliveryChannels.values())}generateConfigRuleCF($){let J={Type:"AWS::Config::ConfigRule",Properties:{ConfigRuleName:$.name,Description:$.description,Source:{Owner:$.source==="AWS_MANAGED"?"AWS":"CUSTOM_LAMBDA"}}};if($.source==="AWS_MANAGED"&&$.identifier)J.Properties.Source.SourceIdentifier=$.identifier;if($.source==="CUSTOM_LAMBDA"&&$.lambdaFunctionArn)J.Properties.Source.SourceIdentifier=$.lambdaFunctionArn,J.Properties.Source.SourceDetails=[{EventSource:"aws.config",MessageType:"ConfigurationItemChangeNotification"}];if($.inputParameters)J.Properties.InputParameters=JSON.stringify($.inputParameters);if($.scope){if(J.Properties.Scope={},$.scope.complianceResourceTypes)J.Properties.Scope.ComplianceResourceTypes=$.scope.complianceResourceTypes;if($.scope.tagKey)J.Properties.Scope.TagKey=$.scope.tagKey;if($.scope.tagValue)J.Properties.Scope.TagValue=$.scope.tagValue}if($.maxExecutionFrequency)J.Properties.MaximumExecutionFrequency=$.maxExecutionFrequency;return J}generateConfigRecorderCF($){return{Type:"AWS::Config::ConfigurationRecorder",Properties:{Name:$.name,RoleArn:$.roleArn,RecordingGroup:$.recordingGroup||{AllSupported:!0,IncludeGlobalResourceTypes:!0}}}}generateDeliveryChannelCF($){return{Type:"AWS::Config::DeliveryChannel",Properties:{Name:$.name,S3BucketName:$.s3BucketName,...$.s3KeyPrefix&&{S3KeyPrefix:$.s3KeyPrefix},...$.snsTopicArn&&{SnsTopicARN:$.snsTopicArn},...$.configSnapshotDeliveryProperties&&{ConfigSnapshotDeliveryProperties:$.configSnapshotDeliveryProperties}}}}clear(){this.configRules.clear(),this.configRecorders.clear(),this.deliveryChannels.clear(),this.ruleCounter=0}}var l7=new rJ;class aJ{trails=new Map;trailCounter=0;createTrail($){let J=`trail-${Date.now()}-${this.trailCounter++}`,Y={id:J,...$};return this.trails.set(J,Y),Y}createOrganizationTrail($){return this.createTrail({name:$.name,s3BucketName:$.s3BucketName,s3KeyPrefix:"organization-trail",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,kmsKeyId:$.kmsKeyId,cloudWatchLogsLogGroupArn:$.cloudWatchLogsLogGroupArn,cloudWatchLogsRoleArn:$.cloudWatchLogsRoleArn})}createSecurityAuditTrail($){return this.createTrail({name:$.name,s3BucketName:$.s3BucketName,s3KeyPrefix:"security-audit",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,kmsKeyId:$.kmsKeyId,cloudWatchLogsLogGroupArn:$.cloudWatchLogsLogGroupArn,cloudWatchLogsRoleArn:$.cloudWatchLogsRoleArn,eventSelectors:[{readWriteType:"All",includeManagementEvents:!0,excludeManagementEventSources:[]}],insightSelectors:[{insightType:"ApiCallRateInsight"},{insightType:"ApiErrorRateInsight"}]})}createDataEventsTrail($){let J=[];if($.s3DataBuckets&&$.s3DataBuckets.length>0)J.push({type:"AWS::S3::Object",values:$.s3DataBuckets.map((Y)=>`arn:aws:s3:::${Y}/*`)});if($.lambdaFunctions&&$.lambdaFunctions.length>0)J.push({type:"AWS::Lambda::Function",values:$.lambdaFunctions});return this.createTrail({name:$.name,s3BucketName:$.s3BucketName,s3KeyPrefix:"data-events",includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"All",includeManagementEvents:!1,dataResources:J}]})}createAdvancedTrail($){return this.createTrail({name:$.name,s3BucketName:$.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,advancedEventSelectors:$.selectors})}createReadOnlyTrail($){return this.createTrail({name:$.name,s3BucketName:$.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"ReadOnly",includeManagementEvents:!0}]})}createWriteOnlyTrail($){return this.createTrail({name:$.name,s3BucketName:$.s3BucketName,includeGlobalServiceEvents:!0,isMultiRegionTrail:!0,enableLogFileValidation:!0,eventSelectors:[{readWriteType:"WriteOnly",includeManagementEvents:!0}]})}getTrail($){return this.trails.get($)}listTrails(){return Array.from(this.trails.values())}generateTrailCF($){let J={Type:"AWS::CloudTrail::Trail",Properties:{TrailName:$.name,S3BucketName:$.s3BucketName,IsLogging:!0,IncludeGlobalServiceEvents:$.includeGlobalServiceEvents??!0,IsMultiRegionTrail:$.isMultiRegionTrail??!0,EnableLogFileValidation:$.enableLogFileValidation??!0}};if($.s3KeyPrefix)J.Properties.S3KeyPrefix=$.s3KeyPrefix;if($.cloudWatchLogsLogGroupArn)J.Properties.CloudWatchLogsLogGroupArn=$.cloudWatchLogsLogGroupArn;if($.cloudWatchLogsRoleArn)J.Properties.CloudWatchLogsRoleArn=$.cloudWatchLogsRoleArn;if($.snsTopicName)J.Properties.SnsTopicName=$.snsTopicName;if($.kmsKeyId)J.Properties.KMSKeyId=$.kmsKeyId;if($.eventSelectors)J.Properties.EventSelectors=$.eventSelectors.map((Y)=>({ReadWriteType:Y.readWriteType,IncludeManagementEvents:Y.includeManagementEvents??!0,...Y.dataResources&&{DataResources:Y.dataResources.map((Q)=>({Type:Q.type,Values:Q.values}))},...Y.excludeManagementEventSources&&{ExcludeManagementEventSources:Y.excludeManagementEventSources}}));if($.insightSelectors)J.Properties.InsightSelectors=$.insightSelectors.map((Y)=>({InsightType:Y.insightType}));if($.advancedEventSelectors)J.Properties.AdvancedEventSelectors=$.advancedEventSelectors.map((Y)=>({Name:Y.name,FieldSelectors:Y.fieldSelectors.map((Q)=>({Field:Q.field,...Q.equals&&{Equals:Q.equals},...Q.startsWith&&{StartsWith:Q.startsWith},...Q.endsWith&&{EndsWith:Q.endsWith},...Q.notEquals&&{NotEquals:Q.notEquals},...Q.notStartsWith&&{NotStartsWith:Q.notStartsWith},...Q.notEndsWith&&{NotEndsWith:Q.notEndsWith}}))}));return J}generateBucketPolicy($,J){return{Version:"2012-10-17",Statement:[{Sid:"AWSCloudTrailAclCheck",Effect:"Allow",Principal:{Service:"cloudtrail.amazonaws.com"},Action:"s3:GetBucketAcl",Resource:`arn:aws:s3:::${$}`},{Sid:"AWSCloudTrailWrite",Effect:"Allow",Principal:{Service:"cloudtrail.amazonaws.com"},Action:"s3:PutObject",Resource:J.map((Y)=>`arn:aws:s3:::${$}/AWSLogs/${Y}/*`),Condition:{StringEquals:{"s3:x-amz-acl":"bucket-owner-full-control"}}}]}}clear(){this.trails.clear(),this.trailCounter=0}}var p7=new aJ;class nJ{detectors=new Map;threatIntelSets=new Map;ipSets=new Map;filters=new Map;detectorCounter=0;threatIntelCounter=0;ipSetCounter=0;filterCounter=0;createDetector($){let J=`detector-${Date.now()}-${this.detectorCounter++}`,Y={id:J,...$};return this.detectors.set(J,Y),Y}createComprehensiveDetector(){return this.createDetector({enable:!0,findingPublishingFrequency:"FIFTEEN_MINUTES",dataSources:{s3Logs:{enable:!0},kubernetes:{auditLogs:{enable:!0}},malwareProtection:{scanEc2InstanceWithFindings:{ebsVolumes:{enable:!0}}}},features:[{name:"S3_DATA_EVENTS",status:"ENABLED"},{name:"EKS_AUDIT_LOGS",status:"ENABLED"},{name:"EBS_MALWARE_PROTECTION",status:"ENABLED"},{name:"RDS_LOGIN_EVENTS",status:"ENABLED"},{name:"LAMBDA_NETWORK_LOGS",status:"ENABLED"}]})}createBasicDetector(){return this.createDetector({enable:!0,findingPublishingFrequency:"SIX_HOURS"})}createThreatIntelSet($){let J=`threat-intel-${Date.now()}-${this.threatIntelCounter++}`,Y={id:J,...$};return this.threatIntelSets.set(J,Y),Y}createIPSet($){let J=`ip-set-${Date.now()}-${this.ipSetCounter++}`,Y={id:J,...$};return this.ipSets.set(J,Y),Y}createFindingFilter($){let J=`filter-${Date.now()}-${this.filterCounter++}`,Y={id:J,...$};return this.filters.set(J,Y),Y}createLowSeverityArchiveFilter($){return this.createFindingFilter({detectorId:$,name:"archive-low-severity",description:"Automatically archive low severity findings",action:"ARCHIVE",rank:1,findingCriteria:{criterion:{severity:{lt:4}}}})}createFindingTypeFilter($,J,Y){return this.createFindingFilter({detectorId:$,name:`filter-finding-types-${Y.toLowerCase()}`,description:`${Y==="ARCHIVE"?"Archive":"Keep"} specific finding types`,action:Y,rank:2,findingCriteria:{criterion:{type:{eq:J}}}})}createTrustedIPFilter($,J){return this.createFindingFilter({detectorId:$,name:"trusted-ip-addresses",description:"Archive findings from trusted IP addresses",action:"ARCHIVE",rank:3,findingCriteria:{criterion:{"resource.instanceDetails.networkInterfaces.privateIpAddress":{eq:J}}}})}getDetector($){return this.detectors.get($)}listDetectors(){return Array.from(this.detectors.values())}getThreatIntelSet($){return this.threatIntelSets.get($)}listThreatIntelSets(){return Array.from(this.threatIntelSets.values())}getIPSet($){return this.ipSets.get($)}listIPSets(){return Array.from(this.ipSets.values())}getFindingFilter($){return this.filters.get($)}listFindingFilters(){return Array.from(this.filters.values())}generateDetectorCF($){let J={Type:"AWS::GuardDuty::Detector",Properties:{Enable:$.enable}};if($.findingPublishingFrequency)J.Properties.FindingPublishingFrequency=$.findingPublishingFrequency;if($.dataSources){if(J.Properties.DataSources={},$.dataSources.s3Logs)J.Properties.DataSources.S3Logs={Enable:$.dataSources.s3Logs.enable};if($.dataSources.kubernetes)J.Properties.DataSources.Kubernetes={AuditLogs:{Enable:$.dataSources.kubernetes.auditLogs.enable}};if($.dataSources.malwareProtection)J.Properties.DataSources.MalwareProtection={ScanEc2InstanceWithFindings:{EbsVolumes:{Enable:$.dataSources.malwareProtection.scanEc2InstanceWithFindings.ebsVolumes.enable}}}}if($.features)J.Properties.Features=$.features.map((Y)=>({Name:Y.name,Status:Y.status,...Y.additionalConfiguration&&{AdditionalConfiguration:Y.additionalConfiguration}}));return J}generateThreatIntelSetCF($){return{Type:"AWS::GuardDuty::ThreatIntelSet",Properties:{DetectorId:$.detectorId,Name:$.name,Format:$.format,Location:$.location,Activate:$.activate}}}generateIPSetCF($){return{Type:"AWS::GuardDuty::IPSet",Properties:{DetectorId:$.detectorId,Name:$.name,Format:$.format,Location:$.location,Activate:$.activate}}}generateFilterCF($){return{Type:"AWS::GuardDuty::Filter",Properties:{DetectorId:$.detectorId,Name:$.name,Description:$.description,Action:$.action,Rank:$.rank,FindingCriteria:{Criterion:$.findingCriteria.criterion}}}}clear(){this.detectors.clear(),this.threatIntelSets.clear(),this.ipSets.clear(),this.filters.clear(),this.detectorCounter=0,this.threatIntelCounter=0,this.ipSetCounter=0,this.filterCounter=0}}var r7=new nJ;class S0{hubs=new Map;hubCounter=0;ruleCounter=0;static Standards={AWS_FOUNDATIONAL_SECURITY:{arn:"arn:aws:securityhub:::ruleset/aws-foundational-security-best-practices/v/1.0.0",name:"AWS Foundational Security Best Practices",description:"AWS recommended security best practices"},CIS_AWS_FOUNDATIONS_1_2:{arn:"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0",name:"CIS AWS Foundations Benchmark v1.2.0",description:"CIS AWS Foundations Benchmark v1.2.0"},CIS_AWS_FOUNDATIONS_1_4:{arn:"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.4.0",name:"CIS AWS Foundations Benchmark v1.4.0",description:"CIS AWS Foundations Benchmark v1.4.0"},PCI_DSS:{arn:"arn:aws:securityhub:us-east-1::standards/pci-dss/v/3.2.1",name:"PCI DSS v3.2.1",description:"Payment Card Industry Data Security Standard"},NIST_800_53:{arn:"arn:aws:securityhub:us-east-1::standards/nist-800-53/v/5.0.0",name:"NIST SP 800-53 Rev. 5",description:"NIST Special Publication 800-53 Revision 5"}};createHub($){let J=`hub-${Date.now()}-${this.hubCounter++}`,Y={id:J,...$};return this.hubs.set(J,Y),Y}createComprehensiveHub(){return this.createHub({enable:!0,controlFindingGenerator:"SECURITY_CONTROL",enableDefaultStandards:!0,standards:[{id:"aws-foundational",...S0.Standards.AWS_FOUNDATIONAL_SECURITY,enabled:!0},{id:"cis-1-4",...S0.Standards.CIS_AWS_FOUNDATIONS_1_4,enabled:!0},{id:"pci-dss",...S0.Standards.PCI_DSS,enabled:!0}]})}createBasicHub(){return this.createHub({enable:!0,controlFindingGenerator:"STANDARD_CONTROL",enableDefaultStandards:!0,standards:[{id:"aws-foundational",...S0.Standards.AWS_FOUNDATIONAL_SECURITY,enabled:!0}]})}createLowSeveritySuppressionRule(){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Suppress Low Severity Informational Findings",description:"Automatically suppress informational findings",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"SUPPRESSED"},note:{text:"Automatically suppressed low severity finding",updatedBy:"SecurityHub Automation"}}}],criteria:{severityLabel:[{value:"INFORMATIONAL",comparison:"EQUALS"}],recordState:[{value:"ACTIVE",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:1}}createResourceTypeNotificationRule($){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Notify on Critical Resource Findings",description:"Set findings for critical resources to NOTIFIED status",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"NOTIFIED"},note:{text:"Critical resource finding requires attention",updatedBy:"SecurityHub Automation"}}}],criteria:{resourceType:$.map((J)=>({value:J,comparison:"EQUALS"})),severityLabel:[{value:"HIGH",comparison:"EQUALS"},{value:"CRITICAL",comparison:"EQUALS"}],workflowStatus:[{value:"NEW",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:2}}createComplianceFailureRule(){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:"Flag Compliance Failures",description:"Increase severity for compliance failures",actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{severity:{label:"HIGH"},workflow:{status:"NOTIFIED"},note:{text:"Compliance failure detected - requires immediate attention",updatedBy:"SecurityHub Automation"}}}],criteria:{complianceStatus:[{value:"FAILED",comparison:"EQUALS"}],recordState:[{value:"ACTIVE",comparison:"EQUALS"}]},ruleStatus:"ENABLED",ruleOrder:3}}createFalsePositiveSuppressionRule($,J){return{id:`rule-${Date.now()}-${this.ruleCounter++}`,ruleName:`Suppress False Positives - ${$}`,description:`Automatically suppress known false positives from ${$}`,actions:[{type:"FINDING_FIELDS_UPDATE",findingFieldsUpdate:{workflow:{status:"SUPPRESSED"},note:{text:"Known false positive - automatically suppressed",updatedBy:"SecurityHub Automation"}}}],criteria:{productName:[{value:$,comparison:"EQUALS"}],title:J.map((Y)=>({value:Y,comparison:"PREFIX"}))},ruleStatus:"ENABLED",ruleOrder:10}}getHub($){return this.hubs.get($)}listHubs(){return Array.from(this.hubs.values())}generateHubCF($){let J={Type:"AWS::SecurityHub::Hub",Properties:{}};if($.controlFindingGenerator)J.Properties.ControlFindingGenerator=$.controlFindingGenerator;if($.enableDefaultStandards!==void 0)J.Properties.EnableDefaultStandards=$.enableDefaultStandards;return J}generateStandardCF($){let J={Type:"AWS::SecurityHub::Standard",Properties:{StandardsArn:$.arn}};if($.disabledControls&&$.disabledControls.length>0)J.Properties.DisabledStandardsControls=$.disabledControls.map((Y)=>({StandardsControlArn:Y,Reason:"Disabled by configuration"}));return J}generateAutomationRuleCF($){return{Type:"AWS::SecurityHub::AutomationRule",Properties:{RuleName:$.ruleName,Description:$.description,Actions:$.actions.map((J)=>({Type:J.type,FindingFieldsUpdate:J.findingFieldsUpdate})),Criteria:$.criteria,RuleStatus:$.ruleStatus,RuleOrder:$.ruleOrder}}}clear(){this.hubs.clear(),this.hubCounter=0,this.ruleCounter=0}}var a7=new S0;class sJ{deployments=new Map;deploymentHistory=new Map;deploymentCounter=0;resultCounter=0;createDeployment($){let J=`bg-deployment-${Date.now()}-${this.deploymentCounter++}`,Y={id:J,...$};return this.deployments.set(J,Y),Y}createALBDeployment($){return this.createDeployment({name:$.name,blueEnvironment:{name:"blue",targetGroupArn:$.blueTargetGroupArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:$.greenTargetGroupArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"alb",listenerArn:$.listenerArn,switchoverTimeSeconds:0},autoPromote:$.autoPromote,healthCheckConfig:$.healthCheckConfig})}createRoute53Deployment($){return this.createDeployment({name:$.name,blueEnvironment:{name:"blue",targetGroupArn:$.blueTargetGroupArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:$.greenTargetGroupArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"route53",hostedZoneId:$.hostedZoneId,switchoverTimeSeconds:$.switchoverTimeSeconds||60}})}createECSDeployment($){return this.createDeployment({name:$.name,blueEnvironment:{name:"blue",targetGroupArn:$.blueTargetGroupArn,taskDefinitionArn:$.blueTaskDefinitionArn,weight:100},greenEnvironment:{name:"green",targetGroupArn:$.greenTargetGroupArn,taskDefinitionArn:$.greenTaskDefinitionArn,weight:0},activeEnvironment:"blue",routingConfig:{type:"alb",listenerArn:$.listenerArn},autoRollback:$.autoRollback??!0})}async executeDeployment($,J=!1){let Y=this.deployments.get($);if(!Y)throw Error(`Deployment not found: ${$}`);let Q={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,healthChecksPassed:!1,errors:[]};console.log(`${J?"[DRY RUN] ":""}Starting blue/green deployment: ${Y.name}`),console.log(` Active environment: ${Y.activeEnvironment}`),console.log(` Routing type: ${Y.routingConfig.type}`);let W=Y.activeEnvironment==="blue"?"green":"blue";if(console.log(` Switching to: ${W}`),console.log(`\\n1. Deploying to ${W} environment`),!J)await new Promise((U)=>setTimeout(U,100));if(console.log(`\\n2. Running health checks on ${W} environment`),Y.healthCheckConfig){let U=await this.runHealthChecks(Y,W,J);if(Q.healthChecksPassed=U,!U){if(Q.errors?.push("Health checks failed"),Q.endTime=new Date,Y.autoRollback)console.log(" Auto-rollback enabled - keeping current environment active"),Q.rolledBackAt=new Date;return this.recordDeployment($,Q),Q}}else Q.healthChecksPassed=!0;if(console.log(`\\n3. Switching traffic to ${W} environment`),!J)Y.activeEnvironment=W,Q.switchedAt=new Date;if(console.log(`\\n4. Monitoring ${W} environment`),!J)await new Promise((U)=>setTimeout(U,100));return Q.success=!0,Q.endTime=new Date,console.log("\\n✓ Deployment completed successfully"),this.recordDeployment($,Q),Q}async rollback($){let J=this.deployments.get($);if(!J)throw Error(`Deployment not found: ${$}`);let Y={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,healthChecksPassed:!0,errors:[]};console.log(`Rolling back deployment: ${J.name}`);let Q=J.activeEnvironment==="blue"?"green":"blue";return J.activeEnvironment=Q,Y.success=!0,Y.rolledBackAt=new Date,Y.endTime=new Date,console.log(` Switched back to: ${Q}`),this.recordDeployment($,Y),Y}async runHealthChecks($,J,Y){let Q=$.healthCheckConfig;if(console.log(` Health check path: ${Q.path||"/"}`),console.log(` Healthy threshold: ${Q.healthyThreshold}`),console.log(` Interval: ${Q.interval}s`),Y)return console.log(" [SKIPPED - DRY RUN]"),!0;let W=0,U=Q.healthyThreshold+2;for(let Z=0;Z<U;Z++)if(await new Promise((H)=>setTimeout(H,50)),Math.random()>0.1){if(W++,console.log(` Check ${Z+1}: ✓ Healthy (${W}/${Q.healthyThreshold})`),W>=Q.healthyThreshold)return!0}else W=0,console.log(` Check ${Z+1}: ✗ Unhealthy`);return!1}recordDeployment($,J){if(!this.deploymentHistory.has($))this.deploymentHistory.set($,[]);this.deploymentHistory.get($).push(J)}getDeployment($){return this.deployments.get($)}listDeployments(){return Array.from(this.deployments.values())}getDeploymentHistory($){return this.deploymentHistory.get($)||[]}generateALBListenerCF($){let J=$.activeEnvironment==="blue"?$.blueEnvironment:$.greenEnvironment;return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:$.routingConfig.listenerArn,Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",TargetGroupArn:J.targetGroupArn}]}}}generateRoute53RecordSetCF($,J){return[{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:$.routingConfig.hostedZoneId,Name:J,Type:"A",SetIdentifier:"blue",Weight:$.activeEnvironment==="blue"?100:0,AliasTarget:{HostedZoneId:$.routingConfig.hostedZoneId,DNSName:$.blueEnvironment.targetGroupArn,EvaluateTargetHealth:!0}}},{Type:"AWS::Route53::RecordSet",Properties:{HostedZoneId:$.routingConfig.hostedZoneId,Name:J,Type:"A",SetIdentifier:"green",Weight:$.activeEnvironment==="green"?100:0,AliasTarget:{HostedZoneId:$.routingConfig.hostedZoneId,DNSName:$.greenEnvironment.targetGroupArn,EvaluateTargetHealth:!0}}}]}clear(){this.deployments.clear(),this.deploymentHistory.clear(),this.deploymentCounter=0,this.resultCounter=0}}var n7=new sJ;class i0{deployments=new Map;deploymentHistory=new Map;deploymentCounter=0;resultCounter=0;static Strategies={CONSERVATIVE:[{name:"Initial Canary",trafficPercentage:10,durationMinutes:10},{name:"Quarter Traffic",trafficPercentage:25,durationMinutes:10},{name:"Half Traffic",trafficPercentage:50,durationMinutes:15},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],BALANCED:[{name:"Initial Canary",trafficPercentage:20,durationMinutes:5},{name:"Half Traffic",trafficPercentage:50,durationMinutes:10},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],AGGRESSIVE:[{name:"Half Traffic",trafficPercentage:50,durationMinutes:5},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}],LINEAR_10:[{name:"Canary 10%",trafficPercentage:10,durationMinutes:5},{name:"Canary 20%",trafficPercentage:20,durationMinutes:5},{name:"Canary 30%",trafficPercentage:30,durationMinutes:5},{name:"Canary 40%",trafficPercentage:40,durationMinutes:5},{name:"Canary 50%",trafficPercentage:50,durationMinutes:5},{name:"Canary 60%",trafficPercentage:60,durationMinutes:5},{name:"Canary 70%",trafficPercentage:70,durationMinutes:5},{name:"Canary 80%",trafficPercentage:80,durationMinutes:5},{name:"Canary 90%",trafficPercentage:90,durationMinutes:5},{name:"Full Traffic",trafficPercentage:100,durationMinutes:5}]};createDeployment($){let J=`canary-${Date.now()}-${this.deploymentCounter++}`,Y={id:J,...$};return this.deployments.set(J,Y),Y}createLambdaCanaryDeployment($){let J=$.strategy||"BALANCED",Y=i0.Strategies[J].map((Q)=>({...Q,alarmThresholds:{errorRate:$.errorRateThreshold||1,latencyP99:$.latencyThreshold||1000}}));return this.createDeployment({name:$.name,baselineVersion:{version:"baseline",functionVersionArn:$.baselineVersionArn,weight:100},canaryVersion:{version:"canary",functionVersionArn:$.canaryVersionArn,weight:0},stages:Y,currentStage:0,status:"pending",autoPromote:$.autoPromote??!0,autoRollback:!0})}createECSCanaryDeployment($){let J=$.strategy||"CONSERVATIVE",Y=i0.Strategies[J];return this.createDeployment({name:$.name,baselineVersion:{version:"baseline",taskDefinitionArn:$.baselineTaskDefinitionArn,targetGroupArn:$.baselineTargetGroupArn,weight:100},canaryVersion:{version:"canary",taskDefinitionArn:$.canaryTaskDefinitionArn,targetGroupArn:$.canaryTargetGroupArn,weight:0},stages:Y,currentStage:0,status:"pending",autoRollback:!0})}async executeDeployment($,J=!1){let Y=this.deployments.get($);if(!Y)throw Error(`Deployment not found: ${$}`);let Q={success:!1,deploymentId:`result-${Date.now()}-${this.resultCounter++}`,startTime:new Date,completedStages:0,rolledBack:!1};console.log(`${J?"[DRY RUN] ":""}Starting canary deployment: ${Y.name}`),console.log(` Strategy: ${Y.stages.length} stages`),console.log(` Auto-promote: ${Y.autoPromote}`),console.log(` Auto-rollback: ${Y.autoRollback}`),console.log(""),Y.status="in_progress";for(let W=0;W<Y.stages.length;W++){let U=Y.stages[W];if(Y.currentStage=W,console.log(`Stage ${W+1}/${Y.stages.length}: ${U.name}`),console.log(` Traffic: ${U.trafficPercentage}% canary, ${100-U.trafficPercentage}% baseline`),console.log(` Duration: ${U.durationMinutes} minutes`),!J)Y.baselineVersion.weight=100-U.trafficPercentage,Y.canaryVersion.weight=U.trafficPercentage;if(!await this.monitorStage(Y,U,J)){if(console.log(" ✗ Stage failed - metrics exceeded thresholds"),Y.autoRollback)console.log("\\n Rolling back deployment..."),await this.rollback($,J),Q.rolledBack=!0,Q.reason="Metrics exceeded thresholds";return Q.endTime=new Date,Y.status="rolled_back",this.recordDeployment($,Q),Q}console.log(" ✓ Stage completed successfully"),Q.completedStages++,console.log("")}return Y.status="completed",Q.success=!0,Q.endTime=new Date,console.log("✓ Canary deployment completed successfully"),this.recordDeployment($,Q),Q}async monitorStage($,J,Y){if(console.log(" Monitoring metrics..."),Y)return console.log(" [SKIPPED - DRY RUN]"),!0;await new Promise((W)=>setTimeout(W,100));let Q={baselineErrorRate:Math.random()*0.5,canaryErrorRate:Math.random()*0.8,baselineLatencyP99:200+Math.random()*100,canaryLatencyP99:180+Math.random()*150,baselineRequestCount:Math.floor(Math.random()*1000)+500,canaryRequestCount:Math.floor((Math.random()*1000+500)*J.trafficPercentage/100)};if($.metrics=Q,console.log(` Baseline: ${Q.baselineErrorRate.toFixed(2)}% errors, ${Q.baselineLatencyP99.toFixed(0)}ms P99`),console.log(` Canary: ${Q.canaryErrorRate.toFixed(2)}% errors, ${Q.canaryLatencyP99.toFixed(0)}ms P99`),J.alarmThresholds){let{errorRate:W,latencyP99:U}=J.alarmThresholds;if(W&&Q.canaryErrorRate>W)return console.log(` ⚠ Error rate exceeded threshold: ${Q.canaryErrorRate.toFixed(2)}% > ${W}%`),!1;if(U&&Q.canaryLatencyP99>U)return console.log(` ⚠ Latency P99 exceeded threshold: ${Q.canaryLatencyP99.toFixed(0)}ms > ${U}ms`),!1}return!0}async rollback($,J=!1){let Y=this.deployments.get($);if(!Y)throw Error(`Deployment not found: ${$}`);if(console.log(`${J?"[DRY RUN] ":""}Rolling back canary deployment: ${Y.name}`),!J)Y.baselineVersion.weight=100,Y.canaryVersion.weight=0,Y.status="rolled_back";console.log(" Traffic restored to baseline: 100%")}promoteCanary($){let J=this.deployments.get($);if(!J)throw Error(`Deployment not found: ${$}`);console.log(`Promoting canary to baseline: ${J.name}`);let Y=J.baselineVersion;J.baselineVersion=J.canaryVersion,J.canaryVersion=Y,J.baselineVersion.weight=100,J.canaryVersion.weight=0,J.status="completed",console.log(" Canary promoted successfully")}recordDeployment($,J){if(!this.deploymentHistory.has($))this.deploymentHistory.set($,[]);this.deploymentHistory.get($).push(J)}getDeployment($){return this.deployments.get($)}listDeployments(){return Array.from(this.deployments.values())}getDeploymentHistory($){return this.deploymentHistory.get($)||[]}generateLambdaAliasCF($,J){return{Type:"AWS::Lambda::Alias",Properties:{FunctionName:{Ref:"LambdaFunction"},Name:J,FunctionVersion:$.canaryVersion.version,RoutingConfig:{AdditionalVersionWeights:[{FunctionVersion:$.baselineVersion.version,FunctionWeight:$.baselineVersion.weight/100}]}}}}generateALBListenerRuleCF($){return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:{Ref:"LoadBalancerListener"},Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",ForwardConfig:{TargetGroups:[{TargetGroupArn:$.baselineVersion.targetGroupArn,Weight:$.baselineVersion.weight},{TargetGroupArn:$.canaryVersion.targetGroupArn,Weight:$.canaryVersion.weight}],TargetGroupStickinessConfig:{Enabled:!1}}}]}}}clear(){this.deployments.clear(),this.deploymentHistory.clear(),this.deploymentCounter=0,this.resultCounter=0}}var s7=new i0;class iJ{tests=new Map;testCounter=0;createTest($){let J=`abtest-${Date.now()}-${this.testCounter++}`,Y={id:J,...$};return this.tests.set(J,Y),Y}createSimpleABTest($){let J=$.variantTrafficPercentage||50;return this.createTest({name:$.name,description:$.description,variants:[{id:"control",name:"Control",description:"Original version",trafficPercentage:100-J,targetGroupArn:$.controlTargetGroupArn,weight:100-J},{id:"variant-a",name:"Variant A",description:"Test version",trafficPercentage:J,targetGroupArn:$.variantTargetGroupArn,weight:J}],routingStrategy:{type:$.stickySession?"cookie":"random",cookieName:$.stickySession?"ab_variant":void 0,stickySession:$.stickySession??!1,sessionDuration:1440},startTime:new Date,status:"draft"})}createMultivariateTest($){let J=$.variants.reduce((Y,Q)=>Y+Q.trafficPercentage,0);if(J!==100)throw Error(`Traffic percentages must sum to 100, got ${J}`);return this.createTest({name:$.name,description:$.description,variants:$.variants.map((Y,Q)=>({id:`variant-${Q}`,name:Y.name,description:Y.description,trafficPercentage:Y.trafficPercentage,targetGroupArn:Y.targetGroupArn,weight:Y.trafficPercentage})),routingStrategy:$.routingStrategy||{type:"random",stickySession:!1},startTime:new Date,status:"draft"})}createHeaderBasedTest($){return this.createTest({name:$.name,description:`Route based on ${$.headerName} header`,variants:[{id:"control",name:"Control",trafficPercentage:50,targetGroupArn:$.controlTargetGroupArn,weight:50},{id:"variant-a",name:"Variant A",trafficPercentage:50,targetGroupArn:$.variantTargetGroupArn,weight:50}],routingStrategy:{type:"header",headerName:$.headerName,stickySession:!1},startTime:new Date,status:"draft"})}createGeoBasedTest($){return this.createTest({name:$.name,description:"Route based on geographic location",variants:[{id:"control",name:"Control (Rest of World)",trafficPercentage:50,targetGroupArn:$.controlTargetGroupArn,weight:50},{id:"variant-a",name:`Variant A (${$.regions.join(", ")})`,trafficPercentage:50,targetGroupArn:$.variantTargetGroupArn,weight:50}],routingStrategy:{type:"geo",stickySession:!0,sessionDuration:1440},startTime:new Date,status:"draft"})}startTest($){let J=this.tests.get($);if(!J)throw Error(`Test not found: ${$}`);if(J.status!=="draft"&&J.status!=="paused")throw Error(`Cannot start test in ${J.status} status`);J.status="active",J.startTime=new Date,console.log(`Started A/B test: ${J.name}`),console.log(` Variants: ${J.variants.length}`),J.variants.forEach((Y)=>{console.log(` - ${Y.name}: ${Y.trafficPercentage}%`)})}pauseTest($){let J=this.tests.get($);if(!J)throw Error(`Test not found: ${$}`);J.status="paused",console.log(`Paused A/B test: ${J.name}`)}updateTrafficSplit($,J,Y){let Q=this.tests.get($);if(!Q)throw Error(`Test not found: ${$}`);let W=Q.variants.find((Z)=>Z.id===J);if(!W)throw Error(`Variant not found: ${J}`);let U=W.trafficPercentage;W.trafficPercentage=Y,W.weight=Y,console.log(`Updated ${W.name} traffic: ${U}% → ${Y}%`)}analyzeResults($){let J=this.tests.get($);if(!J)throw Error(`Test not found: ${$}`);if(!J.metrics)J.metrics=this.collectMetrics(J);let Y=J.variants[0],Q=0;for(let K of J.variants){let B=J.metrics.variants[K.id];if(B&&B.conversionRate>Q)Q=B.conversionRate,Y=K}let W=J.metrics.variants.control||J.metrics.variants[J.variants[0].id],U=J.metrics.variants[Y.id],Z=(U.conversionRate-W.conversionRate)/W.conversionRate*100,z=100,H=U.requests>z&&W.requests>z&&Math.abs(Z)>10;return{testId:$,winningVariant:Y.name,confidence:H?95:75,improvement:Z,statisticalSignificance:H,metrics:J.metrics,recommendation:this.generateRecommendation(Z,H,Y.name)}}declareWinner($,J){let Y=this.tests.get($);if(!Y)throw Error(`Test not found: ${$}`);let Q=Y.variants.find((W)=>W.id===J);if(!Q)throw Error(`Variant not found: ${J}`);Y.variants.forEach((W)=>{if(W.id===J)W.trafficPercentage=100,W.weight=100;else W.trafficPercentage=0,W.weight=0}),Y.status="completed",Y.endTime=new Date,Y.winner=J,console.log(`Declared winner: ${Q.name}`),console.log(` All traffic now routed to ${Q.name}`)}collectMetrics($){let J={},Y=0;for(let Q of $.variants){let W=Math.floor(Math.random()*1000)+500,U=Math.floor(W*(Math.random()*0.1+0.05)),Z=U/W*100;J[Q.id]={requests:W,conversions:U,conversionRate:Z,averageLatency:150+Math.random()*100,errorRate:Math.random()*0.5,revenue:U*(Math.random()*50+100)},Y+=W}return{variants:J,totalRequests:Y,startTime:$.startTime,lastUpdated:new Date}}generateRecommendation($,J,Y){if(!J)return"Continue test - sample size too small or no significant difference detected";if($>20)return`Strong winner detected - ${Y} shows ${$.toFixed(1)}% improvement. Recommend deploying to all traffic.`;if($>10)return`Moderate improvement - ${Y} shows ${$.toFixed(1)}% improvement. Consider deploying.`;if($>0)return`Minor improvement - ${Y} shows ${$.toFixed(1)}% improvement. May not be worth the complexity.`;return"No improvement detected - consider reverting to control variant"}getTest($){return this.tests.get($)}listTests(){return Array.from(this.tests.values())}generateALBListenerRuleCF($){return{Type:"AWS::ElasticLoadBalancingV2::ListenerRule",Properties:{ListenerArn:{Ref:"LoadBalancerListener"},Priority:1,Conditions:[{Field:"path-pattern",Values:["/*"]}],Actions:[{Type:"forward",ForwardConfig:{TargetGroups:$.variants.map((J)=>({TargetGroupArn:J.targetGroupArn,Weight:J.weight})),TargetGroupStickinessConfig:{Enabled:$.routingStrategy.stickySession||!1,DurationSeconds:$.routingStrategy.sessionDuration?$.routingStrategy.sessionDuration*60:void 0}}}]}}}generateLambdaEdgeFunction($){return`'use strict';
|
|
866
866
|
|
|
867
|
-
exports.handler = (event,
|
|
867
|
+
exports.handler = (event, _context, _callback) => {
|
|
868
868
|
const request = event.Records[0].cf.request;
|
|
869
869
|
const headers = request.headers;
|
|
870
870
|
|
|
@@ -884,7 +884,7 @@ exports.handler = (event, context, callback) => {
|
|
|
884
884
|
// Assign variant if not already assigned
|
|
885
885
|
if (!variant) {
|
|
886
886
|
const random = Math.random() * 100;
|
|
887
|
-
|
|
887
|
+
const _cumulative = 0;
|
|
888
888
|
|
|
889
889
|
${$.variants.map((J,Y)=>{return`if (random < ${J.trafficPercentage+(Y>0?$.variants.slice(0,Y).reduce((Q,W)=>Q+W.trafficPercentage,0):0)}) {
|
|
890
890
|
variant = '${J.id}';
|
|
@@ -892,7 +892,7 @@ exports.handler = (event, context, callback) => {
|
|
|
892
892
|
}
|
|
893
893
|
|
|
894
894
|
// Set variant cookie
|
|
895
|
-
const
|
|
895
|
+
const _response = {
|
|
896
896
|
status: '200',
|
|
897
897
|
statusDescription: 'OK',
|
|
898
898
|
headers: {
|
|
@@ -945,7 +945,7 @@ const log = require('SyntheticsLogger');
|
|
|
945
945
|
|
|
946
946
|
const apiCheck = async function () {
|
|
947
947
|
const page = await synthetics.getPage();
|
|
948
|
-
let
|
|
948
|
+
let _response;
|
|
949
949
|
|
|
950
950
|
${$.endpoints.map((Q,W)=>`
|
|
951
951
|
// Endpoint ${W+1}: ${Q.method} ${Q.path}
|
|
@@ -1130,7 +1130,7 @@ exports.handler = async (event) => {
|
|
|
1130
1130
|
};
|
|
1131
1131
|
`.trim()}generateMessageHandlerCode(){return`
|
|
1132
1132
|
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
|
|
1133
|
-
const { DynamoDBDocumentClient, PutCommand, DeleteCommand, QueryCommand
|
|
1133
|
+
const { DynamoDBDocumentClient, PutCommand, DeleteCommand, QueryCommand } = require('@aws-sdk/lib-dynamodb');
|
|
1134
1134
|
const { ApiGatewayManagementApiClient, PostToConnectionCommand } = require('@aws-sdk/client-apigatewaymanagementapi');
|
|
1135
1135
|
|
|
1136
1136
|
const dynamoClient = new DynamoDBClient({});
|
|
@@ -1447,7 +1447,7 @@ Add this team member?`,!0)){G("Operation cancelled");return}let U=new M("Creatin
|
|
|
1447
1447
|
Team member added!`),G("An invitation email has been sent with access credentials"),G(`
|
|
1448
1448
|
Access Details:`),G(` - Email: ${J}`),G(` - Role: ${Y}`),G(" - Status: Pending")}),$.command("team:list","List team members").action(async()=>{V("Team Members");let J=new M("Fetching team members...");J.start(),await new Promise((Y)=>setTimeout(Y,1500)),J.stop(),b(["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"]]),G("\nTip: Use `cloud team:add` to add new team members"),G("Tip: Use `cloud team:remove` to remove team members")}),$.command("team:remove <email>","Remove team member").action(async(J)=>{if(V("Removing Team Member"),G(`Email: ${J}`),N(`
|
|
1449
1449
|
This will revoke all access for this team member`),!await P("Remove this team member?",!1)){G("Operation cancelled");return}let Q=new M("Removing IAM user and access...");Q.start(),await new Promise((W)=>setTimeout(W,2000)),Q.succeed("Team member removed successfully"),A(`
|
|
1450
|
-
Team member removed!`),G("All access credentials have been revoked")})}import{existsSync as E0,copyFileSync as t0,readFileSync as bW}from"node:fs";G0();V0();M0();W$();class A6{client;region;constructor($="us-east-1",J){this.region=$,this.client=new l}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}}}W$();class R6{client;region;constructor($="us-east-1",J){this.region=$,this.client=new l}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 W=0;W<Y;W++){let Z=(await this.describeServices({cluster:$,services:[J]})).services?.[0];if(Z){let z=Z.deployments?.find((H)=>H.status==="PRIMARY");if(z&&z.runningCount===z.desiredCount&&Z.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})}}C6();import{existsSync as AW,readdirSync as RW,readFileSync as SW,statSync as DW}from"node:fs";import{join as PW,relative as CW,extname as NW}from"node:path";var kW=[{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"}],IW=[".js",".jsx",".ts",".tsx",".mjs",".cjs",".vue",".svelte",".html",".htm",".css",".scss",".less",".json",".yaml",".yml",".toml",".xml",".env",".config",".conf"],xW=["node_modules",".git",".svn",".hg","dist","build","coverage",".nyc_output","__pycache__",".pytest_cache","vendor",".idea",".vscode",".turbo",".next",".nuxt"],hW=["package-lock.json","yarn.lock","pnpm-lock.yaml","bun.lockb","*.min.js","*.min.css","*.map"];class k6{patterns;excludeDirs;excludeFiles;maxFileSize;constructor($){this.patterns=[...kW,...$?.customPatterns||[]],this.excludeDirs=[...xW,...$?.excludeDirs||[]],this.excludeFiles=[...hW,...$?.excludeFiles||[]],this.maxFileSize=$?.maxFileSize||1048576}async scan($){let J=Date.now(),Y=[],Q=0,{directory:W,exclude:U=[],include:Z,skipPatterns:z=[]}=$,H=$.failOnSeverity||"critical";if(!AW(W))throw Error(`Directory not found: ${W}`);let K=this.getFilesToScan(W,[...this.excludeDirs,...U],Z);for(let q of K){let E=CW(W,q);if(this.shouldExcludeFile(E))continue;try{if(DW(q).size>this.maxFileSize)continue;let T=SW(q,"utf-8"),w=this.scanContent(T,E,z);Y.push(...w),Q++}catch{continue}}let B={critical:Y.filter((q)=>q.pattern.severity==="critical").length,high:Y.filter((q)=>q.pattern.severity==="high").length,medium:Y.filter((q)=>q.pattern.severity==="medium").length,low:Y.filter((q)=>q.pattern.severity==="low").length},O=["low","medium","high","critical"],X=O.indexOf(H),j=!0;for(let q=X;q<O.length;q++)if(B[O[q]]>0){j=!1;break}return{passed:j,findings:Y,scannedFiles:Q,duration:Date.now()-J,summary:B}}scanContent($,J,Y){let Q=[],W=$.split(`
|
|
1450
|
+
Team member removed!`),G("All access credentials have been revoked")})}import{existsSync as E0,copyFileSync as t0,readFileSync as bW}from"node:fs";G0();V0();M0();W$();class A6{client;region;constructor($="us-east-1",J){this.region=$,this.client=new l}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}}}W$();class R6{client;region;constructor($="us-east-1",J){this.region=$,this.client=new l}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 W=0;W<Y;W++){let Z=(await this.describeServices({cluster:$,services:[J]})).services?.[0];if(Z){let z=Z.deployments?.find((H)=>H.status==="PRIMARY");if(z&&z.runningCount===z.desiredCount&&Z.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})}}C6();import{existsSync as AW,readdirSync as RW,readFileSync as SW,statSync as DW}from"node:fs";import{join as PW,relative as CW,extname as NW}from"node:path";var kW=[{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"}],IW=[".js",".jsx",".ts",".tsx",".mjs",".cjs",".vue",".svelte",".html",".htm",".css",".scss",".less",".json",".yaml",".yml",".toml",".xml",".env",".config",".conf"],xW=["node_modules",".git",".svn",".hg","dist","build","coverage",".nyc_output","__pycache__",".pytest_cache","vendor",".idea",".vscode",".turbo",".next",".nuxt"],hW=["package-lock.json","yarn.lock","pnpm-lock.yaml","bun.lockb","*.min.js","*.min.css","*.map"];class k6{patterns;excludeDirs;excludeFiles;maxFileSize;constructor($){this.patterns=[...kW,...$?.customPatterns||[]],this.excludeDirs=[...xW,...$?.excludeDirs||[]],this.excludeFiles=[...hW,...$?.excludeFiles||[]],this.maxFileSize=$?.maxFileSize||1048576}async scan($){let J=Date.now(),Y=[],Q=0,{directory:W,exclude:U=[],include:Z,skipPatterns:z=[]}=$,H=$.failOnSeverity||"critical";if(!AW(W))throw Error(`Directory not found: ${W}`);let K=this.getFilesToScan(W,[...this.excludeDirs,...U],Z);for(let q of K){let E=CW(W,q);if(this.shouldExcludeFile(E))continue;try{if(DW(q).size>this.maxFileSize)continue;let T=SW(q,"utf-8"),w=this.scanContent(T,E,z);Y.push(...w),Q++}catch{continue}}let B={critical:Y.filter((q)=>q.pattern.severity==="critical").length,high:Y.filter((q)=>q.pattern.severity==="high").length,medium:Y.filter((q)=>q.pattern.severity==="medium").length,low:Y.filter((q)=>q.pattern.severity==="low").length},O=["low","medium","high","critical"],X=O.indexOf(H),j=!0;for(let q=X;q<O.length;q++)if(B[O[q]]>0){j=!1;break}return{passed:j,findings:Y,scannedFiles:Q,duration:Date.now()-J,summary:B}}scanContent($,J,Y){let Q=[],W=$.split(`
|
|
1451
1451
|
`);for(let U of this.patterns){if(Y.includes(U.name))continue;U.pattern.lastIndex=0;let Z;while((Z=U.pattern.exec($))!==null){let z=$.substring(0,Z.index),H=z.split(`
|
|
1452
1452
|
`).length,K=z.lastIndexOf(`
|
|
1453
1453
|
`),B=Z.index-K,O=W[H-1]||"";if(this.isLikelyPlaceholder(Z[0],O))continue;Q.push({file:J,line:H,column:B,match:this.maskSecret(Z[0]),pattern:U,context:this.maskSecret(O.trim())})}}return Q}isLikelyPlaceholder($,J){let Y=["example","placeholder","your_","YOUR_","xxx","XXX","***","test","TEST","dummy","DUMMY","fake","FAKE","sample","SAMPLE","<your","${","{{","process.env","import.meta.env","CHANGEME","TODO","FIXME"],Q=$.toLowerCase(),W=J.toLowerCase();for(let Z of Y)if(Q.includes(Z.toLowerCase())||W.includes(Z.toLowerCase()))return!0;let U=J.trim();if(U.startsWith("//")||U.startsWith("#")||U.startsWith("*")||U.startsWith("/*")){if(W.includes("example")||W.includes("format:")||W.includes("e.g."))return!0}return!1}maskSecret($){if($.length<=8)return"*".repeat($.length);let J=Math.min(4,Math.floor($.length*0.2));return $.substring(0,J)+"*".repeat($.length-J*2)+$.substring($.length-J)}getFilesToScan($,J,Y){let Q=[],W=Y||IW,U=(Z)=>{let z=RW(Z,{withFileTypes:!0});for(let H of z){let K=PW(Z,H.name);if(H.isDirectory()){if(!J.includes(H.name))U(K)}else if(H.isFile()){let B=NW(H.name).toLowerCase();if(W.includes(B)||H.name.startsWith(".env")||H.name.endsWith(".config"))Q.push(K)}}};return U($),Q}shouldExcludeFile($){let J=$.split("/").pop()||"";for(let Y of this.excludeFiles)if(Y.startsWith("*")){let Q=Y.substring(1);if(J.endsWith(Q))return!0}else if(J===Y)return!0;return!1}addPattern($){this.patterns.push($)}getPatterns(){return[...this.patterns]}}async function c1($){let J=new k6;r("Running pre-deployment security scan...");let Y=await J.scan({directory:$.sourceDir,failOnSeverity:$.failOnSeverity||"critical",skipPatterns:$.skipPatterns});return{passed:Y.passed,result:Y}}function l1($){let{summary:J,findings:Y,scannedFiles:Q,duration:W}=$;if(G(`
|
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TemplateBuilder, } from '
|
|
2
|
-
import type { CloudConfig } from '
|
|
1
|
+
import { TemplateBuilder, } from 'ts-cloud-core';
|
|
2
|
+
import type { CloudConfig } from 'ts-cloud-types';
|
|
3
3
|
export declare interface GenerationOptions {
|
|
4
4
|
config: CloudConfig
|
|
5
5
|
environment: 'production' | 'staging' | 'development'
|
package/dist/index.d.ts
CHANGED
|
@@ -58,7 +58,7 @@ export type {
|
|
|
58
58
|
CloudFrontOriginAccessControl,
|
|
59
59
|
CloudFrontCacheBehavior,
|
|
60
60
|
CloudFrontOrigin,
|
|
61
|
-
} from '
|
|
61
|
+
} from 'ts-cloud-aws-types';
|
|
62
62
|
export * from './config';
|
|
63
63
|
export * from './generators';
|
|
64
64
|
export {
|
|
@@ -136,5 +136,5 @@ export {
|
|
|
136
136
|
createGoDaddyValidator,
|
|
137
137
|
createRoute53Validator,
|
|
138
138
|
} from './dns';
|
|
139
|
-
export * from '
|
|
140
|
-
export * from '
|
|
139
|
+
export * from 'ts-cloud-core';
|
|
140
|
+
export * from 'ts-cloud-types';
|