@stacksjs/ts-cloud 0.7.27 → 0.7.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +6 -6
- package/dist/{chunk-arz8x67j.js → chunk-5m8y0gx1.js} +4 -4
- package/dist/{chunk-x5yfwpaf.js → chunk-a71qr72q.js} +2 -2
- package/dist/deploy/index.js +2 -2
- package/dist/drivers/aws/driver.d.ts +1 -1
- package/dist/drivers/hetzner/state.d.ts +1 -0
- package/dist/drivers/index.js +1 -1
- package/dist/index.js +2 -2
- package/dist/ui/index.html +3 -3
- package/dist/ui/server/actions.html +3 -3
- package/dist/ui/server/backups.html +3 -3
- package/dist/ui/server/database.html +3 -3
- package/dist/ui/server/deployments.html +3 -3
- package/dist/ui/server/firewall.html +3 -3
- package/dist/ui/server/logs.html +3 -3
- package/dist/ui/server/services.html +3 -3
- package/dist/ui/server/sites.html +3 -3
- package/dist/ui/server/ssh-keys.html +3 -3
- package/dist/ui/server/team.html +3 -3
- package/dist/ui/server/terminal.html +3 -3
- package/dist/ui/server/workers.html +3 -3
- package/dist/ui/serverless/alarms.html +3 -3
- package/dist/ui/serverless/assets.html +3 -3
- package/dist/ui/serverless/data.html +3 -3
- package/dist/ui/serverless/deployments.html +3 -3
- package/dist/ui/serverless/functions.html +3 -3
- package/dist/ui/serverless/logs.html +3 -3
- package/dist/ui/serverless/queues.html +3 -3
- package/dist/ui/serverless/scheduler.html +3 -3
- package/dist/ui/serverless/secrets.html +3 -3
- package/dist/ui/serverless/traces.html +3 -3
- package/dist/ui/serverless.html +3 -3
- package/package.json +3 -3
package/dist/bin/cli.js
CHANGED
|
@@ -7275,7 +7275,7 @@ ${Object.entries($).filter(([G])=>!G.startsWith("@_")).map(([G,W])=>Q(G,W," ","
|
|
|
7275
7275
|
│ After verification, re-run: bunx bunpress deploy │
|
|
7276
7276
|
└─────────────────────────────────────────────────────────────────────────────┘`),{success:!1,stackId:q,stackName:G,bucket:A,message:"CloudFront account verification required. Please contact AWS Support."}}return{success:!1,stackId:q,stackName:G,bucket:A,message:`Stack deployment failed: ${x.message}`}}let w=(await W.describeStacks({stackName:G})).Stacks[0]?.Outputs||[],N=(x)=>w.find((h)=>h.OutputKey===x)?.OutputValue,I=N("DistributionDomain");if(I&&U)console.log(`Creating DNS records via ${U.name}...`),await cQ(U,Z,I);else if(I&&!U)console.log("Skipping DNS record creation (DNS verification was skipped)");return{success:!0,stackId:q,stackName:G,bucket:N("BucketName")||A,distributionId:N("DistributionId"),distributionDomain:I,domain:Z,certificateArn:H,message:"Static site infrastructure deployed successfully with external DNS"}}async function cQ($,J,Y){if(!$){console.log("Skipping DNS record creation (DNS verification was skipped)");return}if(J.split(".").length===2)if($ instanceof O$){console.log(`Creating Route53 alias record for apex domain ${J} -> ${Y}`);let G=await $.createCloudFrontAlias({domain:J,name:J,cloudFrontDomainName:Y});if(!G.success)console.warn(`Warning: Could not create Route53 alias record: ${G.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created Route53 alias record: ${J} -> ${Y}`);let W=`www.${J}`;console.log(`Creating Route53 alias record for ${W} -> ${Y}`);let z=await $.createCloudFrontAlias({domain:J,name:W,cloudFrontDomainName:Y});if(!z.success)console.warn(`Warning: Could not create www Route53 alias: ${z.message}`),console.warn("Please manually create an A-record alias in Route53:"),console.warn(` ${W} -> ${Y}`);else console.log(`Created Route53 alias record: ${W} -> ${Y}`)}else{try{let U=await $.listRecords(J,"A");if(U.success)for(let H of U.records){let X=H.name.replace(/\.$/,"");if(X===J||X==="")console.log(`Removing existing root A record (${H.content}) to make room for ALIAS...`),await $.deleteRecord(J,{name:J,type:"A",content:H.content})}}catch(U){console.log(`Note: Could not check for conflicting A records: ${U instanceof Error?U.message:U}`)}console.log(`Creating ALIAS record for apex domain ${J} -> ${Y}`);let G=await $.upsertRecord(J,{name:J,type:"ALIAS",content:Y,ttl:600});if(!G.success)console.warn(`Warning: Could not create ALIAS record: ${G.message}`),console.warn("Please manually create an ALIAS record in your DNS provider:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created ALIAS record: ${J} -> ${Y}`);let W=`www.${J}`;console.log(`Creating CNAME record for ${W} -> ${Y}`);let z=await $.upsertRecord(J,{name:W,type:"CNAME",content:Y,ttl:600});if(!z.success)console.warn(`Warning: Could not create www DNS record: ${z.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${W} -> ${Y}`);else console.log(`Created CNAME record: ${W} -> ${Y}`)}else{console.log(`Creating CNAME record for ${J} -> ${Y}`);let G=await $.upsertRecord(J,{name:J,type:"CNAME",content:Y,ttl:600});if(!G.success)console.warn(`Warning: Could not create DNS record: ${G.message}`),console.warn("Please manually create a CNAME record:"),console.warn(` ${J} -> ${Y}`);else console.log(`Created CNAME record: ${J} -> ${Y}`)}}async function a7($){let{sourceDir:J,cleanBucket:Y=!1,onProgress:Z,...Q}=$;Z?.("infrastructure","Deploying CloudFormation stack...");let G=await i7(Q);if(!G.success)return G;if(Y){Z?.("clean","Cleaning old files from S3...");try{await new H0(Q.region||"us-east-1").emptyBucket(G.bucket)}catch(H){console.log(`Note: Could not clean bucket: ${H.message}`)}}Z?.("upload","Uploading files to S3...");let{uploadStaticFiles:W}=await Promise.resolve().then(() => (h9(),n7)),z=await W({sourceDir:J,bucket:G.bucket,region:Q.region||"us-east-1",cacheControl:Q.cacheControl,onProgress:(H,X,K)=>{Z?.("upload",`${H}/${X}: ${K}`)}});if(z.errors.length>0)return{...G,success:!1,message:`Upload errors: ${z.errors.join(", ")}`,filesUploaded:z.uploaded};if(G.distributionId&&z.uploaded>0){Z?.("invalidate","Invalidating CloudFront cache...");let{invalidateCache:H}=await Promise.resolve().then(() => (h9(),n7));await H(G.distributionId)}Z?.("complete","Deployment complete!");let U=z.skipped>0?`Deployed ${z.uploaded} files (${z.skipped} unchanged) with external DNS`:`Deployed ${z.uploaded} files successfully with external DNS`;return{...G,filesUploaded:z.uploaded,filesSkipped:z.skipped,message:U}}var b9=Y0(()=>{_1();k0();z2();N2();B2();Q7();YY()});var DX={};b0(DX,{EC2Client:()=>s0});class s0{client;region;constructor($="us-east-1"){this.region=$,this.client=new $0}async describeInstances($){let J={Action:"DescribeInstances",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Q,G)=>{J[`InstanceId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((W,z)=>{J[`Filter.${G+1}.Value.${z+1}`]=W})});if($?.MaxResults)J.MaxResults=String($.MaxResults);if($?.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=Y.DescribeInstancesResponse||Y;return{Reservations:this.parseReservations(Z.reservationSet?.item),NextToken:Z.nextToken}}async getInstance($){return(await this.describeInstances({InstanceIds:[$]})).Reservations?.[0]?.Instances?.[0]}async getConsoleOutput($,J){let Y={Action:"GetConsoleOutput",Version:"2016-11-15",InstanceId:$};if(J)Y.Latest="true";let Z=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()}),Q=Z.GetConsoleOutputResponse||Z;return{InstanceId:Q.instanceId,Output:Q.output,Timestamp:Q.timestamp}}async getConsoleOutputDecoded($,J){let Y=await this.getConsoleOutput($,J?.latest);if(!Y.Output)return"No console output available yet";let Z=Buffer.from(Y.Output,"base64").toString("utf-8");if(J?.tailLines)return Z.split(`
|
|
7277
7277
|
`).slice(-J.tailLines).join(`
|
|
7278
|
-
`);return Z}async describeInstanceStatus($){let J={Action:"DescribeInstanceStatus",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Z,Q)=>{J[`InstanceId.${Q+1}`]=Z});if($?.IncludeAllInstances)J.IncludeAllInstances="true";if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InstanceStatuses:this.parseArray(Y.instanceStatusSet?.item).map((Z)=>({InstanceId:Z.instanceId,InstanceState:Z.instanceState?{Code:Number.parseInt(Z.instanceState.code),Name:Z.instanceState.name}:void 0,InstanceStatus:Z.instanceStatus?{Status:Z.instanceStatus.status,Details:this.parseArray(Z.instanceStatus.details?.item).map((Q)=>({Name:Q.name,Status:Q.status}))}:void 0,SystemStatus:Z.systemStatus?{Status:Z.systemStatus.status,Details:this.parseArray(Z.systemStatus.details?.item).map((Q)=>({Name:Q.name,Status:Q.status}))}:void 0}))}}async startInstances($){let J={Action:"StartInstances",Version:"2016-11-15"};$.forEach((Z,Q)=>{J[`InstanceId.${Q+1}`]=Z});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{StartingInstances:this.parseArray(Y.instancesSet?.item).map((Z)=>({InstanceId:Z.instanceId,CurrentState:Z.currentState?{Name:Z.currentState.name}:void 0,PreviousState:Z.previousState?{Name:Z.previousState.name}:void 0}))}}async stopInstances($,J){let Y={Action:"StopInstances",Version:"2016-11-15"};if($.forEach((Q,G)=>{Y[`InstanceId.${G+1}`]=Q}),J)Y.Force="true";let Z=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()});return{StoppingInstances:this.parseArray(Z.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async rebootInstances($){let J={Action:"RebootInstances",Version:"2016-11-15"};$.forEach((Y,Z)=>{J[`InstanceId.${Z+1}`]=Y}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async terminateInstances($){let J={Action:"TerminateInstances",Version:"2016-11-15"};$.forEach((Z,Q)=>{J[`InstanceId.${Q+1}`]=Z});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{TerminatingInstances:this.parseArray(Y.instancesSet?.item).map((Z)=>({InstanceId:Z.instanceId,CurrentState:Z.currentState?{Name:Z.currentState.name}:void 0,PreviousState:Z.previousState?{Name:Z.previousState.name}:void 0}))}}async createImage($){let J={Action:"CreateImage",Version:"2016-11-15",InstanceId:$.InstanceId,Name:$.Name};if($.Description)J.Description=$.Description;if($.NoReboot!==void 0)J.NoReboot=String($.NoReboot);if($.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((W,z)=>{J[`TagSpecification.${G+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${G+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{ImageId:(Y.CreateImageResponse||Y).imageId}}async deregisterImage($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeregisterImage",Version:"2016-11-15",ImageId:$}).toString()})}async describeVpcs($){let J={Action:"DescribeVpcs",Version:"2016-11-15"};if($?.VpcIds)$.VpcIds.forEach((Z,Q)=>{J[`VpcId.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Vpcs:this.parseArray(Y.vpcSet?.item).map((Z)=>({VpcId:Z.vpcId,CidrBlock:Z.cidrBlock,State:Z.state,DhcpOptionsId:Z.dhcpOptionsId,InstanceTenancy:Z.instanceTenancy,IsDefault:Z.isDefault==="true",Tags:this.parseTags(Z.tagSet?.item)}))}}async describeSubnets($){let J={Action:"DescribeSubnets",Version:"2016-11-15"};if($?.SubnetIds)$.SubnetIds.forEach((Z,Q)=>{J[`SubnetId.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Subnets:this.parseArray(Y.subnetSet?.item).map((Z)=>({SubnetId:Z.subnetId,VpcId:Z.vpcId,CidrBlock:Z.cidrBlock,AvailabilityZone:Z.availabilityZone,AvailableIpAddressCount:Number.parseInt(Z.availableIpAddressCount),State:Z.state,MapPublicIpOnLaunch:Z.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Z.tagSet?.item)}))}}async describeSecurityGroups($){let J={Action:"DescribeSecurityGroups",Version:"2016-11-15"};if($?.GroupIds)$.GroupIds.forEach((Z,Q)=>{J[`GroupId.${Q+1}`]=Z});if($?.GroupNames)$.GroupNames.forEach((Z,Q)=>{J[`GroupName.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{SecurityGroups:this.parseArray(Y.securityGroupInfo?.item).map((Z)=>({GroupId:Z.groupId,GroupName:Z.groupName,Description:Z.groupDescription,VpcId:Z.vpcId,IpPermissions:this.parseIpPermissions(Z.ipPermissions?.item),IpPermissionsEgress:this.parseIpPermissions(Z.ipPermissionsEgress?.item),Tags:this.parseTags(Z.tagSet?.item)}))}}async describeInternetGateways($){let J={Action:"DescribeInternetGateways",Version:"2016-11-15"};if($?.InternetGatewayIds)$.InternetGatewayIds.forEach((Z,Q)=>{J[`InternetGatewayId.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InternetGateways:this.parseArray(Y.internetGatewaySet?.item).map((Z)=>({InternetGatewayId:Z.internetGatewayId,Attachments:this.parseArray(Z.attachmentSet?.item).map((Q)=>({VpcId:Q.vpcId,State:Q.state})),Tags:this.parseTags(Z.tagSet?.item)}))}}async describeAddresses($){let J={Action:"DescribeAddresses",Version:"2016-11-15"};if($?.AllocationIds)$.AllocationIds.forEach((Z,Q)=>{J[`AllocationId.${Q+1}`]=Z});if($?.PublicIps)$.PublicIps.forEach((Z,Q)=>{J[`PublicIp.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Addresses:this.parseArray(Y.addressesSet?.item).map((Z)=>({PublicIp:Z.publicIp,AllocationId:Z.allocationId,AssociationId:Z.associationId,InstanceId:Z.instanceId,NetworkInterfaceId:Z.networkInterfaceId,PrivateIpAddress:Z.privateIpAddress,Domain:Z.domain,Tags:this.parseTags(Z.tagSet?.item)}))}}async allocateAddress($){let J={Action:"AllocateAddress",Version:"2016-11-15"};if($?.Domain)J.Domain=$.Domain;if($?.TagSpecifications)$.TagSpecifications.forEach((Z,Q)=>{J[`TagSpecification.${Q+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((G,W)=>{J[`TagSpecification.${Q+1}.Tag.${W+1}.Key`]=G.Key,J[`TagSpecification.${Q+1}.Tag.${W+1}.Value`]=G.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{AllocationId:Y.allocationId,PublicIp:Y.publicIp,Domain:Y.domain}}async associateAddress($){let J={Action:"AssociateAddress",Version:"2016-11-15"};if($.AllocationId)J.AllocationId=$.AllocationId;if($.PublicIp)J.PublicIp=$.PublicIp;if($.InstanceId)J.InstanceId=$.InstanceId;if($.NetworkInterfaceId)J.NetworkInterfaceId=$.NetworkInterfaceId;if($.PrivateIpAddress)J.PrivateIpAddress=$.PrivateIpAddress;if($.AllowReassociation)J.AllowReassociation="true";return{AssociationId:(await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})).associationId}}async createTags($){let J={Action:"CreateTags",Version:"2016-11-15"};$.Resources.forEach((Y,Z)=>{J[`ResourceId.${Z+1}`]=Y}),$.Tags.forEach((Y,Z)=>{J[`Tag.${Z+1}.Key`]=Y.Key,J[`Tag.${Z+1}.Value`]=Y.Value}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async waitForInstanceState($,J,Y){let Z=Y?.maxWaitMs||300000,Q=Y?.pollIntervalMs||5000,G=Date.now();while(Date.now()-G<Z){let W;try{W=await this.getInstance($)}catch{W=void 0}if(W?.State?.Name===J)return W;await new Promise((z)=>setTimeout(z,Q))}return}async createVpc($){let J={Action:"CreateVpc",Version:"2016-11-15",CidrBlock:$.CidrBlock};if($.InstanceTenancy)J.InstanceTenancy=$.InstanceTenancy;if($.TagSpecifications)$.TagSpecifications.forEach((G,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((z,U)=>{J[`TagSpecification.${W+1}.Tag.${U+1}.Key`]=z.Key,J[`TagSpecification.${W+1}.Tag.${U+1}.Value`]=z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=(Y.CreateVpcResponse||Y).vpc;return{Vpc:Q?{VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,State:Q.state,DhcpOptionsId:Q.dhcpOptionsId,InstanceTenancy:Q.instanceTenancy,IsDefault:Q.isDefault==="true",Tags:this.parseTags(Q.tagSet?.item)}:void 0}}async createSubnet($){let J={Action:"CreateSubnet",Version:"2016-11-15",VpcId:$.VpcId,CidrBlock:$.CidrBlock};if($.AvailabilityZone)J.AvailabilityZone=$.AvailabilityZone;if($.TagSpecifications)$.TagSpecifications.forEach((G,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((z,U)=>{J[`TagSpecification.${W+1}.Tag.${U+1}.Key`]=z.Key,J[`TagSpecification.${W+1}.Tag.${U+1}.Value`]=z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=(Y.CreateSubnetResponse||Y).subnet;return{Subnet:Q?{SubnetId:Q.subnetId,VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,AvailabilityZone:Q.availabilityZone,AvailableIpAddressCount:Q.availableIpAddressCount?Number.parseInt(Q.availableIpAddressCount):void 0,State:Q.state,MapPublicIpOnLaunch:Q.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Q.tagSet?.item)}:void 0}}async modifySubnetAttribute($){let J={Action:"ModifySubnetAttribute",Version:"2016-11-15",SubnetId:$.SubnetId};if($.MapPublicIpOnLaunch!==void 0)J["MapPublicIpOnLaunch.Value"]=String($.MapPublicIpOnLaunch.Value);await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async createSecurityGroup($){let J={Action:"CreateSecurityGroup",Version:"2016-11-15",GroupName:$.GroupName,GroupDescription:$.Description};if($.VpcId)J.VpcId=$.VpcId;if($.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((W,z)=>{J[`TagSpecification.${G+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${G+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{GroupId:(Y.CreateSecurityGroupResponse||Y).groupId}}async authorizeSecurityGroupIngress($){let J={Action:"AuthorizeSecurityGroupIngress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async authorizeSecurityGroupEgress($){let J={Action:"AuthorizeSecurityGroupEgress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRouteTables($){let J={Action:"DescribeRouteTables",Version:"2016-11-15"};if($?.RouteTableIds)$.RouteTableIds.forEach((Q,G)=>{J[`RouteTableId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((W,z)=>{J[`Filter.${G+1}.Value.${z+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=Y.DescribeRouteTablesResponse||Y;return{RouteTables:this.parseArray(Z.routeTableSet?.item).map((Q)=>({RouteTableId:Q.routeTableId,VpcId:Q.vpcId,Routes:this.parseArray(Q.routeSet?.item).map((G)=>({DestinationCidrBlock:G.destinationCidrBlock,GatewayId:G.gatewayId,NatGatewayId:G.natGatewayId,State:G.state})),Associations:this.parseArray(Q.associationSet?.item).map((G)=>({RouteTableAssociationId:G.routeTableAssociationId,SubnetId:G.subnetId,Main:G.main==="true"||G.main===!0})),Tags:this.parseTags(Q.tagSet?.item)}))}}async deleteVpc($){let J={Action:"DeleteVpc",Version:"2016-11-15",VpcId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSubnet($){let J={Action:"DeleteSubnet",Version:"2016-11-15",SubnetId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSecurityGroup($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeleteSecurityGroup",Version:"2016-11-15",GroupId:$}).toString()})}async describeNetworkInterfaces($){let J={Action:"DescribeNetworkInterfaces",Version:"2016-11-15"};if($?.NetworkInterfaceIds)$.NetworkInterfaceIds.forEach((Q,G)=>{J[`NetworkInterfaceId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((W,z)=>{J[`Filter.${G+1}.Value.${z+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=Y.DescribeNetworkInterfacesResponse||Y;return{NetworkInterfaces:this.parseArray(Z.networkInterfaceSet?.item).map((Q)=>({NetworkInterfaceId:Q.networkInterfaceId,SubnetId:Q.subnetId,VpcId:Q.vpcId,Status:Q.status,Attachment:Q.attachment?{AttachmentId:Q.attachment.attachmentId,InstanceId:Q.attachment.instanceId,Status:Q.attachment.status}:void 0}))}}async detachNetworkInterface($,J){let Y={Action:"DetachNetworkInterface",Version:"2016-11-15",AttachmentId:$};if(J)Y.Force="true";await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()})}async deleteNetworkInterface($){let J={Action:"DeleteNetworkInterface",Version:"2016-11-15",NetworkInterfaceId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRegions(){let $={Action:"DescribeRegions",Version:"2016-11-15"},J=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams($).toString()}),Y=J.DescribeRegionsResponse||J;return{Regions:this.parseArray(Y.regionInfo?.item).map((Z)=>({RegionName:Z.regionName,Endpoint:Z.regionEndpoint}))}}async runInstances($){let J={Action:"RunInstances",Version:"2016-11-15",ImageId:$.ImageId,InstanceType:$.InstanceType,MinCount:String($.MinCount),MaxCount:String($.MaxCount)};if($.SecurityGroupIds)$.SecurityGroupIds.forEach((Q,G)=>{J[`SecurityGroupId.${G+1}`]=Q});if($.SubnetId)J.SubnetId=$.SubnetId;if($.UserData)J.UserData=$.UserData;if($.IamInstanceProfile){if($.IamInstanceProfile.Name)J["IamInstanceProfile.Name"]=$.IamInstanceProfile.Name;if($.IamInstanceProfile.Arn)J["IamInstanceProfile.Arn"]=$.IamInstanceProfile.Arn}if($.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((W,z)=>{J[`TagSpecification.${G+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${G+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=Y.RunInstancesResponse||Y;return{Instances:this.parseInstances(Z.instancesSet?.item||Z.instancesSet)}}encodeIpPermissions($,J){J.forEach((Y,Z)=>{let Q=`IpPermissions.${Z+1}`;if(Y.IpProtocol!==void 0)$[`${Q}.IpProtocol`]=Y.IpProtocol;if(Y.FromPort!==void 0)$[`${Q}.FromPort`]=String(Y.FromPort);if(Y.ToPort!==void 0)$[`${Q}.ToPort`]=String(Y.ToPort);if(Y.IpRanges)Y.IpRanges.forEach((G,W)=>{if(G.CidrIp)$[`${Q}.IpRanges.${W+1}.CidrIp`]=G.CidrIp;if(G.Description)$[`${Q}.IpRanges.${W+1}.Description`]=G.Description});if(Y.Ipv6Ranges)Y.Ipv6Ranges.forEach((G,W)=>{if(G.CidrIpv6)$[`${Q}.Ipv6Ranges.${W+1}.CidrIpv6`]=G.CidrIpv6;if(G.Description)$[`${Q}.Ipv6Ranges.${W+1}.Description`]=G.Description});if(Y.UserIdGroupPairs)Y.UserIdGroupPairs.forEach((G,W)=>{if(G.GroupId)$[`${Q}.Groups.${W+1}.GroupId`]=G.GroupId;if(G.UserId)$[`${Q}.Groups.${W+1}.UserId`]=G.UserId;if(G.Description)$[`${Q}.Groups.${W+1}.Description`]=G.Description})})}parseArray($){if(!$)return[];return Array.isArray($)?$:[$]}parseTags($){return this.parseArray($).map((J)=>({Key:J.key,Value:J.value}))}parseReservations($){return this.parseArray($).map((J)=>({ReservationId:J.reservationId,Instances:this.parseInstances(J.instancesSet?.item||J.instancesSet)}))}parseInstances($){return this.parseArray($).map((J)=>({InstanceId:J.instanceId,ImageId:J.imageId,InstanceType:J.instanceType,State:J.instanceState?{Code:Number.parseInt(J.instanceState.code),Name:J.instanceState.name}:void 0,PrivateIpAddress:J.privateIpAddress,PublicIpAddress:J.ipAddress,SubnetId:J.subnetId,VpcId:J.vpcId,SecurityGroups:this.parseArray(J.groupSet?.item).map((Y)=>({GroupId:Y.groupId,GroupName:Y.groupName})),Tags:this.parseTags(J.tagSet?.item),LaunchTime:J.launchTime,Placement:J.placement?{AvailabilityZone:J.placement.availabilityZone,Tenancy:J.placement.tenancy}:void 0,Architecture:J.architecture,RootDeviceType:J.rootDeviceType,RootDeviceName:J.rootDeviceName,BlockDeviceMappings:this.parseArray(J.blockDeviceMapping?.item).map((Y)=>({DeviceName:Y.deviceName,Ebs:Y.ebs?{VolumeId:Y.ebs.volumeId,Status:Y.ebs.status,AttachTime:Y.ebs.attachTime,DeleteOnTermination:Y.ebs.deleteOnTermination==="true"}:void 0})),IamInstanceProfile:J.iamInstanceProfile?{Arn:J.iamInstanceProfile.arn,Id:J.iamInstanceProfile.id}:void 0}))}parseIpPermissions($){return this.parseArray($).map((J)=>({IpProtocol:J.ipProtocol,FromPort:J.fromPort?Number.parseInt(J.fromPort):void 0,ToPort:J.toPort?Number.parseInt(J.toPort):void 0,IpRanges:this.parseArray(J.ipRanges?.item).map((Y)=>({CidrIp:Y.cidrIp,Description:Y.description})),Ipv6Ranges:this.parseArray(J.ipv6Ranges?.item).map((Y)=>({CidrIpv6:Y.cidrIpv6,Description:Y.description})),UserIdGroupPairs:this.parseArray(J.groups?.item).map((Y)=>({GroupId:Y.groupId,UserId:Y.userId,Description:Y.description}))}))}}var y9=Y0(()=>{G0()});class v9{client;region;constructor($="us-east-1",J){this.region=$,this.client=new $0}async putParameter($){let J={Name:$.Name,Value:$.Value};if($.Type)J.Type=$.Type;if($.Description)J.Description=$.Description;if($.KeyId)J.KeyId=$.KeyId;if($.Overwrite!==void 0)J.Overwrite=$.Overwrite;if($.AllowedPattern)J.AllowedPattern=$.AllowedPattern;if($.Tags&&$.Tags.length>0)J.Tags=$.Tags;if($.Tier)J.Tier=$.Tier;if($.DataType)J.DataType=$.DataType;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.PutParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Version:Y.Version,Tier:Y.Tier}}async getParameter($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameter:Y.Parameter?this.parseParameter(Y.Parameter):void 0}}async getParameters($){let J={Names:$.Names};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>this.parseParameter(Z)),InvalidParameters:Y.InvalidParameters}}async getParametersByPath($){let J={Path:$.Path};if($.Recursive!==void 0)J.Recursive=$.Recursive;if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;if($.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParametersByPath","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:Y.NextToken}}async deleteParameter($){let J={Name:$.Name};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async deleteParameters($){let J={Names:$},Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{DeletedParameters:Y.DeletedParameters,InvalidParameters:Y.InvalidParameters}}async describeParameters($){let J={};if($?.Filters&&$.Filters.length>0)J.Filters=$.Filters;if($?.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;if($?.MaxResults)J.MaxResults=$.MaxResults;if($?.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DescribeParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:Y.NextToken}}async getParameterHistory($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameterHistory","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>({Name:Z.Name,Type:Z.Type,KeyId:Z.KeyId,LastModifiedDate:Z.LastModifiedDate,LastModifiedUser:Z.LastModifiedUser,Description:Z.Description,Value:Z.Value,Version:Z.Version,Labels:Z.Labels,Tier:Z.Tier})),NextToken:Y.NextToken}}async labelParameterVersion($){let J={Name:$.Name,Labels:$.Labels};if($.ParameterVersion!==void 0)J.ParameterVersion=$.ParameterVersion;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.LabelParameterVersion","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{InvalidLabels:Y.InvalidLabels,ParameterVersion:Y.ParameterVersion}}async addTagsToResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,Tags:$.Tags};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.AddTagsToResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async removeTagsFromResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,TagKeys:$.TagKeys};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.RemoveTagsFromResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async listTagsForResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId};return{TagList:(await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListTagsForResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})).TagList}}async setString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"String",Description:Y?.description,Overwrite:Y?.overwrite??!0,Tags:Y?.tags})}async setSecureString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"SecureString",Description:Y?.description,Overwrite:Y?.overwrite??!0,KeyId:Y?.kmsKeyId,Tags:Y?.tags})}async getValue($){return(await this.getParameter({Name:$,WithDecryption:!0})).Parameter?.Value}async getAllByPath($,J=!0){let Y=[],Z;do{let Q=await this.getParametersByPath({Path:$,Recursive:J,WithDecryption:!0,NextToken:Z});if(Q.Parameters)Y.push(...Q.Parameters);Z=Q.NextToken}while(Z);return Y}parseParameter($){return{Name:$.Name,Type:$.Type,Value:$.Value,Version:$.Version,LastModifiedDate:$.LastModifiedDate,ARN:$.ARN,DataType:$.DataType,Description:$.Description,AllowedPattern:$.AllowedPattern,KeyId:$.KeyId,Tier:$.Tier}}async sendCommand($){if(!$.InstanceIds&&!$.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let J={DocumentName:$.DocumentName};if($.InstanceIds)J.InstanceIds=$.InstanceIds;if($.Targets)J.Targets=$.Targets;if($.Parameters)J.Parameters=$.Parameters;if($.TimeoutSeconds)J.TimeoutSeconds=$.TimeoutSeconds;if($.Comment)J.Comment=$.Comment;if($.OutputS3BucketName)J.OutputS3BucketName=$.OutputS3BucketName;if($.OutputS3KeyPrefix)J.OutputS3KeyPrefix=$.OutputS3KeyPrefix;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.SendCommand","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{CommandId:Y.Command?.CommandId,Status:Y.Command?.Status,StatusDetails:Y.Command?.StatusDetails}}async getCommandInvocation($){let J={CommandId:$.CommandId,InstanceId:$.InstanceId},Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetCommandInvocation","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Status:Y.Status,StatusDetails:Y.StatusDetails,StandardOutputContent:Y.StandardOutputContent,StandardErrorContent:Y.StandardErrorContent,ResponseCode:Y.ResponseCode}}async runShellCommand($,J,Y){let Z=await this.sendCommand({InstanceIds:[$],DocumentName:"AWS-RunShellScript",Parameters:{commands:J},TimeoutSeconds:Y?.timeoutSeconds||600});if(!Z.CommandId)return{success:!1,error:"Failed to send command"};if(Y?.waitForCompletion===!1)return{success:!0,status:"Pending"};let Q=Y?.pollIntervalMs||2000,G=Y?.maxWaitMs||300000,W=Date.now();while(Date.now()-W<G){await new Promise((z)=>setTimeout(z,Q));try{let z=await this.getCommandInvocation({CommandId:Z.CommandId,InstanceId:$});if(z.Status==="Success")return{success:!0,output:z.StandardOutputContent,error:z.StandardErrorContent,status:z.Status};if(z.Status==="Failed"||z.Status==="Cancelled"||z.Status==="TimedOut")return{success:!1,output:z.StandardOutputContent,error:z.StandardErrorContent||z.StatusDetails,status:z.Status}}catch(z){if(!z.message?.includes("InvocationDoesNotExist"))return{success:!1,error:z.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations($){let J={CommandId:$.CommandId};if($.Details)J.Details=!0;return((await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListCommandInvocations","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})).CommandInvocations||[]).map((Q)=>({InstanceId:Q.InstanceId,Status:Q.Status,StatusDetails:Q.StatusDetails,StandardOutputContent:Q.CommandPlugins?.[0]?.Output,StandardErrorContent:Q.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags($){let J=Object.entries($.tags).map(([U,H])=>({Key:`tag:${U}`,Values:[H]})),Y=await this.sendCommand({Targets:J,DocumentName:"AWS-RunShellScript",Parameters:{commands:$.commands},TimeoutSeconds:$.timeoutSeconds||600,Comment:$.comment});if(!Y.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let Z=$.pollIntervalMs||3000,Q=$.maxWaitMs||600000,G=Date.now(),W=new Set(["Success","Failed","Cancelled","TimedOut"]),z=[];while(Date.now()-G<Q){await new Promise((U)=>setTimeout(U,Z));try{if(z=await this.listCommandInvocations({CommandId:Y.CommandId,Details:!0}),z.length===0)continue;if(z.every((H)=>W.has(H.Status||""))){let H=z.map((K)=>({instanceId:K.InstanceId,status:K.Status||"Unknown",output:K.StandardOutputContent,error:K.StandardErrorContent||K.StatusDetails})),X=z.every((K)=>K.Status==="Success");return{success:X,instanceCount:z.length,perInstance:H,error:X?void 0:"One or more instances reported a non-success status"}}}catch(U){if(!U.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:U.message}}}return{success:!1,instanceCount:z.length,perInstance:z.map((U)=>({instanceId:U.InstanceId,status:U.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}var lQ=Y0(()=>{G0()});function s7($){return`'${$.split("'").join("'\\''")}'`}function o7($={}){return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system","export PANTRY_INSTALL_DIR=/usr/local/bin",$.version?`export PANTRY_VERSION=${s7($.version)}`:'export PANTRY_VERSION="${PANTRY_VERSION:-latest}"',"command -v curl >/dev/null 2>&1 || (apt-get update -y && apt-get install -y curl ca-certificates)","command -v unzip >/dev/null 2>&1 || (apt-get update -y && apt-get install -y unzip)","command -v pantry >/dev/null 2>&1 || curl -fsSL https://pantry.dev | bash",'export PATH="/usr/local/bin:$PATH"',"mkdir -p /opt/pantry"]}function N$(){return'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true'}function X8($){if($.length===0)return[];return[`(cd /opt/pantry && pantry install ${[...new Set($)].map(s7).join(" ")})`]}function e7($){return[...new Set($)].flatMap((J)=>[`(cd /opt/pantry && pantry start ${s7(J)})`,`(cd /opt/pantry && pantry enable ${s7(J)})`])}var wX,g1="/opt/pantry";var j2=Y0(()=>{wX={php:"php.net",nginx:"nginx.org",composer:"getcomposer.org",mysql:"mysql.com",mariadb:"mariadb.com/server",postgres:"postgresql.org",redis:"redis.io",memcached:"memcached.org",meilisearch:"meilisearch.com",git:"git-scm.com",certbot:"certbot.eff.org",bun:"bun.sh",node:"nodejs.org",deno:"deno.land"}});function h2($){return $===!0||typeof $==="object"&&$!=null}function cT($){let J=[],Y=[];if(h2($.mysql))J.push(typeof $.mysql==="object"&&$.mysql.version?`mysql.com@${$.mysql.version}`:"mysql.com@8.0.43"),Y.push("mysql");else if(h2($.mariadb))J.push(wX.mariadb),Y.push("mariadb");if(h2($.postgres))J.push("postgresql.org"),Y.push("postgres");if(h2($.redis))J.push("redis.io"),Y.push("redis");if(h2($.memcached))J.push("memcached.org"),Y.push("memcached");if(h2($.meilisearch))J.push("meilisearch.com"),Y.push("meilisearch");return{packages:J,services:Y}}function f9($={},J={}){let Y=cT($);if(Y.packages.length===0)return[];return[...X8(Y.packages),...e7(Y.services)]}function g9($,J={}){if(!$?.name)return[];if($.host&&$.host!=="127.0.0.1"&&$.host!=="localhost")return[];let Y=$.name,Z=$.username||Y,Q=$.password||"",G=h2(J.postgres)||$.engine==="postgres",W=h2(J.mariadb)||$.engine==="mariadb",z=h2(J.mysql)||$.engine==="mysql";if(G&&!z&&!W){let V=(j)=>`"${j.replace(/"/g,'""')}"`,O=(j)=>`'${j.replace(/'/g,"''")}'`,A=(j,q)=>["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${O(j)}) THEN`,` CREATE ROLE ${V(j)} LOGIN PASSWORD ${O(q)};`," ELSE",` ALTER ROLE ${V(j)} LOGIN PASSWORD ${O(q)};`," END IF;","END $$;"],_=(j)=>{let q=j.databases&&j.databases.length>0?j.databases:[Y],E=[];for(let T of q)if(j.access==="readonly")E.push(`GRANT CONNECT ON DATABASE ${V(T)} TO ${V(j.username)};`,`\\connect ${V(T)}`,`GRANT USAGE ON SCHEMA public TO ${V(j.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${V(j.username)};`,`ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ${V(j.username)};`,"\\connect postgres");else E.push(`GRANT ALL PRIVILEGES ON DATABASE ${V(T)} TO ${V(j.username)};`);return E},M=$.users||[];return[N$(),"for i in $(seq 1 30); do pg_isready -h 127.0.0.1 -p 5432 -q && break; sleep 2; done","psql -h 127.0.0.1 -p 5432 -U postgres <<'TS_CLOUD_PG_EOF'",...A(Z,Q),`SELECT 'CREATE DATABASE ${V(Y)} OWNER ${V(Z)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${O(Y)})\\gexec`,...M.flatMap((j)=>[...A(j.username,j.password),..._(j)]),"TS_CLOUD_PG_EOF"]}let U=W?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",H=(V)=>V.replace(/`/g,"``"),X=(V)=>V.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),K=(V)=>{let O=V.databases&&V.databases.length>0?V.databases:[Y],A=V.access==="readonly"?"SELECT":"ALL PRIVILEGES",_=[`CREATE USER IF NOT EXISTS '${X(V.username)}'@'%' IDENTIFIED BY '${X(V.password)}';`,`CREATE USER IF NOT EXISTS '${X(V.username)}'@'localhost' IDENTIFIED BY '${X(V.password)}';`,`ALTER USER '${X(V.username)}'@'%' IDENTIFIED BY '${X(V.password)}';`,`ALTER USER '${X(V.username)}'@'localhost' IDENTIFIED BY '${X(V.password)}';`];for(let M of O)_.push(`GRANT ${A} ON \`${H(M)}\`.* TO '${X(V.username)}'@'%';`,`GRANT ${A} ON \`${H(M)}\`.* TO '${X(V.username)}'@'localhost';`);return _},B=$.users||[];return[N$(),`for i in $(seq 1 30); do mysqladmin --socket=${U} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${U} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${H(Y)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...K({username:Z,password:Q}),...B.flatMap(K),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}function NX($){if(!$?.name)return{};let J=$.engine==="singlestore",Y=$.engine==="postgres"?"pgsql":J?"singlestore":"mysql",Z=$.port??($.engine==="postgres"?5432:3306),Q={DB_CONNECTION:Y,DB_HOST:$.host||"127.0.0.1",DB_PORT:String(Z),DB_DATABASE:$.name};if($.username)Q.DB_USERNAME=$.username;if($.password)Q.DB_PASSWORD=$.password;if(J&&$.ssl!==!1)Q.DB_SSL="true";return Q}var $5=Y0(()=>{j2()});function PX($){return lT}function pT($={}){let J=$.versions?.length?$.versions:["8.3"];return $.default&&J.includes($.default)?$.default:J[0]}function rT($={}){return{...$.optimizeForProduction===!1?{}:{...mT},...$.ini||{}}}function nT($={}){let J=rT($),Y=Object.keys(J);if(Y.length===0)return[];let Z=Y.map((G)=>`${G}=${J[G]}`),Q="ts-cloud-managed";return[N$(),"TS_CLOUD_SCAN_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Scan this dir for additional .ini files/{print $2}' | head -1)",`TS_CLOUD_LOADED_INI=$(php -r 'echo php_ini_loaded_file() ?: "";' 2>/dev/null)`,'if [ -n "$TS_CLOUD_SCAN_DIR" ] && [ "$TS_CLOUD_SCAN_DIR" != "(none)" ]; then',' mkdir -p "$TS_CLOUD_SCAN_DIR"',' TS_CLOUD_PHP_INI="$TS_CLOUD_SCAN_DIR/zz-ts-cloud.ini"',` cat > "$TS_CLOUD_PHP_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${Q} — production PHP tuning`,...Z,"TS_CLOUD_PHPINI_EOF","else",' if [ -z "$TS_CLOUD_LOADED_INI" ]; then'," TS_CLOUD_INI_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Configuration File \\(php.ini\\) Path/{print $2}' | head -1)",' TS_CLOUD_LOADED_INI="$TS_CLOUD_INI_DIR/php.ini"',' mkdir -p "$TS_CLOUD_INI_DIR"',' touch "$TS_CLOUD_LOADED_INI"'," fi",` sed -i '/; ${Q} BEGIN/,/; ${Q} END/d' "$TS_CLOUD_LOADED_INI"`,` cat >> "$TS_CLOUD_LOADED_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${Q} BEGIN`,...Z,`; ${Q} END`,"TS_CLOUD_PHPINI_EOF","fi",`(cd ${g1} && pantry restart php-fpm) 2>/dev/null || true`]}function J5($={}){let J=pT($),Y=$.installNginx!==!1,Z=$.installComposer!==!1,Q=[`php.net@${J}`];if(Z)Q.push("getcomposer.org");if(Y)Q.push("nginx.org");return[...X8(Q),...e7(["php-fpm"]),...nT($)]}var mT,lT="127.0.0.1:9074";var Y5=Y0(()=>{j2();mT={"opcache.enable":"1","opcache.enable_cli":"1","opcache.memory_consumption":"256","opcache.interned_strings_buffer":"16","opcache.max_accelerated_files":"20000","opcache.validate_timestamps":"0","opcache.revalidate_freq":"0","opcache.save_comments":"1","opcache.fast_shutdown":"1",realpath_cache_size:"4096K",realpath_cache_ttl:"600"}});function pQ($,J){if(!$)return[];let Y=[];if($.template&&J?.[$.template])Y.push(...J[$.template]);if($.serverSnippet)Y.push(...$.serverSnippet);return Y}function iT($){if(!$)return"";let J=typeof $==="object"?$:{},Z=[`max-age=${J.maxAge??31536000}`];if(J.includeSubDomains??!0)Z.push("includeSubDomains");if(J.preload)Z.push("preload");return` add_header Strict-Transport-Security "${Z.join("; ")}" always;`}function aT($){if(!$||!$.allow?.length&&!$.deny?.length)return[];let J=[];for(let Y of $.deny||[])J.push(` deny ${Y};`);if($.allow?.length){for(let Y of $.allow)J.push(` allow ${Y};`);J.push(" deny all;")}return J}function SX($){return`/etc/nginx/.htpasswd-${$}`}function sT($){return tT.has($)}function oT($){return $==="laravel"||$==="statamic"?"public":""}function eT($,J){let Y=$.replace(/\/+$/,""),Z=J.replace(/^\/+|\/+$/g,"");return Z?`${Y}/${Z}`:Y}function $R($){let J=$.type??"laravel",Y=$.webDirectory??oT(J),Z=eT($.appDir,Y),Q=sT(J),G=$.phpVersion??"8.3",W=[` root ${Z};`,"",' add_header X-Frame-Options "SAMEORIGIN";',' add_header X-Content-Type-Options "nosniff";'],z=iT($.hsts);if(z)W.push(z);for(let U of aT($.security))W.push(U);if(W.push("",` index ${Q?"index.php index.html":"index.html index.htm"};`,""," charset utf-8;",""),$.clientMaxBodySize)W.push(` client_max_body_size ${$.clientMaxBodySize};`,"");if($.auth)W.push(` auth_basic "${$.auth.realm||"Restricted"}";`,` auth_basic_user_file ${SX($.siteName)};`,"");for(let[U,H]of Object.entries($.redirects||{}))W.push(` location = ${U} { return 301 ${H}; }`);if(Object.keys($.redirects||{}).length>0)W.push("");if(Q){if(W.push(" location / {"," try_files $uri $uri/ /index.php?$query_string;"," }",""," location = /favicon.ico { access_log off; log_not_found off; }"," location = /robots.txt { access_log off; log_not_found off; }",""," error_page 404 /index.php;",""," location ~ \\.php$ {",` fastcgi_pass ${$.fastcgiPass??PX(G)};`," fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;"," include fastcgi_params;"," }",""," location ~ /\\.(?!well-known).* {"," deny all;"," }"),J==="wordpress")W.push(""," location = /xmlrpc.php { deny all; }"," location ~* /(?:wp-config\\.php|readme\\.html|license\\.txt)$ { deny all; }"," location ~* /wp-content/uploads/.*\\.php$ { deny all; }")}else if(J==="spa")W.push(" location / {"," try_files $uri $uri/ /index.html;"," }");else W.push(" location / {"," try_files $uri $uri/ =404;"," }");if($.serverSnippet&&$.serverSnippet.length>0){W.push("");for(let U of $.serverSnippet)W.push(U?` ${U}`:"")}return W}function JR($){let J=[$.domain,...$.aliases||[]].filter(Boolean).join(" "),Y=$R($);if($.ssl){let Q=["server {"," listen 80;"," listen [::]:80;",` server_name ${J};`," return 301 https://$host$request_uri;","}"],G=["server {"," listen 443 ssl;"," listen [::]:443 ssl;",` server_name ${J};`,` ssl_certificate ${$.ssl.certPath};`,` ssl_certificate_key ${$.ssl.keyPath};`,...$.tlsProtocols?.length?[` ssl_protocols ${$.tlsProtocols.join(" ")};`]:[],"",...Y,"}"];return`${[...Q,"",...G].join(`
|
|
7278
|
+
`);return Z}async describeInstanceStatus($){let J={Action:"DescribeInstanceStatus",Version:"2016-11-15"};if($?.InstanceIds)$.InstanceIds.forEach((Z,Q)=>{J[`InstanceId.${Q+1}`]=Z});if($?.IncludeAllInstances)J.IncludeAllInstances="true";if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InstanceStatuses:this.parseArray(Y.instanceStatusSet?.item).map((Z)=>({InstanceId:Z.instanceId,InstanceState:Z.instanceState?{Code:Number.parseInt(Z.instanceState.code),Name:Z.instanceState.name}:void 0,InstanceStatus:Z.instanceStatus?{Status:Z.instanceStatus.status,Details:this.parseArray(Z.instanceStatus.details?.item).map((Q)=>({Name:Q.name,Status:Q.status}))}:void 0,SystemStatus:Z.systemStatus?{Status:Z.systemStatus.status,Details:this.parseArray(Z.systemStatus.details?.item).map((Q)=>({Name:Q.name,Status:Q.status}))}:void 0}))}}async startInstances($){let J={Action:"StartInstances",Version:"2016-11-15"};$.forEach((Z,Q)=>{J[`InstanceId.${Q+1}`]=Z});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{StartingInstances:this.parseArray(Y.instancesSet?.item).map((Z)=>({InstanceId:Z.instanceId,CurrentState:Z.currentState?{Name:Z.currentState.name}:void 0,PreviousState:Z.previousState?{Name:Z.previousState.name}:void 0}))}}async stopInstances($,J){let Y={Action:"StopInstances",Version:"2016-11-15"};if($.forEach((Q,G)=>{Y[`InstanceId.${G+1}`]=Q}),J)Y.Force="true";let Z=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()});return{StoppingInstances:this.parseArray(Z.instancesSet?.item).map((Q)=>({InstanceId:Q.instanceId,CurrentState:Q.currentState?{Name:Q.currentState.name}:void 0,PreviousState:Q.previousState?{Name:Q.previousState.name}:void 0}))}}async rebootInstances($){let J={Action:"RebootInstances",Version:"2016-11-15"};$.forEach((Y,Z)=>{J[`InstanceId.${Z+1}`]=Y}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async terminateInstances($){let J={Action:"TerminateInstances",Version:"2016-11-15"};$.forEach((Z,Q)=>{J[`InstanceId.${Q+1}`]=Z});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{TerminatingInstances:this.parseArray(Y.instancesSet?.item).map((Z)=>({InstanceId:Z.instanceId,CurrentState:Z.currentState?{Name:Z.currentState.name}:void 0,PreviousState:Z.previousState?{Name:Z.previousState.name}:void 0}))}}async createImage($){let J={Action:"CreateImage",Version:"2016-11-15",InstanceId:$.InstanceId,Name:$.Name};if($.Description)J.Description=$.Description;if($.NoReboot!==void 0)J.NoReboot=String($.NoReboot);if($.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((W,z)=>{J[`TagSpecification.${G+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${G+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{ImageId:(Y.CreateImageResponse||Y).imageId}}async deregisterImage($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeregisterImage",Version:"2016-11-15",ImageId:$}).toString()})}async describeVpcs($){let J={Action:"DescribeVpcs",Version:"2016-11-15"};if($?.VpcIds)$.VpcIds.forEach((Z,Q)=>{J[`VpcId.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Vpcs:this.parseArray(Y.vpcSet?.item).map((Z)=>({VpcId:Z.vpcId,CidrBlock:Z.cidrBlock,State:Z.state,DhcpOptionsId:Z.dhcpOptionsId,InstanceTenancy:Z.instanceTenancy,IsDefault:Z.isDefault==="true",Tags:this.parseTags(Z.tagSet?.item)}))}}async describeSubnets($){let J={Action:"DescribeSubnets",Version:"2016-11-15"};if($?.SubnetIds)$.SubnetIds.forEach((Z,Q)=>{J[`SubnetId.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Subnets:this.parseArray(Y.subnetSet?.item).map((Z)=>({SubnetId:Z.subnetId,VpcId:Z.vpcId,CidrBlock:Z.cidrBlock,AvailabilityZone:Z.availabilityZone,AvailableIpAddressCount:Number.parseInt(Z.availableIpAddressCount),State:Z.state,MapPublicIpOnLaunch:Z.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Z.tagSet?.item)}))}}async describeSecurityGroups($){let J={Action:"DescribeSecurityGroups",Version:"2016-11-15"};if($?.GroupIds)$.GroupIds.forEach((Z,Q)=>{J[`GroupId.${Q+1}`]=Z});if($?.GroupNames)$.GroupNames.forEach((Z,Q)=>{J[`GroupName.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{SecurityGroups:this.parseArray(Y.securityGroupInfo?.item).map((Z)=>({GroupId:Z.groupId,GroupName:Z.groupName,Description:Z.groupDescription,VpcId:Z.vpcId,IpPermissions:this.parseIpPermissions(Z.ipPermissions?.item),IpPermissionsEgress:this.parseIpPermissions(Z.ipPermissionsEgress?.item),Tags:this.parseTags(Z.tagSet?.item)}))}}async describeInternetGateways($){let J={Action:"DescribeInternetGateways",Version:"2016-11-15"};if($?.InternetGatewayIds)$.InternetGatewayIds.forEach((Z,Q)=>{J[`InternetGatewayId.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{InternetGateways:this.parseArray(Y.internetGatewaySet?.item).map((Z)=>({InternetGatewayId:Z.internetGatewayId,Attachments:this.parseArray(Z.attachmentSet?.item).map((Q)=>({VpcId:Q.vpcId,State:Q.state})),Tags:this.parseTags(Z.tagSet?.item)}))}}async describeAddresses($){let J={Action:"DescribeAddresses",Version:"2016-11-15"};if($?.AllocationIds)$.AllocationIds.forEach((Z,Q)=>{J[`AllocationId.${Q+1}`]=Z});if($?.PublicIps)$.PublicIps.forEach((Z,Q)=>{J[`PublicIp.${Q+1}`]=Z});if($?.Filters)$.Filters.forEach((Z,Q)=>{J[`Filter.${Q+1}.Name`]=Z.Name,Z.Values.forEach((G,W)=>{J[`Filter.${Q+1}.Value.${W+1}`]=G})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{Addresses:this.parseArray(Y.addressesSet?.item).map((Z)=>({PublicIp:Z.publicIp,AllocationId:Z.allocationId,AssociationId:Z.associationId,InstanceId:Z.instanceId,NetworkInterfaceId:Z.networkInterfaceId,PrivateIpAddress:Z.privateIpAddress,Domain:Z.domain,Tags:this.parseTags(Z.tagSet?.item)}))}}async allocateAddress($){let J={Action:"AllocateAddress",Version:"2016-11-15"};if($?.Domain)J.Domain=$.Domain;if($?.TagSpecifications)$.TagSpecifications.forEach((Z,Q)=>{J[`TagSpecification.${Q+1}.ResourceType`]=Z.ResourceType,Z.Tags.forEach((G,W)=>{J[`TagSpecification.${Q+1}.Tag.${W+1}.Key`]=G.Key,J[`TagSpecification.${Q+1}.Tag.${W+1}.Value`]=G.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{AllocationId:Y.allocationId,PublicIp:Y.publicIp,Domain:Y.domain}}async associateAddress($){let J={Action:"AssociateAddress",Version:"2016-11-15"};if($.AllocationId)J.AllocationId=$.AllocationId;if($.PublicIp)J.PublicIp=$.PublicIp;if($.InstanceId)J.InstanceId=$.InstanceId;if($.NetworkInterfaceId)J.NetworkInterfaceId=$.NetworkInterfaceId;if($.PrivateIpAddress)J.PrivateIpAddress=$.PrivateIpAddress;if($.AllowReassociation)J.AllowReassociation="true";return{AssociationId:(await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})).associationId}}async createTags($){let J={Action:"CreateTags",Version:"2016-11-15"};$.Resources.forEach((Y,Z)=>{J[`ResourceId.${Z+1}`]=Y}),$.Tags.forEach((Y,Z)=>{J[`Tag.${Z+1}.Key`]=Y.Key,J[`Tag.${Z+1}.Value`]=Y.Value}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async waitForInstanceState($,J,Y){let Z=Y?.maxWaitMs||300000,Q=Y?.pollIntervalMs||5000,G=Date.now();while(Date.now()-G<Z){let W;try{W=await this.getInstance($)}catch{W=void 0}if(W?.State?.Name===J)return W;await new Promise((z)=>setTimeout(z,Q))}return}async createVpc($){let J={Action:"CreateVpc",Version:"2016-11-15",CidrBlock:$.CidrBlock};if($.InstanceTenancy)J.InstanceTenancy=$.InstanceTenancy;if($.TagSpecifications)$.TagSpecifications.forEach((G,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((z,U)=>{J[`TagSpecification.${W+1}.Tag.${U+1}.Key`]=z.Key,J[`TagSpecification.${W+1}.Tag.${U+1}.Value`]=z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=(Y.CreateVpcResponse||Y).vpc;return{Vpc:Q?{VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,State:Q.state,DhcpOptionsId:Q.dhcpOptionsId,InstanceTenancy:Q.instanceTenancy,IsDefault:Q.isDefault==="true",Tags:this.parseTags(Q.tagSet?.item)}:void 0}}async createSubnet($){let J={Action:"CreateSubnet",Version:"2016-11-15",VpcId:$.VpcId,CidrBlock:$.CidrBlock};if($.AvailabilityZone)J.AvailabilityZone=$.AvailabilityZone;if($.TagSpecifications)$.TagSpecifications.forEach((G,W)=>{J[`TagSpecification.${W+1}.ResourceType`]=G.ResourceType,G.Tags.forEach((z,U)=>{J[`TagSpecification.${W+1}.Tag.${U+1}.Key`]=z.Key,J[`TagSpecification.${W+1}.Tag.${U+1}.Value`]=z.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Q=(Y.CreateSubnetResponse||Y).subnet;return{Subnet:Q?{SubnetId:Q.subnetId,VpcId:Q.vpcId,CidrBlock:Q.cidrBlock,AvailabilityZone:Q.availabilityZone,AvailableIpAddressCount:Q.availableIpAddressCount?Number.parseInt(Q.availableIpAddressCount):void 0,State:Q.state,MapPublicIpOnLaunch:Q.mapPublicIpOnLaunch==="true",Tags:this.parseTags(Q.tagSet?.item)}:void 0}}async modifySubnetAttribute($){let J={Action:"ModifySubnetAttribute",Version:"2016-11-15",SubnetId:$.SubnetId};if($.MapPublicIpOnLaunch!==void 0)J["MapPublicIpOnLaunch.Value"]=String($.MapPublicIpOnLaunch.Value);await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async createSecurityGroup($){let J={Action:"CreateSecurityGroup",Version:"2016-11-15",GroupName:$.GroupName,GroupDescription:$.Description};if($.VpcId)J.VpcId=$.VpcId;if($.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((W,z)=>{J[`TagSpecification.${G+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${G+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()});return{GroupId:(Y.CreateSecurityGroupResponse||Y).groupId}}async authorizeSecurityGroupIngress($){let J={Action:"AuthorizeSecurityGroupIngress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async authorizeSecurityGroupEgress($){let J={Action:"AuthorizeSecurityGroupEgress",Version:"2016-11-15",GroupId:$.GroupId};this.encodeIpPermissions(J,$.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRouteTables($){let J={Action:"DescribeRouteTables",Version:"2016-11-15"};if($?.RouteTableIds)$.RouteTableIds.forEach((Q,G)=>{J[`RouteTableId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((W,z)=>{J[`Filter.${G+1}.Value.${z+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=Y.DescribeRouteTablesResponse||Y;return{RouteTables:this.parseArray(Z.routeTableSet?.item).map((Q)=>({RouteTableId:Q.routeTableId,VpcId:Q.vpcId,Routes:this.parseArray(Q.routeSet?.item).map((G)=>({DestinationCidrBlock:G.destinationCidrBlock,GatewayId:G.gatewayId,NatGatewayId:G.natGatewayId,State:G.state})),Associations:this.parseArray(Q.associationSet?.item).map((G)=>({RouteTableAssociationId:G.routeTableAssociationId,SubnetId:G.subnetId,Main:G.main==="true"||G.main===!0})),Tags:this.parseTags(Q.tagSet?.item)}))}}async deleteVpc($){let J={Action:"DeleteVpc",Version:"2016-11-15",VpcId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSubnet($){let J={Action:"DeleteSubnet",Version:"2016-11-15",SubnetId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async deleteSecurityGroup($){await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({Action:"DeleteSecurityGroup",Version:"2016-11-15",GroupId:$}).toString()})}async describeNetworkInterfaces($){let J={Action:"DescribeNetworkInterfaces",Version:"2016-11-15"};if($?.NetworkInterfaceIds)$.NetworkInterfaceIds.forEach((Q,G)=>{J[`NetworkInterfaceId.${G+1}`]=Q});if($?.Filters)$.Filters.forEach((Q,G)=>{J[`Filter.${G+1}.Name`]=Q.Name,Q.Values.forEach((W,z)=>{J[`Filter.${G+1}.Value.${z+1}`]=W})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=Y.DescribeNetworkInterfacesResponse||Y;return{NetworkInterfaces:this.parseArray(Z.networkInterfaceSet?.item).map((Q)=>({NetworkInterfaceId:Q.networkInterfaceId,SubnetId:Q.subnetId,VpcId:Q.vpcId,Status:Q.status,Attachment:Q.attachment?{AttachmentId:Q.attachment.attachmentId,InstanceId:Q.attachment.instanceId,Status:Q.attachment.status}:void 0}))}}async detachNetworkInterface($,J){let Y={Action:"DetachNetworkInterface",Version:"2016-11-15",AttachmentId:$};if(J)Y.Force="true";await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Y).toString()})}async deleteNetworkInterface($){let J={Action:"DeleteNetworkInterface",Version:"2016-11-15",NetworkInterfaceId:$};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()})}async describeRegions(){let $={Action:"DescribeRegions",Version:"2016-11-15"},J=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams($).toString()}),Y=J.DescribeRegionsResponse||J;return{Regions:this.parseArray(Y.regionInfo?.item).map((Z)=>({RegionName:Z.regionName,Endpoint:Z.regionEndpoint}))}}async runInstances($){let J={Action:"RunInstances",Version:"2016-11-15",ImageId:$.ImageId,InstanceType:$.InstanceType,MinCount:String($.MinCount),MaxCount:String($.MaxCount)};if($.SecurityGroupIds)$.SecurityGroupIds.forEach((Q,G)=>{J[`SecurityGroupId.${G+1}`]=Q});if($.SubnetId)J.SubnetId=$.SubnetId;if($.UserData)J.UserData=$.UserData;if($.IamInstanceProfile){if($.IamInstanceProfile.Name)J["IamInstanceProfile.Name"]=$.IamInstanceProfile.Name;if($.IamInstanceProfile.Arn)J["IamInstanceProfile.Arn"]=$.IamInstanceProfile.Arn}if($.TagSpecifications)$.TagSpecifications.forEach((Q,G)=>{J[`TagSpecification.${G+1}.ResourceType`]=Q.ResourceType,Q.Tags.forEach((W,z)=>{J[`TagSpecification.${G+1}.Tag.${z+1}.Key`]=W.Key,J[`TagSpecification.${G+1}.Tag.${z+1}.Value`]=W.Value})});let Y=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(J).toString()}),Z=Y.RunInstancesResponse||Y;return{Instances:this.parseInstances(Z.instancesSet?.item||Z.instancesSet)}}encodeIpPermissions($,J){J.forEach((Y,Z)=>{let Q=`IpPermissions.${Z+1}`;if(Y.IpProtocol!==void 0)$[`${Q}.IpProtocol`]=Y.IpProtocol;if(Y.FromPort!==void 0)$[`${Q}.FromPort`]=String(Y.FromPort);if(Y.ToPort!==void 0)$[`${Q}.ToPort`]=String(Y.ToPort);if(Y.IpRanges)Y.IpRanges.forEach((G,W)=>{if(G.CidrIp)$[`${Q}.IpRanges.${W+1}.CidrIp`]=G.CidrIp;if(G.Description)$[`${Q}.IpRanges.${W+1}.Description`]=G.Description});if(Y.Ipv6Ranges)Y.Ipv6Ranges.forEach((G,W)=>{if(G.CidrIpv6)$[`${Q}.Ipv6Ranges.${W+1}.CidrIpv6`]=G.CidrIpv6;if(G.Description)$[`${Q}.Ipv6Ranges.${W+1}.Description`]=G.Description});if(Y.UserIdGroupPairs)Y.UserIdGroupPairs.forEach((G,W)=>{if(G.GroupId)$[`${Q}.Groups.${W+1}.GroupId`]=G.GroupId;if(G.UserId)$[`${Q}.Groups.${W+1}.UserId`]=G.UserId;if(G.Description)$[`${Q}.Groups.${W+1}.Description`]=G.Description})})}parseArray($){if(!$)return[];return Array.isArray($)?$:[$]}parseTags($){return this.parseArray($).map((J)=>({Key:J.key,Value:J.value}))}parseReservations($){return this.parseArray($).map((J)=>({ReservationId:J.reservationId,Instances:this.parseInstances(J.instancesSet?.item||J.instancesSet)}))}parseInstances($){return this.parseArray($).map((J)=>({InstanceId:J.instanceId,ImageId:J.imageId,InstanceType:J.instanceType,State:J.instanceState?{Code:Number.parseInt(J.instanceState.code),Name:J.instanceState.name}:void 0,PrivateIpAddress:J.privateIpAddress,PublicIpAddress:J.ipAddress,SubnetId:J.subnetId,VpcId:J.vpcId,SecurityGroups:this.parseArray(J.groupSet?.item).map((Y)=>({GroupId:Y.groupId,GroupName:Y.groupName})),Tags:this.parseTags(J.tagSet?.item),LaunchTime:J.launchTime,Placement:J.placement?{AvailabilityZone:J.placement.availabilityZone,Tenancy:J.placement.tenancy}:void 0,Architecture:J.architecture,RootDeviceType:J.rootDeviceType,RootDeviceName:J.rootDeviceName,BlockDeviceMappings:this.parseArray(J.blockDeviceMapping?.item).map((Y)=>({DeviceName:Y.deviceName,Ebs:Y.ebs?{VolumeId:Y.ebs.volumeId,Status:Y.ebs.status,AttachTime:Y.ebs.attachTime,DeleteOnTermination:Y.ebs.deleteOnTermination==="true"}:void 0})),IamInstanceProfile:J.iamInstanceProfile?{Arn:J.iamInstanceProfile.arn,Id:J.iamInstanceProfile.id}:void 0}))}parseIpPermissions($){return this.parseArray($).map((J)=>({IpProtocol:J.ipProtocol,FromPort:J.fromPort?Number.parseInt(J.fromPort):void 0,ToPort:J.toPort?Number.parseInt(J.toPort):void 0,IpRanges:this.parseArray(J.ipRanges?.item).map((Y)=>({CidrIp:Y.cidrIp,Description:Y.description})),Ipv6Ranges:this.parseArray(J.ipv6Ranges?.item).map((Y)=>({CidrIpv6:Y.cidrIpv6,Description:Y.description})),UserIdGroupPairs:this.parseArray(J.groups?.item).map((Y)=>({GroupId:Y.groupId,UserId:Y.userId,Description:Y.description}))}))}}var y9=Y0(()=>{G0()});class v9{client;region;constructor($="us-east-1",J){this.region=$,this.client=new $0}async putParameter($){let J={Name:$.Name,Value:$.Value};if($.Type)J.Type=$.Type;if($.Description)J.Description=$.Description;if($.KeyId)J.KeyId=$.KeyId;if($.Overwrite!==void 0)J.Overwrite=$.Overwrite;if($.AllowedPattern)J.AllowedPattern=$.AllowedPattern;if($.Tags&&$.Tags.length>0)J.Tags=$.Tags;if($.Tier)J.Tier=$.Tier;if($.DataType)J.DataType=$.DataType;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.PutParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Version:Y.Version,Tier:Y.Tier}}async getParameter($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameter:Y.Parameter?this.parseParameter(Y.Parameter):void 0}}async getParameters($){let J={Names:$.Names};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>this.parseParameter(Z)),InvalidParameters:Y.InvalidParameters}}async getParametersByPath($){let J={Path:$.Path};if($.Recursive!==void 0)J.Recursive=$.Recursive;if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;if($.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParametersByPath","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:Y.NextToken}}async deleteParameter($){let J={Name:$.Name};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameter","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async deleteParameters($){let J={Names:$},Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DeleteParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{DeletedParameters:Y.DeletedParameters,InvalidParameters:Y.InvalidParameters}}async describeParameters($){let J={};if($?.Filters&&$.Filters.length>0)J.Filters=$.Filters;if($?.ParameterFilters&&$.ParameterFilters.length>0)J.ParameterFilters=$.ParameterFilters;if($?.MaxResults)J.MaxResults=$.MaxResults;if($?.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.DescribeParameters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>this.parseParameter(Z)),NextToken:Y.NextToken}}async getParameterHistory($){let J={Name:$.Name};if($.WithDecryption!==void 0)J.WithDecryption=$.WithDecryption;if($.MaxResults)J.MaxResults=$.MaxResults;if($.NextToken)J.NextToken=$.NextToken;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetParameterHistory","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Parameters:Y.Parameters?.map((Z)=>({Name:Z.Name,Type:Z.Type,KeyId:Z.KeyId,LastModifiedDate:Z.LastModifiedDate,LastModifiedUser:Z.LastModifiedUser,Description:Z.Description,Value:Z.Value,Version:Z.Version,Labels:Z.Labels,Tier:Z.Tier})),NextToken:Y.NextToken}}async labelParameterVersion($){let J={Name:$.Name,Labels:$.Labels};if($.ParameterVersion!==void 0)J.ParameterVersion=$.ParameterVersion;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.LabelParameterVersion","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{InvalidLabels:Y.InvalidLabels,ParameterVersion:Y.ParameterVersion}}async addTagsToResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,Tags:$.Tags};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.AddTagsToResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async removeTagsFromResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId,TagKeys:$.TagKeys};await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.RemoveTagsFromResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})}async listTagsForResource($){let J={ResourceType:$.ResourceType,ResourceId:$.ResourceId};return{TagList:(await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListTagsForResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})).TagList}}async setString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"String",Description:Y?.description,Overwrite:Y?.overwrite??!0,Tags:Y?.tags})}async setSecureString($,J,Y){return this.putParameter({Name:$,Value:J,Type:"SecureString",Description:Y?.description,Overwrite:Y?.overwrite??!0,KeyId:Y?.kmsKeyId,Tags:Y?.tags})}async getValue($){return(await this.getParameter({Name:$,WithDecryption:!0})).Parameter?.Value}async getAllByPath($,J=!0){let Y=[],Z;do{let Q=await this.getParametersByPath({Path:$,Recursive:J,WithDecryption:!0,NextToken:Z});if(Q.Parameters)Y.push(...Q.Parameters);Z=Q.NextToken}while(Z);return Y}parseParameter($){return{Name:$.Name,Type:$.Type,Value:$.Value,Version:$.Version,LastModifiedDate:$.LastModifiedDate,ARN:$.ARN,DataType:$.DataType,Description:$.Description,AllowedPattern:$.AllowedPattern,KeyId:$.KeyId,Tier:$.Tier}}async sendCommand($){if(!$.InstanceIds&&!$.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let J={DocumentName:$.DocumentName};if($.InstanceIds)J.InstanceIds=$.InstanceIds;if($.Targets)J.Targets=$.Targets;if($.Parameters)J.Parameters=$.Parameters;if($.TimeoutSeconds)J.TimeoutSeconds=$.TimeoutSeconds;if($.Comment)J.Comment=$.Comment;if($.OutputS3BucketName)J.OutputS3BucketName=$.OutputS3BucketName;if($.OutputS3KeyPrefix)J.OutputS3KeyPrefix=$.OutputS3KeyPrefix;let Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.SendCommand","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{CommandId:Y.Command?.CommandId,Status:Y.Command?.Status,StatusDetails:Y.Command?.StatusDetails}}async getCommandInvocation($){let J={CommandId:$.CommandId,InstanceId:$.InstanceId},Y=await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.GetCommandInvocation","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)});return{Status:Y.Status,StatusDetails:Y.StatusDetails,StandardOutputContent:Y.StandardOutputContent,StandardErrorContent:Y.StandardErrorContent,ResponseCode:Y.ResponseCode}}async runShellCommand($,J,Y){let Z=await this.sendCommand({InstanceIds:[$],DocumentName:"AWS-RunShellScript",Parameters:{commands:J},TimeoutSeconds:Y?.timeoutSeconds||600});if(!Z.CommandId)return{success:!1,error:"Failed to send command"};if(Y?.waitForCompletion===!1)return{success:!0,status:"Pending"};let Q=Y?.pollIntervalMs||2000,G=Y?.maxWaitMs||300000,W=Date.now();while(Date.now()-W<G){await new Promise((z)=>setTimeout(z,Q));try{let z=await this.getCommandInvocation({CommandId:Z.CommandId,InstanceId:$});if(z.Status==="Success")return{success:!0,output:z.StandardOutputContent,error:z.StandardErrorContent,status:z.Status};if(z.Status==="Failed"||z.Status==="Cancelled"||z.Status==="TimedOut")return{success:!1,output:z.StandardOutputContent,error:z.StandardErrorContent||z.StatusDetails,status:z.Status}}catch(z){if(!z.message?.includes("InvocationDoesNotExist"))return{success:!1,error:z.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations($){let J={CommandId:$.CommandId};if($.Details)J.Details=!0;return((await this.client.request({service:"ssm",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonSSM.ListCommandInvocations","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(J)})).CommandInvocations||[]).map((Q)=>({InstanceId:Q.InstanceId,Status:Q.Status,StatusDetails:Q.StatusDetails,StandardOutputContent:Q.CommandPlugins?.[0]?.Output,StandardErrorContent:Q.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags($){let J=Object.entries($.tags).map(([U,H])=>({Key:`tag:${U}`,Values:[H]})),Y=await this.sendCommand({Targets:J,DocumentName:"AWS-RunShellScript",Parameters:{commands:$.commands},TimeoutSeconds:$.timeoutSeconds||600,Comment:$.comment});if(!Y.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let Z=$.pollIntervalMs||3000,Q=$.maxWaitMs||600000,G=Date.now(),W=new Set(["Success","Failed","Cancelled","TimedOut"]),z=[];while(Date.now()-G<Q){await new Promise((U)=>setTimeout(U,Z));try{if(z=await this.listCommandInvocations({CommandId:Y.CommandId,Details:!0}),z.length===0)continue;if(z.every((H)=>W.has(H.Status||""))){let H=z.map((K)=>({instanceId:K.InstanceId,status:K.Status||"Unknown",output:K.StandardOutputContent,error:K.StandardErrorContent||K.StatusDetails})),X=z.every((K)=>K.Status==="Success");return{success:X,instanceCount:z.length,perInstance:H,error:X?void 0:"One or more instances reported a non-success status"}}}catch(U){if(!U.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:U.message}}}return{success:!1,instanceCount:z.length,perInstance:z.map((U)=>({instanceId:U.InstanceId,status:U.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}var lQ=Y0(()=>{G0()});function s7($){return`'${$.split("'").join("'\\''")}'`}function o7($={}){return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system","export PANTRY_INSTALL_DIR=/usr/local/bin",$.version?`export PANTRY_VERSION=${s7($.version)}`:'export PANTRY_VERSION="${PANTRY_VERSION:-latest}"',"command -v curl >/dev/null 2>&1 || (apt-get update -y && apt-get install -y curl ca-certificates)","command -v unzip >/dev/null 2>&1 || (apt-get update -y && apt-get install -y unzip)",'command -v pantry >/dev/null 2>&1 || { OS=$(uname -s | tr \'[:upper:]\' \'[:lower:]\'); ARCH=$(uname -m); case "$ARCH" in x86_64|amd64) ARCH=x64 ;; arm64|aarch64) ARCH=arm64 ;; esac; ZIP="pantry-${OS}-${ARCH}.zip"; if [ "${PANTRY_VERSION:-latest}" = latest ]; then REL=\'latest/download\'; else REL="download/v${PANTRY_VERSION}"; fi; TMP=$(mktemp -d); curl -fsSL -o "${TMP}/${ZIP}" "https://github.com/home-lang/pantry/releases/${REL}/${ZIP}"; unzip -o "${TMP}/${ZIP}" -d /usr/local/bin; chmod +x /usr/local/bin/pantry; rm -rf "${TMP}"; }','export PATH="/usr/local/bin:$PATH"',"mkdir -p /opt/pantry"]}function N$(){return'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true'}function X8($){if($.length===0)return[];return[`(cd /opt/pantry && pantry install ${[...new Set($)].map(s7).join(" ")})`]}function e7($){return[...new Set($)].flatMap((J)=>[`(cd /opt/pantry && pantry start ${s7(J)})`,`(cd /opt/pantry && pantry enable ${s7(J)})`])}var wX,g1="/opt/pantry";var j2=Y0(()=>{wX={php:"php.net",nginx:"nginx.org",composer:"getcomposer.org",mysql:"mysql.com",mariadb:"mariadb.com/server",postgres:"postgresql.org",redis:"redis.io",memcached:"memcached.org",meilisearch:"meilisearch.com",git:"git-scm.com",certbot:"certbot.eff.org",bun:"bun.sh",node:"nodejs.org",deno:"deno.land"}});function h2($){return $===!0||typeof $==="object"&&$!=null}function cT($){let J=[],Y=[];if(h2($.mysql))J.push(typeof $.mysql==="object"&&$.mysql.version?`mysql.com@${$.mysql.version}`:"mysql.com@8.0.43"),Y.push("mysql");else if(h2($.mariadb))J.push(wX.mariadb),Y.push("mariadb");if(h2($.postgres))J.push("postgresql.org"),Y.push("postgres");if(h2($.redis))J.push("redis.io"),Y.push("redis");if(h2($.memcached))J.push("memcached.org"),Y.push("memcached");if(h2($.meilisearch))J.push("meilisearch.com"),Y.push("meilisearch");return{packages:J,services:Y}}function f9($={},J={}){let Y=cT($);if(Y.packages.length===0)return[];return[...X8(Y.packages),...e7(Y.services)]}function g9($,J={}){if(!$?.name)return[];if($.host&&$.host!=="127.0.0.1"&&$.host!=="localhost")return[];let Y=$.name,Z=$.username||Y,Q=$.password||"",G=h2(J.postgres)||$.engine==="postgres",W=h2(J.mariadb)||$.engine==="mariadb",z=h2(J.mysql)||$.engine==="mysql";if(G&&!z&&!W){let V=(j)=>`"${j.replace(/"/g,'""')}"`,O=(j)=>`'${j.replace(/'/g,"''")}'`,A=(j,q)=>["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${O(j)}) THEN`,` CREATE ROLE ${V(j)} LOGIN PASSWORD ${O(q)};`," ELSE",` ALTER ROLE ${V(j)} LOGIN PASSWORD ${O(q)};`," END IF;","END $$;"],_=(j)=>{let q=j.databases&&j.databases.length>0?j.databases:[Y],E=[];for(let T of q)if(j.access==="readonly")E.push(`GRANT CONNECT ON DATABASE ${V(T)} TO ${V(j.username)};`,`\\connect ${V(T)}`,`GRANT USAGE ON SCHEMA public TO ${V(j.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${V(j.username)};`,`ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ${V(j.username)};`,"\\connect postgres");else E.push(`GRANT ALL PRIVILEGES ON DATABASE ${V(T)} TO ${V(j.username)};`);return E},M=$.users||[];return[N$(),"for i in $(seq 1 30); do pg_isready -h 127.0.0.1 -p 5432 -q && break; sleep 2; done","psql -h 127.0.0.1 -p 5432 -U postgres <<'TS_CLOUD_PG_EOF'",...A(Z,Q),`SELECT 'CREATE DATABASE ${V(Y)} OWNER ${V(Z)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${O(Y)})\\gexec`,...M.flatMap((j)=>[...A(j.username,j.password),..._(j)]),"TS_CLOUD_PG_EOF"]}let U=W?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",H=(V)=>V.replace(/`/g,"``"),X=(V)=>V.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),K=(V)=>{let O=V.databases&&V.databases.length>0?V.databases:[Y],A=V.access==="readonly"?"SELECT":"ALL PRIVILEGES",_=[`CREATE USER IF NOT EXISTS '${X(V.username)}'@'%' IDENTIFIED BY '${X(V.password)}';`,`CREATE USER IF NOT EXISTS '${X(V.username)}'@'localhost' IDENTIFIED BY '${X(V.password)}';`,`ALTER USER '${X(V.username)}'@'%' IDENTIFIED BY '${X(V.password)}';`,`ALTER USER '${X(V.username)}'@'localhost' IDENTIFIED BY '${X(V.password)}';`];for(let M of O)_.push(`GRANT ${A} ON \`${H(M)}\`.* TO '${X(V.username)}'@'%';`,`GRANT ${A} ON \`${H(M)}\`.* TO '${X(V.username)}'@'localhost';`);return _},B=$.users||[];return[N$(),`for i in $(seq 1 30); do mysqladmin --socket=${U} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${U} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${H(Y)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...K({username:Z,password:Q}),...B.flatMap(K),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}function NX($){if(!$?.name)return{};let J=$.engine==="singlestore",Y=$.engine==="postgres"?"pgsql":J?"singlestore":"mysql",Z=$.port??($.engine==="postgres"?5432:3306),Q={DB_CONNECTION:Y,DB_HOST:$.host||"127.0.0.1",DB_PORT:String(Z),DB_DATABASE:$.name};if($.username)Q.DB_USERNAME=$.username;if($.password)Q.DB_PASSWORD=$.password;if(J&&$.ssl!==!1)Q.DB_SSL="true";return Q}var $5=Y0(()=>{j2()});function PX($){return lT}function pT($={}){let J=$.versions?.length?$.versions:["8.3"];return $.default&&J.includes($.default)?$.default:J[0]}function rT($={}){return{...$.optimizeForProduction===!1?{}:{...mT},...$.ini||{}}}function nT($={}){let J=rT($),Y=Object.keys(J);if(Y.length===0)return[];let Z=Y.map((G)=>`${G}=${J[G]}`),Q="ts-cloud-managed";return[N$(),"TS_CLOUD_SCAN_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Scan this dir for additional .ini files/{print $2}' | head -1)",`TS_CLOUD_LOADED_INI=$(php -r 'echo php_ini_loaded_file() ?: "";' 2>/dev/null)`,'if [ -n "$TS_CLOUD_SCAN_DIR" ] && [ "$TS_CLOUD_SCAN_DIR" != "(none)" ]; then',' mkdir -p "$TS_CLOUD_SCAN_DIR"',' TS_CLOUD_PHP_INI="$TS_CLOUD_SCAN_DIR/zz-ts-cloud.ini"',` cat > "$TS_CLOUD_PHP_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${Q} — production PHP tuning`,...Z,"TS_CLOUD_PHPINI_EOF","else",' if [ -z "$TS_CLOUD_LOADED_INI" ]; then'," TS_CLOUD_INI_DIR=$(php -i 2>/dev/null | awk -F' => ' '/^Configuration File \\(php.ini\\) Path/{print $2}' | head -1)",' TS_CLOUD_LOADED_INI="$TS_CLOUD_INI_DIR/php.ini"',' mkdir -p "$TS_CLOUD_INI_DIR"',' touch "$TS_CLOUD_LOADED_INI"'," fi",` sed -i '/; ${Q} BEGIN/,/; ${Q} END/d' "$TS_CLOUD_LOADED_INI"`,` cat >> "$TS_CLOUD_LOADED_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${Q} BEGIN`,...Z,`; ${Q} END`,"TS_CLOUD_PHPINI_EOF","fi",`(cd ${g1} && pantry restart php-fpm) 2>/dev/null || true`]}function J5($={}){let J=pT($),Y=$.installNginx!==!1,Z=$.installComposer!==!1,Q=[`php.net@${J}`];if(Z)Q.push("getcomposer.org");if(Y)Q.push("nginx.org");return[...X8(Q),...e7(["php-fpm"]),...nT($)]}var mT,lT="127.0.0.1:9074";var Y5=Y0(()=>{j2();mT={"opcache.enable":"1","opcache.enable_cli":"1","opcache.memory_consumption":"256","opcache.interned_strings_buffer":"16","opcache.max_accelerated_files":"20000","opcache.validate_timestamps":"0","opcache.revalidate_freq":"0","opcache.save_comments":"1","opcache.fast_shutdown":"1",realpath_cache_size:"4096K",realpath_cache_ttl:"600"}});function pQ($,J){if(!$)return[];let Y=[];if($.template&&J?.[$.template])Y.push(...J[$.template]);if($.serverSnippet)Y.push(...$.serverSnippet);return Y}function iT($){if(!$)return"";let J=typeof $==="object"?$:{},Z=[`max-age=${J.maxAge??31536000}`];if(J.includeSubDomains??!0)Z.push("includeSubDomains");if(J.preload)Z.push("preload");return` add_header Strict-Transport-Security "${Z.join("; ")}" always;`}function aT($){if(!$||!$.allow?.length&&!$.deny?.length)return[];let J=[];for(let Y of $.deny||[])J.push(` deny ${Y};`);if($.allow?.length){for(let Y of $.allow)J.push(` allow ${Y};`);J.push(" deny all;")}return J}function SX($){return`/etc/nginx/.htpasswd-${$}`}function sT($){return tT.has($)}function oT($){return $==="laravel"||$==="statamic"?"public":""}function eT($,J){let Y=$.replace(/\/+$/,""),Z=J.replace(/^\/+|\/+$/g,"");return Z?`${Y}/${Z}`:Y}function $R($){let J=$.type??"laravel",Y=$.webDirectory??oT(J),Z=eT($.appDir,Y),Q=sT(J),G=$.phpVersion??"8.3",W=[` root ${Z};`,"",' add_header X-Frame-Options "SAMEORIGIN";',' add_header X-Content-Type-Options "nosniff";'],z=iT($.hsts);if(z)W.push(z);for(let U of aT($.security))W.push(U);if(W.push("",` index ${Q?"index.php index.html":"index.html index.htm"};`,""," charset utf-8;",""),$.clientMaxBodySize)W.push(` client_max_body_size ${$.clientMaxBodySize};`,"");if($.auth)W.push(` auth_basic "${$.auth.realm||"Restricted"}";`,` auth_basic_user_file ${SX($.siteName)};`,"");for(let[U,H]of Object.entries($.redirects||{}))W.push(` location = ${U} { return 301 ${H}; }`);if(Object.keys($.redirects||{}).length>0)W.push("");if(Q){if(W.push(" location / {"," try_files $uri $uri/ /index.php?$query_string;"," }",""," location = /favicon.ico { access_log off; log_not_found off; }"," location = /robots.txt { access_log off; log_not_found off; }",""," error_page 404 /index.php;",""," location ~ \\.php$ {",` fastcgi_pass ${$.fastcgiPass??PX(G)};`," fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;"," include fastcgi_params;"," }",""," location ~ /\\.(?!well-known).* {"," deny all;"," }"),J==="wordpress")W.push(""," location = /xmlrpc.php { deny all; }"," location ~* /(?:wp-config\\.php|readme\\.html|license\\.txt)$ { deny all; }"," location ~* /wp-content/uploads/.*\\.php$ { deny all; }")}else if(J==="spa")W.push(" location / {"," try_files $uri $uri/ /index.html;"," }");else W.push(" location / {"," try_files $uri $uri/ =404;"," }");if($.serverSnippet&&$.serverSnippet.length>0){W.push("");for(let U of $.serverSnippet)W.push(U?` ${U}`:"")}return W}function JR($){let J=[$.domain,...$.aliases||[]].filter(Boolean).join(" "),Y=$R($);if($.ssl){let Q=["server {"," listen 80;"," listen [::]:80;",` server_name ${J};`," return 301 https://$host$request_uri;","}"],G=["server {"," listen 443 ssl;"," listen [::]:443 ssl;",` server_name ${J};`,` ssl_certificate ${$.ssl.certPath};`,` ssl_certificate_key ${$.ssl.keyPath};`,...$.tlsProtocols?.length?[` ssl_protocols ${$.tlsProtocols.join(" ")};`]:[],"",...Y,"}"];return`${[...Q,"",...G].join(`
|
|
7279
7279
|
`)}
|
|
7280
7280
|
`}return`${["server {"," listen 80;"," listen [::]:80;",` server_name ${J};`,...Y,"}"].join(`
|
|
7281
7281
|
`)}
|
|
@@ -7466,7 +7466,7 @@ ${B.join(`
|
|
|
7466
7466
|
`)}
|
|
7467
7467
|
`}return K+=`
|
|
7468
7468
|
echo "ts-cloud bootstrap complete — instance is ready for site deploys"
|
|
7469
|
-
`,K}function dX($){let J=[{port:22,protocol:"tcp",cidr:"0.0.0.0/0"},{port:80,protocol:"tcp",cidr:"0.0.0.0/0"},{port:443,protocol:"tcp",cidr:"0.0.0.0/0"}],Y=new Set;for(let Z of Object.values($.sites||{}))if(Z&&typeof Z.port==="number"&&![22,80,443].includes(Z.port))Y.add(Z.port);for(let Z of Y)J.push({port:Z,protocol:"tcp",cidr:"0.0.0.0/0"});return J}function cX($){let J=$.infrastructure?.compute??{},Y=p9($);return s1({runtime:Y.runtime,runtimeVersion:Y.runtimeVersion,systemPackages:J.systemPackages,database:$.infrastructure?.database,phpProvision:Y.phpProvision,servicesProvision:Y.servicesProvision,baked:J.bakedImage===!0})}function mX($){return Buffer.from($,"utf8").toString("base64")}function lX($){return $.infrastructure?.compute?.image??null}var uX="/aws/service/canonical/ubuntu/server/24.04/stable/current/amd64/hvm/ebs-gp3/ami-id";var pX=Y0(async()=>{await GG()});import{readFileSync as rX}from"node:fs";import{join as LR}from"node:path";function MR($){try{let J=rX(LR(process.cwd(),"
|
|
7469
|
+
`,K}function dX($){let J=[{port:22,protocol:"tcp",cidr:"0.0.0.0/0"},{port:80,protocol:"tcp",cidr:"0.0.0.0/0"},{port:443,protocol:"tcp",cidr:"0.0.0.0/0"}],Y=new Set;for(let Z of Object.values($.sites||{}))if(Z&&typeof Z.port==="number"&&![22,80,443].includes(Z.port))Y.add(Z.port);for(let Z of Y)J.push({port:Z,protocol:"tcp",cidr:"0.0.0.0/0"});return J}function cX($){let J=$.infrastructure?.compute??{},Y=p9($);return s1({runtime:Y.runtime,runtimeVersion:Y.runtimeVersion,systemPackages:J.systemPackages,database:$.infrastructure?.database,phpProvision:Y.phpProvision,servicesProvision:Y.servicesProvision,baked:J.bakedImage===!0})}function mX($){return Buffer.from($,"utf8").toString("base64")}function lX($){return $.infrastructure?.compute?.image??null}var uX="/aws/service/canonical/ubuntu/server/24.04/stable/current/amd64/hvm/ebs-gp3/ami-id";var pX=Y0(async()=>{await GG()});import{readFileSync as rX}from"node:fs";import{join as LR}from"node:path";function MR($){try{let J=rX(LR(process.cwd(),"storage/cloud/state",`${$}.json`),"utf8"),Y=JSON.parse(J);return typeof Y.instanceId==="string"&&Y.instanceId.length>0?Y.instanceId:null}catch{return null}}class r9{name="aws";usesCloudFormation=!0;region;constructor($={}){this.region=$.region||"us-east-1"}resolveRegion($){return $.project.region||this.region}async provisionComputeInfrastructure($){let{config:J,environment:Y}=$,Z=this.resolveRegion(J),Q=J.project.slug,G=J.infrastructure?.compute;if(!G)throw Error("infrastructure.compute is required to provision AWS compute");let W=new s0(Z),z=await this.findComputeTargets({slug:Q,environment:Y,role:"app"});if(z.length>0){let N=z[0];return{appInstanceId:N.id,appPublicIp:N.publicIp,sshUser:"ubuntu",deployStoragePath:"/var/ts-cloud/staging"}}let U=lX(J);if(!U){if(U=(await new v9(Z).getParameter({Name:uX})).Parameter?.Value??null,!U)throw Error("Could not resolve the Ubuntu 24.04 AMI from SSM")}let H=await W.describeVpcs(),X=(H.Vpcs||[]).find((N)=>N.IsDefault)||(H.Vpcs||[])[0];if(!X?.VpcId)throw Error("No VPC found to launch the instance into");let K=(await W.describeSubnets({Filters:[{Name:"vpc-id",Values:[X.VpcId]}]})).Subnets||[],B=K.find((N)=>N.MapPublicIpOnLaunch)||K[0],V=B?.SubnetId;if(!B?.MapPublicIpOnLaunch)console.warn("ts-cloud: no public subnet found; the instance may not get a public IP (deploys/SSL need one).");let O=`${Q}-${Y}-app-sg`,_=(await W.describeSecurityGroups({Filters:[{Name:"group-name",Values:[O]},{Name:"vpc-id",Values:[X.VpcId]}]})).SecurityGroups?.[0]?.GroupId;if(!_)_=(await W.createSecurityGroup({GroupName:O,Description:`ts-cloud ${Q}/${Y} app`,VpcId:X.VpcId})).GroupId;let M=dX(J);await W.authorizeSecurityGroupIngress({GroupId:_,IpPermissions:M.map((N)=>({IpProtocol:N.protocol,FromPort:N.port,ToPort:N.port,IpRanges:[{CidrIp:N.cidr}]}))}).catch((N)=>{if(!/InvalidPermission\.Duplicate/.test(N instanceof Error?N.message:""))throw N});let j=mX(cX(J)),q=G.server?.instanceType||"t3.small",T=(await W.runInstances({ImageId:U,InstanceType:q,MinCount:1,MaxCount:1,SecurityGroupIds:_?[_]:void 0,SubnetId:V,UserData:j,IamInstanceProfile:G.server?.iamInstanceProfile?{Name:G.server.iamInstanceProfile}:void 0,TagSpecifications:[{ResourceType:"instance",Tags:[{Key:"Name",Value:`${Q}-${Y}-app`},{Key:"Project",Value:Q},{Key:"Environment",Value:Y},{Key:"Role",Value:"app"}]}]})).Instances?.[0]?.InstanceId;if(!T)throw Error("RunInstances did not return an instance id");let w=await W.waitForInstanceState(T,"running");if(!w)throw Error(`Instance ${T} did not reach 'running' before timeout`);return{appInstanceId:T,appPublicIp:w.PublicIpAddress,sshUser:"ubuntu",deployStoragePath:"/var/ts-cloud/staging"}}async destroyCompute($){let{config:J,environment:Y}=$,Z=this.resolveRegion(J),Q=new s0(Z),G=[],z=(await this.findComputeTargets({slug:J.project.slug,environment:Y,role:"app"})).map((K)=>K.id);if(z.length>0)await Q.terminateInstances(z),G.push(...z.map((K)=>`instance ${K}`)),await Promise.all(z.map((K)=>Q.waitForInstanceState(K,"terminated").catch(()=>{return})));let U=`${J.project.slug}-${Y}-app-sg`,X=(await Q.describeSecurityGroups({Filters:[{Name:"group-name",Values:[U]}]}).catch(()=>({SecurityGroups:[]}))).SecurityGroups?.[0]?.GroupId;if(X)for(let K=0;K<10;K++)try{await Q.deleteSecurityGroup(X),G.push(`security group ${U}`);break}catch{await new Promise((B)=>setTimeout(B,3000))}return{destroyed:G}}async getComputeOutputs($){let J=this.resolveRegion($.config),Y=a0($.config,$.environment),Z=new A0(J);try{let Q=await Z.getStackOutputs(Y);return{deployBucketName:Q.deployBucketName,appInstanceId:Q.appInstanceId,appPublicIp:Q.appPublicIp,sshUser:"ec2-user"}}catch(Q){if(!/does not exist|ValidationError/i.test(Q instanceof Error?Q.message:""))throw Q;let W=(await this.findComputeTargets({slug:$.config.project.slug,environment:$.environment,role:"app"}))[0];return{appInstanceId:W?.id,appPublicIp:W?.publicIp,sshUser:"ubuntu",deployStoragePath:"/var/ts-cloud/staging"}}}async uploadRelease($){let J=this.resolveRegion($.config),Z=(await this.getComputeOutputs({config:$.config,environment:$.environment})).deployBucketName;if(!Z)throw Error("No deployBucketName in stack outputs. Re-deploy infrastructure to add the staging bucket.");return await new H0(J).putObject({bucket:Z,key:$.remoteKey,body:rX($.localPath),contentType:"application/gzip"}),{artifactRef:`s3://${Z}/${$.remoteKey}`}}async findComputeTargets($){let J=this.region,Y=new s0(J),Z=[{Name:"tag:Project",Values:[$.slug]},{Name:"tag:Environment",Values:[$.environment]},{Name:"tag:Role",Values:[$.role||"app"]},{Name:"instance-state-name",Values:["running","pending"]}],Q=await Y.describeInstances({Filters:Z}),G=this.reservationsToTargets(Q.Reservations);if(G.length>0||($.role||"app")!=="app")return G;let W=$.stackName??`${$.slug}-${$.environment}`,z=MR(W);if(!z)try{z=(await new A0(J).getStackOutputs(W)).appInstanceId??null}catch{z=null}if(!z)return[];try{let U=await Y.describeInstances({InstanceIds:[z],Filters:[{Name:"instance-state-name",Values:["running","pending"]}]});return this.reservationsToTargets(U.Reservations)}catch{return[]}}reservationsToTargets($){let J=[];for(let Y of $||[])for(let Z of Y.Instances||[]){if(!Z.InstanceId)continue;let Q=Z.Tags?.find((G)=>G.Key==="Name")?.Value;J.push({id:Z.InstanceId,name:Q,publicIp:Z.PublicIpAddress,privateIp:Z.PrivateIpAddress,status:Z.State?.Name})}return J}bashWrap($){return["bash <<'TS_CLOUD_BASH_EOF'",$.join(`
|
|
7470
7470
|
`),"TS_CLOUD_BASH_EOF"]}async runRemoteDeploy($){let J=this.region,Y=new v9(J);if($.targets.length>0){let Q=await Y.sendCommand({InstanceIds:$.targets.map((G)=>G.id),DocumentName:"AWS-RunShellScript",Parameters:{commands:this.bashWrap($.commands)},TimeoutSeconds:$.timeoutSeconds||600,Comment:$.comment});if(!Q.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send SSM command"};return this.pollSsmCommand(Y,Q.CommandId,$.targets.length)}if(!$.tags||Object.keys($.tags).length===0)return{success:!1,instanceCount:0,perInstance:[],error:"No targets or tags provided for AWS deploy"};let Z=await Y.sendCommandByTags({tags:$.tags,commands:this.bashWrap($.commands),timeoutSeconds:$.timeoutSeconds||600,comment:$.comment});return{success:Z.success,instanceCount:Z.instanceCount,perInstance:Z.perInstance.map((Q)=>({instanceId:Q.instanceId,status:Q.status,output:Q.output,error:Q.error})),error:Z.error}}async pollSsmCommand($,J,Y){let G=Date.now(),W=new Set(["Success","Failed","Cancelled","TimedOut"]),z=[];while(Date.now()-G<600000){await new Promise((X)=>setTimeout(X,3000));try{if(z=await $.listCommandInvocations({CommandId:J,Details:!0}),z.length>=Y&&z.every((K)=>W.has(K.Status||"")))break}catch{}}let U=z.map((X)=>({instanceId:X.InstanceId,status:X.Status||"Unknown",output:X.StandardOutputContent,error:X.StandardErrorContent})),H=U.length>0&&U.every((X)=>X.status==="Success");return{success:H,instanceCount:U.length,perInstance:U,error:H?void 0:"One or more SSM command invocations failed"}}}var WG=Y0(async()=>{_1();y9();k0();lQ();await u2([f0(),pX()])});import{homedir as ER}from"node:os";import{join as qR}from"node:path";function nX($){return $.startsWith("~/")?qR(ER(),$.slice(2)):$}function j8(...$){for(let J of $){let Y=process.env[J]?.trim();if(Y)return Y}return}function L8(...$){for(let J of $){let Y=J?.trim();if(Y)return Y}return}function zG($,J){return L8($,J?.hetzner?.apiToken,j8("HCLOUD_TOKEN","HETZNER_API_TOKEN"))}function UG($,J){return L8(J,$?.hetzner?.location,j8("HCLOUD_LOCATION","HETZNER_LOCATION"))??U5.location}function n9($,J){let Y=$?.infrastructure?.compute;return L8(J,Y?.image,$?.hetzner?.image,j8("HCLOUD_IMAGE","HETZNER_IMAGE"))??U5.image}function TR($,J){return L8(J,$?.hetzner?.sshUser,j8("HCLOUD_SSH_USER","HETZNER_SSH_USER"))??U5.sshUser}function iX($,J){return nX(L8(J,$?.hetzner?.sshPrivateKeyPath,j8("HCLOUD_SSH_KEY","HETZNER_SSH_KEY"))??U5.sshPrivateKeyPath)}function RR($,J,Y){let Z=L8(J,$?.hetzner?.sshPublicKeyPath,j8("HCLOUD_SSH_PUBLIC_KEY","HETZNER_SSH_PUBLIC_KEY"));if(Z)return nX(Z);return`${Y??iX($)}.pub`}function aX($,J={}){let Y=iX($,J.sshPrivateKeyPath);return{apiToken:zG(J.apiToken,$),location:UG($,J.location),image:n9($,J.image),sshUser:TR($,J.sshUser),sshPrivateKeyPath:Y,sshPublicKeyPath:RR($,J.sshPublicKeyPath,Y)}}var U5;var H5=Y0(()=>{U5={location:"fsn1",image:"ubuntu-24.04",sshUser:"root",sshPrivateKeyPath:"~/.ssh/id_ed25519"}});class i9{name="hetzner";apiToken;baseUrl;fetchImpl;constructor($){this.apiToken=$.apiToken,this.baseUrl=$.baseUrl??DR,this.fetchImpl=$.fetchImpl??fetch}async request($,J,Y){let Z=await this.fetchImpl(`${this.baseUrl}${J}`,{method:$,headers:{Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},body:Y===void 0?void 0:JSON.stringify(Y)}),Q=await Z.text(),G;try{G=Q?JSON.parse(Q):{}}catch{if(!Z.ok){let W=Q.trim().slice(0,200)||Z.statusText||"Hetzner API error";throw Error(`Hetzner API ${$} ${J} (${Z.status}): ${W}`)}throw Error(`Hetzner API ${$} ${J}: unexpected non-JSON response`)}if(!Z.ok){let W=G.error?.message||Z.statusText||"Hetzner API error",z=G.error?.code?` [${G.error.code}]`:"";throw Error(`Hetzner API ${$} ${J} (${Z.status})${z}: ${W}`)}return G}async listServers(){return(await this.request("GET","/servers")).servers}async getServer($){return(await this.request("GET",`/servers/${$}`)).server}async createServer($){let J=await this.request("POST","/servers",{name:$.name,server_type:$.serverType,image:$.image,location:$.location,datacenter:$.datacenter,ssh_keys:$.sshKeys,user_data:$.userData,labels:$.labels,firewalls:$.firewalls,networks:$.networks,start_after_create:!0});return{server:J.server,action:J.action}}async listNetworks(){return(await this.request("GET","/networks")).networks}async createNetwork($){let J=$.ipRange??"10.0.0.0/16";return(await this.request("POST","/networks",{name:$.name,ip_range:J,subnets:[{type:"cloud",ip_range:J,network_zone:"eu-central"}],labels:$.labels})).network}async deleteNetwork($){await this.request("DELETE",`/networks/${$}`)}async listLoadBalancers(){return(await this.request("GET","/load_balancers")).load_balancers}async createLoadBalancer($){return(await this.request("POST","/load_balancers",{name:$.name,load_balancer_type:$.type??"lb11",location:$.location,network_zone:$.network?void 0:$.networkZone??"eu-central",network:$.network,labels:$.labels,targets:[{type:"label_selector",label_selector:{selector:$.labelSelector},use_private_ip:!!$.network}],services:$.services.map((Y)=>({protocol:Y.protocol??"tcp",listen_port:Y.listenPort,destination_port:Y.destinationPort,health_check:{protocol:"http",port:80,interval:15,timeout:10,retries:3,http:{path:"/",status_codes:["2??","3??"]}}}))})).load_balancer}async deleteLoadBalancer($){await this.request("DELETE",`/load_balancers/${$}`)}async deleteServer($){return(await this.request("DELETE",`/servers/${$}`)).action}async listFirewalls(){return(await this.request("GET","/firewalls")).firewalls}async createFirewall($){let J=await this.request("POST","/firewalls",{name:$.name,rules:$.rules,labels:$.labels,apply_to:$.applyTo});return{firewall:J.firewall,actions:J.actions}}async setFirewallRules($,J){return(await this.request("POST",`/firewalls/${$}/actions/set_rules`,{rules:J})).actions??[]}async deleteFirewall($){await this.request("DELETE",`/firewalls/${$}`)}async applyFirewallToResources($,J){return(await this.request("POST",`/firewalls/${$}/actions/apply_to_resources`,{apply_to:J})).actions}async listSshKeys(){return(await this.request("GET","/ssh_keys")).ssh_keys}async createSshKey($){return(await this.request("POST","/ssh_keys",{name:$.name,public_key:$.publicKey,labels:$.labels})).ssh_key}async waitForAction($,J){let Y=J?.pollIntervalMs??2000,Z=J?.maxWaitMs??300000,Q=Date.now();while(Date.now()-Q<Z){let G=await this.request("GET",`/actions/${$}`);if(G.action.status==="success")return G.action;if(G.action.status==="error")throw Error(G.action.error?.message||"Hetzner action failed");await new Promise((W)=>setTimeout(W,Y))}throw Error(`Timed out waiting for Hetzner action ${$}`)}async waitForServerRunning($,J){let Y=J?.pollIntervalMs??3000,Z=J?.maxWaitMs??600000,Q=Date.now();while(Date.now()-Q<Z){let G=await this.getServer($);if(G.status==="running")return G;await new Promise((W)=>setTimeout(W,Y))}throw Error(`Timed out waiting for server ${$} to reach running state`)}}function X5($,J){let Y=zG($,J);if(!Y)throw Error("Hetzner API token required. Set hetzner.apiToken in cloud.config.ts or HCLOUD_TOKEN / HETZNER_API_TOKEN.");return Y}function M8($){let[J,Y]=$.trim().split(/\s+/);return Y?`${J} ${Y}`:J}var DR="https://api.hetzner.cloud/v1";var F5=Y0(()=>{H5()});function y2($){return`#cloud-config
|
|
7471
7471
|
write_files:
|
|
7472
7472
|
- path: /var/lib/cloud/ts-cloud-bootstrap.sh
|
|
@@ -7479,7 +7479,7 @@ ${$.split(`
|
|
|
7479
7479
|
runcmd:
|
|
7480
7480
|
- [ bash, /var/lib/cloud/ts-cloud-bootstrap.sh ]
|
|
7481
7481
|
`}var HG=()=>{};function tX($={}){let J=Math.max(1,$.appServers??$.instances??1),Y=!!$.servicesServer||J>1,Z=J>1||!!$.server?.loadBalancer;return{appServers:J,loadBalancer:Z,dedicatedServices:Y,servicesOnApp:!Y}}function sX($,J){let Y={REDIS_HOST:$,MEILISEARCH_HOST:`http://${$}:7700`};if(J?.name){if(Y.DB_CONNECTION=J.engine==="postgres"?"pgsql":"mysql",Y.DB_HOST=$,Y.DB_PORT=String(J.port??(J.engine==="postgres"?5432:3306)),Y.DB_DATABASE=J.name,J.username)Y.DB_USERNAME=J.username;if(J.password)Y.DB_PASSWORD=J.password}return Y}function K5($){let J=new Set([80,443,...$.sitePorts]);if($.allowSsh)J.add(22);return[...J].map((Y)=>{return{direction:"in",protocol:"tcp",port:String(Y),source_ips:["0.0.0.0/0","::/0"],description:`ts-cloud port ${Y}`}})}function S$($){if(!$)return XG.micro;if($ in XG)return XG[$];return $}function H1($,J,Y="app"){return{[`${j1}/project`]:$,[`${j1}/environment`]:J,[`${j1}/role`]:Y,[`${j1}/managed-by`]:"ts-cloud"}}function U2($,J,Y,Z="app"){if(!$)return!1;return $[`${j1}/project`]===J&&$[`${j1}/environment`]===Y&&$[`${j1}/role`]===Z}var XG,j1="ts-cloud";var oX=Y0(()=>{XG={micro:"cpx11",small:"cx23",medium:"cx33",large:"cx43",xlarge:"cx53","2xlarge":"ccx33"}});import{mkdir as wR,readFile as NR,writeFile as PR}from"node:fs/promises";import{join as eX}from"node:path";function JF($){return eX(process.cwd(),$F,`${$}.json`)}async function C$($){try{let J=await NR(JF($),"utf8");return JSON.parse(J)}catch{return null}}async function E8($,J){let Y=JF($);await wR(eX(process.cwd(),$F),{recursive:!0}),await PR(Y,`${JSON.stringify(J,null,2)}
|
|
7482
|
-
`,"utf8")}var $F="
|
|
7482
|
+
`,"utf8")}var $F="storage/cloud/state";var YF=()=>{};import{existsSync as SR,readFileSync as CR}from"node:fs";import{execSync as FG}from"node:child_process";function ZF($){return(Buffer.isBuffer($)?$.toString("utf8"):typeof $==="string"?$:"").replace(/(^|\n)([A-Z][A-Z0-9_]*=).*$/gm,"$1$2[redacted]").replace(/encrypted:[A-Za-z0-9+/=]+/g,"encrypted:[redacted]").trim().slice(-xR)}function QF($){let J=$,Y=typeof J?.status==="number"?` (exit ${J.status})`:"",Z=J?.signal?` (signal ${J.signal})`:"",Q=[ZF(J?.stderr),ZF(J?.stdout)].filter(Boolean).join(`
|
|
7483
7483
|
`);return`Remote SSH command failed${Y}${Z}${Q?`
|
|
7484
7484
|
${Q}`:""}`}var KG=268435456,xR=8000,v2;var BG=Y0(async()=>{F5();H5();HG();Y5();$5();JG();oX();YF();await u2([f0(),c9(),GG()]);v2=class v2{name="hetzner";usesCloudFormation=!1;client;sshPrivateKeyPath;sshPublicKeyPath;sshUser;location;waitForBoot;bootWait;constructor($={}){this.client=$.client??new i9({apiToken:X5($.apiToken)});let J=aX(void 0,{sshPrivateKeyPath:$.sshPrivateKeyPath,sshPublicKeyPath:$.sshPublicKeyPath,sshUser:$.sshUser,location:$.location});this.sshPrivateKeyPath=J.sshPrivateKeyPath,this.sshPublicKeyPath=J.sshPublicKeyPath,this.sshUser=J.sshUser,this.location=J.location,this.waitForBoot=$.waitForBoot??!0,this.bootWait={sshIntervalMs:$.bootWait?.sshIntervalMs??5000,sshTimeoutMs:$.bootWait?.sshTimeoutMs??300000,cloudInitIntervalMs:$.bootWait?.cloudInitIntervalMs??5000,cloudInitTimeoutMs:$.bootWait?.cloudInitTimeoutMs??600000}}async provisionComputeInfrastructure($){let{config:J,environment:Y}=$,Z=J.project.slug,Q=J.infrastructure?.compute;if(!Q)throw Error("infrastructure.compute is required to provision Hetzner compute");let G=a0(J,Y),W=`${Z}-${Y}-app`,z=Q.runtime==="php"||!!Q.php,U=tX(Q);if(U.dedicatedServices||U.appServers>1)return z?this.provisionFleet($,U):this.provisionBunFleet($,U);let H=await C$(G);if(H?.serverId){let k=await this.tryGetServer(H.serverId);if(k&&k.status!=="off")return this.outputsFromState(H,k)}let X=H1(Z,Y,"app"),K=await this.findExistingServer(Z,Y,W);if(K&&K.status!=="off"){let k={provider:"hetzner",stackName:G,serverId:K.id,serverName:K.name,publicIp:K.public_net.ipv4?.ip,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser};return await E8(G,k),this.outputsFromState(k,K)}let B=J.sites||{},V=this.collectUpstreamPorts(B),O=Q.proxy?.engine==="rpx"?V8({proxy:Q.proxy,config:d9(B,{proxy:Q.proxy,slug:J.project.slug}),slug:J.project.slug,bunBin:Q.runtime==="node"||Q.runtime==="deno"?void 0:"/usr/local/bin/bun"}):void 0,A=p9(J),_=Q.bakedImage===!0,M=s1({runtime:A.runtime,runtimeVersion:A.runtimeVersion,systemPackages:Q.systemPackages,database:J.infrastructure?.database,phpProvision:A.phpProvision,servicesProvision:A.servicesProvision,rpxProvision:O,baked:_}),j=y2(M),q=S$(Q.size),E=n9(J),T=`${Z}-${Y}-app-fw`,{firewall:w}=await this.ensureFirewall(T,X,K5({allowSsh:Q.allowSsh!==!1,sitePorts:V})),N=await this.ensureSshKey(Z,Y,X),{server:I,action:x}=await this.client.createServer({name:W,serverType:q,image:E,location:J.hetzner?.location||this.location,userData:j,labels:X,sshKeys:N?[N]:void 0,firewalls:[{firewall:w.id}]});await this.client.waitForAction(x.id);let h=await this.client.waitForServerRunning(I.id),S={provider:"hetzner",stackName:G,serverId:h.id,serverName:h.name,firewallId:w.id,publicIp:h.public_net.ipv4?.ip,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser};await E8(G,S);let g=h.public_net.ipv4?.ip;if(g&&this.waitForBoot)await this.waitForSshReady(g),await this.waitForCloudInit(g);return this.outputsFromState(S,h)}async provisionFleet($,J){let{config:Y,environment:Z}=$,Q=Y.project.slug,G=Y.infrastructure.compute,W=a0(Y,Z),z=S$(G.size),U=n9(Y),H=Y.hetzner?.location||this.location,X=G.bakedImage===!0,K=await C$(W);if(K?.loadBalancerId){let m=(await this.client.listLoadBalancers().catch(()=>[])).find((s)=>s.id===K.loadBalancerId);if(m)return{appPublicIp:m.public_net?.ipv4?.ip,loadBalancerIp:m.public_net?.ipv4?.ip,servicesPrivateIp:K.servicesPrivateIp,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser}}let B=await this.ensureSshKey(Q,Z,H1(Q,Z,"app")),V=`${Q}-${Z}-net`,A=(await this.client.listNetworks().catch(()=>[])).find((u)=>u.name===V)??await this.client.createNetwork({name:V,labels:H1(Q,Z,"app")}),{firewall:_}=await this.ensureFirewall(`${Q}-${Z}-app-fw`,H1(Q,Z,"app"),K5({allowSsh:!0,sitePorts:[]})),{firewall:M}=await this.ensureFirewall(`${Q}-${Z}-services-fw`,H1(Q,Z,"services"),[{direction:"in",protocol:"tcp",port:"22",source_ips:["0.0.0.0/0","::/0"]},{direction:"in",protocol:"tcp",port:"3306",source_ips:[A.ip_range]},{direction:"in",protocol:"tcp",port:"5432",source_ips:[A.ip_range]},{direction:"in",protocol:"tcp",port:"6379",source_ips:[A.ip_range]},{direction:"in",protocol:"tcp",port:"7700",source_ips:[A.ip_range]}]),j=[...f9(G.managedServices??{mysql:!0,redis:!0},{bindPrivate:!0}),...g9(Y.infrastructure?.appDatabase,G.managedServices??{mysql:!0}),...O8(!0),...A8(!0),..._8(G.sshKeys)],q=y2(s1({runtime:"php",servicesProvision:j,baked:X})),E=await this.client.listServers().catch(()=>[]),T=[],w=E.find((u)=>U2(u.labels,Q,Z,"services"));if(!w){let{server:u,action:m}=await this.client.createServer({name:`${Q}-${Z}-services`,serverType:S$(typeof G.servicesServer==="object"?G.servicesServer.size:G.size),image:U,location:H,userData:q,labels:H1(Q,Z,"services"),sshKeys:B?[B]:void 0,firewalls:[{firewall:M.id}],networks:[A.id]});await this.client.waitForAction(m.id),w=await this.client.waitForServerRunning(u.id),T.push(u.id)}let N=w.id,I=w.private_net?.[0]?.ip??(await this.client.getServer(N)).private_net?.[0]?.ip,x=[...O8(!0),...A8(!0),..._8(G.sshKeys),...z5(Y.notifications)],h=J5({versions:G.php?.versions,default:G.php?.default,extensions:G.php?.extensions,installNginx:!P$(G),optimizeForProduction:G.php?.optimizeForProduction,ini:G.php?.ini}),S=y2(s1({runtime:"php",phpProvision:h,servicesProvision:x,baked:X})),g=E.filter((u)=>U2(u.labels,Q,Z,"app")),k=g.map((u)=>u.id);if(g.length>J.appServers)for(let u of g.slice(J.appServers))await this.client.deleteServer(u.id).catch(()=>{}),k.splice(k.indexOf(u.id),1);for(let u=g.length;u<J.appServers;u++){let{server:m,action:s}=await this.client.createServer({name:`${Q}-${Z}-app-${u+1}`,serverType:z,image:U,location:H,userData:S,labels:H1(Q,Z,"app"),sshKeys:B?[B]:void 0,firewalls:[{firewall:_.id}],networks:[A.id]});await this.client.waitForAction(s.id),k.push(m.id),T.push(m.id)}if(this.waitForBoot&&T.length>0)await Promise.all(T.map(async(u)=>{let s=(await this.client.waitForServerRunning(u)).public_net.ipv4?.ip;if(s)await this.waitForSshReady(s),await this.waitForCloudInit(s)}));let i=`${Q}-${Z}-lb`,c,n;if(J.loadBalancer){let m=(await this.client.listLoadBalancers().catch(()=>[])).find((s)=>s.name===i)??await this.client.createLoadBalancer({name:i,location:H,network:A.id,labels:H1(Q,Z,"lb"),labelSelector:`ts-cloud/project=${Q},ts-cloud/environment=${Z},ts-cloud/role=app`,services:[{listenPort:80,destinationPort:80},{listenPort:443,destinationPort:443}]});n=m.id,c=m.public_net?.ipv4?.ip}let C=c??(await this.client.getServer(k[0]).catch(()=>{return}))?.public_net.ipv4?.ip,b={provider:"hetzner",stackName:W,networkId:A.id,loadBalancerId:n,servicesServerId:N,servicesPrivateIp:I,publicIp:C,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser};return await E8(W,b),{appPublicIp:C,loadBalancerIp:c,servicesPrivateIp:I,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser}}async provisionBunFleet($,J){let{config:Y,environment:Z}=$,Q=Y.project.slug,G=Y.infrastructure.compute,W=a0(Y,Z),z=S$(G.size),U=n9(Y),H=Y.hetzner?.location||this.location,X=G.bakedImage===!0,K=Y.sites||{},B=await C$(W);if(B?.lbServerId){let u=await this.tryGetServer(B.lbServerId);if(u&&u.status!=="off")return{appPublicIp:u.public_net.ipv4?.ip??B.publicIp,loadBalancerIp:u.public_net.ipv4?.ip??B.publicIp,servicesPrivateIp:B.servicesPrivateIp,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser}}let V=await this.ensureSshKey(Q,Z,H1(Q,Z,"app")),O=`${Q}-${Z}-net`,_=(await this.client.listNetworks().catch(()=>[])).find((u)=>u.name===O)??await this.client.createNetwork({name:O,labels:H1(Q,Z,"app")}),M=this.collectUpstreamPorts(K),{firewall:j}=await this.ensureFirewall(`${Q}-${Z}-app-fw`,H1(Q,Z,"app"),[{direction:"in",protocol:"tcp",port:"22",source_ips:["0.0.0.0/0","::/0"]},...M.map((u)=>({direction:"in",protocol:"tcp",port:String(u),source_ips:[_.ip_range],description:`ts-cloud port ${u} (private, LB-only)`}))]),{firewall:q}=await this.ensureFirewall(`${Q}-${Z}-lb-fw`,H1(Q,Z,"lb"),K5({allowSsh:!0,sitePorts:[]})),E=await this.client.listServers().catch(()=>[]),T=[],w,N,I=!!G.servicesServer||!!G.managedServices;if(J.dedicatedServices&&I){let{firewall:u}=await this.ensureFirewall(`${Q}-${Z}-services-fw`,H1(Q,Z,"services"),[{direction:"in",protocol:"tcp",port:"22",source_ips:["0.0.0.0/0","::/0"]},{direction:"in",protocol:"tcp",port:"3306",source_ips:[_.ip_range]},{direction:"in",protocol:"tcp",port:"5432",source_ips:[_.ip_range]},{direction:"in",protocol:"tcp",port:"6379",source_ips:[_.ip_range]},{direction:"in",protocol:"tcp",port:"7700",source_ips:[_.ip_range]}]),m=[...f9(G.managedServices??{mysql:!0,redis:!0},{bindPrivate:!0}),...g9(Y.infrastructure?.appDatabase,G.managedServices??{mysql:!0}),...O8(!0),...A8(!0),..._8(G.sshKeys)],s=y2(s1({runtime:"bun",servicesProvision:m,baked:X})),J0=E.find((Z0)=>U2(Z0.labels,Q,Z,"services"));if(!J0){let{server:Z0,action:B0}=await this.client.createServer({name:`${Q}-${Z}-services`,serverType:S$(typeof G.servicesServer==="object"?G.servicesServer.size:G.size),image:U,location:H,userData:s,labels:H1(Q,Z,"services"),sshKeys:V?[V]:void 0,firewalls:[{firewall:u.id}],networks:[_.id]});await this.client.waitForAction(B0.id),J0=await this.client.waitForServerRunning(Z0.id),T.push(Z0.id)}w=J0.id,N=J0.private_net?.[0]?.ip??(await this.client.getServer(w)).private_net?.[0]?.ip}let x=p9(Y),h=y2(s1({runtime:x.runtime,runtimeVersion:x.runtimeVersion,systemPackages:G.systemPackages,database:Y.infrastructure?.database,servicesProvision:x.servicesProvision,baked:X})),S=E.filter((u)=>U2(u.labels,Q,Z,"app")),g=S.map((u)=>u.id);if(S.length>J.appServers)for(let u of S.slice(J.appServers))await this.client.deleteServer(u.id).catch(()=>{}),g.splice(g.indexOf(u.id),1);for(let u=S.length;u<J.appServers;u++){let{server:m,action:s}=await this.client.createServer({name:`${Q}-${Z}-app-${u+1}`,serverType:z,image:U,location:H,userData:h,labels:H1(Q,Z,"app"),sshKeys:V?[V]:void 0,firewalls:[{firewall:j.id}],networks:[_.id]});await this.client.waitForAction(s.id),g.push(m.id),T.push(m.id)}if(this.waitForBoot&&T.length>0)await Promise.all(T.map(async(u)=>{let s=(await this.client.waitForServerRunning(u)).public_net.ipv4?.ip;if(s)await this.waitForSshReady(s),await this.waitForCloudInit(s)}));let k=[];for(let u of g){let m=E.find((s)=>s.id===u);if(!m||!m.private_net?.[0]?.ip)m=await this.client.getServer(u).catch(()=>m);k.push({privateIp:m?.private_net?.[0]?.ip,publicIp:m?.public_net.ipv4?.ip})}let i=`${Q}-${Z}-lb`,c,n;if(J.loadBalancer){let u=E.find((m)=>U2(m.labels,Q,Z,"lb"));if(!u){let m=G.proxy?.engine==="rpx"?G.proxy:{engine:"rpx"},s=V8({proxy:m,config:$G(K,k,{proxy:m,slug:Q}),slug:Q,bunBin:x.runtime==="node"||x.runtime==="deno"?void 0:"/usr/local/bin/bun"}),J0=y2(s1({runtime:"bun",rpxProvision:s,baked:!1})),Z0=typeof G.loadBalancer==="object"?G.loadBalancer.size:void 0,{server:B0,action:q0}=await this.client.createServer({name:i,serverType:S$(Z0??"micro"),image:U,location:H,userData:J0,labels:H1(Q,Z,"lb"),sshKeys:V?[V]:void 0,firewalls:[{firewall:q.id}],networks:[_.id]});if(await this.client.waitForAction(q0.id),u=await this.client.waitForServerRunning(B0.id),this.waitForBoot){let X1=u.public_net.ipv4?.ip;if(X1)await this.waitForSshReady(X1),await this.waitForCloudInit(X1)}}c=u.id,n=u.public_net.ipv4?.ip}let C=n??(await this.client.getServer(g[0]).catch(()=>{return}))?.public_net.ipv4?.ip,b={provider:"hetzner",stackName:W,networkId:_.id,lbServerId:c,appServerIds:g,servicesServerId:w,servicesPrivateIp:N,publicIp:C,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser};return await E8(W,b),{appPublicIp:C,loadBalancerIp:n,servicesPrivateIp:N,deployStoragePath:"/var/ts-cloud/staging",sshUser:this.sshUser}}async destroyCompute($){let{config:J,environment:Y}=$,Z=J.project.slug,Q=a0(J,Y),G=await C$(Q),W=[],z=`${Z}-${Y}-lb`,H=(await this.client.listLoadBalancers().catch(()=>[])).find((_)=>_.name===z);if(H)try{await this.client.deleteLoadBalancer(H.id),W.push(`load balancer ${z}`)}catch{}let X=await this.client.listServers().catch(()=>[]),K=new Set;for(let _ of X)if(U2(_.labels,Z,Y,"app")||U2(_.labels,Z,Y,"services")||U2(_.labels,Z,Y,"lb"))K.add(_.id);if(G?.serverId)K.add(G.serverId);if(G?.servicesServerId)K.add(G.servicesServerId);if(G?.lbServerId)K.add(G.lbServerId);for(let _ of G?.appServerIds??[])K.add(_);for(let _ of K)try{await this.client.deleteServer(_),W.push(`server ${_}`)}catch{}let B=await this.client.listFirewalls().catch(()=>[]);for(let _ of[`${Z}-${Y}-app-fw`,`${Z}-${Y}-services-fw`,`${Z}-${Y}-lb-fw`]){let M=B.find((j)=>j.name===_);if(!M)continue;for(let j=0;j<12;j++)try{await this.client.deleteFirewall(M.id),W.push(`firewall ${_}`);break}catch{await this.sleep(3000)}}let V=`${Z}-${Y}-net`,A=(await this.client.listNetworks().catch(()=>[])).find((_)=>_.name===V);if(A)for(let _=0;_<12;_++)try{await this.client.deleteNetwork(A.id),W.push(`network ${V}`);break}catch{await this.sleep(3000)}return await E8(Q,{provider:"hetzner",stackName:Q}).catch(()=>{}),{destroyed:W}}async getComputeOutputs($){let J=a0($.config,$.environment),Y=await C$(J);if(Y?.serverId){let G=await this.client.getServer(Y.serverId);return this.outputsFromState(Y,G)}if(Y?.lbServerId){let W=(await this.tryGetServer(Y.lbServerId))?.public_net.ipv4?.ip??Y.publicIp;return{...this.outputsFromState(Y),appPublicIp:W,loadBalancerIp:W}}if(Y?.loadBalancerId||Y?.servicesPrivateIp)return this.outputsFromState(Y);let Q=(await this.findComputeTargets({slug:$.config.project.slug,environment:$.environment,role:"app",stackName:a0($.config,$.environment)}))[0];return{deployStoragePath:"/var/ts-cloud/staging",appInstanceId:Q?.id,appPublicIp:Q?.publicIp,sshUser:this.sshUser}}async uploadRelease($){let J=$.targets?.length?$.targets:await this.findComputeTargets({slug:$.config.project.slug,environment:$.environment,role:"app",stackName:a0($.config,$.environment)});if(J.length===0)throw Error("No Hetzner compute targets found for release upload");let Z=`/var/ts-cloud/staging/${$.remoteKey.replace(/^releases\//,"").replace(/\//g,"-")}`;for(let Q of J){if(!Q.publicIp)throw Error(`Target ${Q.id} has no public IP for SCP upload`);this.scpToHost(Q.publicIp,$.localPath,Z)}return{artifactRef:Z}}async findComputeTargets($){let J=await this.client.listServers(),Y=$.role||"app",Z=(G)=>({id:String(G.id),name:G.name,publicIp:G.public_net.ipv4?.ip,privateIp:G.private_net?.[0]?.ip,status:G.status}),Q=J.filter((G)=>U2(G.labels,$.slug,$.environment,Y));if(Q.length>0)return Q.map(Z);if(Y==="app"){let G=await C$($.stackName??`${$.slug}-${$.environment}`),W=[G?.serverId,...G?.appServerIds??[]].filter((z)=>typeof z==="number");if(W.length>0){let z=[];for(let U of W){let H=J.find((X)=>X.id===U)??await this.tryGetServer(U);if(H&&H.status!=="off")z.push(H)}if(z.length>0)return z.map(Z)}}if(Y==="app"){let G=J.filter((W)=>W.status!=="off"&&W.labels?.[`${j1}/managed-by`]==="ts-cloud"&&W.labels?.[`${j1}/environment`]===$.environment&&W.labels?.[`${j1}/role`]==="app");if(G.length===1)return G.map(Z)}return[]}async runRemoteDeploy($){if($.targets.length===0)return{success:!1,instanceCount:0,perInstance:[],error:"No targets provided"};let J=$.commands.join(`
|
|
7485
7485
|
`),Y=[];for(let Q of $.targets){if(!Q.publicIp){Y.push({instanceId:Q.id,status:"Failed",error:"Missing public IP"});continue}try{let G=this.sshExec(Q.publicIp,J);Y.push({instanceId:Q.id,status:"Success",output:G})}catch(G){Y.push({instanceId:Q.id,status:"Failed",error:G.message})}}let Z=Y.every((Q)=>Q.status==="Success");return{success:Z,instanceCount:$.targets.length,perInstance:Y,error:Z?void 0:"One or more SSH deploy commands failed"}}async ensureSshKey($,J,Y){if(!SR(this.sshPublicKeyPath))throw Error(`SSH public key not found at ${this.sshPublicKeyPath}. ts-cloud deploys to Hetzner over SSH and needs a public key to authorize on the server. Generate one (\`ssh-keygen -t ed25519\`) or set hetzner.sshPrivateKeyPath / HCLOUD_SSH_PUBLIC_KEY.`);let Z=CR(this.sshPublicKeyPath,"utf8").trim(),Q=M8(Z),W=(await this.client.listSshKeys()).find((U)=>M8(U.public_key)===Q);if(W)return W.id;return(await this.client.createSshKey({name:`${$}-${J}-deploy`,publicKey:Z,labels:Y})).id}async tryGetServer($){try{return await this.client.getServer($)}catch{return null}}async findExistingServer($,J,Y){let Z=await this.client.listServers(),Q=Z.find((W)=>U2(W.labels,$,J,"app")||W.name===Y);if(Q)return Q;let G=Z.filter((W)=>W.status!=="off"&&W.labels?.[`${j1}/managed-by`]==="ts-cloud"&&W.labels?.[`${j1}/environment`]===J&&W.labels?.[`${j1}/role`]==="app");if(G.length===1){let W=G[0],z=W.labels?.[`${j1}/project`]??"unknown";return console.warn(`[ts-cloud] No server named '${Y}' found; adopting existing ts-cloud app server '${W.name}' (project label '${z}') for project '${$}' — `+"updating it in place instead of provisioning a new server."),W}return}async ensureFirewall($,J,Y){let Q=(await this.client.listFirewalls()).find((W)=>W.name===$);if(Q)return await this.client.setFirewallRules(Q.id,Y),{firewall:Q};let{firewall:G}=await this.client.createFirewall({name:$,labels:J,rules:Y});return{firewall:G}}collectUpstreamPorts($){let J=new Set;for(let Y of Object.values($))if(typeof Y.port==="number")J.add(Y.port);return[...J].filter((Y)=>![80,443].includes(Y))}async sleep($){await new Promise((J)=>setTimeout(J,$))}async waitForSshReady($){let{sshIntervalMs:J,sshTimeoutMs:Y}=this.bootWait,Z=Date.now(),Q;while(Date.now()-Z<Y)try{FG(`ssh ${this.sshBaseArgs($,["-o","ConnectTimeout=5"]).map((G)=>`"${G.replace(/"/g,"\\\"")}"`).join(" ")} true`,{stdio:"pipe",maxBuffer:KG});return}catch(G){Q=G,await this.sleep(J)}throw Error(`Timed out waiting for SSH on ${$} after ${Y}ms: ${Q?.message??"unknown error"}`)}async waitForCloudInit($){let{cloudInitIntervalMs:J,cloudInitTimeoutMs:Y}=this.bootWait,Z=Date.now();while(Date.now()-Z<Y){try{let Q=this.sshExec($,"cloud-init status --long 2>/dev/null || cloud-init status 2>/dev/null || echo status:\\ done");if(/status:\s*done/.test(Q))return;if(/status:\s*error/.test(Q))throw Error(`cloud-init reported an error on ${$}:
|
|
@@ -7493,7 +7493,7 @@ ${Q}`)}catch(Q){if(Q instanceof Error&&/cloud-init reported an error/.test(Q.mes
|
|
|
7493
7493
|
`)}
|
|
7494
7494
|
`}function IG($,J){return[`cat > /etc/systemd/system/${$}.service <<'TS_CLOUD_UNIT_EOF'`,J.replace(/\n$/,""),"TS_CLOUD_UNIT_EOF"]}function ZD($,J){return`/etc/cron.d/${$}-${J}-scheduler`}function kG($){let{slug:J,siteName:Y,site:Z}=$,G=`${$.appBase??`/var/www/${Y}`}/current`,W=yF(P8(Z)),z={current:G},U=[],H=[];(Z.queues||[]).forEach((M,j)=>{let q=Math.max(1,M.processes??1);for(let E=0;E<q;E++){let T=JD(J,Y,H.length);H.push(T),U.push(...IG(T,xG({description:`${Y} queue worker ${j}.${E} (managed by ts-cloud)`,workingDir:G,execStart:W.wrapExec(W.queueWorkerCommand(M,z)),environment:W.execEnv,stopWaitSecs:M.stopWaitSecs??90})))}}),(Z.daemons||[]).forEach((M,j)=>{let q=Math.max(1,M.processes??1);for(let E=0;E<q;E++){let T=`${YD(J,Y,M,j)}-${E}`;H.push(T),U.push(...IG(T,xG({description:`${Y} daemon ${M.name||M.command} (managed by ts-cloud)`,workingDir:M.directory||G,execStart:W.wrapExec(M.command),environment:W.execEnv,restart:M.restart,user:M.user})))}});let B=Z.scheduler,V=B===!0||typeof B==="object"&&B!==null,O=`${J}-${Y}-scheduler`;if(V&&W.schedulerMode==="daemon")H.push(O),U.push(...IG(O,xG({description:`${Y} scheduler (managed by ts-cloud)`,workingDir:G,execStart:W.wrapExec(W.schedulerCommand(z)),environment:W.execEnv})));let A=H.map((M)=>`${M}.service`).join(" ");U.push("systemctl daemon-reload",`TS_CLOUD_DESIRED="${A}"`,`for unit in $(ls /etc/systemd/system/ 2>/dev/null | grep -E '^${vF(J)}-${vF(Y)}-((queue|daemon)-.*|scheduler)\\.service$' || true); do`,' case " $TS_CLOUD_DESIRED " in',' *" $unit "*) ;;',' *) systemctl stop "$unit" 2>/dev/null || true; systemctl disable "$unit" 2>/dev/null || true; rm -f "/etc/systemd/system/$unit" ;;'," esac","done","systemctl daemon-reload");for(let M of H)U.push(`systemctl enable ${M}.service`,`systemctl restart ${M}.service`);let _=ZD(J,Y);if(V&&W.schedulerMode==="cron"){let M=typeof B==="object"&&B!==null?B:void 0,j=`${W.schedulerCommand(z)} >> /dev/null 2>&1`;if(M?.heartbeatUrl){let E=M.heartbeatMethod||"GET",T=E==="GET"?"":`-X ${E} `;j+=` && curl -fsS -m 10 ${T}${$D(M.heartbeatUrl)} >/dev/null 2>&1`}let q=`* * * * * root ${j}
|
|
7495
7495
|
`.replace(/%/g,"\\%");U.push(`cat > ${_} <<'TS_CLOUD_CRON_EOF'`,q.replace(/\n$/,""),"TS_CLOUD_CRON_EOF",`chmod 644 ${_}`)}else U.push(`rm -f ${_}`);return U}function hG($){return!!($.queues?.length||$.daemons?.length||$.scheduler)}var gF=Y0(()=>{CG()});function w5($){return($.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"site").slice(0,28)}function dF($){return`web_${w5($)}`}function WD($){let J=w5($),Y=0;for(let Z=0;Z<J.length;Z++)Y=Y*31+J.charCodeAt(Z)>>>0;return QD+Y%GD}function bG($){return`127.0.0.1:${WD($)}`}function zD($){let J=w5($.siteName),Y=dF($.siteName),Z=$.maxChildren??10;return[`; ts-cloud-managed pool for ${$.siteName} (site isolation)`,`[${J}]`,`user = ${Y}`,`group = ${Y}`,`listen = ${bG($.siteName)}`,"pm = dynamic",`pm.max_children = ${Z}`,"pm.start_servers = 2","pm.min_spare_servers = 1","pm.max_spare_servers = 3","pm.max_requests = 500","catch_workers_output = yes",`php_admin_value[open_basedir] = ${$.appBase}:/tmp`,""].join(`
|
|
7496
|
-
`)}function cF($){let J=dF($.siteName),Y=w5($.siteName),Z=`${uF}/${Y}.conf`;return[`getent group ${J} >/dev/null || groupadd --system ${J}`,`id -u ${J} >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin -g ${J} ${J}`,`usermod -aG ${J} www-data 2>/dev/null || true`,`chown -R ${J}:${J} ${$.appBase} || true`,`chmod -R g+rX ${$.appBase} || true`,`chmod 600 ${$.appBase}/shared/.env 2>/dev/null || true`,`mkdir -p ${uF}`,`cat > ${Z} <<'TS_CLOUD_FPMPOOL_EOF'`,zD($).replace(/\n$/,""),"TS_CLOUD_FPMPOOL_EOF",`(cd ${g1} && pantry restart php-fpm) 2>/dev/null || true`]}var uF="/var/lib/pantry/php-fpm/pool.d",QD=9100,GD=400;var mF=Y0(()=>{j2()});import{copyFileSync as UD}from"node:fs";import{tmpdir as HD}from"node:os";import{join as XD}from"node:path";async function vG($,J,Y=yG){let{config:Z,environment:Q,siteName:G,site:W,slug:z,sha:U,runtime:H,localTarballPath:X}=J,K=`releases/${G}/${U}.tar.gz`,B=a0(Z,Q),V=await $.getComputeOutputs({config:Z,environment:Q}),O=await $.findComputeTargets({slug:z,environment:Q,role:"app",stackName:B});if(O.length===0)return{success:!1,error:$.name==="aws"?`Stack '${B}' has no EC2 instances tagged Project=${z} Environment=${Q} Role=app, and
|
|
7496
|
+
`)}function cF($){let J=dF($.siteName),Y=w5($.siteName),Z=`${uF}/${Y}.conf`;return[`getent group ${J} >/dev/null || groupadd --system ${J}`,`id -u ${J} >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin -g ${J} ${J}`,`usermod -aG ${J} www-data 2>/dev/null || true`,`chown -R ${J}:${J} ${$.appBase} || true`,`chmod -R g+rX ${$.appBase} || true`,`chmod 600 ${$.appBase}/shared/.env 2>/dev/null || true`,`mkdir -p ${uF}`,`cat > ${Z} <<'TS_CLOUD_FPMPOOL_EOF'`,zD($).replace(/\n$/,""),"TS_CLOUD_FPMPOOL_EOF",`(cd ${g1} && pantry restart php-fpm) 2>/dev/null || true`]}var uF="/var/lib/pantry/php-fpm/pool.d",QD=9100,GD=400;var mF=Y0(()=>{j2()});import{copyFileSync as UD}from"node:fs";import{tmpdir as HD}from"node:os";import{join as XD}from"node:path";async function vG($,J,Y=yG){let{config:Z,environment:Q,siteName:G,site:W,slug:z,sha:U,runtime:H,localTarballPath:X}=J,K=`releases/${G}/${U}.tar.gz`,B=a0(Z,Q),V=await $.getComputeOutputs({config:Z,environment:Q}),O=await $.findComputeTargets({slug:z,environment:Q,role:"app",stackName:B});if(O.length===0)return{success:!1,error:$.name==="aws"?`Stack '${B}' has no EC2 instances tagged Project=${z} Environment=${Q} Role=app, and storage/cloud/state/${B}.json pins no live instance. For a shared box, record its instanceId there.`:`No Hetzner servers labeled ts-cloud/project=${z} ts-cloud/environment=${Q} ts-cloud/role=app, and storage/cloud/state/${B}.json pins no live server. For a shared box, record its serverId there.`};if(u9(W)){let S=Z.infrastructure?.compute,g=W.phpVersion??S?.php?.default??S?.php?.versions?.[0],k=t1(z,G),i=V.servicesPrivateIp?sX(V.servicesPrivateIp,Z.infrastructure?.appDatabase):NX(Z.infrastructure?.appDatabase),c=Object.keys(i).length>0?{...W,env:{...i,...W.env||{}}}:W,n=CF({siteName:G,site:c,releaseId:U,appBase:k,defaultPhpVersion:g}),C=!P$(S),u=PG(W)==="custom"&&W.ssl?.certPath&&W.ssl?.keyPath?{certPath:W.ssl.certPath,keyPath:W.ssl.keyPath}:void 0,m=W.isolation?cF({siteName:G,appBase:k}):[],s=C?rQ({siteName:G,domain:W.domain||G,aliases:W.aliases,type:W.type,appDir:`${k}/current`,webDirectory:W.webDirectory,phpVersion:g,fastcgiPass:W.isolation?bG(G):void 0,redirects:W.redirects,ssl:u,auth:W.auth&&W.auth.enabled!==!1&&W.auth.password?{username:W.auth.username||"admin",password:W.auth.password,realm:W.auth.realm}:void 0,serverSnippet:pQ(W.nginx,S?.nginxTemplates),clientMaxBodySize:W.nginx?.clientMaxBodySize,hsts:W.ssl?.hsts,tlsProtocols:W.ssl?.tlsProtocols,security:W.security}):[],J0=C?SG(W):[],Z0=hG(W)?kG({slug:z,siteName:G,site:W,phpVersion:g,appBase:k}):[],B0=C?SF(W):[];Y.step(`Deploying PHP site '${G}' to ${O.length} target(s)...`);let q0=await $.runRemoteDeploy({targets:O,commands:[...jG(k,z),...n,...m,...s,...J0,...Z0,...B0],comment:`ts-cloud deploy ${z}/${G}@${U}`,tags:{Project:z,Environment:Q,Role:"app"}}),X1=vX(Z.notifications,W.notifications);if(!q0.success)return await ZG(X1,"deploy-failed",`❌ Deploy of ${z}/${G}@${U} failed: ${q0.error||"unknown error"}`),{success:!1,error:q0.error||"Remote PHP deploy failed",instanceCount:q0.instanceCount,perInstance:q0.perInstance};let X0=W.domain?` → https://${W.domain}`:"";return await ZG(X1,"deploy",`✅ Deployed ${z}/${G}@${U}${X0}`),{success:!0,instanceCount:q0.instanceCount,perInstance:q0.perInstance}}if(!X)return{success:!1,error:`Site '${G}' requires a release tarball but none was provided`};let A=await $.uploadRelease({config:Z,environment:Q,localPath:X,remoteKey:K,targets:O}),_=$.name==="aws"?LG(V.deployBucketName,K,Z.project.region||"us-east-1",G):MG(A.artifactRef,G),M=n0(W),j=t1(z,G),q=M==="server-static"?E5({siteName:G,appDir:j,artifactFetch:_,releaseId:U,preStartCommands:W.preStart}):M5({siteName:G,slug:z,appDir:j,artifactFetch:_,releaseId:U,execStart:L5(W.start,H),envEntries:W.env||{},port:W.port,preStartCommands:W.preStart,sharedPaths:W.sharedPaths,zeroDowntime:W.zeroDowntime!==!1,healthCheckPath:W.healthCheck?.path}),E=Z.infrastructure?.compute,T=M==="server-static"&&!P$(E)&&!!W.domain,w=T?rQ({siteName:G,domain:W.domain,aliases:W.aliases,type:W.type==="spa"?"spa":"static",appDir:`${j}/current`,webDirectory:"",redirects:W.redirects,auth:W.auth&&W.auth.enabled!==!1&&W.auth.password?{username:W.auth.username||"admin",password:W.auth.password,realm:W.auth.realm}:void 0,serverSnippet:pQ(W.nginx,E?.nginxTemplates),clientMaxBodySize:W.nginx?.clientMaxBodySize,hsts:W.ssl?.hsts,tlsProtocols:W.ssl?.tlsProtocols,security:W.security}):[],N=T?SG(W):[],I=hG(W)?kG({slug:z,siteName:G,site:W,appBase:j}):[],x=[...j5(j,{releaseId:U,commit:U,branch:W.branch??"main"}),...jG(j,z),...q,...w,...N,...I];Y.step(`Deploying to ${O.length} target(s)...`);let h=await $.runRemoteDeploy({targets:O,commands:x,comment:`ts-cloud deploy ${z}/${G}@${U}`,tags:{Project:z,Environment:Q,Role:"app"}});if(!h.success)return{success:!1,error:h.error||"Remote deploy failed",instanceCount:h.instanceCount,perInstance:h.perInstance};return{success:!0,instanceCount:h.instanceCount,perInstance:h.perInstance}}async function N5($){let{config:J,environment:Y,driver:Z,sha:Q,runtime:G,tarballForSite:W,logger:z=yG}=$,U=J.project.slug,H=$.cwd??process.cwd(),X=T$(J);N8(J,{cwd:H,logger:{info:z.info,warn:z.warn}});let K=X?[]:NG(J);if($.rpxConfig&&$.rpxConfig!==J&&!T$($.rpxConfig))N8($.rpxConfig,{cwd:H,logger:{info:()=>{},warn:()=>{}}});let B=null,V=new Map;if(K.length>0)if(B=o9(J.sites?.[K[0]],{cwd:H,slug:U,sha:Q,siteName:K[0],logger:{info:z.info,warn:z.warn}}),!B){z.warn("Management dashboard: no artifact available — skipping dashboard site(s) for this deploy.");for(let j of K)if(J.sites)delete J.sites[j]}else for(let j of K){if(j===K[0]){V.set(j,B);continue}try{let q=XD(HD(),`${U}-${j}-${Q}.tar.gz`);UD(B,q),V.set(j,q)}catch{V.set(j,B)}}let O=J.sites||{},A=Object.entries(O).filter(([j,q])=>{if(!q)return!1;let E=n0(q);if(E==="bucket")return z.warn(`Site '${j}' targets a bucket — skipping (handled by the static-site path, not compute).`),!1;if(E==="redirect")return!1;return!0});if(A.length===0)return!0;let _=(j)=>V.get(j)??W(j);for(let[j,q]of A){z.step(`Deploying site: ${j}`);let E=u9(q)?void 0:_(j),T=await vG(Z,{config:J,environment:Y,siteName:j,site:q,slug:U,sha:Q,runtime:G,localTarballPath:E},z);if(!T.success){if(z.error(`Deploy of '${j}' failed: ${T.error||"unknown error"}`),T.perInstance)for(let w of T.perInstance)z.error(` ${w.instanceId}: ${w.status}${w.error?` — ${w.error}`:""}`);return!1}if(z.success(`Deployed ${U}/${j}@${Q} to ${T.instanceCount} target(s)`),T.perInstance)for(let w of T.perInstance)z.info(` ✓ ${w.instanceId}: ${w.status}`)}if(!await lF($))return!1;return!0}async function lF($){let{config:J,environment:Y,driver:Z,logger:Q=yG}=$,G=$.rpxConfig??J,W=G.infrastructure?.compute?.proxy??J.infrastructure?.compute?.proxy;if(W?.engine!=="rpx")return!0;let z=G.sites||{},U=d9(z,{proxy:W,slug:J.project.slug});if(U.proxies.length===0)return Q.warn("rpx gateway: no server sites with a domain to route — skipping gateway reload."),!0;let H=await Z.findComputeTargets({slug:J.project.slug,environment:Y,role:"app",stackName:a0(J,Y)});if(H.length===0)return Q.warn("rpx gateway: no compute targets found — skipping gateway reload."),!0;Q.step(`Reloading rpx gateway with ${U.proxies.length} route(s)...`);let X=V8({proxy:W,config:U,slug:J.project.slug}),K=await Z.runRemoteDeploy({targets:H,commands:X,comment:`ts-cloud rpx gateway reload ${J.project.slug}`,tags:{Project:J.project.slug,Environment:Y,Role:"app"}});if(!K.success)return Q.error(`rpx gateway reload failed: ${K.error||"unknown error"}`),!1;return Q.success(`rpx gateway reloaded on ${K.instanceCount} target(s)`),!0}var yG;var fG=Y0(async()=>{EG();TF();$5();xF();gF();iQ();mF();s9();await u2([f0(),e9(),G$(),c9()]);yG={info:()=>{},warn:()=>{},error:()=>{},step:()=>{},success:()=>{}}});var I$=Y0(async()=>{F5();HG();AG();XF();EG();await u2([WG(),BG(),fG(),c9()]);GF()});function LD($){return`'${$.split("'").join("'\\''")}'`}function pF($){let J=$.user||"root",Y=$.script.join(`
|
|
7497
7497
|
`),Z=J==="root"?'bash -l "$TS_CLOUD_RECIPE"':`runuser -l ${LD(J)} -c "bash $TS_CLOUD_RECIPE"`;return["set -uo pipefail",`echo "__TS_CLOUD_RECIPE_BEGIN__ ${$.name} (user=${J})"`,"TS_CLOUD_RECIPE=$(mktemp)",`cat > "$TS_CLOUD_RECIPE" <<'TS_CLOUD_RECIPE_EOF'`,Y,"TS_CLOUD_RECIPE_EOF",'chmod +r "$TS_CLOUD_RECIPE"',Z,"TS_CLOUD_RC=$?",'rm -f "$TS_CLOUD_RECIPE"',`echo "__TS_CLOUD_RECIPE_END__ ${$.name} exit=$TS_CLOUD_RC"`,"exit $TS_CLOUD_RC"]}var J6={};b0(J6,{runComputeRecipe:()=>ED,rollbackComputeSite:()=>uG,restoreDatabaseBackup:()=>dG,getComputeDeployHistory:()=>MD});async function P5($){return await $.driver.findComputeTargets({slug:$.slug,environment:$.environment,role:$.role||"app"})}async function uG($,J){let Y=$.logger||gG,Z=await P5($);if(Z.length===0)return{success:!1,error:`No '${$.role||"app"}' servers found for ${$.slug}/${$.environment}.`};let Q=t1($.slug,J.siteName),G=x$(Q,J.to||"unused"),W=["set -uo pipefail",...FF(G,{...J.to?{to:J.to}:{},unitBase:`${$.slug}-${J.siteName}`}),`(cd ${g1} && pantry restart php-fpm) 2>/dev/null || true`,`(cd ${G.current} && eval "$(cd ${g1} && pantry env 2>/dev/null)" && php artisan queue:restart) 2>/dev/null || true`];Y.step(`Rolling back ${J.siteName}${J.to?` to ${J.to}`:" to the previous release"} on ${Z.length} server(s)...`);let z=await $.driver.runRemoteDeploy({targets:Z,commands:W,comment:`ts-cloud rollback ${$.slug}/${J.siteName}`,tags:{Project:$.slug,Environment:$.environment,Role:$.role||"app"}});if(!z.success)Y.error(`Rollback failed: ${z.error||"unknown error"}`);else Y.success(`Rolled back ${J.siteName}.`);return{success:z.success,error:z.error,perInstance:z.perInstance}}async function MD($,J){let Y=await P5($);if(Y.length===0)return{success:!1,error:`No '${$.role||"app"}' servers found for ${$.slug}/${$.environment}.`};let Z=_G(t1($.slug,J.siteName)),Q=Math.max(1,J.limit??20),G=[`[ -f ${Z} ] && tail -n ${Q} ${Z} || echo "no deploy history for ${J.siteName}"`],W=await $.driver.runRemoteDeploy({targets:Y,commands:G,comment:`ts-cloud deploy:history ${$.slug}/${J.siteName}`,tags:{Project:$.slug,Environment:$.environment,Role:$.role||"app"}});return{success:W.success,error:W.error,perInstance:W.perInstance}}async function ED($,J){let Y=$.logger||gG,Z=await P5($);if(Z.length===0)return{success:!1,error:`No '${$.role||"app"}' servers found for ${$.slug}/${$.environment}.`};Y.step(`Running recipe '${J.name}' as ${J.user||"root"} on ${Z.length} server(s)...`);let Q=await $.driver.runRemoteDeploy({targets:Z,commands:pF({name:J.name,script:J.script,user:J.user}),comment:`ts-cloud recipe ${J.name}`,tags:{Project:$.slug,Environment:$.environment,Role:$.role||"app"}});if(!Q.success)Y.error(`Recipe '${J.name}' failed: ${Q.error||"unknown error"}`);else Y.success(`Recipe '${J.name}' completed.`);return{success:Q.success,error:Q.error,perInstance:Q.perInstance}}async function dG($,J){let Y=$.logger||gG;if(!J.database?.name)return{success:!1,error:"No appDatabase configured to restore."};let Z=await P5($);if(Z.length===0)return{success:!1,error:`No '${$.role||"app"}' servers found for ${$.slug}/${$.environment}.`};Y.step(`Restoring database '${J.database.name}'${J.from?` from ${J.from}`:" from the latest backup"} on ${Z.length} server(s)...`);let Q=await $.driver.runRemoteDeploy({targets:Z,commands:gX(J.database,{from:J.from}),comment:`ts-cloud db:restore ${$.slug}/${J.database.name}`,tags:{Project:$.slug,Environment:$.environment,Role:$.role||"app"}});if(!Q.success)Y.error(`Restore failed: ${Q.error||"unknown error"}`);else Y.success(`Restored ${J.database.name}.`);return{success:Q.success,error:Q.error,perInstance:Q.perInstance}}var gG;var S8=Y0(async()=>{j2();s9();await G$();gG={info:()=>{},warn:()=>{},error:()=>{},step:()=>{},success:()=>{}}});var rF={};b0(rF,{buildQuickDeployCi:()=>TD});function qD($){let J=$.sites||{};for(let Y of Object.values(J))if(Y?.repository?.url)return{provider:Y.repository.provider,branch:Y.repository.branch};return}function TD($,J="production"){let Y=qD($),Z=Y?.provider;if(Z!=="github"&&Z!=="gitlab"&&Z!=="bitbucket")return null;let Q=Y?.branch||"main",G=`bunx --bun ts-cloud deploy ${J}`;if(Z==="github")return{provider:Z,branch:Q,path:".github/workflows/deploy.yml",content:`name: Deploy
|
|
7498
7498
|
on:
|
|
7499
7499
|
push:
|
|
@@ -7541,7 +7541,7 @@ ${$.map((Y)=>[" {",` name: '${sF(Y.name)}',`,` publicKe
|
|
|
7541
7541
|
`)}
|
|
7542
7542
|
]`}function ND($){let J=new Map;for(let Y of $){let Z=pG(Y.name);if(J.has(Z))throw Error(`SSH key '${Z}' already exists in compute.sshKeys`);J.set(Z,{name:Z,publicKey:rG(Y.publicKey)})}return[...J.values()]}function pG($){let J=$.trim();if(!/^[\w@.+-]{2,80}$/.test(J))throw Error("SSH key name must be 2-80 characters and use letters, numbers, @, ., +, _, or -.");return J}function rG($){let J=$.trim().replace(/\s+/g," "),[Y,Z]=J.split(" ");if(!/^(?:ssh-(?:ed25519|rsa)|ecdsa-sha2-nistp(?:256|384|521))$/.test(Y??"")||!Z)throw Error("Public key must be an OpenSSH public key, e.g. ssh-ed25519 AAAA... name@host.");return J}function PD($){return $.trim().split(/\s+/)[0]||"ssh"}function SD($){let J=$.trim().split(/\s+/)[1];if(!J)return"-";try{return`SHA256:${DD("sha256").update(Buffer.from(J,"base64")).digest("base64").replace(/=+$/,"")}`}catch{return"-"}}function sF($){return $.replace(/\\/g,"\\\\").replaceAll(String.fromCharCode(39),"\\'")}function CD($,J){let Y=new RegExp(`\\b${J}\\s*:\\s*{`,"g").exec($);if(!Y)throw Error(`Could not find ${J}: { ... } in cloud config.`);let Z=$.indexOf("{",Y.index);return{propertyStart:Y.index,start:Z,end:Q6($,Z,"{","}")}}function xD($,J,Y,Z){let Q=$.slice(J+1,Y),G=new RegExp(`\\b${Z}\\s*:\\s*\\[`,"g").exec(Q);if(!G)return null;let W=J+1+G.index,z=$.indexOf("[",W);return{propertyStart:W,start:z,end:Q6($,z,"[","]")}}function Q6($,J,Y,Z){let Q=0,G,W=!1,z=!1,U=!1;for(let H=J;H<$.length;H++){let X=$[H],K=$[H+1];if(z){if(X===`
|
|
7543
7543
|
`)z=!1;continue}if(U){if(X==="*"&&K==="/")U=!1,H++;continue}if(G){if(W){W=!1;continue}if(X==="\\"){W=!0;continue}if(X===G)G=void 0;continue}if(X==="/"&&K==="/"){z=!0,H++;continue}if(X==="/"&&K==="*"){U=!0,H++;continue}if(X==='"'||X==="'"||X==="`"){G=X;continue}if(X===Y)Q++;if(X===Z){if(Q--,Q===0)return H}}throw Error(`Could not find matching ${Z} in cloud config.`)}var I5=()=>{};var _K={};b0(_K,{serverLogSources:()=>UK,resolveServerDashboardData:()=>tG,resolveConfigOnlyServerDashboardData:()=>AK,parseServerSecurity:()=>KK,parseServerLogs:()=>XK,parseDeployHistory:()=>OK,parseBlock:()=>YK});import{existsSync as ID,readFileSync as kD}from"node:fs";import{join as hD}from"node:path";function yD(){return["set +e",'echo "CPUS=$(nproc 2>/dev/null || echo 1)"',`echo "LOAD=$(cut -d' ' -f1 /proc/loadavg 2>/dev/null || echo 0)"`,`echo "MEMTOTAL=$(free -m 2>/dev/null | awk '/^Mem:/{print $2}')"`,`echo "MEMUSED=$(free -m 2>/dev/null | awk '/^Mem:/{print $3}')"`,`echo "DISKPCT=$(df -P / 2>/dev/null | awk 'NR==2{gsub("%","",$5);print $5}')"`,`echo "DISKUSEDG=$(df -BG / 2>/dev/null | awk 'NR==2{gsub("G","",$3);print $3}')"`,`echo "DISKTOTG=$(df -BG / 2>/dev/null | awk 'NR==2{gsub("G","",$2);print $2}')"`,`echo "UPTIME=$(uptime -p 2>/dev/null | sed 's/^up //' || echo unknown)"`,'echo "OS=$(. /etc/os-release 2>/dev/null; echo "$PRETTY_NAME")"',`for s in ${bD.join(" ")}; do st=$(systemctl is-active "$s" 2>/dev/null); if [ -n "$st" ] && [ "$st" != "inactive" ] && [ "$st" != "unknown" ]; then mem=$(systemctl show "$s" -p MemoryCurrent --value 2>/dev/null); en=$(systemctl is-enabled "$s" 2>/dev/null); since=$(systemctl show "$s" -p ActiveEnterTimestamp --value 2>/dev/null); echo "SVC=$s=$st=$mem=$en=$since"; fi; done`,"true"]}function YK($){let J={services:[]};for(let Y of $.split(`
|
|
7544
|
-
`)){let Z=Y.trim();if(Z.startsWith("SVC=")){let[,Q,G,W,z,U]=/^SVC=([^=]+)=([^=]+)(?:=([^=]*)(?:=([^=]*)(?:=(.*))?)?)?$/.exec(Z)??[];if(Q)J.services.push({name:Q,status:G,memBytes:Number(W||0),enabled:z||L1,since:U||L1})}else{let Q=Z.indexOf("=");if(Q>0)J[Z.slice(0,Q)]=Z.slice(Q+1)}}return J}function ZK($){let J=$.infrastructure?.compute,Y=[];if(J?.webServer==="rpx"||J?.proxy?.engine==="rpx")Y.push({name:"rpx-gateway",status:"configured"});else if(J?.webServer==="nginx"||J?.webServer==null)Y.push({name:"ts-cloud-nginx",status:"configured"});let Z=J?.php?.versions??(J?.runtime==="php"?["8.3"]:[]);for(let W of Z)Y.push({name:`php${W}-fpm`,status:"configured"});let Q=J?.managedServices??{},G=[["mysql","mysql"],["mariadb","mariadb"],["postgres","postgresql"],["redis","redis"],["memcached","memcached"],["meilisearch","meilisearch"]];for(let[W,z]of G)if(Q[W])Y.push({name:z,status:"configured"});return Y}function vD($){let J=$.infrastructure?.compute?.backups,Y=!!J?.enabled,Z=J?.schedule??"0 2 * * *";return{enabled:Y,schedule:Z,destination:Y?J?.bucket??"local":"off",retention:Y?J?.retentionCount??5:0,last:Y?"pending first run":"not configured",size:Y?L1:"0 MB"}}function QK($){return $.infrastructure?.compute?.provider??$.cloud?.provider??$.provider??"aws"}function fD($){if(QK($)==="hetzner")return UG($);return $.project.region??"us-east-1"}function gD($,J){let Y=hD(process.cwd(),"
|
|
7544
|
+
`)){let Z=Y.trim();if(Z.startsWith("SVC=")){let[,Q,G,W,z,U]=/^SVC=([^=]+)=([^=]+)(?:=([^=]*)(?:=([^=]*)(?:=(.*))?)?)?$/.exec(Z)??[];if(Q)J.services.push({name:Q,status:G,memBytes:Number(W||0),enabled:z||L1,since:U||L1})}else{let Q=Z.indexOf("=");if(Q>0)J[Z.slice(0,Q)]=Z.slice(Q+1)}}return J}function ZK($){let J=$.infrastructure?.compute,Y=[];if(J?.webServer==="rpx"||J?.proxy?.engine==="rpx")Y.push({name:"rpx-gateway",status:"configured"});else if(J?.webServer==="nginx"||J?.webServer==null)Y.push({name:"ts-cloud-nginx",status:"configured"});let Z=J?.php?.versions??(J?.runtime==="php"?["8.3"]:[]);for(let W of Z)Y.push({name:`php${W}-fpm`,status:"configured"});let Q=J?.managedServices??{},G=[["mysql","mysql"],["mariadb","mariadb"],["postgres","postgresql"],["redis","redis"],["memcached","memcached"],["meilisearch","meilisearch"]];for(let[W,z]of G)if(Q[W])Y.push({name:z,status:"configured"});return Y}function vD($){let J=$.infrastructure?.compute?.backups,Y=!!J?.enabled,Z=J?.schedule??"0 2 * * *";return{enabled:Y,schedule:Z,destination:Y?J?.bucket??"local":"off",retention:Y?J?.retentionCount??5:0,last:Y?"pending first run":"not configured",size:Y?L1:"0 MB"}}function QK($){return $.infrastructure?.compute?.provider??$.cloud?.provider??$.provider??"aws"}function fD($){if(QK($)==="hetzner")return UG($);return $.project.region??"us-east-1"}function gD($,J){let Y=hD(process.cwd(),"storage","cloud","state",`${$.project.slug}-${J}.json`);if(!ID(Y))return null;try{return JSON.parse(kD(Y,"utf8"))}catch{return null}}function uD($){let J=$.sites??{},Y=[];for(let[Z,Q]of Object.entries(J)){let G=Q.queues??Q.workers;if(Array.isArray(G)){for(let W of G)if(typeof W==="string")Y.push({name:`${Z}:${W}`,site:Z,processes:1,status:"configured"});else if(W?.name)Y.push({name:`${Z}:${W.name}`,site:Z,processes:W.processes??1,status:"configured"})}}return Y}function GK($){if(!$||$==="")return"/";return $.startsWith("/")?$:`/${$}`}function dD($){let J=GK($.path);if(!$.domain)return{route:"internal"};return{route:J==="/"?$.domain:`${$.domain}${J}`,href:`https://${$.domain}${J==="/"?"":J}`}}function JK($,J){let Y=n0(J);if(Y==="redirect")return"redirect";let Z=String(J.build??"").toLowerCase(),Q=String(J.start??"").toLowerCase();if($==="main"||Q.includes("buddy/src/cli.ts serve"))return"stacks";if($==="api"||Q.includes("/serve/api"))return"api";if(Z.includes("buildblog"))return"bunpress blog";if(Z.includes("bunpress"))return"bunpress";if(Z.includes("site:build")||Z.includes("stx"))return"stx static";if(Y==="server-static")return J.spa?"spa":"static";if(Y==="server-app")return"app";if(Y==="server-php")return J.type??"php";return"bucket"}function cD($){let J=n0($);if(J==="redirect")return"—";let Y=`${$.start??""} ${$.build??""}`.toLowerCase();if(J==="server-static")return Y.includes("bunpress")||Y.includes("bun ")||Y.includes("bunx ")?"static/bun":"static";if(J==="server-app")return Y.includes("bun")?"bun":"node";if(J==="server-php")return`php ${$.php??$.phpVersion??"8.3"}`;return"static"}function mD($){let J=n0($);if(J==="redirect")return"redirect";if(J==="server-app")return"service";if(J==="server-static")return"server static";if(J==="server-php")return"php release";return"bucket"}function lD($){let J=new Map;return Object.entries($.sites??{}).map(([Y,Z])=>{let Q=GK(Z.path),{route:G,href:W}=dD(Z),z=Z.domain?`${Z.domain}${Q}`:"",U=z?J.get(z):void 0;if(z&&!U)J.set(z,Y);return{name:Y,route:G,href:W,domain:Z.domain??"internal",path:Q,kind:JK(Y,Z),type:JK(Y,Z),runtime:cD(Z),deploy:mD(Z),tls:Z.domain?Z.ssl===!1?"http":"https":"loopback",ssl:Z.domain?Z.ssl!==!1:!1,status:U?"shadowed":"live",shadowedBy:U,lastDeploy:L1}})}function nG($){return`'${$.replaceAll("'","'\\''")}'`}function WK($){return $.replace(/[\\&/]/g,"\\$&")}function pD($,J){if($.length===0)return["true"];return["set +e",...$.map((Y)=>{let Z=nG(`${t1(J,Y)}/.ts-cloud/deploy-history.log`),Q=WK(Y);return`TS_CLOUD_HISTORY=${Z}; { [ -f "$TS_CLOUD_HISTORY" ] && tail -n 24 "$TS_CLOUD_HISTORY" | sed "s/^/DEPLOY=${Q}\\t/"; } || true`}),"true"]}function zK($){return[...new Set(Object.values($.sites??{}).map((J)=>J.domain).filter((J)=>typeof J==="string"&&J.length>0))]}function rD($){return["set +e",'if command -v ss >/dev/null 2>&1; then ss -H -lntup 2>/dev/null | while read -r proto _state _recv _send local _peer rest; do [ -n "$proto" ] && [ -n "$local" ] && printf "PORT=%s\\t%s\\t%s\\n" "$proto" "$local" "$rest"; done; fi','if command -v ufw >/dev/null 2>&1; then ufw status numbered 2>/dev/null | sed "s/^/FIREWALL=/"; else echo "FIREWALL=ufw unavailable"; fi','journalctl _COMM=sshd --no-pager -n 30 -o short-iso 2>/dev/null | sed "s/^/AUTH=/" || true',...zK($).map((Y)=>{return`TS_CLOUD_DOMAIN=${nG(Y)}; TS_CLOUD_EXPIRY=$(echo | timeout 8 openssl s_client -servername "$TS_CLOUD_DOMAIN" -connect "$TS_CLOUD_DOMAIN:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2-); [ -n "$TS_CLOUD_EXPIRY" ] && printf "CERT=%s\\t%s\\n" "$TS_CLOUD_DOMAIN" "$TS_CLOUD_EXPIRY" || printf "CERT=%s\\tunavailable\\n" "$TS_CLOUD_DOMAIN"`}),"true"]}function UK($){let J=new Map,Y=(G,W)=>{if(G&&W&&!J.has(W))J.set(W,{pattern:G,label:W})},Z=$.infrastructure?.compute,Q=$.project.slug;if(Z?.webServer==="rpx"||Z?.proxy?.engine==="rpx")Y("rpx-gateway","rpx-gateway");else Y("nginx","nginx");for(let G of ZK($))Y(G.name,G.name);for(let[G,W]of Object.entries($.sites??{})){if(n0(W)!=="server-app")continue;if(Y(`${Q}-${G}`,`${Q}-${G}`),Array.isArray(W.queues??W.workers)&&(W.queues??W.workers).length)Y(`${Q}-${G}-queue-*`,`${Q}-${G}-queues`);if(Array.isArray(W.daemons)&&W.daemons.length)Y(`${Q}-${G}-daemon-*`,`${Q}-${G}-daemons`)}return[...J.values()]}function nD($){let J=UK($);if(J.length===0)return["true"];return["set +e",...J.map((Y)=>{let Z=nG(Y.pattern),Q=WK(Y.label);return`journalctl -u ${Z} --no-pager -n 150 -o short-iso 2>/dev/null | sed "s/^/LOG=${Q}\\t/" || true`}),'[ -f /var/log/ts-cloud-backup.log ] && tail -n 60 /var/log/ts-cloud-backup.log 2>/dev/null | sed "s/^/LOG=backups\\t/" || true',"true"]}function iG($){let J=new Date($);if(Number.isNaN(J.getTime()))return $||L1;let Y=Math.max(0,Math.round((Date.now()-J.getTime())/1000));if(Y<60)return`${Y}s ago`;let Z=Math.round(Y/60);if(Z<60)return`${Z}m ago`;let Q=Math.round(Z/60);if(Q<48)return`${Q}h ago`;return`${Math.round(Q/24)}d ago`}function HK($){if(/(?:error|failed|panic|fatal|exception|denied|unhealthy)/i.test($))return"error";if(/(?:warn|warning|retry|restart|deprecated|timeout)/i.test($))return"warn";return"info"}function XK($){let J=[];for(let Y of $.split(`
|
|
7545
7545
|
`)){let Z=Y.trim();if(!Z.startsWith("LOG="))continue;let Q=Z.indexOf("\t");if(Q<0)continue;let G=Z.slice(4,Q),W=Z.slice(Q+1),z=/^(\d{4}-\d{2}-\d{2}T[^\s]+)\s+(\S+)\s+(.*)$/.exec(W),U=z?.[1]??"",H=z?.[2]??"",X=(z?.[3]??W).trim();if(!X)continue;J.push({source:G,timestamp:U,when:U?iG(U):L1,host:H,message:X,level:HK(X)})}return J.sort((Y,Z)=>String(Z.timestamp).localeCompare(String(Y.timestamp))).slice(0,600)}function FK($){if(/^(?:127\.|localhost:|\[?::1\]?)/.test($))return"loopback";if(/^(?:10\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.|169\.254\.|\[?f[cd][0-9a-f:])/i.test($))return"private";return"public"}function iD($){if(FK($)!=="public")return"ok";if(/:(?:22|80|443)$/.test($)||/^\*:(?:22|80|443)$/.test($))return"ok";return"warn"}function aD($){if($==null)return"warn";if($<8)return"bad";if($<30)return"warn";return"ok"}function KK($){let J=[],Y=[],Z=[],Q=[];for(let z of $.split(`
|
|
7546
7546
|
`)){let U=z.trim();if(U.startsWith("PORT=")){let[H="",X="",K=""]=U.slice(5).split("\t");if(H&&X)J.push({proto:H,listen:X,processName:K||L1,exposure:FK(X),tone:iD(X)})}else if(U.startsWith("FIREWALL=")){let H=U.slice(9).trim();if(H)Y.push(H)}else if(U.startsWith("AUTH=")){let H=U.slice(5),X=/^(\d{4}-\d{2}-\d{2}T[^\s]+)\s+(\S+)\s+(.*)$/.exec(H),K=(X?.[3]??H).trim();if(K)Z.push({timestamp:X?.[1]??"",when:X?.[1]?iG(X[1]):L1,host:X?.[2]??"",message:K,level:HK(K)})}else if(U.startsWith("CERT=")){let[H="",X=""]=U.slice(5).split("\t");if(!H)continue;let K=new Date(X),B=Number.isNaN(K.getTime())?null:Math.ceil((K.getTime()-Date.now())/86400000);Q.push({domain:H,expires:Number.isNaN(K.getTime())?X||L1:K.toISOString().slice(0,10),daysRemaining:B,status:aD(B)})}}let G=Y.some((z)=>/Status:\s*active/i.test(z)),W=Y.some((z)=>/unavailable/i.test(z));return{ports:J.slice(0,80),firewall:{status:G?"active":W?"unavailable":"inactive",summary:G?"ufw active":W?"ufw unavailable":"ufw inactive or not configured",rules:Y.filter((z)=>z&&!/^Status:/i.test(z)).slice(0,60)},tlsCertificates:Q,authEvents:Z.sort((z,U)=>String(U.timestamp).localeCompare(String(z.timestamp))).slice(0,30)}}function aG($){let Y=$.infrastructure?.compute?.firewall??{},Z=[...new Set([22,80,443,...Y.allowedPorts??[]])],Q=zK($);return{ports:Z.map((G)=>({proto:"tcp",listen:`0.0.0.0:${G}`,processName:"configured firewall",exposure:"public",tone:[22,80,443].includes(Number(G))?"ok":"warn"})),firewall:{status:Y.enabled===!1?"disabled":"configured",summary:Y.enabled===!1?"host firewall disabled in config":"host firewall configured declaratively",rules:Z.map((G)=>`ALLOW ${G}/tcp`)},tlsCertificates:Q.map((G)=>({domain:G,expires:L1,daysRemaining:null,status:"warn"})),authEvents:[]}}function BK($,J){let Y=J.security??aG($),Z=!!J._serverReachable&&!J.metricsUnavailable,Q=J.sites??[],G=Q.filter((H)=>H.status==="shadowed"),W=(J.services??[]).filter((H)=>["failed","stopped"].includes(H.status)),z=(Y.tlsCertificates??[]).filter((H)=>H.status!=="ok"),U=J.sshKeys??[];return[{name:"Live server probe",status:Z?"pass":"warn",detail:Z?"Metrics and remote checks are coming from the compute box.":"The dashboard is rendering config/state data until the box probe succeeds."},{name:"Managed services",status:W.length?"fail":"pass",detail:W.length?`${W.length} service(s) need attention.`:`${(J.services??[]).length} service(s) reported healthy or configured.`},{name:"Route conflicts",status:G.length?"warn":"pass",detail:G.length?`${G.map((H)=>H.name).join(", ")} is shadowed by an earlier route.`:`${Q.length} site route(s) are unshadowed.`},{name:"SSH access",status:U.length?"pass":"warn",detail:U.length?`${U.length} declarative authorized key(s) configured.`:"No declarative SSH keys are configured."},{name:"Firewall",status:["active","configured"].includes(Y.firewall?.status)?"pass":"warn",detail:Y.firewall?.summary??"Firewall status unavailable."},{name:"TLS certificates",status:z.length?"warn":"pass",detail:z.length?`${z.length} certificate(s) need renewal visibility.`:`${(Y.tlsCertificates??[]).length} certificate(s) look healthy.`}]}function VK($){let J=[];for(let Y of $.serverDeploymentsDetail??$.serverDeployments??[])J.push({type:"deploy",tone:Y.status==="failed"?"bad":"ok",title:`${Y.site} deployed ${Y.sha}`,detail:`${Y.branch} · ${Y.status}`,when:Y.when,timestamp:Y.timestamp});for(let Y of $.serverLogs??[])if(Y.level==="error"||Y.level==="warn")J.push({type:"log",tone:Y.level==="error"?"bad":"warn",title:`${Y.source} ${Y.level}`,detail:Y.message,when:Y.when,timestamp:Y.timestamp});for(let Y of $.sshKeys??[])J.push({type:"ssh",tone:"ok",title:`${Y.name} authorized`,detail:Y.fingerprint,when:Y.added??L1,timestamp:""});return J.sort((Y,Z)=>String(Z.timestamp).localeCompare(String(Y.timestamp))).slice(0,80)}function OK($,J={}){let Y=[];for(let Z of $.split(`
|
|
7547
7547
|
`)){let Q=Z.trim();if(!Q.startsWith("DEPLOY="))continue;let G=Q.split("\t"),W=G[0]?.replace(/^DEPLOY=/,"")??"",[z,U,H,X,K]=G.slice(1);if(!W||!z||!U)continue;let B=J[W]??{},V=n0(B),O=(H||U).slice(0,7);Y.push({sha:O,release:U,commit:H||U,site:W,branch:B.branch??(V==="server-static"?"build artifact":"main"),status:X||"unknown",when:iG(z),timestamp:z,took:"-",by:"ts-cloud",rc:K?.replace(/^rc=/,"")??"",steps:V==="server-static"?["upload artifact","publish static files"]:["upload artifact","restart service"]})}return Y.sort((Z,Q)=>String(Q.timestamp).localeCompare(String(Z.timestamp)))}function AK($,J){let Y=gD($,J),Z=ZK($),Q=lD($),G=Math.max(1,Number($.infrastructure?.compute?.disk?.size??1)),W={server:{name:Y?.serverName??`${$.project.slug}-${J}-app`,provider:Y?.provider??QK($),region:fD($),ip:Y?.publicIp??L1,os:"Linux",uptime:L1,probeStatus:"unavailable"},systemMetrics:{load:0,cpus:Math.max(1,Number($.infrastructure?.compute?.instances??1)),memUsedMb:0,memTotalMb:0,diskUsedPct:0,diskUsedGb:0,diskTotalGb:G},metricsUnavailable:!0,services:Z,servicesDetail:Z.map((z)=>({...z,since:L1,memMb:0,auto:!0})),backup:vD($),backupHistory:[],workers:uD($),serverScheduler:{enabled:!1,lastRun:"not configured"},serverDeployments:[],serverDeploymentsDetail:[],deploymentsEmptyReason:"No deployment history has been recorded yet. Future server deploys will write /var/www/<site>/.ts-cloud/deploy-history.log.",serverLogs:[],serverLogsEmptyReason:"Live server logs are unavailable until the dashboard can reach the compute box.",security:aG($),securityEmptyReason:"Live security checks are unavailable until the dashboard can reach the compute box.",sites:Q,sitesDetail:Q.map((z)=>{let U=$.sites?.[z.name]??{},H=n0(U);return{...z,root:H==="server-static"?t1($.project.slug,z.name):`${t1($.project.slug,z.name)}/current`,branch:H==="server-static"?"build artifact":"main",build:U.build,php:U.php??U.phpVersion,aliases:Array.isArray(U.aliases)?U.aliases:[],redirects:U.redirects&&typeof U.redirects==="object"?U.redirects:{},envKeys:Object.keys(U.env??U.environment??{})}}),sshKeys:W$($.infrastructure?.compute?.sshKeys??[]),_serverReachable:!1,_metricsStatus:"unavailable"};return W.diagnostics=BK($,W),W.activity=VK(W),W}async function tG($,J){if(!$.infrastructure?.compute)return null;let Y=null;try{Y=o0({config:$})}catch{Y=null}let Z=null,Q=0,G=[];if(Y)try{if(G=await Y.findComputeTargets({slug:$.project.slug,environment:J,role:"app"}),Q=G.length,G.length){let X=(await Y.runRemoteDeploy({targets:[G[0]],commands:yD(),comment:`ts-cloud dashboard:build ${$.project.slug}`,tags:{Project:$.project.slug,Environment:J,Role:"app"}})).perInstance?.[0]?.output;if(X)Z=YK(X)}}catch{}let W=AK($,J),z=(H,X=0)=>{let K=Number(H);return Number.isFinite(K)?K:X};if(W.server.os=Z?.OS||W.server.os,W.server.uptime=Z?.UPTIME||W.server.uptime,Z){if(W.server.probeStatus="live",W.metricsUnavailable=!1,W._metricsStatus="live",W.systemMetrics={load:z(Z.LOAD),cpus:z(Z.CPUS,1),memUsedMb:z(Z.MEMUSED),memTotalMb:z(Z.MEMTOTAL,1),diskUsedPct:z(Z.DISKPCT),diskUsedGb:z(Z.DISKUSEDG),diskTotalGb:z(Z.DISKTOTG,1)},Z.services.length)W.services=Z.services.map((H)=>({name:H.name,status:H.status==="active"?"running":H.status})),W.servicesDetail=Z.services.map((H)=>({name:H.name,status:H.status==="active"?"running":H.status,since:H.since&&H.since!==L1?H.since:W.server.uptime,memMb:Math.max(0,Math.round(Number(H.memBytes??0)/1024/1024)),auto:H.enabled?!["disabled","static","masked"].includes(H.enabled):!0}))}if(Y&&G.length)try{let H=Object.keys($.sites??{}),K=(await Y.runRemoteDeploy({targets:[G[0]],commands:pD(H,$.project.slug),comment:`ts-cloud dashboard:deploy-history ${$.project.slug}`,tags:{Project:$.project.slug,Environment:J,Role:"app"}})).perInstance?.[0]?.output??"",B=OK(K,$.sites);W.serverDeployments=B.slice(0,5),W.serverDeploymentsDetail=B.slice(0,50),W.deploymentsEmptyReason=B.length?void 0:"No deployment history was found on the server yet. Deploy again to populate this timeline."}catch{W.deploymentsEmptyReason="Deployment history could not be read from the server."}else if(Y&&Q===0)W.deploymentsEmptyReason="No app server target was found for this environment.";if(Y&&G.length)try{let X=(await Y.runRemoteDeploy({targets:[G[0]],commands:nD($),comment:`ts-cloud dashboard:server-logs ${$.project.slug}`,tags:{Project:$.project.slug,Environment:J,Role:"app"}})).perInstance?.[0]?.output??"",K=XK(X);W.serverLogs=K,W.serverLogsEmptyReason=K.length?void 0:"No recent journal entries were found for the managed server units."}catch{W.serverLogsEmptyReason="Server logs could not be read from the box."}if(Y&&G.length)try{let X=(await Y.runRemoteDeploy({targets:[G[0]],commands:rD($),comment:`ts-cloud dashboard:security ${$.project.slug}`,tags:{Project:$.project.slug,Environment:J,Role:"app"}})).perInstance?.[0]?.output??"",K=KK(X),B=aG($);if(!K.ports.length)K.ports=B.ports;if(!K.tlsCertificates.length)K.tlsCertificates=B.tlsCertificates;W.security=K,W.securityEmptyReason=void 0}catch{W.securityEmptyReason="Server security checks could not be read from the box."}let U=$.infrastructure?.compute?.sshKeys??$.infrastructure?.ssh?.keys??$.infrastructure?.sshKeys;if(Array.isArray(U)&&U.length)W.sshKeys=W$(U);return W._serverReachable=Q>0&&!!Z,W.diagnostics=BK($,W),W.activity=VK(W),W}var bD,L1="-";var sG=Y0(async()=>{H5();I5();await u2([I$(),G$()]);bD=["rpx-gateway","nginx","php8.3-fpm","php8.2-fpm","mysql","mariadb","postgresql","redis","redis-server","meilisearch"]});import{existsSync as pB}from"node:fs";import r5 from"node:fs/promises";import iW from"node:os";import n5 from"node:path";import K$ from"node:process";import{EventEmitter as rB}from"node:events";import d2 from"node:process";import aW from"node:process";import s5 from"node:process";import B6 from"node:process";import d8 from"node:process";import oW from"node:tty";import kV,{stdin as WP,stdout as zP}from"node:process";import $4,{stdin as yV,stdout as vV}from"node:process";import fV from"node:readline";class Y4{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let $=iW.homedir(),J=n5.join($,".config","clapp");this.configPath=n5.join(J,"telemetry.json")}async isEnabled(){if(K$.env.DO_NOT_TRACK==="1"||K$.env.DO_NOT_TRACK==="true")return!1;if(K$.env.NO_TELEMETRY==="1"||K$.env.NO_TELEMETRY==="true")return!1;return(await this.loadConfig()).enabled}async enable(){let $=await this.loadConfig();if($.enabled=!0,!$.userId)$.userId=this.generateUserId();await this.saveConfig($)}async disable(){let $=await this.loadConfig();$.enabled=!1,await this.saveConfig($)}async track($,J){if(!await this.isEnabled())return;let Z={event:$,...J,timestamp:Date.now(),platform:iW.platform(),nodeVersion:K$.version};if(this.events.push(Z),this.events.length>=10)await this.send()}async trackCommand($,J){await this.track("command",{command:$,duration:J})}async trackError($,J){await this.track("error",{error:$,command:J})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let J=await this.loadConfig();return J.lastSent=Date.now(),await this.saveConfig(J),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let J=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(J),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep($){return new Promise((J)=>setTimeout(J,$))}async status(){let $=await this.loadConfig();return{enabled:$.enabled,doNotTrack:K$.env.DO_NOT_TRACK==="1"||K$.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:$.lastSent}}async loadConfig(){if(this.config)return this.config;try{if(pB(this.configPath)){let $=await r5.readFile(this.configPath,"utf-8");return this.config=JSON.parse($),this.config}}catch{}return this.config={enabled:!1},this.config}async saveConfig($){this.config=$;try{let J=n5.dirname(this.configPath);await r5.mkdir(J,{recursive:!0}),await r5.writeFile(this.configPath,JSON.stringify($,null,2),"utf-8")}catch{}}generateUserId(){let $=Math.random().toString(36).substring(2,15),J=Date.now().toString(36);return`${$}-${J}`}}var iN=new Y4;function nB($,J={}){let Y={_:[]},Z=J.alias||{},Q=new Set(J.boolean||[]),G={};for(let z of Object.keys(Z))for(let U of Z[z])G[U]=z;for(let z of Q)if(Z[z])for(let U of Z[z])Q.add(U);function W(z,U){let H=G[z]||z;if(Y[H]=U,Z[H])for(let X of Z[H])Y[X]=U;if(G[z]&&Z[G[z]])for(let X of Z[G[z]])Y[X]=U;Y[z]=U}for(let z=0;z<$.length;z++){let U=$[z];if(U==="--"){Y._.push(...$.slice(z+1));break}if(U.startsWith("--")){let H=U.indexOf("=");if(H!==-1){let X=U.slice(2,H),K=U.slice(H+1);W(X,K)}else{let X=U.slice(2);if(X.startsWith("no-")){let B=X.slice(3);W(B,!1);continue}let K=G[X]||X;if(Q.has(K)||Q.has(X))W(X,!0);else{let B=$[z+1];if(B!==void 0&&!B.startsWith("-"))W(X,B),z++;else W(X,!0)}}}else if(U.startsWith("-")&&U.length>1){let H=U.slice(1);for(let X=0;X<H.length;X++){let K=H[X],B=G[K]||K;if(X===H.length-1&&!Q.has(B)&&!Q.has(K)){let V=$[z+1];if(V!==void 0&&!V.startsWith("-"))W(K,V),z++;else W(K,!0)}else W(K,!0)}}else Y._.push(U)}return Y}function t5($){return $.replace(/[<[].+/,"").trim()}function iB($){let J=/<([^>]+)>/g,Y=/\[([^\]]+)\]/g,Z=[],Q=(z)=>{let U=!1,H=z[1];if(H.startsWith("..."))H=H.slice(3),U=!0;return{required:z[0].startsWith("<"),value:H,variadic:U}},G;while(G=J.exec($))Z.push(Q(G));let W;while(W=Y.exec($))Z.push(Q(W));return Z}function aB($){let J={alias:{},boolean:[]};for(let[Y,Z]of $.entries()){if(Z.names.length>1)J.alias[Z.names[0]]=Z.names.slice(1);if(Z.isBoolean)if(Z.negated){if(!$.some((G,W)=>{return W!==Y&&G.names.some((z)=>Z.names.includes(z))&&typeof G.required==="boolean"}))J.boolean.push(Z.names[0])}else J.boolean.push(Z.names[0])}return J}function tW($){return $.reduce((J,Y)=>J.length>=Y.length?J:Y,"")}function i5($,J){return $.length>=J?$:`${$}${" ".repeat(J-$.length)}`}function tB($){return $.replace(/([a-z])-([a-z])/g,(J,Y,Z)=>{return Y+Z.toUpperCase()})}function sB($,J,Y){let Z=0,Q=J.length,G=$,W;for(;Z<Q;++Z)W=G[J[Z]],G=G[J[Z]]=Z===Q-1?Y:W!=null?W:!!~J[Z+1].indexOf(".")||!(+J[Z+1]>-1)?{}:[]}function oB($,J){for(let Y of Object.keys(J)){let Z=J[Y];if(Z.shouldTransform){if($[Y]=Array.prototype.concat.call([],$[Y]),typeof Z.transformFunction==="function")$[Y]=$[Y].map(Z.transformFunction)}}}function eB($){let J=/([^\\/]+)$/.exec($);return J?J[1]:""}function Z4($){return $.split(".").map((J,Y)=>{return Y===0?tB(J):J}).join(".")}class K6 extends Error{exitCode=2;isUsageError=!0;constructor($){super($);if(this.name=this.constructor.name,typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error($).stack}format($=!1){if($&&this.stack)return`${this.message}
|
|
@@ -7582,7 +7582,7 @@ Run \`${this.name??"cli"} --help\` for usage.`;d2.stderr.write(`${G}${Q}${W}
|
|
|
7582
7582
|
`).length-1;this.output.write(M2.move(-999,$*-1))}render(){let $=J4(this._render(this)??"",$4.stdout.columns,{hard:!0,trim:!1});if($===this._prevFrame)return;if(this.state==="initial")this.output.write(M2.hide);else{let J=bV(this._prevFrame,$);if(this.restoreCursor(),J&&J?.length===1){let Y=J[0];this.output.write(M2.move(0,Y)),this.output.write(a5.lines(1));let Z=$.split(`
|
|
7583
7583
|
`);this.output.write(Z[Y]),this._prevFrame=$,this.output.write(M2.move(0,Z.length-Y-1));return}if(J&&J?.length>1){let Y=J[0];this.output.write(M2.move(0,Y)),this.output.write(a5.down());let Q=$.split(`
|
|
7584
7584
|
`).slice(Y);this.output.write(Q.join(`
|
|
7585
|
-
`)),this._prevFrame=$;return}this.output.write(a5.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function dV($,J){if($===void 0)return 0;if(J.length===0)return 0;let Z=J.findIndex((Q)=>Q.value===$);return Z!==-1?Z:0}function cV($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function mV($,J){if(!J)return;if($)return J;return J[0]}class lV extends JJ{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Z;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return V6.inverse(V6.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`${$}${V6.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.#Z=$.filter??cV;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 Z of Y){let Q=J.findIndex((G)=>G.value===Z);if(Q!==-1)this.toggleSelected(Z),this.#$=Q}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Z,Q)=>this.#Q(Z,Q)),this.on("userInput",(Z)=>this.#G(Z))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#Q($,J){let Y=J.name==="up",Z=J.name==="down",Q=J.name==="return";if(Y||Z){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(Q)this.value=mV(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=[$]}#G($){if($!==this.#Y){this.#Y=$;let J=this.options;if($)this.filteredOptions=J.filter((Y)=>this.#Z($,Y));else this.filteredOptions=[...J];if(this.#$=dV(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 pV 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((Z)=>Y.includes(Z.value))}toggleValue(){let $=this.options[this.cursor];if(this.value===void 0)this.value=[];if($.group===!0){let J=String($.value),Y=this.getGroupItems(J);if(this.isGroupSelected(J))this.value=this.value.filter((Z)=>Y.findIndex((Q)=>Q.value===Z)===-1);else this.value=[...this.value,...Y.map((Z)=>Z.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,Z])=>[{value:Y,group:!0,label:Y},...Z.map((Q)=>({...Q,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 Z=this.options[this.cursor]?.group===!0;if(!this.#$&&Z)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 Z=this.options[this.cursor]?.group===!0;if(!this.#$&&Z)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var rV=$V();var P0=($,J)=>rV?$:J,FP=P0("◆","*"),KP=P0("■","x"),BP=P0("▲","x"),VP=P0("◇","o"),OP=P0("┌","T"),nV=P0("│","|"),AP=P0("└","—"),_P=P0("●",">"),jP=P0("○"," "),LP=P0("◻","[•]"),MP=P0("◼","[+]"),EP=P0("◻","[ ]"),qP=P0("▪","•"),TP=P0("─","-"),RP=P0("╮","+"),DP=P0("├","+"),wP=P0("╯","+"),NP=P0("●","•"),PP=P0("◆","*"),SP=P0("▲","!"),CP=P0("■","x");var xP={light:P0("─","-"),heavy:P0("━","="),block:P0("█","#")};function iV(){return`${V6.gray(nV)} `}var IP=iV();var YJ="0.7.
|
|
7585
|
+
`)),this._prevFrame=$;return}this.output.write(a5.down())}if(this.output.write($),this.state==="initial")this.state="active";this._prevFrame=$}}function dV($,J){if($===void 0)return 0;if(J.length===0)return 0;let Z=J.findIndex((Q)=>Q.value===$);return Z!==-1?Z:0}function cV($,J){return(J.label??String(J.value)).toLowerCase().includes($.toLowerCase())}function mV($,J){if(!J)return;if($)return J;return J[0]}class lV extends JJ{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#$=0;#Y="";#Z;#J;get cursor(){return this.#$}get userInputWithCursor(){if(!this.userInput)return V6.inverse(V6.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`${$}${V6.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.#Z=$.filter??cV;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 Z of Y){let Q=J.findIndex((G)=>G.value===Z);if(Q!==-1)this.toggleSelected(Z),this.#$=Q}this.focusedValue=this.options[this.#$]?.value,this.on("key",(Z,Q)=>this.#Q(Z,Q)),this.on("userInput",(Z)=>this.#G(Z))}_isActionKey($,J){return $==="\t"||this.multiple&&this.isNavigating&&J.name==="space"&&$!==void 0&&$!==""}#Q($,J){let Y=J.name==="up",Z=J.name==="down",Q=J.name==="return";if(Y||Z){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(Q)this.value=mV(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=[$]}#G($){if($!==this.#Y){this.#Y=$;let J=this.options;if($)this.filteredOptions=J.filter((Y)=>this.#Z($,Y));else this.filteredOptions=[...J];if(this.#$=dV(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 pV 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((Z)=>Y.includes(Z.value))}toggleValue(){let $=this.options[this.cursor];if(this.value===void 0)this.value=[];if($.group===!0){let J=String($.value),Y=this.getGroupItems(J);if(this.isGroupSelected(J))this.value=this.value.filter((Z)=>Y.findIndex((Q)=>Q.value===Z)===-1);else this.value=[...this.value,...Y.map((Z)=>Z.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,Z])=>[{value:Y,group:!0,label:Y},...Z.map((Q)=>({...Q,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 Z=this.options[this.cursor]?.group===!0;if(!this.#$&&Z)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 Z=this.options[this.cursor]?.group===!0;if(!this.#$&&Z)this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}case"space":this.toggleValue();break}})}}var rV=$V();var P0=($,J)=>rV?$:J,FP=P0("◆","*"),KP=P0("■","x"),BP=P0("▲","x"),VP=P0("◇","o"),OP=P0("┌","T"),nV=P0("│","|"),AP=P0("└","—"),_P=P0("●",">"),jP=P0("○"," "),LP=P0("◻","[•]"),MP=P0("◼","[+]"),EP=P0("◻","[ ]"),qP=P0("▪","•"),TP=P0("─","-"),RP=P0("╮","+"),DP=P0("├","+"),wP=P0("╯","+"),NP=P0("●","•"),PP=P0("◆","*"),SP=P0("▲","!"),CP=P0("■","x");var xP={light:P0("─","-"),heavy:P0("━","="),block:P0("█","#")};function iV(){return`${V6.gray(nV)} `}var IP=iV();var YJ="0.7.28";F0();import{existsSync as KJ}from"node:fs";import{mkdir as GO,writeFile as L4}from"node:fs/promises";function BJ($){$.command("init","Initialize a new ts-cloud project").option("--mode <mode>","Deployment mode: server or serverless").option("--name <name>","Project name").option("--region <region>","AWS Region").action(async(J)=>{if(D("Initializing ts-cloud Project"),KJ("cloud.config.ts")){if(!await p("cloud.config.ts already exists. Overwrite?",!1)){F("Initialization cancelled");return}}let Y=J?.name||await D0("Project name","my-app"),Z=J?.mode||await _6("Select deployment mode",["serverless","server"]),Q=J?.region||await _6("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),G=new P("Creating configuration file...");G.start();let W=`import { defineConfig } from '@ts-cloud/core'
|
|
7586
7586
|
|
|
7587
7587
|
export default defineConfig({
|
|
7588
7588
|
project: {
|